From ba003fc01510e34643b87253d494ab613ad59eb3 Mon Sep 17 00:00:00 2001 From: Vignesh Hari Date: Mon, 15 Jan 2018 23:49:39 +0530 Subject: [PATCH 01/98] Changed Base --- .idea/competitive_programming.iml | 11 + .../inspectionProfiles/profiles_settings.xml | 7 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/workspace.xml | 1042 + .../1_Simple_Prime_Numbers.py | 62 + Code_It_Out_Questions/2_Free_Chocolates.py | 75 + Code_It_Out_Questions/3_Turn_Game.py | 52 + Code_It_Out_Questions/4_Destroy_Bacteria.py | 66 + Code_It_Out_Questions/5_Motu's_Plants.py | 120 + Code_It_Out_Questions/6_Demonetisation.py | 68 + Code_It_Out_Questions/7_Buildings.py | 33 + Code_It_Out_Questions/Other Files/Email.py | 75 + Code_It_Out_Questions/Other Files/at.csv | 228 + Code_It_Out_Questions/Other Files/test.py | 72 + .../Other_Solutions_Untested/C/1.C | 41 + .../Other_Solutions_Untested/C/2.C | 53 + .../Other_Solutions_Untested/C/3.C | 20 + .../Other_Solutions_Untested/C/4.C | 21 + .../Other_Solutions_Untested/C/5.C | 56 + .../Other_Solutions_Untested/C/6.C | 30 + .../Other_Solutions_Untested/C/7.C | 24 + .../Other_Solutions_Untested/CPP/1.cpp | 41 + .../Other_Solutions_Untested/CPP/2.CPP | 42 + .../Other_Solutions_Untested/CPP/3.cpp | 22 + .../Other_Solutions_Untested/CPP/4.cpp | 23 + .../Other_Solutions_Untested/CPP/5.CPP | 58 + .../Other_Solutions_Untested/CPP/6.CPP | 31 + .../Other_Solutions_Untested/CPP/7.cpp | 24 + .../Other_Solutions_Untested/Georgy/Q7.c | 24 + .../Other_Solutions_Untested/Georgy/Q7.cpp | 24 + .../Java Solutions/1.java | 38 + .../Mathew/1_Simple_Prime_Numbers.py | 62 + .../Mathew/2_Free_Chocolates.py | 71 + .../Mathew/3_Turn_Game.py | 55 + .../Mathew/4_Destroy_Bacteria.py | 63 + .../Mathew/5_Motu's_Plants.py | 120 + .../Mathew/6_Demonetisation.py | 65 + .../Other_Solutions_Untested/Mathew/Q1.cpp | 36 + .../Other_Solutions_Untested/Mathew/Q2.BAK | 37 + .../Other_Solutions_Untested/Mathew/Q2.C | 34 + .../Mathew/Q2.C-issues.txt | 1 + .../Other_Solutions_Untested/Mathew/Q2.CPP | 36 + .../Mathew/Q2.CPP-issues.txt | 1 + .../Other_Solutions_Untested/Mathew/Q3.BAK | 18 + .../Other_Solutions_Untested/Mathew/Q3.CPP | 15 + .../Other_Solutions_Untested/Mathew/Q4.BAK | 27 + .../Other_Solutions_Untested/Mathew/Q4.CPP | 27 + .../Other_Solutions_Untested/Mathew/Q5.C | 56 + .../Other_Solutions_Untested/Mathew/Q5.CPP | 60 + .../Other_Solutions_Untested/Mathew/Q6.BAK | 33 + .../Other_Solutions_Untested/Mathew/Q6.CPP | 33 + .../Other_Solutions_Untested/Mathew/Q6.py | 17 + .../Other_Solutions_Untested/melbin/5.cpp | 47 + Code_It_Out_Questions/README.md | 4 + .../Test_Cases/Test_Case_Q1/1 | 101 + .../Test_Cases/Test_Case_Q1/1_O | 0 .../Test_Cases/Test_Case_Q1/2 | 201 + .../Test_Cases/Test_Case_Q1/2_O | 0 .../Test_Cases/Test_Case_Q1/3 | 201 + .../Test_Cases/Test_Case_Q1/3_O | 0 .../Test_Cases/Test_Case_Q1/4 | 10001 + .../Test_Cases/Test_Case_Q1/4_O | 0 .../Test_Cases/Test_Case_Q1/5 | 72813 ++++++ .../Test_Cases/Test_Case_Q1/5_O | 0 .../Test_Cases/Test_Case_Q1/TestCase_Maker.py | 46 + .../Test_Cases/Test_Case_Q2/1 | 1009 + .../Test_Cases/Test_Case_Q2/1_O | 0 .../Test_Cases/Test_Case_Q2/2 | 1501 + .../Test_Cases/Test_Case_Q2/2_O | 0 .../Test_Cases/Test_Case_Q2/3 | 5001 + .../Test_Cases/Test_Case_Q2/3_O | 0 .../Test_Cases/Test_Case_Q2/4 | 13007 ++ .../Test_Cases/Test_Case_Q2/4_O | 0 .../Test_Cases/Test_Case_Q2/5 | 10001 + .../Test_Cases/Test_Case_Q2/5_O | 0 .../Test_Cases/Test_Case_Q2/TestCase_Maker.py | 57 + .../Test_Cases/Test_Case_Q3/1 | 101 + .../Test_Cases/Test_Case_Q3/1_O | 0 .../Test_Cases/Test_Case_Q3/2 | 501 + .../Test_Cases/Test_Case_Q3/2_O | 0 .../Test_Cases/Test_Case_Q3/3 | 1001 + .../Test_Cases/Test_Case_Q3/3_O | 0 .../Test_Cases/Test_Case_Q3/4 | 5001 + .../Test_Cases/Test_Case_Q3/4_O | 0 .../Test_Cases/Test_Case_Q3/5 | 10001 + .../Test_Cases/Test_Case_Q3/5_O | 0 .../Test_Cases/Test_Case_Q3/TestCase_Maker.py | 57 + .../Test_Cases/Test_Case_Q4/1 | 1001 + .../Test_Cases/Test_Case_Q4/1_O | 0 .../Test_Cases/Test_Case_Q4/2 | 1501 + .../Test_Cases/Test_Case_Q4/2_O | 0 .../Test_Cases/Test_Case_Q4/3 | 5001 + .../Test_Cases/Test_Case_Q4/3_O | 0 .../Test_Cases/Test_Case_Q4/4 | 10001 + .../Test_Cases/Test_Case_Q4/4_O | 0 .../Test_Cases/Test_Case_Q4/5 | 10001 + .../Test_Cases/Test_Case_Q4/5_O | 0 .../Test_Cases/Test_Case_Q4/TestCase_Maker.py | 57 + .../Test_Cases/Test_Case_Q5/1 | 1 + .../Test_Cases/Test_Case_Q5/1_O | 1 + .../Test_Cases/Test_Case_Q5/2 | 1 + .../Test_Cases/Test_Case_Q5/2_O | 1 + .../Test_Cases/Test_Case_Q5/3 | 1 + .../Test_Cases/Test_Case_Q5/3_O | 1 + .../Test_Cases/Test_Case_Q5/4 | 1 + .../Test_Cases/Test_Case_Q5/4_O | 1 + .../Test_Cases/Test_Case_Q5/5 | 1 + .../Test_Cases/Test_Case_Q5/5_O | 1 + .../Test_Cases/Test_Case_Q6/1 | 2 + .../Test_Cases/Test_Case_Q6/1_O | 1 + .../Test_Cases/Test_Case_Q6/2 | 2 + .../Test_Cases/Test_Case_Q6/2_O | 1 + .../Test_Cases/Test_Case_Q6/3 | 2 + .../Test_Cases/Test_Case_Q6/3_O | 1 + .../Test_Cases/Test_Case_Q6/4 | 2 + .../Test_Cases/Test_Case_Q6/4_O | 1 + .../Test_Cases/Test_Case_Q6/5 | 2 + .../Test_Cases/Test_Case_Q6/5_O | 1 + .../Test_Cases/Test_Case_Q7/1 | 2 + .../Test_Cases/Test_Case_Q7/2 | 2 + .../Test_Cases/Test_Case_Q7/3 | 2 + .../Test_Cases/Test_Case_Q7/4 | 2 + .../Test_Cases/Test_Case_Q7/5 | 2 + .../Test_Case_Q7/Testcase_Generator.py | 35 + Extras/1.py | 20 + Extras/2.py | 36 + Extras/3.py | 40 + Extras/4.py | 15 + Extras/5.py | 21 + Extras/test.py | 24 + Hacker_Earth_Learning/find_coprime.py | 15 + Hacker_Earth_Learning/football_test_stack.py | 17 + Hacker_Earth_Learning/prime_string.py | 84 + Hacker_Earth_Learning/save_girlfriend.py | 25 + Hacker_Earth_Learning/signal_range_stack.py | 15 + Hacker_Earth_Study/Graph_Theory/check_tree.py | 40 + .../Graph_Theory/learning_graph.py | 53 + Iem_delete.py | 8 + LLTN_iem_16.py | 30 + Level1_1_1_Foobar.py | 7 + Level1_1_Foo.py | 18 + Level2_2_Foo.py | 63 + Level2_3_Foo.py | 18 + Level3_1_Foo.py | 23 + Level3_2_Foo.py | 13 + Level3_3_Foo.py | 44 + Level4_1_Foo.py | 76 + Level4_2.py | 65 + November_easy_hackerearth/divisible_trio.py | 13 + November_easy_hackerearth/funny_sub_array.py | 21 + November_easy_hackerearth/max_inser.py | 16 + README.md | 2 + Select_city.py | 40 + Sieve_prime_Check.py | 30 + .../.aesthetic_building.py.swp | Bin 0 -> 12288 bytes .../aesthetic_building.py | 23 + Tcs_CodeVita_2017_Round2/antidote.py | 174 + Tcs_CodeVita_2017_Round2/enclosing_items.py | 30 + Tcs_CodeVita_2017_Round2/photograph.py | 33 + Xtreme/Jarawi and The Interview.py | 22 + Xtreme/batbear.py | 45 + Xtreme/beetlebag.py | 40 + Xtreme/cheering_up_bob.py | 36 + Xtreme/circular_disk.py | 21 + Xtreme/dr.fibonacci.py | 9 + Xtreme/factorial.py | 6 + Xtreme/fast_and_curious.py | 73 + Xtreme/odd_paths.py | 40 + Xtreme/pre1.py | 37 + Xtreme/quipu func.py | 15 + Xtreme/rexor.py | 48 + Xtreme/steps.py | 9 + Xtreme/tree.py | 20 + Xtreme/xor.py | 13 + Xtreme/xtreme_study.py | 30 + abel.py | 31 + appendanddelete.py | 26 + brick_count.py | 42 + choco_hr.py | 5 + comp1.py | 0 consecletter.py | 12 + die_iem_16.py | 3 + distict.py | 15 + foobar2.py | 87 + formula.py | 0 gift_friends.py | 18 + google/lead.py | 22 + google/rain.py | 23 + ict1.py | 9 + ict2.py | 12 + ieee_dog_walk.py | 19 + ieee_food_truck.py | 29 + ieee_full_adder.py | 49 + ieee_password.py | 17 + ieee_petals.py | 10 + ieee_prime.py | 17 + ieee_stone.py | 14 + lambs.py | 36 + luggage.py | 15 + max_val.py | 33 + merger.py | 18 + misc.py | 21 + monk_in_grass.py | 43 + monk_palindrome.py | 15 + monk_welcome_problem.py | 4 + myst_maze.py | 49 + navendu.py | 7 + pretty_print.py | 34 + primer.py | 16 + pytudes/LICENSE | 21 + pytudes/README.md | 75 + pytudes/data/advent2016/input1.txt | 1 + pytudes/data/advent2016/input10.txt | 231 + pytudes/data/advent2016/input12.txt | 23 + pytudes/data/advent2016/input2.txt | 5 + pytudes/data/advent2016/input20.txt | 1176 + pytudes/data/advent2016/input21.txt | 100 + pytudes/data/advent2016/input22.txt | 914 + pytudes/data/advent2016/input24.txt | 39 + pytudes/data/advent2016/input3.txt | 1908 + pytudes/data/advent2016/input4.txt | 980 + pytudes/data/advent2016/input6.txt | 598 + pytudes/data/advent2016/input7.txt | 2000 + pytudes/data/advent2016/input8.txt | 194 + pytudes/data/advent2016/input9.txt | 1 + pytudes/data/advent2017/input1.txt | 1 + pytudes/data/advent2017/input11.txt | 1 + pytudes/data/advent2017/input12.txt | 2000 + pytudes/data/advent2017/input13.txt | 43 + pytudes/data/advent2017/input16.txt | 1 + pytudes/data/advent2017/input18.txt | 41 + pytudes/data/advent2017/input19.txt | 201 + pytudes/data/advent2017/input20.txt | 1000 + pytudes/data/advent2017/input4.txt | 512 + pytudes/data/advent2017/input5.txt | 1074 + pytudes/data/advent2017/input7.txt | 1337 + pytudes/data/advent2017/input8.txt | 1000 + pytudes/data/advent2017/input9.txt | 1 + .../Advent 2017-checkpoint.ipynb | 3667 + pytudes/ipynb/Advent 2017.ipynb | 3667 + pytudes/ipynb/Advent of Code.ipynb | 3226 + pytudes/ipynb/BASIC.ipynb | 1957 + pytudes/ipynb/Beal.ipynb | 1070 + pytudes/ipynb/Bike Speed versus Grade.ipynb | 184 + pytudes/ipynb/Cheryl-and-Eve.ipynb | 1202 + pytudes/ipynb/Cheryl.ipynb | 504 + pytudes/ipynb/Coin Flip.ipynb | 1191 + pytudes/ipynb/Convex Hull.ipynb | 2039 + pytudes/ipynb/Countdown.ipynb | 2867 + pytudes/ipynb/Differentiation.ipynb | 1392 + pytudes/ipynb/Economics.ipynb | 1500 + pytudes/ipynb/Fred Buns.ipynb | 1475 + pytudes/ipynb/Gesture Typing.ipynb | 2111 + pytudes/ipynb/Ghost.ipynb | 1231 + pytudes/ipynb/Golomb-Puzzle.ipynb | 1326 + pytudes/ipynb/How To Count Things.ipynb | 1196 + .../ipynb/How to Do Things with Words.ipynb | 2307 + pytudes/ipynb/Life.ipynb | 836 + pytudes/ipynb/Mean Misanthrope Density.ipynb | 1075 + pytudes/ipynb/Palindrome.ipynb | 534 + pytudes/ipynb/Probability.ipynb | 3322 + pytudes/ipynb/ProbabilityParadox.ipynb | 3102 + pytudes/ipynb/Project Euler Utils.ipynb | 1011 + pytudes/ipynb/PropositionalLogic.ipynb | 483 + pytudes/ipynb/Riddler Battle Royale.ipynb | 868 + pytudes/ipynb/SET.ipynb | 697 + pytudes/ipynb/Scrabble.ipynb | 13389 ++ pytudes/ipynb/Sicherman Dice.ipynb | 2087 + pytudes/ipynb/Sierpinski.ipynb | 335 + pytudes/ipynb/Snobol.ipynb | 276 + pytudes/ipynb/Sudoku IPython Notebook.ipynb | 1275 + pytudes/ipynb/TSP.ipynb | 4651 + pytudes/ipynb/WWW.ipynb | 871 + pytudes/ipynb/dist-climb-time.csv | 1 + pytudes/ipynb/enable1.txt | 172820 +++++++++++++++ pytudes/ipynb/money.png | Bin 0 -> 17886 bytes pytudes/ipynb/pal3.ipynb | 559 + pytudes/ipynb/xkcd1313-part2.ipynb | 3706 + pytudes/ipynb/xkcd1313.ipynb | 1220 + pytudes/ipynb/xkxd-part3.ipynb | 428 + pytudes/py/SET.py | 134 + pytudes/py/beal.py | 159 + pytudes/py/docex.py | 238 + pytudes/py/ibol.py | 193 + pytudes/py/lettercount.py | 443 + pytudes/py/lis.py | 145 + pytudes/py/lispy.py | 318 + pytudes/py/lispytest.py | 121 + pytudes/py/pal.py | 154 + pytudes/py/pal2.py | 262 + pytudes/py/pal3.py | 170 + pytudes/py/parse.py | 52 + pytudes/py/py2html.py | 110 + pytudes/py/spell.py | 106 + pytudes/py/sudoku-easy50.txt | 50 + pytudes/py/sudoku-hardest.txt | 11 + pytudes/py/sudoku-top95.txt | 95 + pytudes/py/sudoku.py | 161 + pytudes/py/testaccum.py | 73 + pytudes/py/yaptu.py | 170 + pytudes/requirements.txt | 1 + quantum.py | 28 + quest.py | 11 + rabbit_maze.py | 66 + reverse.py | 3 + reverse_sort.py | 11 + round2/1.py | 28 + round2/2.py | 17 + round2/3.py | 25 + round2/4.py | 24 + soldier.py | 23 + string_uppercase.py | 5 + tcs 2016/arr].py | 13 + tcs 2016/atoms.py | 23 + tcs 2016/iter.py | 17 + tcs 2016/mango.py | 22 + tcs 2016/prime.py | 13 + tcs 2016/tcs1.py | 16 + tcs 2016/tcs2.py | 41 + test.py | 20 + testingf.py | 9 + tree.py | 29 + 323 files changed, 430759 insertions(+) create mode 100644 .idea/competitive_programming.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/workspace.xml create mode 100644 Code_It_Out_Questions/1_Simple_Prime_Numbers.py create mode 100644 Code_It_Out_Questions/2_Free_Chocolates.py create mode 100644 Code_It_Out_Questions/3_Turn_Game.py create mode 100644 Code_It_Out_Questions/4_Destroy_Bacteria.py create mode 100644 Code_It_Out_Questions/5_Motu's_Plants.py create mode 100644 Code_It_Out_Questions/6_Demonetisation.py create mode 100644 Code_It_Out_Questions/7_Buildings.py create mode 100644 Code_It_Out_Questions/Other Files/Email.py create mode 100644 Code_It_Out_Questions/Other Files/at.csv create mode 100644 Code_It_Out_Questions/Other Files/test.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/1.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/2.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/3.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/4.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/5.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/6.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/C/7.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/1.cpp create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/2.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/3.cpp create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/4.cpp create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/5.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/6.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/CPP/7.cpp create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Georgy/Q7.c create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Georgy/Q7.cpp create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Java Solutions/1.java create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/1_Simple_Prime_Numbers.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/2_Free_Chocolates.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/3_Turn_Game.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/4_Destroy_Bacteria.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/5_Motu's_Plants.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/6_Demonetisation.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q1.cpp create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.BAK create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.C-issues.txt create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.CPP-issues.txt create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q3.BAK create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q3.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q4.BAK create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q4.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q5.C create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q5.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q6.BAK create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q6.CPP create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q6.py create mode 100644 Code_It_Out_Questions/Other_Solutions_Untested/melbin/5.cpp create mode 100644 Code_It_Out_Questions/README.md create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/1_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/2_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/3_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/4_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/5_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q1/TestCase_Maker.py create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/1_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/2_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/3_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/4_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/5_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q2/TestCase_Maker.py create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/1_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/2_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/3_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/4_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/5_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q3/TestCase_Maker.py create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/1_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/2_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/3_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/4_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/5_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q4/TestCase_Maker.py create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/1_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/2_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/3_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/4_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q5/5_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/1_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/2_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/3_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/4_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q6/5_O create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q7/1 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q7/2 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q7/3 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q7/4 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q7/5 create mode 100644 Code_It_Out_Questions/Test_Cases/Test_Case_Q7/Testcase_Generator.py create mode 100755 Extras/1.py create mode 100755 Extras/2.py create mode 100755 Extras/3.py create mode 100755 Extras/4.py create mode 100755 Extras/5.py create mode 100755 Extras/test.py create mode 100644 Hacker_Earth_Learning/find_coprime.py create mode 100644 Hacker_Earth_Learning/football_test_stack.py create mode 100644 Hacker_Earth_Learning/prime_string.py create mode 100644 Hacker_Earth_Learning/save_girlfriend.py create mode 100644 Hacker_Earth_Learning/signal_range_stack.py create mode 100644 Hacker_Earth_Study/Graph_Theory/check_tree.py create mode 100644 Hacker_Earth_Study/Graph_Theory/learning_graph.py create mode 100755 Iem_delete.py create mode 100755 LLTN_iem_16.py create mode 100644 Level1_1_1_Foobar.py create mode 100644 Level1_1_Foo.py create mode 100644 Level2_2_Foo.py create mode 100644 Level2_3_Foo.py create mode 100644 Level3_1_Foo.py create mode 100644 Level3_2_Foo.py create mode 100644 Level3_3_Foo.py create mode 100644 Level4_1_Foo.py create mode 100644 Level4_2.py create mode 100644 November_easy_hackerearth/divisible_trio.py create mode 100644 November_easy_hackerearth/funny_sub_array.py create mode 100644 November_easy_hackerearth/max_inser.py create mode 100644 README.md create mode 100644 Select_city.py create mode 100644 Sieve_prime_Check.py create mode 100644 Tcs_CodeVita_2017_Round2/.aesthetic_building.py.swp create mode 100644 Tcs_CodeVita_2017_Round2/aesthetic_building.py create mode 100644 Tcs_CodeVita_2017_Round2/antidote.py create mode 100644 Tcs_CodeVita_2017_Round2/enclosing_items.py create mode 100644 Tcs_CodeVita_2017_Round2/photograph.py create mode 100644 Xtreme/Jarawi and The Interview.py create mode 100644 Xtreme/batbear.py create mode 100644 Xtreme/beetlebag.py create mode 100644 Xtreme/cheering_up_bob.py create mode 100644 Xtreme/circular_disk.py create mode 100644 Xtreme/dr.fibonacci.py create mode 100644 Xtreme/factorial.py create mode 100644 Xtreme/fast_and_curious.py create mode 100644 Xtreme/odd_paths.py create mode 100644 Xtreme/pre1.py create mode 100644 Xtreme/quipu func.py create mode 100644 Xtreme/rexor.py create mode 100644 Xtreme/steps.py create mode 100644 Xtreme/tree.py create mode 100644 Xtreme/xor.py create mode 100644 Xtreme/xtreme_study.py create mode 100644 abel.py create mode 100644 appendanddelete.py create mode 100644 brick_count.py create mode 100755 choco_hr.py create mode 100644 comp1.py create mode 100755 consecletter.py create mode 100755 die_iem_16.py create mode 100644 distict.py create mode 100644 foobar2.py create mode 100755 formula.py create mode 100755 gift_friends.py create mode 100755 google/lead.py create mode 100755 google/rain.py create mode 100755 ict1.py create mode 100755 ict2.py create mode 100755 ieee_dog_walk.py create mode 100755 ieee_food_truck.py create mode 100755 ieee_full_adder.py create mode 100755 ieee_password.py create mode 100755 ieee_petals.py create mode 100755 ieee_prime.py create mode 100755 ieee_stone.py create mode 100644 lambs.py create mode 100755 luggage.py create mode 100755 max_val.py create mode 100755 merger.py create mode 100755 misc.py create mode 100755 monk_in_grass.py create mode 100644 monk_palindrome.py create mode 100644 monk_welcome_problem.py create mode 100755 myst_maze.py create mode 100644 navendu.py create mode 100644 pretty_print.py create mode 100644 primer.py create mode 100644 pytudes/LICENSE create mode 100644 pytudes/README.md create mode 100644 pytudes/data/advent2016/input1.txt create mode 100644 pytudes/data/advent2016/input10.txt create mode 100644 pytudes/data/advent2016/input12.txt create mode 100644 pytudes/data/advent2016/input2.txt create mode 100644 pytudes/data/advent2016/input20.txt create mode 100644 pytudes/data/advent2016/input21.txt create mode 100644 pytudes/data/advent2016/input22.txt create mode 100644 pytudes/data/advent2016/input24.txt create mode 100644 pytudes/data/advent2016/input3.txt create mode 100644 pytudes/data/advent2016/input4.txt create mode 100644 pytudes/data/advent2016/input6.txt create mode 100644 pytudes/data/advent2016/input7.txt create mode 100644 pytudes/data/advent2016/input8.txt create mode 100644 pytudes/data/advent2016/input9.txt create mode 100644 pytudes/data/advent2017/input1.txt create mode 100644 pytudes/data/advent2017/input11.txt create mode 100644 pytudes/data/advent2017/input12.txt create mode 100644 pytudes/data/advent2017/input13.txt create mode 100644 pytudes/data/advent2017/input16.txt create mode 100644 pytudes/data/advent2017/input18.txt create mode 100644 pytudes/data/advent2017/input19.txt create mode 100644 pytudes/data/advent2017/input20.txt create mode 100644 pytudes/data/advent2017/input4.txt create mode 100644 pytudes/data/advent2017/input5.txt create mode 100644 pytudes/data/advent2017/input7.txt create mode 100644 pytudes/data/advent2017/input8.txt create mode 100644 pytudes/data/advent2017/input9.txt create mode 100644 pytudes/ipynb/.ipynb_checkpoints/Advent 2017-checkpoint.ipynb create mode 100644 pytudes/ipynb/Advent 2017.ipynb create mode 100644 pytudes/ipynb/Advent of Code.ipynb create mode 100644 pytudes/ipynb/BASIC.ipynb create mode 100644 pytudes/ipynb/Beal.ipynb create mode 100644 pytudes/ipynb/Bike Speed versus Grade.ipynb create mode 100644 pytudes/ipynb/Cheryl-and-Eve.ipynb create mode 100644 pytudes/ipynb/Cheryl.ipynb create mode 100644 pytudes/ipynb/Coin Flip.ipynb create mode 100644 pytudes/ipynb/Convex Hull.ipynb create mode 100644 pytudes/ipynb/Countdown.ipynb create mode 100644 pytudes/ipynb/Differentiation.ipynb create mode 100644 pytudes/ipynb/Economics.ipynb create mode 100644 pytudes/ipynb/Fred Buns.ipynb create mode 100644 pytudes/ipynb/Gesture Typing.ipynb create mode 100644 pytudes/ipynb/Ghost.ipynb create mode 100644 pytudes/ipynb/Golomb-Puzzle.ipynb create mode 100644 pytudes/ipynb/How To Count Things.ipynb create mode 100644 pytudes/ipynb/How to Do Things with Words.ipynb create mode 100644 pytudes/ipynb/Life.ipynb create mode 100644 pytudes/ipynb/Mean Misanthrope Density.ipynb create mode 100644 pytudes/ipynb/Palindrome.ipynb create mode 100644 pytudes/ipynb/Probability.ipynb create mode 100644 pytudes/ipynb/ProbabilityParadox.ipynb create mode 100644 pytudes/ipynb/Project Euler Utils.ipynb create mode 100644 pytudes/ipynb/PropositionalLogic.ipynb create mode 100644 pytudes/ipynb/Riddler Battle Royale.ipynb create mode 100644 pytudes/ipynb/SET.ipynb create mode 100644 pytudes/ipynb/Scrabble.ipynb create mode 100644 pytudes/ipynb/Sicherman Dice.ipynb create mode 100644 pytudes/ipynb/Sierpinski.ipynb create mode 100644 pytudes/ipynb/Snobol.ipynb create mode 100644 pytudes/ipynb/Sudoku IPython Notebook.ipynb create mode 100644 pytudes/ipynb/TSP.ipynb create mode 100644 pytudes/ipynb/WWW.ipynb create mode 100644 pytudes/ipynb/dist-climb-time.csv create mode 100644 pytudes/ipynb/enable1.txt create mode 100644 pytudes/ipynb/money.png create mode 100644 pytudes/ipynb/pal3.ipynb create mode 100644 pytudes/ipynb/xkcd1313-part2.ipynb create mode 100644 pytudes/ipynb/xkcd1313.ipynb create mode 100644 pytudes/ipynb/xkxd-part3.ipynb create mode 100644 pytudes/py/SET.py create mode 100644 pytudes/py/beal.py create mode 100644 pytudes/py/docex.py create mode 100644 pytudes/py/ibol.py create mode 100644 pytudes/py/lettercount.py create mode 100644 pytudes/py/lis.py create mode 100644 pytudes/py/lispy.py create mode 100644 pytudes/py/lispytest.py create mode 100644 pytudes/py/pal.py create mode 100644 pytudes/py/pal2.py create mode 100644 pytudes/py/pal3.py create mode 100644 pytudes/py/parse.py create mode 100644 pytudes/py/py2html.py create mode 100644 pytudes/py/spell.py create mode 100644 pytudes/py/sudoku-easy50.txt create mode 100644 pytudes/py/sudoku-hardest.txt create mode 100644 pytudes/py/sudoku-top95.txt create mode 100644 pytudes/py/sudoku.py create mode 100644 pytudes/py/testaccum.py create mode 100644 pytudes/py/yaptu.py create mode 100644 pytudes/requirements.txt create mode 100644 quantum.py create mode 100755 quest.py create mode 100644 rabbit_maze.py create mode 100755 reverse.py create mode 100755 reverse_sort.py create mode 100755 round2/1.py create mode 100755 round2/2.py create mode 100755 round2/3.py create mode 100755 round2/4.py create mode 100755 soldier.py create mode 100644 string_uppercase.py create mode 100755 tcs 2016/arr].py create mode 100755 tcs 2016/atoms.py create mode 100755 tcs 2016/iter.py create mode 100755 tcs 2016/mango.py create mode 100755 tcs 2016/prime.py create mode 100755 tcs 2016/tcs1.py create mode 100755 tcs 2016/tcs2.py create mode 100644 test.py create mode 100644 testingf.py create mode 100644 tree.py diff --git a/.idea/competitive_programming.iml b/.idea/competitive_programming.iml new file mode 100644 index 0000000..6711606 --- /dev/null +++ b/.idea/competitive_programming.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..c23ecac --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..12f37ed --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..dff51e4 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..58fe99d --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,1042 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1501598665662 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code_It_Out_Questions/1_Simple_Prime_Numbers.py b/Code_It_Out_Questions/1_Simple_Prime_Numbers.py new file mode 100644 index 0000000..a400ff0 --- /dev/null +++ b/Code_It_Out_Questions/1_Simple_Prime_Numbers.py @@ -0,0 +1,62 @@ +''' +Question +Today Motu learned a new concept in maths called least prime factor, +(ie It is the smallest prime divisor of a number), The teacher gave Motu an assignment +to find all numbers with the same smallest prime factor as a number X upto a limit L +Motu is really lazy and is asking you to solve it for him. Can you take up the challenge ? + +Input +The first line takes into account N and L +N is the number of questions Teacher asked and L is the limit upto which we have to check the numbers +After that N lines follow Each with one input X + +Output +Output the number of numbers upto L (Inclusive) with the same least prime factor as the number X (Inclusive) + + +0 and 1 are not considered as least prime factors and hence excluded from all calculations + +Sample Cases + +Sample input | Sample Output +4 16 | +3 | 3 +2 | 8 +5 | 1 +10 | 0 + +Explanation + +For 3 the numbers 3 , 9 , 15 has their least prime divisor as 3 +For 2 the numbers 2 , 4 , 6 , 8 , 10 , 12 , 14 , 16 has their least prime divisor as 2 +For 5 There is no other number other than 5 +For 10 , 10 itself is not the least prime divisor , hence the answer is 0 + +Constraints + +N <= 100000 +L <= 10^7 + +''' + +#Answer in Python 2 + + +X,M = map(int , raw_input().split(" ")) + + +P = [1 for _ in xrange(M+1)] +P[0] , P[1] = 0,0 +i = 2 +while i*i <= M : + if P[i] == 1 : + for j in xrange(i*i,M+1,i) : + if P[j] == 1: + P[j] = 0 + P[i] += 1 + i += 1 + +for i in range(X): + num = input() + print P[num] + diff --git a/Code_It_Out_Questions/2_Free_Chocolates.py b/Code_It_Out_Questions/2_Free_Chocolates.py new file mode 100644 index 0000000..90667fe --- /dev/null +++ b/Code_It_Out_Questions/2_Free_Chocolates.py @@ -0,0 +1,75 @@ +''' +Motu visits a new chocolate shop in the town called BioChocolates . Its run by a Biology professor called Damu +Damu makes chocolates using uses special type of organic cells. + +Damu agress to give Motu Free chocolates if he solves his problem. + +Damu has two types of Cells A and B +The cells are highly active so in one step either Every cell from A regenerates and moves to B. Or Every cell from B regenerates and moves to A + +For Example if you had 3 Cells of Type A and 2 Cells of Type B +Either you get 5 Cells of type A and 2 Cells of Type B +or You get 3 Cells of Type A and 5 Cells of Type B +Motu has to find the least number of steps it takes for one cell of type A and B to reach a given number of Cells + +Example + +if we have to reach 4,7 +Initially we have A = 1 and B = 1 +After step 1 we have A = 1 and B = 2 ( A goes to B ) +After step 2 we have A = 1 and B = 3 ( A goes to B ) +After step 3 we have A = 4 and B = 3 ( B goes to A ) +After step 4 we have A = 4 and B = 7 ( A goes to B ) +So in 4 steps we reach required cell count + +Input +The first line contains the number of test cases +The next line consists of the required cell counts of Cell A followed by required cell counts of Cell B + +Output +Output one line containing the number of steps required to reach the required cell count from initial condition ( Initially Both Cell Counts are 1) +If a particular cell count cannot be achived Print "impossible" + +Constraints +The number of cells can be upto 10^19 + +Sample input | Sample Output +4 | +2 1 | 1 +4 7 | 4 +2 4 | impossible +4 2 | impossible + +Constraints + +N < 100000 +M,F > 0 +M,F < 10^50 + +*You might wanna consider using large variable datatypes to avoid overflow errors and other issues* + +''' + +#Python 2 + +def recsol(a,b,lev): + if (a <= 0 or b <= 0): return + if (a == 1 and b == 1): return lev + if(a > b and (( a / b ) -1) > 0 ): + time = (a / b) -1 + a = a - b * ((a / b) - 1) + return recsol(a, b, time + lev) + elif(b> a and (( b / a ) -1) > 0 ): + time = (( b / a ) ) -1 + b = b - a * (( b / a ) - 1) + return recsol(a, b,time + lev) + return recsol(a-b,b,lev+1) or recsol(a,b-a,lev+1) + +inp = input() +for i in range(inp): + M , F = map(int , raw_input("").split(" ")) + if(M > 10 ** 50 or F > 10 ** 50 or M < 0 or F < 0):print "-1" + val = recsol(M,F,0) + if(val == None):print "impossible" + else: print val + diff --git a/Code_It_Out_Questions/3_Turn_Game.py b/Code_It_Out_Questions/3_Turn_Game.py new file mode 100644 index 0000000..6f969f4 --- /dev/null +++ b/Code_It_Out_Questions/3_Turn_Game.py @@ -0,0 +1,52 @@ +''' + +Motu wants to play a game with his friends. +All of his play a new game where every player is named numbers from 1 and are made to stand in a circle, +And from player 1 they would shout numbers from 1 .. if its a multiple of 2 they are removed from the game. the game continues the cyle (last one left --> first one left) +The last player standing wins the game + +Motu wants to know where he has to stand to win. You are asked to find the position he has to stand given the number of players + +Input Format +The first line indicates N the number of test cases. +N test cases follow the first Line Each with the Number of Players (P) + +Constraints +1 ≤ P ≤ 100000 + +1 ≤ N < 10000 + +Output Format +The position That will win has to be outputted for each test case + +Sample input | Sample Output +4 | +2 | 1 +3 | 3 +4 | 1 +6 | 5 + + +Explanation +There are four test cases in the input. + +With 6 Players, First Player Yells 1 , Second Player Yells 2 and he is removed , Third Player Yells 3 , Fourth Player Yells 4 and he is removed , +5th Player yells 5 , 6th Player Yells 6 and is removed , 1st player yells 7 , 3rd player yells 8 and is removed , 5th player yells 9 , +1st player yells 10 and is removed +Only 5th player Remains + +With 5 Players, First Player Yells 1 , Second Player Yells 2 and he is removed , Third Player Yells 3 , Fourth Player Yells 4 and he is removed , +5th Player yells 5, First Player Yells 6 and is removed, Third player yells 7 , 5th Player yells 8 anb is removed , +Only Third Player remains and he wins the game + +''' + + +#Solution for python 3 Py3 + +for _ in range(int(input())): + num = int(input()) + last_roll = 2 ** (num.bit_length() - 1) + n = (num - (last_roll - 1)) * 2 - 1 + print(n) + diff --git a/Code_It_Out_Questions/4_Destroy_Bacteria.py b/Code_It_Out_Questions/4_Destroy_Bacteria.py new file mode 100644 index 0000000..c34dca0 --- /dev/null +++ b/Code_It_Out_Questions/4_Destroy_Bacteria.py @@ -0,0 +1,66 @@ +''' + +Motu was called in for an emergency at the hospital. +A Disease is spereading and only Motu can solve it + +He is given with a bacteria count of a person and he has to reuce the bacteria count to zero in the most minimun no of steps + +The hospital has 3 methods to control the count of the bacteria + +1) They can use their advanced machines to remove one Bacteria +2) They can use their bacteria Inserter to insert one Bacteria +3) They have a speical prototype machine which can exactly divide the number of bacteria into two . (since its a prototype machine only even number of bacteria can be divided using this method) + +Motu cannot handle all the cases at the hospial so he is asking for your help ! Can you help Him ? + +You will be given a Bacteria count as input , You have to find the least no of steps to reduce the number of bacteria to 0 with the provided 3 methods in the hospital + +For example: + +Given Input 4 :> +4 --> 2 --> 1 --> 0 +In 3 steps we can reduce to 0 hence the answer is 0 + +Given Input 15 :> +15 --> 16 --> 8 --> 4 --> 2 --> 1 --> 0 +We can reduce to 0 in 6 steps hence 6 is the answer + +Since the bacteria is spreading quickly you can expect bacteria count upto 10^19 . So Use Large datatypes to input data and handle it. + +Input +The first line takes into account N +N is the number of Test Cases that follow +After that N lines contain the bacteria count for each test case + +Output +Output the number of steps required to reduce the bacteria count to 0 with the methods given in the questions + +Sample Cases + +Sample input | Sample Output +4 | +4 | 3 +5 | 4 +15 | 6 +20 | 6 + + +''' + +def answer(n): + counter = 0 + num = long(n) + while(num > 1): + if num % 2 == 0: + num = num / 2 + elif num == 3 or num % 4 == 1: + num -= 1 + elif num % 4 == 3 : + num += 1 + else: + break + counter += 1 + return counter + 1 + +for i in range(input()): + print answer(input()) \ No newline at end of file diff --git a/Code_It_Out_Questions/5_Motu's_Plants.py b/Code_It_Out_Questions/5_Motu's_Plants.py new file mode 100644 index 0000000..a3ee5b8 --- /dev/null +++ b/Code_It_Out_Questions/5_Motu's_Plants.py @@ -0,0 +1,120 @@ +''' + +Motu Has got a special formula fertilizer for growing plants, +one applying one unit of the fertilizer the plant grows one unit + +Motu wants to know how many ways he can plant his plants in such a way that he has atleast two plants and +-> Two plants should not have same height +-> Each plant must have increasing heights +-> every unit of the fertilizer has to be used + +Given the amount of fertilizer. Find how many ways motu can plant his plants. + +Assuming he has an unlimited supply of plant seeds + +Explanation + +Given that he has 5 units of fertilizer + +he can plant the plants in the following fasion + +| +| | +| | | +| | or | | +4 1 3 2 + +Constraint +He can have a maximum of 500 units of fertilizers + +Input +It has an input of F , The amount of fertilizer he has + +Output +The different number of ways he can plant his plants + +Sample Cases + +Sample input | Sample Output + | +6 | 3 +7 | 4 +10 | 9 + +''' + +''' +def answer(n): + combinations = [[0 for rows in range(n)] for cols in range(n + 1)] + + # If n < 3, there are no possibilities for building the stairwell. + for first_three in range(3): + for num in range(first_three, n): + combinations[first_three][num] = 1 + + # For the rest of them, the formula is incremental. + for num in range(3, n + 1): + for bot in range(2, n): + combinations[num][bot] = combinations[num][bot - 1] + if bot <= num: + combinations[num][bot] += combinations[num - bot][bot - 1] + + # This index on the matrix should contain our solution to the number of distinct combinations. + return combinations[n][n - 1] + +if __name__ == '__main__': + # This prints out the results of this function on any value between (including) 3 and 200. + # It's just for debugging. + print("Format:\n Number of Bricks --> Distinct Partitions") + for bricks in range(3, 200): + print(' ', bricks, " --> ", str(answer(bricks))) + +''' + + +# Alternate solutions + + +steps = 0 + +#Grandest Staircase + +def memoize(f): + + class memodict(dict): + def __init__(self, f): + self.f = f + def __call__(self, *args): + return self[args] + def __missing__(self, key): + ret = self[key] = self.f(*key) + return ret + return memodict(f) + +@memoize +def step(num): + ss=0 + if(num <= 2):return 0 + if(num < 5):return 1 + for i in range(num-1,0,-1): + if ((num - i) > i ):ss = ss + smallsteps(i,num-i);continue + elif(i == (num - i)):pass + else:ss += 1 + temp = step(num - i) + ss = ss + temp + return ss + +def natsum(n):return ((n*(n+1))/2) + +@memoize +def smallsteps(num,lim): + sum = 0 + if(natsum(num-1) < lim):return 0 + for i in range(num - 1 , 0 , -1): + if(i > lim):continue + nlim = lim - i + if(nlim == 0):sum = sum + 1 + else:sum = sum + smallsteps(i,nlim) + return sum + +print(step(int(input()))) diff --git a/Code_It_Out_Questions/6_Demonetisation.py b/Code_It_Out_Questions/6_Demonetisation.py new file mode 100644 index 0000000..a5a29bf --- /dev/null +++ b/Code_It_Out_Questions/6_Demonetisation.py @@ -0,0 +1,68 @@ +''' + +Motu Has Just recieved some amount of money from the bank and as he reaches home he hears news of demonetisation ! +Given the type of Money Denominations in Existence Show how many different ways he can make change for his money, +Motu is Really desparate for your help ! + +Assume we have infinite amount of Each Denominations + +Explanation + +If there are 5 avaliable notes now [7,6,3,1,2] if Motu took 3 Rs from Bank he can +Change it into ( (1,1,1),(2,1),(3) ) So there are 3 ways to change his notes + + +Input Format +First Line contains the Money he has With him Followed by the number of denominations of Notes avaliable +Second line contatins all the various denominations that are avaliable + +Output Format +Output one number containing the number of possible ways to get change + +Constraints + +Each Denomination <= 50 +Number of Denominations <= 50 +Money He Has <= 250 + +Sample Cases + +Sample input | Sample Output +4 4 | +8 1 2 3 | 4 + +''' +// Solution In C++ + +#include + +using namespace std; + +int c[52]; +int numCoins; +long long table[52][252]; +bool calculated[52][252]; +long long solve(int i, int make) +{ + if(make<0) return 0; + if(make==0)return 1; + if(i > numCoins) return 0; + if(calculated[i][make] == false){ //eliminating overlap + table[i][make] = solve(i, make - c[i]) + solve(i+1, make); + calculated[i][make] = true; + } + return table[i][make]; +} +int main(){ + + int make; + cin>>make>>numCoins; + for(int i=1;i<=numCoins;i++){ + cin>>c[i]; + } + cout< + +int main() +{ + int X,M,i,num; + scanf("%d",&X); + scanf("%d",&M); + X = 1; + M = 200; + //P = [1 for _ in xrange(M+1)] + int P[M+1]; + for(int x=0; x < M+1; x++) + P[x] = 1; + + P[0] = 0, P[1] = 0; + i = 2; + while(i*i <= M) + { + if(P[i] == 1) + { + //for j in xrange(i*i,M+1,i) + for(int j=i*i; j < M+1; j+=i) + { + if (P[j] == 1) + { + P[j] = 0; + P[i] += 1; + } + } + } + i += 1; + } + + for(i=0; i + + +unsigned long long int recsol(unsigned long long int a,unsigned long long int b,unsigned long long int lev) { + unsigned long long int time; + while (a >= 1 && b >= 1) { + if (a > b && ((a / b) - 1) > 0 ) + { + time = (a / b) - 1; + a = (a) - b * ((a / b) - 1); + lev = time + lev; + } + else if(b > a && ((b / a) - 1) > 0 ){ + time = ((b / a)) - 1; + b = (b) - a * ((b / a) - 1); + lev =time + lev; + } + else{ + if (b > a){ + b = b - a; + lev = lev + 1;} + else if (a > b){ + a = a-b; + lev = lev + 1;} + else + return 0; + } + if (a == 1 && b == 1) + return lev; + if(a <= 0 || b <= 0 ) + return -1; + } +} + +int main(){ + int inp ; + unsigned long long int data1 , data2 , ans ; + scanf("%d",&inp) ; + for(int i=0 ; i < inp ; i++){ + scanf("%llu %llu",&data1,&data2); + ans = recsol(data1,data2,0); + if(ans == 0){ + printf("impossible\n"); + continue; + } + + printf("%llu\n" , ans); + + } + return 0; + +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/C/3.C b/Code_It_Out_Questions/Other_Solutions_Untested/C/3.C new file mode 100644 index 0000000..e8bcdd5 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/C/3.C @@ -0,0 +1,20 @@ + +#include +#include + +int main() +{ + int y,n; + //for _ in range(int(input())) + scanf("%d",&y); + for(int x=0;x + +int main() +{ + int counter,num; + scanf("%d",&num); + counter = 0; + while(num > 1){ + if (num % 2 == 0) + num = num / 2; + else if (num == 3 || num % 4 == 1) + num -= 1; + else if (num % 4 == 3) + num += 1; + else + break; + counter += 1; + } + printf("%d",&counter); + +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/C/5.C b/Code_It_Out_Questions/Other_Solutions_Untested/C/5.C new file mode 100644 index 0000000..737e2d5 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/C/5.C @@ -0,0 +1,56 @@ + +#include + +unsigned long long int array[501], list[501][501]; + +unsigned long long int natsum(unsigned long long int n){ + return ((n*(n+1))/2); +} + +unsigned long long int smallsteps(unsigned long long int num,unsigned long long int lim){ + if(list[num][lim] != 0)return list[num][lim]; + unsigned long long int sum = 0, nlim,i; + if(natsum(num-1) < lim) return 0; + for (i=num-1; i>0; i--){ + if(i > lim){ continue;} + nlim = lim - i; + if(nlim == 0){ sum = sum + 1;} + else sum = sum + smallsteps(i,nlim); + } + list[num][lim] = sum; + return sum; +} + +unsigned long long int step(unsigned long long int num) { + + if(array[num] != 0)return array[num]; + unsigned long long int ss=0,i,temp; + if(num <= 2) return 0; + if(num < 5) return 1; + for (i=num-1;i>0;i--){ + + if ((num - i) > i ){ + ss = ss + smallsteps(i,num-i);continue; + } + else if(i == (num - i)) + {} + else{ + ss += 1;} + temp = step(num - i); + ss = ss + temp; + } + array[num] = ss; + return ss; +} + +int main() +{ + for(int i =0; i<501; i++) + {array[i] = 0; + for(int j =0; j<501; j++) { + list[i][j] = 0; + } + } + printf("%llu",step(500)); + return 0; +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/C/6.C b/Code_It_Out_Questions/Other_Solutions_Untested/C/6.C new file mode 100644 index 0000000..be38399 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/C/6.C @@ -0,0 +1,30 @@ +#include + +int c[52]; +int numCoins; +long long table[52][252]; +int calculated[52][252]; +long long solve(int i, int make) +{ + if(make<0) return 0; + if(make==0)return 1; + if(i > numCoins) return 0; + if(calculated[i][make] == 0){ //eliminating overlap + table[i][make] = solve(i, make - c[i]) + solve(i+1, make); + calculated[i][make] = 1; + } + return table[i][make]; +} +int main(){ + + int make,i,j; + scanf("%d%d",&make,&numCoins); + for(i = 0; i< 52; i++) + for(j = 0; j< 252; j++) + calculated[i][j] = 0; + for(i=0;i<=numCoins;i++){ + scanf("%d",&c[i]); + } + printf("%d",solve(1, make)); + return 0; +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/C/7.C b/Code_It_Out_Questions/Other_Solutions_Untested/C/7.C new file mode 100644 index 0000000..9c30dd9 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/C/7.C @@ -0,0 +1,24 @@ +#include +// #include +void main(){ + int ar[100],size,i,largest,count=0; + // clrscr(); + scanf("%d",&size); + for(i=0;ilargest){ + largest=ar[i]; + } + } + for(i=0;i +using namespace std; + +int main() +{ + int X,M,i,num; + cin>>X; + cin>>M; + + //P = [1 for _ in xrange(M+1)] + int P[M+1]; + for(int x=0; x < M+1; x++) + P[x] = 1; + + P[0] = 0, P[1] = 0; + i = 2; + while(i*i <= M) + { + if(P[i] == 1) + { + //for j in xrange(i*i,M+1,i) + for(int j=i*i; j < M+1; j+=i) + { + if (P[j] == 1) + { + P[j] = 0; + P[i] += 1; + } + } + } + i += 1; + } + + for(i=0; i>num; + cout< +#include + +using namespace std; + +unsigned long long int recsol(unsigned long long int a,unsigned long long int b,unsigned long long int lev) { + unsigned long long int time; + while (a >= 1 && b >= 1) { + if (a > b && ((a / b) - 1) > 0 ) + { + time = (a / b) - 1; + a = (a) - b * ((a / b) - 1); + lev = time + lev; + } + else if(b > a && ((b / a) - 1) > 0 ){ + time = ((b / a)) - 1; + b = (b) - a * ((b / a) - 1); + lev =time + lev; + } + else{ + if (b > a){ + b = b - a; + lev = lev + 1;} + else if (a > b){ + a = a-b; + lev = lev + 1;} + else + return 0; + } + if (a == 1 && b == 1) + return lev; + if(a <= 0 || b <= 0 ) + return -1; + } +} + +int main(){ + printf("%llu" , recsol(1,456789,0)); + return 0; + +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/CPP/3.cpp b/Code_It_Out_Questions/Other_Solutions_Untested/CPP/3.cpp new file mode 100644 index 0000000..a37df8b --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/CPP/3.cpp @@ -0,0 +1,22 @@ + +#include +#include +using namespace std; + +int main() +{ + int y,n; + //for _ in range(int(input())) + cin>>y; + for(int x=0;x>num; + last_roll = pow(2,(floor(log2(num)))); + n = (num - (last_roll - 1)) * 2 - 1; + cout< +using namespace std; + +int main() +{ + string n; + int counter=0,num; + cin>>num; + while(num > 1) + { + if(num % 2 == 0) + num = num / 2; + else if(num == 3 || num % 4 == 1) + num -= 1; + else if(num % 4 == 3) + num += 1; + else + break; + counter += 1; + } + cout< + +using namespace std; + +unsigned long long int array[501], list[501][501]; + +unsigned long long int natsum(unsigned long long int n){ + return ((n*(n+1))/2); +} + +unsigned long long int smallsteps(unsigned long long int num,unsigned long long int lim){ + if(list[num][lim] != 0)return list[num][lim]; + unsigned long long int sum = 0, nlim,i; + if(natsum(num-1) < lim) return 0; + for (i=num-1; i>0; i--){ + if(i > lim){ continue;} + nlim = lim - i; + if(nlim == 0){ sum = sum + 1;} + else sum = sum + smallsteps(i,nlim); + } + list[num][lim] = sum; + return sum; +} + +unsigned long long int step(unsigned long long int num) { + + if(array[num] != 0)return array[num]; + unsigned long long int ss=0,i,temp; + if(num <= 2) return 0; + if(num < 5) return 1; + for (i=num-1;i>0;i--){ + + if ((num - i) > i ){ + ss = ss + smallsteps(i,num-i);continue; + } + else if(i == (num - i)) + {} + else{ + ss += 1;} + temp = step(num - i); + ss = ss + temp; + } + array[num] = ss; + return ss; +} + +int main() +{ + for(int i =0; i<501; i++) + {array[i] = 0; + for(int j =0; j<501; j++) { + list[i][j] = 0; + } + } + cout< + +using namespace std; + +long getWays(long n, vector < long > c){ + // Complete this function + vector table(n+1); + table[0]=1; + for(long i=0;i> n >> m; + vector c(m); + for(int c_i = 0; c_i < m; c_i++){ + cin >> c[c_i]; + } + // Print the number of ways of making change for 'n' units using coins having the values given by 'c' + long ways = getWays(n, c); + cout< +// #include +void main(){ + int ar[100],size,i,largest,count=0; + // clrscr(); + cin>>size; + for(i=0;i>ar[i]; + } + largest=ar[0]; + for(i=0;ilargest){ + largest=ar[i]; + } + } + for(i=0;i +// #include +void main(){ + int ar[100],size,i,largest,count=0; + // clrscr(); + scanf("%d",&size); + for(i=0;ilargest){ + largest=ar[i]; + } + } + for(i=0;i +// #include +void main(){ + int ar[100],size,i,largest,count=0; + // clrscr(); + cin>>size; + for(i=0;i>ar[i]; + } + largest=ar[0]; + for(i=0;ilargest){ + largest=ar[i]; + } + } + for(i=0;i 0 +M,F < 10^50 + +*You might wanna consider using large variable datatypes to avoid overflow errors and other issues* + +''' + +#Python 2 + +def recsol(a,b,lev): + if (a <= 0 or b <= 0): return + if (a == 1 and b == 1): return lev + if(a > b and (( a / b ) -1) > 0 ): + time = (a / b) -1 + a = a - b * ((a / b) - 1) + return recsol(a, b, time + lev) + elif(b> a and (( b / a ) -1) > 0 ): + time = (( b / a ) ) -1 + b = b - a * (( b / a ) - 1) + return recsol(a, b,time + lev) + return recsol(a-b,b,lev+1) or recsol(a,b-a,lev+1) + +inp = input() +for i in range(inp): + M , F = map(int , raw_input("").split(" ")) + if(M > 10 ** 50 or F > 10 ** 50 or M < 0 or F < 0):print "-1" + val = recsol(M,F,0) + if(val == None):print "impossible" + else: print val \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/3_Turn_Game.py b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/3_Turn_Game.py new file mode 100644 index 0000000..4247676 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/3_Turn_Game.py @@ -0,0 +1,55 @@ +''' + +Motu wants to play a game with his friends. +All of his play a new game where every player is named numbers from 1 and are made to stand in a circle, +And from player 1 they would shout numbers from 1 .. if its a multiple of 2 they are removed from the game. the game continues the cyle (last one left --> first one left) +The last player standing wins the game + +Motu wants to know where he has to stand to win. You are asked to find the position he has to stand given the number of players + +Input Format +The first line indicates N the number of test cases. +N test cases follow the first Line Each with the Number of Players (P) + +Constraints +1 ≤ P ≤ 100000 + +1 ≤ N < 263 + +Output Format +The position That will win has to be outputted for each test case + +Sample Input +4 +2 +3 +4 +6 +Sample Output +1 +3 +1 +5 +Explanation +There are four test cases in the input. + +With 2 petals, one would skip 1, tear 2, and then only 1 is left. + +With 3 petals, one would skip 1, tear 2, skip 3, tear 1, and then only 3 is left. + +With 4 petals, one would skip 1, tear 2, skip 3, tear 4, skip 1, tear 3, and then only 1 is left. + +With 6 petals, First Player Yells 1 , Second Player Yells 2 and he is removed , Third Player Yells 3 , Fourth Player Yells 4 and he is removed , 5th Player yells 5 , 6th Player Yells 6 and is removed , 1st player yells 7 , 3rd player yells 8 and is removed , 5th player yells 9 , 1st player yells 10 and is removed +Only 5 Remains + +''' + + +#Solution for python 3 Py3 + +for _ in range(int(input())): + num = int(input()) + last_roll = 2 ** (num.bit_length() - 1) + n = (num - (last_roll - 1)) * 2 - 1 + print(n) + diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/4_Destroy_Bacteria.py b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/4_Destroy_Bacteria.py new file mode 100644 index 0000000..12b869b --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/4_Destroy_Bacteria.py @@ -0,0 +1,63 @@ +''' + +Motu was called in for an emergency at the hospital. +A Disease is spereading and only Motu can solve it + +He is given with a bacteria count of a person and he has to reuce the bacteria count to zero in the most minimun no of steps + +The hospital has 3 methods to control the count of the bacteria + +1) They can use their advanced machines to remove one Bacteria +2) They can use their bacteria Inserter to insert one Bacteria +3) They have a speical prototype machine which can exactly divide the number of bacteria into two . (since its a prototype machine only even number of bacteria can be divided using this method) + +Motu cannot handle all the cases at the hospial so he is asking for your help ! Can you help Him ? + +You will be given a Bacteria count as input , You have to find the least no of steps to reduce the number of bacteria to 0 with the provided 3 methods in the hospital + +For example: + +Given Input 4 :> +4 --> 2 --> 1 --> 0 +In 3 steps we can reduce to 0 hence the answer is 0 + +Given Input 15 :> +15 --> 16 --> 8 --> 4 --> 2 --> 1 --> 0 +We can reduce to 0 in 6 steps hence 6 is the answer + +Since the bacteria is spreading quickly you can expect bacteria count with atmost 300 digits . So Use Large datatypes to input data and handle it. + +Input +The first line takes into account N +N is the number of Test Cases that follow +After that N lines contain the bacteria count for each test case + +Output +Output the number of steps required to reduce the bacteria count to 0 with the methods given in the questions + +Sample Cases + +Sample input | Sample Output +4 16 | +3 | 3 +2 | 8 +5 | 1 +10 | 0 + + +''' + +def answer(n): + counter = 0 + num = long(n) + while(num > 1): + if num % 2 == 0: + num = num / 2 + elif num == 3 or num % 4 == 1: + num -= 1 + elif num % 4 == 3 : + num += 1 + else: + break + counter += 1 + return counter + 1 diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/5_Motu's_Plants.py b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/5_Motu's_Plants.py new file mode 100644 index 0000000..a3ee5b8 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/5_Motu's_Plants.py @@ -0,0 +1,120 @@ +''' + +Motu Has got a special formula fertilizer for growing plants, +one applying one unit of the fertilizer the plant grows one unit + +Motu wants to know how many ways he can plant his plants in such a way that he has atleast two plants and +-> Two plants should not have same height +-> Each plant must have increasing heights +-> every unit of the fertilizer has to be used + +Given the amount of fertilizer. Find how many ways motu can plant his plants. + +Assuming he has an unlimited supply of plant seeds + +Explanation + +Given that he has 5 units of fertilizer + +he can plant the plants in the following fasion + +| +| | +| | | +| | or | | +4 1 3 2 + +Constraint +He can have a maximum of 500 units of fertilizers + +Input +It has an input of F , The amount of fertilizer he has + +Output +The different number of ways he can plant his plants + +Sample Cases + +Sample input | Sample Output + | +6 | 3 +7 | 4 +10 | 9 + +''' + +''' +def answer(n): + combinations = [[0 for rows in range(n)] for cols in range(n + 1)] + + # If n < 3, there are no possibilities for building the stairwell. + for first_three in range(3): + for num in range(first_three, n): + combinations[first_three][num] = 1 + + # For the rest of them, the formula is incremental. + for num in range(3, n + 1): + for bot in range(2, n): + combinations[num][bot] = combinations[num][bot - 1] + if bot <= num: + combinations[num][bot] += combinations[num - bot][bot - 1] + + # This index on the matrix should contain our solution to the number of distinct combinations. + return combinations[n][n - 1] + +if __name__ == '__main__': + # This prints out the results of this function on any value between (including) 3 and 200. + # It's just for debugging. + print("Format:\n Number of Bricks --> Distinct Partitions") + for bricks in range(3, 200): + print(' ', bricks, " --> ", str(answer(bricks))) + +''' + + +# Alternate solutions + + +steps = 0 + +#Grandest Staircase + +def memoize(f): + + class memodict(dict): + def __init__(self, f): + self.f = f + def __call__(self, *args): + return self[args] + def __missing__(self, key): + ret = self[key] = self.f(*key) + return ret + return memodict(f) + +@memoize +def step(num): + ss=0 + if(num <= 2):return 0 + if(num < 5):return 1 + for i in range(num-1,0,-1): + if ((num - i) > i ):ss = ss + smallsteps(i,num-i);continue + elif(i == (num - i)):pass + else:ss += 1 + temp = step(num - i) + ss = ss + temp + return ss + +def natsum(n):return ((n*(n+1))/2) + +@memoize +def smallsteps(num,lim): + sum = 0 + if(natsum(num-1) < lim):return 0 + for i in range(num - 1 , 0 , -1): + if(i > lim):continue + nlim = lim - i + if(nlim == 0):sum = sum + 1 + else:sum = sum + smallsteps(i,nlim) + return sum + +print(step(int(input()))) diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/6_Demonetisation.py b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/6_Demonetisation.py new file mode 100644 index 0000000..73ecdf7 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/6_Demonetisation.py @@ -0,0 +1,65 @@ +''' + +Motu Has Just recieved some amount of money from the bank and as he reaches home he hears news of demonetisation ! +Given the type of Money Denominations in Existence Show how many different ways he can make change for his money, +Motu is Really desparate for your help ! + +Assume we have infinite amount of Each Denominations + +Explanation + +If there are 5 avaliable notes now [7,6,3,1,2] if Motu took 3 Rs from Bank he can +Change it into ( (1,1,1),(2,1),(3) ) So there are 3 ways to change his notes + + +Input Format +First Line contains the Money he has With him Followed by the number of denominations of Notes avaliable +Second line contatins all the various denominations that are avaliable + +Output Format +Output one number containing the number of possible ways to get change + +Constraints + +Each Denomination <= 50 +Number of Denominations <= 50 +Money He Has <= 250 + +Sample Cases + +Sample input | Sample Output +4 4 | +8 1 2 3 | 4 + +''' +// Solution In C++ + +#include + +using namespace std; + +int c[52]; +int numCoins; +long long table[52][252]; +bool calculated[52][252]; +long long solve(int i, int make) +{ + if(make<0) return 0; + if(make==0)return 1; + if(i > numCoins) return 0; + if(calculated[i][make] == false){ //eliminating overlap + table[i][make] = solve(i, make - c[i]) + solve(i+1, make); + calculated[i][make] = true; + } + return table[i][make]; +} +int main(){ + + int make; + cin>>make>>numCoins; + for(int i=1;i<=numCoins;i++){ + cin>>c[i]; + } + cout< +#include +void main() +{ + int X,M,*P, i,j,num; + cin>>X>>M; + + P = new int[M+1]; + P[0]= P[1]= 0; + for(int _=2; _<=M; _++) + P[_]= 1; + i=2; + while(i*i <=M) + { + if(P[i] ==1) + for(j= i*i; j>num; + cout< +#include + +unsigned long long int recsol(unsigned long long int a,unsigned long long int b,unsigned long long int lev) { + unsigned long long int time; + while (a >= 1 && b >= 1) { + cout< b && ((a / b) - 1) > 0 ) + { + time = (a / b) - 1; + a = a - b * ((a / b) - 1); + lev = time + lev; + } + else if(b > a && ((b / a) - 1) > 0 ){ + time = ((b / a)) - 1; + b = b - a * ((b / a) - 1); + lev =time + lev; + } + else{ + if (b-a > 0) + b = b - a; + else if (a-b > 0) + a = a-b; + } + if (a == 1 && b == 1) + return lev; + if(a <0 || b < 0 ) + + return -1; + } +} + +int main(){ + clrscr(); + cout< + +unsigned long long int recsol(unsigned long long int a,unsigned long long int b,unsigned long long int lev) { + unsigned long long int time; + while (a >= 1 && b >= 1) { + printf("%d %d \n" , a,b); + if (a > b && ((a / b) - 1) > 0 ) + { + time = (a / b) - 1; + a = a - b * ((a / b) - 1); + lev = time + lev; + } + else if(b > a && ((b / a) - 1) > 0 ){ + time = ((b / a)) - 1; + b = b - a * ((b / a) - 1); + lev =time + lev; + } + else{ + if (b-a > 0) + b = b - a; + else if (a-b > 0) + a = a-b; + } + if (a == 1 && b == 1) + return lev; + if(a <0 || b < 0 ) + return -1; + } +} + +int main(){ + printf("%llu" , recsol(1,12345678912345678999,0)); + +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.C-issues.txt b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.C-issues.txt new file mode 100644 index 0000000..606c460 --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.C-issues.txt @@ -0,0 +1 @@ +printf("%llu" , recsol(1,4294967295,0)); // max number with 1 is 4294967295 (10 digits) \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.CPP b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.CPP new file mode 100644 index 0000000..9cb0a3f --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q2.CPP @@ -0,0 +1,36 @@ +#include + +using namespace std; + +unsigned long long int recsol(unsigned long long int a,unsigned long long int b,unsigned long long int lev) { + unsigned long long int time; + while (a >= 1 && b >= 1) { + cout< b && ((a / b) - 1) > 0 ) + { + time = (a / b) - 1; + a = a - b * ((a / b) - 1); + lev = time + lev; + } + else if(b > a && ((b / a) - 1) > 0 ){ + time = ((b / a)) - 1; + b = b - a * ((b / a) - 1); + lev =time + lev; + } + else{ + if (b-a > 0) + b = b - a; + else if (a-b > 0) + a = a-b; + } + if (a == 1 && b == 1) + return lev; + if(a <0 || b < 0 ) + + return -1; + } +} + +int main(){ + cout< +#include +#include + +void main() +{ +clrscr(); +int t,num,last_roll,n; +cin>>t; +for(int i=0;i>num; + last_roll = pow(2,floor(log(num)/log(2)+1)); + n = (num - (last_roll - 1)) * 2 - 1; + cout<<"BL:"< +#include + +void main() +{ +int t,num,last_roll,n; +cin>>t; +for(int i=0;i>num; + last_roll = pow(2,floor(log(num)/log(2))); + n = (num - (last_roll - 1)) * 2 - 1; + cout<<"Ans:"< +#include + +void main() +{ + clrscr(); + int n=1,counter,num; + while(n) + { + cin>>n; + counter = 0; + num = long(n); + while(num > 1){ + if (num % 2 == 0) + num = num / 2; + else if (num == 3 || num % 4 == 1) + num -= 1; + else if (num % 4 == 3) + num += 1; + else + break; + counter += 1; + } + cout<<"Ans:"< +#include + +void main() +{ + clrscr(); + int n=1,counter,num; + while(n) + { + cin>>n; + counter = 0; + num = long(n); + while(num > 1){ + if (num % 2 == 0) + num = num / 2; + else if (num == 3 || num % 4 == 1) + num -= 1; + else if (num % 4 == 3) + num += 1; + else + break; + counter += 1; + } + cout<<"Ans:"< + +unsigned long long int array[501], list[501][501]; + +unsigned long long int natsum(unsigned long long int n){ + return ((n*(n+1))/2); +} + +unsigned long long int smallsteps(unsigned long long int num,unsigned long long int lim){ + if(list[num][lim] != 0)return list[num][lim]; + unsigned long long int sum = 0, nlim,i; + if(natsum(num-1) < lim) return 0; + for (i=num-1; i>0; i--){ + if(i > lim){ continue;} + nlim = lim - i; + if(nlim == 0){ sum = sum + 1;} + else sum = sum + smallsteps(i,nlim); + } + list[num][lim] = sum; + return sum; +} + +unsigned long long int step(unsigned long long int num) { + + if(array[num] != 0)return array[num]; + unsigned long long int ss=0,i,temp; + if(num <= 2) return 0; + if(num < 5) return 1; + for (i=num-1;i>0;i--){ + + if ((num - i) > i ){ + ss = ss + smallsteps(i,num-i);continue; + } + else if(i == (num - i)) + {} + else{ + ss += 1;} + temp = step(num - i); + ss = ss + temp; + } + array[num] = ss; + return ss; +} + +int main() +{ + for(int i =0; i<501; i++) + {array[i] = 0; + for(int j =0; j<501; j++) { + list[i][j] = 0; + } + } + printf("%llu",step(500)); + return 0; +} \ No newline at end of file diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q5.CPP b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q5.CPP new file mode 100644 index 0000000..48a2c4e --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/Mathew/Q5.CPP @@ -0,0 +1,60 @@ + +#include + +using namespace std; + +unsigned long long int array[501], list[501][501]; + +unsigned long long int natsum(unsigned long long int n){ + return ((n*(n+1))/2); +} + +unsigned long long int smallsteps(unsigned long long int num,unsigned long long int lim){ + if(list[num][lim] != 0)return list[num][lim]; + unsigned long long int sum = 0, nlim,i; + if(natsum(num-1) < lim) return 0; + for (i=num-1; i>0; i--){ + if(i > lim){ continue;} + nlim = lim - i; + if(nlim == 0){ sum = sum + 1;} + else sum = sum + smallsteps(i,nlim); + } + list[num][lim] = sum; + return sum; +} + +unsigned long long int step(unsigned long long int num) { + + if(array[num] != 0)return array[num]; + unsigned long long int ss=0,i,temp; + if(num <= 2) return 0; + if(num < 5) return 1; + for (i=num-1;i>0;i--){ + + if ((num - i) > i ){ + ss = ss + smallsteps(i,num-i);continue; + } + else if(i == (num - i)) + {} + else{ + ss += 1;} + temp = step(num - i); + ss = ss + temp; + } + array[num] = ss; + return ss; +} + +int main() +{ + unsigned long long int i = 0; + for(int i =0; i<501; i++) + {array[i] = 0; + for(int j =0; j<501; j++) { + list[i][j] = 0; + } + } + cin>>i; + cout< + +using namespace std; + + +int c[52]; +int numCoins; +long long table[52][252]; +int calculated[52][252]; +long long solve(int i, int make) +{ + if(make<0) return 0; + if(make==0)return 1; + if(i > numCoins) return 0; + if(calculated[i][make] == 0){ //eliminating overlap + table[i][make] = solve(i, make - c[i]) + solve(i+1, make); + calculated[i][make] = 1; + } + return table[i][make]; +} +int main(){ + + int make,i,j; + cin>>make>>numCoins; + for(i = 0; i< 52; i++) + for(j = 0; j< 252; j++) + calculated[i][j] = 0; + for(i=0;i<=numCoins;i++){ + cin>>c[i]; + } + cout< + +using namespace std; + + +int c[52]; +int numCoins; +long long table[52][252]; +int calculated[52][252]; +long long solve(int i, int make) +{ + if(make<0) return 0; + if(make==0)return 1; + if(i > numCoins) return 0; + if(calculated[i][make] == 0){ //eliminating overlap + table[i][make] = solve(i, make - c[i]) + solve(i+1, make); + calculated[i][make] = 1; + } + return table[i][make]; +} +int main(){ + + int make,i,j; + cin>>make>>numCoins; + for(i = 0; i< 52; i++) + for(j = 0; j< 252; j++) + calculated[i][j] = 0; + for(i=0;i<=numCoins;i++){ + cin>>c[i]; + } + cout<numCoins): return 0 + if(calculated[i][make] == False): #eliminating overlap + table[i][make] = solve(i, make - c[i]) + solve(i+1, make) + calculated[i][make] = True + return table[i][make] +c = [] +make, numCoins = map(int, input().strip().split()) +for i in range(1,numCoins+1): + c.append(int(input())) +print(solve(1, make)) diff --git a/Code_It_Out_Questions/Other_Solutions_Untested/melbin/5.cpp b/Code_It_Out_Questions/Other_Solutions_Untested/melbin/5.cpp new file mode 100644 index 0000000..a156c4d --- /dev/null +++ b/Code_It_Out_Questions/Other_Solutions_Untested/melbin/5.cpp @@ -0,0 +1,47 @@ +#include +using namespace std; + +int answer(int n) +{ + int combinations[n][n+1]; + //combinations = [[0 for rows in range(n)] for cols in range(n + 1)] + for(int rows=0; rows < n; rows++) + { + for (int cols=0; cols < n+1; cols++) + { + combinations[rows][cols] = 0; + } + } + + // If n < 3, there are no possibilities for building the stairwell. + //for first_three in range(3) + for(int first_three=0; first_three < 3; first_three++) + { + for(int num=first_three; num < n; num++) + combinations[first_three][num] = 1; + } + + // For the rest of them, the formula is incremental. + //for num in range(3, n + 1): + for(int num=3; num < n+1; num++) + { + for(int bot=2; bot Distinct Partitions\n"; + //for bricks in range(3, 200): + cin>>bricks; + cout<<" "< "<= len(list) - 1): + break + sum += (list[index + j] - list[index]) ** 2 + i += 1 + print sum, \ No newline at end of file diff --git a/Extras/5.py b/Extras/5.py new file mode 100755 index 0000000..8dcb8a2 --- /dev/null +++ b/Extras/5.py @@ -0,0 +1,21 @@ +def check(lis): + for i in lis: + if i==0:return False + return True + +a = input() +for k in range(1,a+1): + mul = 1 + val = input() + fin = val + if(val == 0):print "Case #{}: INSOMNIA".format(k);continue + chk = [0,0,0,0,0,0,0,0,0,0] + while True: + for i in str(val): + chk[int(i)] = chk[int(i)] + 1 + if(check(chk)): + print "Case #{}: {}".format(k,val) + break + mul+=1 + val = fin * mul + #Case #1: INSOMNIA \ No newline at end of file diff --git a/Extras/test.py b/Extras/test.py new file mode 100755 index 0000000..8c3b78b --- /dev/null +++ b/Extras/test.py @@ -0,0 +1,24 @@ +def fin(num,lis): + lens = lis.__len__() + for i in range(1,lens+1): + if(lis[lens-i] <= num):return lens-i + print lis , " " , min(lis) + return lis.index(min(lis)) +input() +lis = raw_input().split(" ") +len = len(lis) +for i in range(0,len): + lis[i] = int(lis[i]) +lis = sorted(lis) +ans = 0 +for k in range(1,len+1): + num = k ** 2 + ret = fin(num,lis) + print num - int(lis[ret]) + if(num - int(lis[ret]) > 0): + ans = ans + num - int(lis[ret]) + '''else: + ans = ans + (num - int(lis[ret])) * -1 + ''' + del lis[ret] +print ans diff --git a/Hacker_Earth_Learning/find_coprime.py b/Hacker_Earth_Learning/find_coprime.py new file mode 100644 index 0000000..7e8b73f --- /dev/null +++ b/Hacker_Earth_Learning/find_coprime.py @@ -0,0 +1,15 @@ + +def finder(a,b): + if(a > b):return 0 + for i in range(2,b): + if(b % i == 0 ):return 0 + return 1 + +cases = input() +for case in range(cases): + inp = input() + out = 0 + for i in range(1,inp+1): + for k in range(1,inp+1): + if(finder(i,k)):out+=1 + print out \ No newline at end of file diff --git a/Hacker_Earth_Learning/football_test_stack.py b/Hacker_Earth_Learning/football_test_stack.py new file mode 100644 index 0000000..2e92b73 --- /dev/null +++ b/Hacker_Earth_Learning/football_test_stack.py @@ -0,0 +1,17 @@ +times = input() +while times: + num,top = raw_input().split(" ") + num = int(num) + stack = [top] + while num: + current = raw_input() + if(current[0] == "P"): + stack.append(current[2:]) + before = top + top = current[2:] + else: + stack.append(stack[-2]) + num-=1 + print "Player" , stack.pop() + times-=1 + diff --git a/Hacker_Earth_Learning/prime_string.py b/Hacker_Earth_Learning/prime_string.py new file mode 100644 index 0000000..2eb5d69 --- /dev/null +++ b/Hacker_Earth_Learning/prime_string.py @@ -0,0 +1,84 @@ +''' +Alice has just learnt about primeStrings. A string is a primeString if the number of distinct alphabets used in the string is a prime and also the number of occurrences of each alphabet in the string is also a prime. +Given a String you need to tell if it is a primeString or not. + +Input: + +First line contains +T +T which is the number of test cases. +T +T lines follow each containing a string of characters ' +a +a' to ' +z +z'. + +Output: + +For each input, output "YES" if the number is a primeString or "NO" if not. + +SAMPLE INPUT +3 +ababb +abcab +aabbccdd +SAMPLE OUTPUT +YES +NO +NO +Explanation +Case 1: +2 +2 different alphabets each occurring +2 +2 and +3 +3 times respectively so string "ababb" is a PrimeString. + +Case 2: In second string char ' +a +a' occurs +2 +2 times, char ' +b +b' occurs +2 +2 times but char ' +c +c' occur only +1 +1 time which is not a prime number that's why string "abcab" is not a PrimeString. + +Case 3: String contains +4 +4 distinct alphabets and +4 +4 is not a prime Number so the string "aabbccdd" is not a PrimeString. + + +''' + +def normal_prime(num): + if(num == 1):return 0 + if(num < 3 ):return 1 + if(num % 2 == 0 ):return 0 + for i in xrange(3,int(num ** 0.5)+1,2): + if(num % i == 0):return 0 + return 1 + +cases = input() + +for case in range(cases): + no_of_occur = {} + for i in raw_input(): + no_of_occur[i] = no_of_occur.get(i,0) + 1 + done = 1 + if(normal_prime(len(no_of_occur.keys())) == 1): + done = 0 + for k in no_of_occur.keys(): + if(normal_prime(no_of_occur[k]) == 0): + done = 1 + break + if(done == 0):print "YES" + else: print "NO" \ No newline at end of file diff --git a/Hacker_Earth_Learning/save_girlfriend.py b/Hacker_Earth_Learning/save_girlfriend.py new file mode 100644 index 0000000..c0664c7 --- /dev/null +++ b/Hacker_Earth_Learning/save_girlfriend.py @@ -0,0 +1,25 @@ +# Failed Miserably + +val = {} + +def find(num): + init = 0; + if(num in val.keys()):return val[num] + for i in range(1,num/2): + if(num % i == 0):init += 1 + val[num] = init + return init + +cases = input() +for case in range(cases): + a,b = map(int , raw_input().split(" ")) + max_floor = [] + for i in range(a,b+1): + max_floor.append(find(i)) + max_floor.sort() + temp = max_floor[0] + life = 1 + for i in max_floor: + if(i != temp):break + life += 1 + print life \ No newline at end of file diff --git a/Hacker_Earth_Learning/signal_range_stack.py b/Hacker_Earth_Learning/signal_range_stack.py new file mode 100644 index 0000000..fdc2047 --- /dev/null +++ b/Hacker_Earth_Learning/signal_range_stack.py @@ -0,0 +1,15 @@ +times = input() +while times: + val = input() + towers = map(int , raw_input().strip().split(" ")) + temp = 0 + while temp != val: + current = towers[temp] + loopval = 0 ; + for i in range(0,temp+1): + if(current > towers[i]): + loopval+=1 + temp+=1 + print loopval+1, + print + times-=1 \ No newline at end of file diff --git a/Hacker_Earth_Study/Graph_Theory/check_tree.py b/Hacker_Earth_Study/Graph_Theory/check_tree.py new file mode 100644 index 0000000..ba72334 --- /dev/null +++ b/Hacker_Earth_Study/Graph_Theory/check_tree.py @@ -0,0 +1,40 @@ +''' +Our Code Monk recently learnt about Graphs and is very excited! + +He went over to the Graph-making factory to watch some freshly prepared graphs. Incidentally, one of the workers at the factory was ill today, so Monk decided to step in and do her job. + +The Monk's Job is to Identify whether the incoming graph is a tree or not. He is given N, the number of vertices in the graph and the degree of each vertex. + +Find if the graph is a tree or not. + +Input: +First line contains an integer N, the number of vertices. +Second line contains N space-separated integers, the degrees of the N vertices. + +Output: +Print "Yes" (without the quotes) if the graph is a tree or "No" (without the quotes) otherwise. + +Constraints: +1 <= N <= 100 +1 <= Degreei <= 1000 + +References: +Graphs and Trees + +SAMPLE INPUT +3 +1 2 1 +SAMPLE OUTPUT +Yes +Time Limit: + +''' + + +n = int(raw_input()) +l = map(int, raw_input().split()) +ans = sum(l) +if ans == 2*(n-1): + print "Yes" +else: + print "No" \ No newline at end of file diff --git a/Hacker_Earth_Study/Graph_Theory/learning_graph.py b/Hacker_Earth_Study/Graph_Theory/learning_graph.py new file mode 100644 index 0000000..ac17985 --- /dev/null +++ b/Hacker_Earth_Study/Graph_Theory/learning_graph.py @@ -0,0 +1,53 @@ +N,M,K = map(int , raw_input().split(" ")) +K= K-1 +val = map(int , raw_input().split(" ")) + +temp = 1 + +node_val_dict = {} +node_reverse_dict = {} + +for i in val : + node_val_dict[temp] = i + if(i in node_reverse_dict.keys()):node_reverse_dict[i].append(temp) + else: node_reverse_dict[i] = [temp] + temp += 1 +nodes = {} + +for i in range(1,N+1): + nodes[i] = [] + +for i in range(M): + temp = map(int , raw_input().split(" ")) + nodes[temp[0]].append(temp[1]) + nodes[temp[1]].append(temp[0]) + +nodes_changed = {} + +for i in nodes.keys(): + nodes_changed[i] = [node_val_dict[x] for x in nodes[i]] + +ans = [] + +for i in nodes.keys(): + temp = sorted(nodes_changed[i] , reverse=True) + if(len(temp) > K): + ans.append(temp[K]) + else:ans.append(-1) + +tester = 0 + +for i in ans: + tester += 1 + if(i == -1):print "-1" + else: + if len(node_reverse_dict[i]) > 1: + temp = sorted(node_reverse_dict[i]) + for x,y in enumerate(temp): + if(y not in nodes[tester] ):del temp[x] + print temp + for j in temp: + if(j in nodes[tester]):print j;break + else: + print node_reverse_dict[i][0] + diff --git a/Iem_delete.py b/Iem_delete.py new file mode 100755 index 0000000..72e4c33 --- /dev/null +++ b/Iem_delete.py @@ -0,0 +1,8 @@ +for i in range(0,input()): + data = raw_input().split("IEM") + while("".join(data) != "".join("".join(data).split("IEM"))): + data = "".join(data).split("IEM") + if("".join(data).strip() == ""): + print "Yes" + else: + print "No" diff --git a/LLTN_iem_16.py b/LLTN_iem_16.py new file mode 100755 index 0000000..d36012c --- /dev/null +++ b/LLTN_iem_16.py @@ -0,0 +1,30 @@ +temp = [] +check = ["I","E","M"] +current = -1 +ongoing = 0 +score = 0 +i = 0 +data = raw_input() +while i < len(data): + pos = check.index(data[i]) + print score + if(ongoing == 0): + if(data[i] != "I"):i=i+1;continue + else: + current = 0 + score+=1 + ongoing = 1 + else: + if(pos == (current + 1) or pos == current): + score = score + 1 + current = pos + else: + if(current == 2): + temp.append(score) + score = 0 + ongoing = 0 + continue + i=i+1; +if(current ==2): + temp.append(score) +print temp \ No newline at end of file diff --git a/Level1_1_1_Foobar.py b/Level1_1_1_Foobar.py new file mode 100644 index 0000000..6b118fa --- /dev/null +++ b/Level1_1_1_Foobar.py @@ -0,0 +1,7 @@ +def answer(area): + lis = [] + while area>0: + val = int(area ** 0.5) ** 2 + lis.append(val) + area -=val + return lis diff --git a/Level1_1_Foo.py b/Level1_1_Foo.py new file mode 100644 index 0000000..1474de8 --- /dev/null +++ b/Level1_1_Foo.py @@ -0,0 +1,18 @@ +# Braille Translation 2 + +sent = "the quick brown fox jumped over the lazy dog" +temp = "011110110010100010000000111110101001010100100100101000000000110000111010101010010111101110000000110100101010101101000000010110101001101100111100100010100110000000101010111001100010111010000000011110110010100010000000111000100000101011101111000000100110101010110110" +val = {'s' : '011100'} +for i in sent: + val[i] = temp[0:6] + temp = temp[6:] + +def answer(plaintext): + if(len(plaintext) > 50 ):return -1 + out = "" + for i in plaintext: + if(i.isupper()):out = out + "000001";i = i.lower() + out = out + val[i] + return out + +print answer("code") \ No newline at end of file diff --git a/Level2_2_Foo.py b/Level2_2_Foo.py new file mode 100644 index 0000000..383c227 --- /dev/null +++ b/Level2_2_Foo.py @@ -0,0 +1,63 @@ +#dont_get_volunteered (Least Knight Moves) + +def move(x, y, fx,fy): + smallest = [] + stack = [] + limit = range(0, 8) + stack.append((x,y,0)) + movesl = [] + for i in range(0, 8): movesl.append([0] * 8) + movesl[x][y] = 1 + while len(stack)!= 0: + new = stack[0] + x = new[0] + y = new[1] + moves = new[2] + if(x == fx and y == fy):smallest.append(moves) + moves = moves + 1 + if(x+1 in limit and y+2 in limit and movesl[x+1][y+2] == 0 ): + stack.append((x+1,y+2,moves)) + movesl[x+1][y+2] = 1 + if(x-1 in limit and y+2 in limit and movesl[x-1][y+2] == 0 ): + stack.append((x -1, y + 2, moves)) + movesl[x - 1][y + 2] = 1 + if(x+1 in limit and y-2 in limit and movesl[x+1][y-2] == 0 ): + stack.append((x + 1, y - 2, moves)) + movesl[x + 1][y - 2] = 1 + if(x-1 in limit and y-2 in limit and movesl[x-1][y-2] == 0 ): + stack.append((x - 1, y - 2, moves)) + movesl[x - 1][y - 2] = 1 + if(x+2 in limit and y+1 in limit and movesl[x+2][y+1] == 0 ): + stack.append((x + 2, y + 1, moves)) + movesl[x + 2][y + 1] = 1 + if(x+2 in limit and y-1 in limit and movesl[x+2][y-1] == 0 ): + stack.append((x + 2, y -1, moves)) + movesl[x + 2][y - 1] = 1 + if(x-2 in limit and y+1 in limit and movesl[x-2][y+1] == 0 ): + stack.append((x -2 , y + 1, moves)) + movesl[x - 2][y + 1] = 1 + if(x-2 in limit and y-1 in limit and movesl[x-2][y-1] == 0 ): + stack.append((x -2, y -1, moves)) + movesl[x - 2][y - 1] = 1 + del stack[0] + return min(smallest) + + + + + +def answer(src, dest): + if (src == dest): return 0; + if (src < 0 or dest < 0 or src > 63 or dest > 63): return -1 + x = int(src % 8) + y = int((src - x) / 8) + dx = int(dest % 8) + dy = int((dest - dx) / 8) + return move(x, y, dx,dy) + + +for i in range(0,64): + for k in range(0,64): + print "For " , i , " " , k , " " ,answer(i,k) + + diff --git a/Level2_3_Foo.py b/Level2_3_Foo.py new file mode 100644 index 0000000..31970b5 --- /dev/null +++ b/Level2_3_Foo.py @@ -0,0 +1,18 @@ +def prod(n): + out = 1 + for i in n:out *= i + return out + +def answer(list): + if(len(list) > 50):return "-1" + if(len(list) == 1):return str(list[0]) + list.sort() + neg = [];pos=[] + for i in list: + if i < 0 : neg.append(i) + elif(i>0):pos.append(i) + if(len(neg) % 2 != 0):del neg[-1] + if(len(pos) == 0):return 0 + return str(prod(pos) * prod(neg)) + +print answer( [-2,-3,-4,-5]) \ No newline at end of file diff --git a/Level3_1_Foo.py b/Level3_1_Foo.py new file mode 100644 index 0000000..0846e66 --- /dev/null +++ b/Level3_1_Foo.py @@ -0,0 +1,23 @@ + + + +def recsol(a,b,lev): + if (a <= 0 or b <= 0): return + if (a == 1 and b == 1): return lev + if(a > b and (( a / b ) -1) > 0 ): + time = (a / b) -1 + a = a - b * ((a / b) - 1) + return recsol(a, b, time + lev) + elif(b> a and (( b / a ) -1) > 0 ): + time = (( b / a ) ) -1 + b = b - a * (( b / a ) - 1) + return recsol(a, b,time + lev) + return recsol(a-b,b,lev+1) or recsol(a,b-a,lev+1) + +def answer(M, F): + M = int(M) + F = int(F) + if(M > 10 ** 50 or F > 10 ** 50 or M < 0 or F < 0):return "-1" + val = recsol(M,F,0) + if(val == None):return "impossible" + else: return str(val) diff --git a/Level3_2_Foo.py b/Level3_2_Foo.py new file mode 100644 index 0000000..58fb3ee --- /dev/null +++ b/Level3_2_Foo.py @@ -0,0 +1,13 @@ +def f(n): + if(n%4 == 0):return n + elif(n%4==1):return 1 + elif(n%4==2):return n+1 + elif(n%4==3):return 0 + +def answer(start,length): + result = 0 + for i in xrange(length): + result = result ^ f((start + i*length ) -1) ^ f(start + (i+1)*length -(i+1)) + return result + +print answer(17,4000000) \ No newline at end of file diff --git a/Level3_3_Foo.py b/Level3_3_Foo.py new file mode 100644 index 0000000..07e876a --- /dev/null +++ b/Level3_3_Foo.py @@ -0,0 +1,44 @@ + +steps = 0 + +#Grandest Staircase + +def memoize(f): + + class memodict(dict): + def __init__(self, f): + self.f = f + def __call__(self, *args): + return self[args] + def __missing__(self, key): + ret = self[key] = self.f(*key) + return ret + return memodict(f) + +@memoize +def step(num): + ss=0 + if(num <= 2):return 0 + if(num < 5):return 1 + for i in range(num-1,0,-1): + if ((num - i) > i ):ss = ss + smallsteps(i,num-i);continue + elif(i == (num - i)):pass + else:ss += 1 + temp = step(num - i) + ss = ss + temp + return ss + +def natsum(n):return ((n*(n+1))/2) + +@memoize +def smallsteps(num,lim): + sum = 0 + if(natsum(num-1) < lim):return 0 + for i in range(num - 1 , 0 , -1): + if(i > lim):continue + nlim = lim - i + if(nlim == 0):sum = sum + 1 + else:sum = sum + smallsteps(i,nlim) + return sum + +print step() diff --git a/Level4_1_Foo.py b/Level4_1_Foo.py new file mode 100644 index 0000000..225d91e --- /dev/null +++ b/Level4_1_Foo.py @@ -0,0 +1,76 @@ +from fractions import gcd + + +def is_power_of_two(x): + return (x & (x - 1)) == 0 and x != 0 + +def has_exit(i, j): + return is_power_of_two((i+j) / gcd(i,j)) + +class Guard: + def __init__(self, bananas): + self.bananas = bananas + self.exit = [] + self.loop = [] + +def dn(list_nodes, node): + for n in node.exit: + n.exit.remove(node) + for n in node.loop: + n.loop.remove(node) + list_nodes.remove(node) + +def disconnect_pair(list_nodes, node1, node2): + dn(list_nodes, node1) + dn(list_nodes, node2) + + +def answer(banana_list): + nb_guard = len(banana_list) + g = [Guard(banana_list[i]) for i in xrange(nb_guard)] + for i in xrange(0, nb_guard-1): + for j in xrange(i+1, nb_guard): + if has_exit(banana_list[i], banana_list[j]): + g[i].exit.append(g[j]) + g[j].exit.append(g[i]) + else: + g[i].loop.append(g[j]) + g[j].loop.append(g[i]) + + counter = 0 + pairs = [] + + """" + if nb_guard % 2 == 1: + singleton_guard = Guard(-1) + for guard in g: + singleton_guard.exit.append(guard) + guard.exit.append(singleton_guard) + g.append(singleton_guard) + counter -= 1 + """ + + while len(g) > 0: + g.sort(key=lambda x: len(x.exit), reverse=True) + + current_guard = g[0] # + found_good = False + for candidate_pair in g[1:]: + if candidate_pair in current_guard.loop: + pairs.append((current_guard, candidate_pair)) + disconnect_pair(g, current_guard, candidate_pair) + found_good = True + break + if not found_good: + counter += 2 + pairs.append((current_guard, g[1])) + disconnect_pair(g, current_guard, g[1]) + + return counter + + +if __name__ == "__main__": + print answer([1, 1]) + print answer([1, 7, 3, 21, 13, 19]) + print answer([3, 3, 2, 6, 6]) + print answer([1, 7, 21]) \ No newline at end of file diff --git a/Level4_2.py b/Level4_2.py new file mode 100644 index 0000000..514f076 --- /dev/null +++ b/Level4_2.py @@ -0,0 +1,65 @@ +import decimal +inf = decimal.Decimal("Infinity") + +def answer(entrances, exits, path): + transform(entrances, exits, path) + flow = 0 + length = len(path) + flows = [[0 for i in range(length)] for j in range(length)] + start = 0 + end = length - 1 + while True: + ap_flow, parents = bfs(start, end, path, flows) + if ap_flow == 0: + break + flow += ap_flow + v = end + while v != start: + u = parents[v] + flows[u][v] += ap_flow + flows[v][u] -= ap_flow + v = u + return flow + +def bfs(start, end, path, flows): + global inf + length = len(path) + parents = [-1] * length + parents[start] = -2 + queue = [] + queue.append(start) + while queue and parents[end] == -1: + u = queue.pop(0) + for v in range(length): + cf = path[u][v] - flows[u][v] + if cf > 0 and parents[v] == -1: + queue.append(v) + parents[v] = u + if parents[end] == -1: + return 0, parents + v = end + delta = inf + while v != start: + u = parents[v] + cf = path[u][v] - flows[u][v] + delta = min(delta, cf) + v = u + return delta, parents + +def transform(entrances, exits, path): + global inf + length = len(path) + entrances = [i + 1 for i in entrances] + exits = [i + 1 for i in exits] + for row in path: + row.insert(0, 0) + row.append(0) + start_row = [0] * (length + 2) + for i in entrances: + start_row[i] = inf + path.insert(0, start_row) + end_row = [0] * (length + 2) + for i in exits: + path[i][-1] = inf + path.append(end_row) + return entrances, exits, path \ No newline at end of file diff --git a/November_easy_hackerearth/divisible_trio.py b/November_easy_hackerearth/divisible_trio.py new file mode 100644 index 0000000..53587a1 --- /dev/null +++ b/November_easy_hackerearth/divisible_trio.py @@ -0,0 +1,13 @@ +n , m = map(int , raw_input().split(" ")) +lis = map(int , raw_input().split(" ")) +mapper = {} +print lis +for i in lis: + mod = i % m + print mapper + if(mod in mapper.keys()):getval = mapper[mod] + else:getval = [] + if i not in getval: + getval.append(i) + mapper[mod] = getval +print mapper \ No newline at end of file diff --git a/November_easy_hackerearth/funny_sub_array.py b/November_easy_hackerearth/funny_sub_array.py new file mode 100644 index 0000000..a9998b7 --- /dev/null +++ b/November_easy_hackerearth/funny_sub_array.py @@ -0,0 +1,21 @@ + +def max_funny(inp , pos ): + stack = [] + cur = inp[pos] + length = 1 + for i in range(pos+1 , len(inp)): + length += 1 + if(inp[i] == cur):print inp[pos:i+1] ; stack.append(length) + print stack + return max(stack) + +input() +inp = raw_input().split(" ") +looked= [] +large = 0 +for j,i in enumerate(inp): + if i not in looked: + new = max_funny(inp[:] , j ) + looked.append(i) + if(new > large):large = new +print new \ No newline at end of file diff --git a/November_easy_hackerearth/max_inser.py b/November_easy_hackerearth/max_inser.py new file mode 100644 index 0000000..c01f5d3 --- /dev/null +++ b/November_easy_hackerearth/max_inser.py @@ -0,0 +1,16 @@ + +val = input() +uniq = [] +current = [] +series = [0] +for temp in range(val): + i , j , k = map(int , raw_input().split(" ")) + if(i in current):series.append(series[0]);series[0] = 0 + current.append(i) + series[0] += 1 + out = 0 + print series + for lim in range(j,k+1): + for t in series: + if(t >= lim ):out = out + (t//lim) + print out \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..521875d --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Competitive_solutions +All my competitive programming Solutions diff --git a/Select_city.py b/Select_city.py new file mode 100644 index 0000000..b50ace9 --- /dev/null +++ b/Select_city.py @@ -0,0 +1,40 @@ +''' +James has decided to take a break from his work. He makes a plan to visit India for a few days with his family. He knows a lot about India, and also about the various cities he could visit. He decides to write down all the cities on a paper. Let the number of cities be n. Now, he shows the list to his wife and asks her, the city/cities she wants to visit. He tells her that she can select any city/cities and any number of cities. The wife says, she needs a day to decide. + +After this, James calls his son and tells him all about the trip, and the list of cities. He gives him a task and asks him, the number of ways the city/cities can be chosen from the list, if the total number of cities written on the list is n. The cities are numbered from 1 to n. At least 1 city has to be selected. + +He now asks your help to find the answer for the question that was asked to him. +The problem consists of a number of test cases. + +INPUT: +The first line of input contains the number of test cases t. +Then t lines follow, each contains a number n, the number of cities. + +OUTPUT: +Output contains t lines; each line contains the answer for that test case. As the answer can be large, print the answer modulo 10^9+7 + +CONSTRAINTS +1<=t<=100000 +1<=n<=1012 + +Tester: +SAMPLE INPUT +2 +2 +1 +SAMPLE OUTPUT +3 +1 +Explanation +For test case 1: The only ways to select the cities is 1 2 1 2 Therefore the answer is 3. + +For test case 2: The only way to select a city is 1 Therefore the answer is 1. + +Source : Hacker Earth + +''' + +def find(num): + return (2 ** num - 1) % 10**9+7 +for loop in range(input()): + print find(input()) diff --git a/Sieve_prime_Check.py b/Sieve_prime_Check.py new file mode 100644 index 0000000..964f133 --- /dev/null +++ b/Sieve_prime_Check.py @@ -0,0 +1,30 @@ +''' + +The Sieve Method to Find if a number is prime or not + +''' + +all_num = {} #This dict will store all final results i.e which all numbers are prime or not + +def sieve_check(num): + for i in xrange(2,int(num ** 0.5)): + if(all_num.get(i,0) == 0): + for k in xrange(2,num): + if(i*k > num):break + all_num[i*k] = 1 + if(num % k == 0):return + + +def normal_prime(num): + if(num < 3 ):return 1 + if(num % 2 == 0 ):return 0 + for i in xrange(3,int(num ** 0.5)+1,2): + if(num % i == 0):return 0 + return 1 + +for i in range(input()): + if(normal_prime(input()) == 1): + print "prime" + else: + print "composite" +#print sieve_check(3659707955798852) \ No newline at end of file diff --git a/Tcs_CodeVita_2017_Round2/.aesthetic_building.py.swp b/Tcs_CodeVita_2017_Round2/.aesthetic_building.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..da96d0432116a76db11866ef8e8394d7ab474d20 GIT binary patch literal 12288 zcmeI2&x+JQ5XO5w=xJTqJqzV5LT6?&`J=Efkb|rj55gikAi50MNzY7U(rMD2S!H2; z0$)H81aF>v1|LH30X+Eum>0z0PiL~i74x@wVqq0_69Hhe7C1%W~C$-Eo^p5naO)sTqM1Tl%1h(0oI11fn zzjq7vcApR#B0vO)01+SpM1Tko0U|&I{v!fbZ?V@n@0D)m-R{2i+r8V;jR+6{B0vO) z01+SpM1Tko0U|&IhyW4z2MMGZV;{E}yLKI$$KU@izW=}PF!l}g33Z0bQ7=%>QAeno zs2`Z~74;USPzkD!0@NPL)x3(LAOb{y2oM1xKm>>Y5g-CYfCvzQzlH!{SXl@^iI`iv z(5W%ZEktg_xLLWKuB5VHMWNS6ZZk@?7AoUasuqI7D$QZ&uD+^^AcmnIdEPGxkU;C@ zYnL~O+N42r>2;M7DAJew;ve7USyS^Ey_ZM4IrG4ej@w*0cSmqLh9rT|YX?~So06Kl zQHI#Z=~OCRTkegF&ZXr&=ymP78u*^nh(Ag>UCLZED96kJ#iXt>eivg@!q$}nQx|I( zxJH+|4uD5t7(ySon>QLt5BhzGJ@BBh&&vuV7VOA1U3Ja*Fwe`fGT1DlZl`T4hb$9w Rm`jz-N@ICz8@gPy{RFq^$x#3R literal 0 HcmV?d00001 diff --git a/Tcs_CodeVita_2017_Round2/aesthetic_building.py b/Tcs_CodeVita_2017_Round2/aesthetic_building.py new file mode 100644 index 0000000..217e7b1 --- /dev/null +++ b/Tcs_CodeVita_2017_Round2/aesthetic_building.py @@ -0,0 +1,23 @@ +def findcost(floors,base): + sum = 0 + for i in range(base , base - floors , -1): + sum = sum + (1000 * (max(1,i) ** 2) ) + return sum + +time = input() +while time: + num , base = map(int , raw_input().strip().split(" ")) + buildings = map(int , raw_input().strip().split(" ")) + if(num %2 == 0): + val = max(buildings[num/2] , buildings[(num/2) -1]) + temp = range((val-num/2)+1 , val+1) + temp.extend(range( val , val-num/2 ,-1)) + else: + val = buildings[num/2] + temp = range((val-num/2) , val) + temp.extend(range( val , val-num/2 -1 ,-1)) + out = 0 + for i in range(0,num): + out = out + findcost((temp[i] - buildings[i]) , base) + time-=1 + print out \ No newline at end of file diff --git a/Tcs_CodeVita_2017_Round2/antidote.py b/Tcs_CodeVita_2017_Round2/antidote.py new file mode 100644 index 0000000..2772273 --- /dev/null +++ b/Tcs_CodeVita_2017_Round2/antidote.py @@ -0,0 +1,174 @@ +size = input() +temp = size +grid = [] +while temp: + grid.append(map(int,raw_input().strip().split(" "))) + temp-=1 +posinf = map(int,raw_input().strip().split(" ")) +poscur = map(int,raw_input().strip().split(" ")) +posinf[0] = posinf[0]- 1 +posinf[1] = posinf[1] -1 + +poscur[0] = poscur[0]- 1 +poscur[1] = poscur[1] -1 + +infected = [[posinf[0] , posinf[1]]] + +infque = [] + +def infect(posx,posy,level): + if(level == 2 ):return + if(posx + 1 < size ): + if(grid[posx+1][posy] == 1 ): + if( [posx+1,posy] not in infected ): + grid[posx+1][posy] = level - 1 + infected.append([posx+1,posy]) + infque.append([posx+1,posy,level-1]) + if(posy + 1 < size): + if(grid[posx][posy+1] == 1 ): + if([posx,posy+1] not in infected): + grid[posx][posy+1] = level - 1 + infected.append([posx,posy+1]) + infque.append([posx,posy +1 ,level-1]) + if(posx + 1 < size and posy + 1 < size): + if(grid[posx+1][posy+1] == 1 ): + if([posx+1,posy+1] not in infected): + grid[posx+1][posy+1] = level - 1 + infected.append([posx+1 , posy+1]) + infque.append([posx+1,posy+1,level-1]) + if(posx + 1 < size and posy - 1 >= 0): + if(grid[posx+1][posy-1] == 1 ): + if([posx+1 , posy-1] not in infected): + grid[posx+1][posy-1] = level - 1 + infected.append([posx+1,posy-1]) + infque.append([posx+1,posy -1,level-1]) + if(posx - 1 >= 0 ): + if(grid[posx-1][posy] == 1 ): + if( [posx-1,posy] not in infected ): + grid[posx-1][posy] = level - 1 + infected.append([posx-1,posy]) + infque.append([posx-1,posy,level-1]) + + if(posy - 1 >= 0): + if(grid[posx][posy-1] == 1 ): + if([posx,posy-1] not in infected): + grid[posx][posy-1] = level - 1 + infected.append([posx,posy-1]) + infque.append([posx,posy - 1,level-1]) + if(posx - 1 >= 0 and posy - 1 >= 0): + if(grid[posx-1][posy-1] == 1 ): + if([posx-1,posy-1] not in infected): + grid[posx-1][posy-1] = level - 1 + infected.append([posx-1 , posy-1]) + infque.append([posx-1,posy -1,level-1]) + if(posx - 1 >= 0 and posy + 1 < size): + if(grid[posx-1][posy+1] == 1 ): + if([posx-1 , posy+1] not in infected): + grid[posx-1][posy+1] = level - 1 + infected.append([posx-1,posy+1]) + infque.append([posx-1,posy+1,level-1]) + if(len(infque) > 0): + a = infque[0][0] + b = infque[0][1] + c = infque[0][2] + del infque[0] + infect(a,b,c) + return + +cured = [[poscur[0] , poscur[1]]] +curque = [] + +def cure(posx,posy,level): + if(posx + 1 < size ): + if(grid[posx+1][posy] > 1 ): + if( [posx+1,posy] not in cured ): + if(level == 1 ): + grid[posx+1][posy] = 1 + else: + grid[posx+1][posy] = grid[posx+1][posy] - 1 + cured.append([posx+1,posy]) + curque.append([posx+1,posy,level+1]) + if(posy + 1 < size): + if(grid[posx][posy+1] > 1 ): + if([posx,posy+1] not in cured): + if(level == 1 ): + grid[posx][posy+1] = 1 + else: + grid[posx][posy+1] = grid[posx][posy+1] - 1 + cured.append([posx,posy+1]) + curque.append([posx,posy +1 ,level+1]) + if(posx + 1 < size and posy + 1 < size): + if(grid[posx+1][posy+1] > 1 ): + if([posx+1,posy+1] not in cured): + if(level == 1 ): + grid[posx+1][posy+1] = 1 + else: + grid[posx+1][posy+1] = grid[posx+1][posy+1] - 1 + cured.append([posx+1 , posy+1]) + curque.append([posx+1,posy+1,level+1]) + if(posx + 1 < size and posy - 1 >= 0): + if(grid[posx+1][posy-1] > 1 ): + if([posx+1 , posy-1] not in cured): + if(level == 1 ): + grid[posx+1][posy-1] = 1 + else: + grid[posx+1][posy-1] = grid[posx+1][posy-1] - 1 + cured.append([posx+1,posy-1]) + curque.append([posx+1,posy -1,level+1]) + if(posx - 1 >= 0 ): + if(grid[posx-1][posy] > 1 ): + if( [posx-1,posy] not in cured ): + if(level == 1 ): + grid[posx-1][posy] = 1 + else: + grid[posx-1][posy] = grid[posx-1][posy] - 1 + cured.append([posx-1,posy]) + curque.append([posx-1,posy,level+1]) + + if(posy - 1 >= 0): + if(grid[posx][posy-1] > 1 ): + if([posx,posy-1] not in cured): + if(level == 1 ): + grid[posx][posy-1] = 1 + else: + grid[posx][posy-1] = grid[posx][posy-1] - 1 + cured.append([posx,posy-1]) + curque.append([posx,posy - 1,level+1]) + if(posx - 1 >= 0 and posy - 1 >= 0): + if(grid[posx-1][posy-1] > 1 ): + if([posx-1,posy-1] not in cured): + if(level == 1 ): + grid[posx-1][posy-1] = 1 + else: + grid[posx-1][posy-1] = grid[posx-1][posy-1] - 1 + cured.append([posx-1 , posy-1]) + curque.append([posx-1,posy -1,level+1]) + if(posx - 1 >= 0 and posy + 1 < size): + if(grid[posx-1][posy+1] > 1 ): + if([posx-1 , posy+1] not in cured): + if(level == 1 ): + grid[posx-1][posy+1] = 1 + else: + grid[posx-1][posy+1] = grid[posx-1][posy+1] - 1 + cured.append([posx-1,posy+1]) + curque.append([posx-1,posy+1,level+1]) + if(len(curque) > 0): + a = curque[0][0] + b = curque[0][1] + c = curque[0][2] + del curque[0] + cure(a,b,c) + return + +def prgrid(): + for i in grid: + for k in i: + print k, + print + +grid[posinf[0]][posinf[1]] = 5 +infect(posinf[0],posinf[1],6) +grid[poscur[0]][poscur[1]] = 1 +cure(poscur[0] , poscur[1] , 1) +prgrid() + diff --git a/Tcs_CodeVita_2017_Round2/enclosing_items.py b/Tcs_CodeVita_2017_Round2/enclosing_items.py new file mode 100644 index 0000000..b40969e --- /dev/null +++ b/Tcs_CodeVita_2017_Round2/enclosing_items.py @@ -0,0 +1,30 @@ +symb = ["(", ")", "{", "}" ,"[" ,"]" ,"<" ,">", "/","\\"] +open_tag = ["(", "{" ,"[" ,"<" , "/"] +close_tag = [ ")", "}" ,"]" ,">" ,"\\"] + +dic_sym = { ")" : "(" , "}" : "{" , "]" : "[" , ">" : "<" , "\\" : "/" } + +times = input() +while times: + data = raw_input() + string = "" + inside = 0 + for i in range(0,len(data)): + try: + if(data[i] == "@" and data[i+1] == "*"):inside+=1 + if(data[i] == "*" and data[i+1] == "@"):inside-=1 + except: + pass + if inside == 0 and data[i] in symb : string = string + data[i] + out = "True" + tags = [""] + for i in string: + if i in open_tag: + tags.append(i) + elif i in close_tag: + rev = dic_sym.get(i) + if(rev == tags[-1] and len(tags) > 0):del tags[-1] + else: out = "False" + if len(tags) > 1: out = "False" + print out + times-=1 \ No newline at end of file diff --git a/Tcs_CodeVita_2017_Round2/photograph.py b/Tcs_CodeVita_2017_Round2/photograph.py new file mode 100644 index 0000000..3097172 --- /dev/null +++ b/Tcs_CodeVita_2017_Round2/photograph.py @@ -0,0 +1,33 @@ + +def varience(results): + # calculate mean + m = sum(results) / len(results) + + # calculate variance using a list comprehension + return (sum([(xi - m)**2 for xi in results]) / len(results)) + + +inputs = raw_input().split(",") +data = list(map(int , raw_input().split(","))) +"""data_sort = list(data) +data_sort.sort() +print(data_sort) + +print("Printing Varience") +print(data) +print("\n" + str(statistics.stdev(data) ) ) + +sd = statistics.stdev(data) +var = {} +for i in data: + val = 0 + for k in data: + if( ((i -k) **2 )< (sd ** 2) ):continue + val = val + ((i - k) ** 2) + var[i] = val +print(var)""" + +import itertools +dictout = {} +temp = list(itertools.combinations(data,int(inputs[1]),3)) +print temp diff --git a/Xtreme/Jarawi and The Interview.py b/Xtreme/Jarawi and The Interview.py new file mode 100644 index 0000000..3ba16af --- /dev/null +++ b/Xtreme/Jarawi and The Interview.py @@ -0,0 +1,22 @@ + +import re + + +def sequence_in(s1, s2): + """Does `s1` appear in sequence in `s2`?""" + temp = re.findall( + "*".join(s1) , s2) + if(len(temp) >= 1):return True + return False + +maindict = raw_input() +no = input() +for i in range(no): + ans = 0 + sub = "" + temp = raw_input() + for k in range(temp.__len__() - 1 , -1 , -1): + sub = temp[k] + sub + if(sequence_in(sub , maindict )):ans +=1 + else:break + print ans diff --git a/Xtreme/batbear.py b/Xtreme/batbear.py new file mode 100644 index 0000000..099cdf1 --- /dev/null +++ b/Xtreme/batbear.py @@ -0,0 +1,45 @@ +from collections import defaultdict + +class Graph: + def __init__(self, vertices): + self.V = vertices + self.graph = defaultdict(list) + def addEdge(self, v, w): + self.graph[v].append(w) + self.graph[w].append(v) + + + def isCyclicUtil(self, v, visited, parent): + + visited[v] = True + + for i in self.graph[v]: + if visited[i] == False: + if (self.isCyclicUtil(i, visited, v)): + return True + + elif parent != i: + return True + + return False + + def isCyclic(self): + visited = [False] * (self.V) + for i in range(self.V): + if visited[i] == False: + if (self.isCyclicUtil(i, visited, -1)) == True: + return True + + return False + + +inp = input() +for i in range(inp): + lim , gnodes = map(int , raw_input().split(" ")) + g = Graph(lim) + nodes = map(int , raw_input().split(" ")) + while nodes != []: + g.addEdge(nodes[0],nodes[1]) + del nodes[0:2] + if(g.isCyclic()):print"1" + else:print "0" \ No newline at end of file diff --git a/Xtreme/beetlebag.py b/Xtreme/beetlebag.py new file mode 100644 index 0000000..c892e29 --- /dev/null +++ b/Xtreme/beetlebag.py @@ -0,0 +1,40 @@ +def finder(lis , pos,value): + for i,j in enumerate(lis): + if(j[pos] == value): + return i + return -1 + +def finder2(lis , pos,value,pos2,value2): + for i,j in enumerate(lis): + if(j[pos] == value and j[pos2] == value2): + return i + return -1 + +for i in range(input()): + tweight ,no = map(int , raw_input().split(" ")) + lis = [] + for k in range(no): + a,b = map(int , raw_input().split(" ")) + lis.append((b/(a*1.0) , a , b)) + tp = 0 + ans = 0 + while tweight > 0 : + if(no == 0):break + try: + pos = finder(lis , 0 ,(max(map(lambda x: x[0], lis)))) + val = lis[pos][0] + except: + break + + if len([x for x in lis if x[0] == val ]) > 1: + test = [x[2] for x in lis if x[0] == val ] + maxval = max(test) + pos = finder2(lis , 0 , val , 2 , maxval) + val = lis[pos] + if(lis[pos][1] <= tweight ): + tweight = tweight - lis[pos][1] + ans += lis[pos][2] + no -= 1 + del lis[pos] + + print ans \ No newline at end of file diff --git a/Xtreme/cheering_up_bob.py b/Xtreme/cheering_up_bob.py new file mode 100644 index 0000000..c7db700 --- /dev/null +++ b/Xtreme/cheering_up_bob.py @@ -0,0 +1,36 @@ +moves = {} +for i in range(1,10): + moves[i] = map(int , raw_input().split(" ")) + +board = ['-'] * 10 + +def CheckWin(): + if(board[0] == board[1] and board[1] == board[2] and board[0] == 'X'): + return [0,1,2] + elif(board[3] == board[4] and board[4] == board[5] and board[3] == 'X'): + return [3, 4, 5] + elif(board[6] == board[7] and board[7] == board[8] and board[6] == 'X'): + return [6, 7, 8] + elif(board[0] == board[3] and board[3] == board[6] and board[0] == 'X'): + return [0, 3, 6] + elif(board[1] == board[4] and board[4] == board[7] and board[1] == 'X'): + return [1, 4, 7] + elif(board[2] == board[5] and board[5] == board[8] and board[2] == 'X'): + return [2, 5, 8] + elif(board[0] == board[4] and board[4] == board[8] and board[4] == 'X'): + return [0, 4, 8] + elif(board[2] == board[4] and board[4] == board[6] and board[4] == 'X'): + return [2, 4, 6] + return False + +def dicttonum(lis): + return ((lis[0] - 1) * 3) + (lis[1] -1) + +for i in range(1,10): + print dicttonum(moves[i]) + board[dicttonum(moves[i])] = "X" + winningpos = CheckWin() + print board + if CheckWin() != False:print i ; break + +print winningpos \ No newline at end of file diff --git a/Xtreme/circular_disk.py b/Xtreme/circular_disk.py new file mode 100644 index 0000000..3c718d8 --- /dev/null +++ b/Xtreme/circular_disk.py @@ -0,0 +1,21 @@ +import string +import math + +rad = input() +dict = {} +for i in range(26): + char , val = raw_input().split(" ") + dict[char.lower()] = float(val) +inp = raw_input().strip() +prev = '' +out = 0 +for i in inp: + i = i.lower() + if(i not in string.lowercase):continue + if(i == prev):continue + if(prev == ''):prev = i ; out += rad ;continue + temp = abs(( 2 * rad * math.sin(math.radians(abs(dict[prev] - dict[i]) / 2)))) + out = out + temp + prev = i + +print int(math.ceil(out)) \ No newline at end of file diff --git a/Xtreme/dr.fibonacci.py b/Xtreme/dr.fibonacci.py new file mode 100644 index 0000000..ef57e29 --- /dev/null +++ b/Xtreme/dr.fibonacci.py @@ -0,0 +1,9 @@ + +def fib(n): + a,b,c = 0,1,0 + while c < n: + a, b , c = b, a + b , c+1 + return b + +inp = input() +for i in range(inp):print (fib(input() % 60) % 10) diff --git a/Xtreme/factorial.py b/Xtreme/factorial.py new file mode 100644 index 0000000..d000785 --- /dev/null +++ b/Xtreme/factorial.py @@ -0,0 +1,6 @@ +import math + +for i in range(0,20): + print math.factorial(i) + + #371842544 \ No newline at end of file diff --git a/Xtreme/fast_and_curious.py b/Xtreme/fast_and_curious.py new file mode 100644 index 0000000..a8fd2f4 --- /dev/null +++ b/Xtreme/fast_and_curious.py @@ -0,0 +1,73 @@ +looped = [] + +class graph: + def __init__(self): + self.neighbors = {} + + def add_vertex(self, v): + if v not in self.neighbors: + self.neighbors[v] = [] + + def add_edge(self, u, v): + self.neighbors[u].append(v) + # if u == v, do not connect u to itself twice + if u != v: + self.neighbors[v].append(u) + + def vertices(self): + return list(self.neighbors.keys()) + + def vertex_neighbors(self, v): + return self.neighbors[v] + +def is_cyclic_graph(G): + Q = [] + V = G.vertices() + + layer = {v: -1 for v in V} + + for v in V: + layer = {v: -1 for v in V} + # v has already been explored; move on + if layer[v] != -1: + continue + + # take v as a starting vertex + layer[v] = 0 + Q.append(v) + + # as long as Q is not empty + while len(Q) > 0: + + # get the next vertex u of Q that must be looked at + u = Q.pop(0) + + C = G.vertex_neighbors(u) + for z in C: + # if z is being found for the first time + if layer[z] == -1: + layer[z] = layer[u] + 1 + Q.append(z) + elif layer[z] >= layer[u]: + looped.append(z) + + + + + +maxval , no = map(int , raw_input().split(" ")) + +g = graph() + +for i in range(1,no+1): + g.add_vertex(i) + +for i in range(no): + a,b = map(int , raw_input().split(" ")) + g.add_edge(a,b) + +is_cyclic_graph(g) + +val = set(range(1,no)) - set(looped) + +for i in val :print i diff --git a/Xtreme/odd_paths.py b/Xtreme/odd_paths.py new file mode 100644 index 0000000..e5a1fe5 --- /dev/null +++ b/Xtreme/odd_paths.py @@ -0,0 +1,40 @@ +from collections import defaultdict + +looped = [] + +class Graph: + def __init__(self, vertices): + self.V = vertices + self.graph = defaultdict(list) + + def addEdge(self, v, w): + self.graph[v].append(w) + self.graph[w].append(v) + + + + def Checker(self , listvertex ,visited, pvertex,level): + for i in listvertex: + if(i == pvertex ):looped.append(level);return + if(i in visited): continue + visited.append(i) + self.Checker(self.graph[i],visited[:],pvertex,level + 1) + return False + + def CheckCycle(self,vertex): + return self.Checker(self.graph[vertex] , [vertex] , vertex,1) + + +maxval , no = map(int , raw_input().split(" ")) + +g = Graph(no) + +for i in range(no): + a,b = map(int , raw_input().split(" ")) + g.addEdge(a, b) + +for i in range(1,maxval+1): + g.CheckCycle(i) + + +out = set(range(1,maxval+1)) - set(looped) \ No newline at end of file diff --git a/Xtreme/pre1.py b/Xtreme/pre1.py new file mode 100644 index 0000000..b4d2a09 --- /dev/null +++ b/Xtreme/pre1.py @@ -0,0 +1,37 @@ +from collections import defaultdict + +class Graph: + def __init__(self, vertices): + self.V = vertices + self.graph = defaultdict(list) + + def addEdge(self, v, w): + self.graph[v].append(w) + self.graph[w].append(v) + + def Checker(self , listvertex ,visited, pvertex,level): + for i in listvertex: + if(i == pvertex and level > 2):return True + if(i in visited): continue + visited.append(i) + return self.Checker(self.graph[i],visited,pvertex,level + 1) + return False + + def CheckCycle(self,vertex): + return self.Checker(self.graph[vertex] , [] , vertex,1) + + +maxval , no = map(int , raw_input().split(" ")) + +g = Graph(no) + +for i in range(no): + a,b = map(int , raw_input().split(" ")) + g.addEdge(a, b) + +out = [] + +for i in range(1,maxval+1): + if(g.CheckCycle(i) == False):out.append(i) + +for i in out:print i \ No newline at end of file diff --git a/Xtreme/quipu func.py b/Xtreme/quipu func.py new file mode 100644 index 0000000..4b287ba --- /dev/null +++ b/Xtreme/quipu func.py @@ -0,0 +1,15 @@ +def count(n,div): + out = 0 + for i in range(1,n+1): + if(i % div == 0):continue + if(n% i == 0):out += 1 + return out + +no , a , b = map(int,raw_input().split()) + +for i in range(no): + pd = input() + final = 0 + for k in range(a,b+1): + final += count(k,pd) + print final diff --git a/Xtreme/rexor.py b/Xtreme/rexor.py new file mode 100644 index 0000000..e3c7e75 --- /dev/null +++ b/Xtreme/rexor.py @@ -0,0 +1,48 @@ + +def moduleu0(num,length,offset): + while num > length + offset: + + num = num - length + return num + +def minsize(d1,d2,l): + temp = 0 + while d2 > d1: + temp = d2 + d2 -= l + return temp - d1 + +no = input() + + +def f(n): + if (n % 4 == 0): + return n + elif (n % 4 == 1): + return 1 + elif (n % 4 == 2): + return n + 1 + elif (n % 4 == 3): + return 0 + + +for i in range(no): + l,h,n,d1,d2 = map(int , raw_input().split(" ")) + #testing the pos of diagonals + if(moduleu0(d1,l,n) > (l + n)/2 ): + newd1 , newd2 = d1,d2 + while d2 > d1 : d2 = d2 - l + while newd1 < newd2 : newd1 = newd1 + l + d1,d2 = d2,newd1 + remove = [] + minisize = minsize(d1,d2,l) + while d1 b): + a = a//2 + else: + b = b//2 + + + +inp = input() +for i in range(inp): + a,b = map(int ,raw_input().split(" ")) + lca = findlca(a,b) + print int(math.log(a,2)) + int(math.log(b,2)) - (2 * int(math.log(max(lca,1),2) )) + diff --git a/Xtreme/xor.py b/Xtreme/xor.py new file mode 100644 index 0000000..58fb3ee --- /dev/null +++ b/Xtreme/xor.py @@ -0,0 +1,13 @@ +def f(n): + if(n%4 == 0):return n + elif(n%4==1):return 1 + elif(n%4==2):return n+1 + elif(n%4==3):return 0 + +def answer(start,length): + result = 0 + for i in xrange(length): + result = result ^ f((start + i*length ) -1) ^ f(start + (i+1)*length -(i+1)) + return result + +print answer(17,4000000) \ No newline at end of file diff --git a/Xtreme/xtreme_study.py b/Xtreme/xtreme_study.py new file mode 100644 index 0000000..0a7e2cf --- /dev/null +++ b/Xtreme/xtreme_study.py @@ -0,0 +1,30 @@ +dictionary = {} + +temp = [] + +while True: + val = raw_input() + if(val == ""):break + splitted = val.split(" ") + temp.append((int(splitted[0]) , splitted[1:])) + +temper = [] + +for i in temp: + for k in i[1]: + if(k not in temper):temper.append(k) + if(len(i[1]) not in dictionary.keys() ):dictionary[len(i[1])] = [] + dictionary[len(i[1])].append(i) + +for i in dictionary.keys(): + dictionary[i] = sorted(dictionary[i], key=lambda t: t[0]) + +low = [] + +need = temper.__len__() + +def lowest(n,have,time): + if(len(have) == need):return + for i in dictionary[n]: + if(list(set(temper) - set(have)) in i[1]):return + for i in range(len(have),need): diff --git a/abel.py b/abel.py new file mode 100644 index 0000000..b128a2b --- /dev/null +++ b/abel.py @@ -0,0 +1,31 @@ +MAX_SIZE = 20232; +isPrime = [] +SPF = [] +prime = [] + +def mani_sieve(N): + isPrime[0] = False + isPrime[1] = False + for i in range(2,N): + if( isPrime[i] ): + prime.append(i) + SPF[i] = i + j = 0 + while j< len(prime) and i*prime[j] = len(st)):return -1 + return st[pos] + +posi = 0 +for i in range(0,max(len(str1),len(str2))): + if(getter(str1,i) != getter(str2,i)):break + posi +=1 +moves = ((len(str1) - posi) + len(str2) - posi) + +check = 0 + +if(moves <= times): + if(moves != times): + if(len(str1) + len(str2) < times): + print "Yes" + check = 1 + elif((moves - times) %2 != 0):print "No";check = 1 + if(check == 0):print "Yes" + else: + print "Yes" +else:print "No" diff --git a/brick_count.py b/brick_count.py new file mode 100644 index 0000000..02846c0 --- /dev/null +++ b/brick_count.py @@ -0,0 +1,42 @@ + +import math + + +def memoize(f): + + class memodict(dict): + def __init__(self, f): + self.f = f + def __call__(self, *args): + return self[args] + def __missing__(self, key): + ret = self[key] = self.f(*key) + return ret + return memodict(f) + + +@memoize +def build_stair(reserve, previous_step): + if reserve == 0: + return 1 + + + min_brick = (-1+math.sqrt(1+8*reserve)) / 2 + min_brick = int(math.ceil(min_brick)) + + if previous_step == -1: + max_bricks = reserve + else: + max_bricks = previous_step + max_bricks = min(max_bricks, reserve+1) + + nb_stairs = 0 + for i in range(min_brick, max_bricks): + nb_stairs += build_stair(reserve-i, i) + return nb_stairs + + +def answer(n): + return build_stair(n, -1) + +print answer(200) \ No newline at end of file diff --git a/choco_hr.py b/choco_hr.py new file mode 100755 index 0000000..726d69f --- /dev/null +++ b/choco_hr.py @@ -0,0 +1,5 @@ +for i in range(0,input()): + s = sum([int(x) for x in raw_input().split("")]) + if(s % 2 == 0 ): + + else:print "Not Possible" \ No newline at end of file diff --git a/comp1.py b/comp1.py new file mode 100644 index 0000000..e69de29 diff --git a/consecletter.py b/consecletter.py new file mode 100755 index 0000000..cf22ca7 --- /dev/null +++ b/consecletter.py @@ -0,0 +1,12 @@ +#for code monk .. P1 Q2pytho + + +for i in range(0,input()): + dat = raw_input() + temp,chk = dat[0],dat[0] + for i in dat[1:]: + if chk != i: + temp = temp + i + chk = i + print temp + diff --git a/die_iem_16.py b/die_iem_16.py new file mode 100755 index 0000000..6f73520 --- /dev/null +++ b/die_iem_16.py @@ -0,0 +1,3 @@ +lis = ["-","Manish","Manish","Deep","Deep","Utsav","Utsav"] +for i in range(0,input()): + print lis[input()] \ No newline at end of file diff --git a/distict.py b/distict.py new file mode 100644 index 0000000..5426130 --- /dev/null +++ b/distict.py @@ -0,0 +1,15 @@ +import base64 + +MESSAGE = ''' +DU4QHRYLBAEaFhAKVk4EGhAJFVVFERdTGQUPDRQPFBdOEQoQUQwQHBANDBcNFhwQUQwFDhoaFQFO +EQoQUQANCwcNBRsLXVUXWklECRYACBcfVF1VGB1ESE9IRgcHXV9THQwHT1lIRgAIU1JZAhpESE9I +RgEIV1UXWklEDhoHRlJTERdHHwdCTwg= +''' + +KEY = 'vichuhari100' + +result = [] +for i, c in enumerate(base64.b64decode(MESSAGE)): + result.append(chr(ord(c) ^ ord(KEY[i % len(KEY)]))) + +print ''.join(result) \ No newline at end of file diff --git a/foobar2.py b/foobar2.py new file mode 100644 index 0000000..c7b455e --- /dev/null +++ b/foobar2.py @@ -0,0 +1,87 @@ +def get_coord(num): + """ + This will serve as a helper function in our algorithm. + We're solving the knight's shortest path problem, so I'm + breaking the input into a grid-like fashion. + """ + x = int(num%8) + y = int((num-x)/8) + return x, y + + +def answer(src, dest): + """ + I'll tackle this problem using recursion and depth-first search. + :param src: The location we begin at. + :param dest: The destination, an integer. + :return: The shortest number of steps required to reach the destination. + """ + class board: + grid = grid = [[0 for col in range(8)] for row in range(8)] + bunks = board() + + def dfs(srcx, srcy, level): + """ + On each iteration of this algorithm, we will check all eight squares + that our knight can reach from our source tile. If they have not + yet been traversed to, we will mark them with our current + recursion level, and then run this algorithm from those tiles. + We use the created grid mapping to determine how many moves are required + to reach dest from src. + :param srcx: x co-ordinate of this recursive iteration + :param srcy: y co-ordinate of this recursive iteration + :param level: how many times we've called this function + :return: nothing + """ + def mark(x, y, level): + if x not in range(8) or y not in range(8): + return + # A helper function mostly to keep our code readable. + # We change the mark on the tile either if we find a larger level, + if bunks.grid[x][y] > level or bunks.grid[x][y] == 0: + bunks.grid[x][y] = level + return True + # This also isn't java, so we're not protected from out-of-bounds accesses. + if srcx not in range(8) or srcy not in range(8): + return + # If the tile's level is not 0 and less than ours, our traversal to this point + # is pointless. We return. + if bunks.grid[srcx][srcy] != 0 and bunks.grid[srcx][srcy] < level-1: + return + # So first, the 8 possibilities. + # We mark up... + mark(srcx-1, srcy+2, level) + mark(srcx+1, srcy+2, level) + # Right... + mark(srcx+2, srcy-1, level) + mark(srcx+2, srcy+1, level) + # Down... + mark(srcx-1, srcy-2, level) + mark(srcx+1, srcy-2, level) + # Then left. + mark(srcx-2, srcy-1, level) + mark(srcx-2, srcy+1, level) + # Then we traverse to these tiles and repeat the algorithm on each one. + dfs(srcx-1, srcy+2, level+1) + dfs(srcx+1, srcy+2, level+1) + dfs(srcx+2, srcy-1, level+1) + dfs(srcx+2, srcy+1, level+1) + dfs(srcx-1, srcy-2, level+1) + dfs(srcx+1, srcy-2, level+1) + dfs(srcx-2, srcy-1, level+1) + dfs(srcx-2, srcy+1, level+1) + + if src == dest: + # If the coordinates are the same, we have no calculations to do. + return 0 + else: + srcx, srcy = get_coord(src) + destx, desty = get_coord(dest) + dfs(srcx, srcy, 1) + print("End grid:") + for num in range(8): + print(bunks.grid[num]) + print("Moves to dest: " + str(bunks.grid[destx][desty])) + return bunks.grid[destx][desty] + +answer(1,57) \ No newline at end of file diff --git a/formula.py b/formula.py new file mode 100755 index 0000000..e69de29 diff --git a/gift_friends.py b/gift_friends.py new file mode 100755 index 0000000..9cf2776 --- /dev/null +++ b/gift_friends.py @@ -0,0 +1,18 @@ +#for code monk .. P1 Q2 + +for i in range(0,input()): + friends,gift = map(int ,raw_input().split(" ")) + friend_gift = [] + for friend in xrange(0,friends): + friend_gift.append(input()) + print "START" + for val in range(0,friends): + tot_val = 0; + for gifts in friend_gift[val:]: + tot_val = tot_val + int(gifts) + if(tot_val == gift):print "YES" + if(tot_val >= gift):break + if(tot_val == gift):break + if(tot_val != gift ):print "NO" + + diff --git a/google/lead.py b/google/lead.py new file mode 100755 index 0000000..c9541e6 --- /dev/null +++ b/google/lead.py @@ -0,0 +1,22 @@ +val = input() +for k in range(0,val): + dat = [] + lav = input() + for i in range(0,lav): + dat.append(raw_input()) + max_len = 0 + max = "" + new = [] + for i in dat: + p = [] + for l in i: + if(l not in p):p.append(l) + new.append("".join(p)) + for i in new: + if(i.__len__() > max_len): + max_len = i.__len__() + max = i + elif(i.__len__() == max.__len__() and i < max): + max_len = i.__len__() + max = i + print "Case #" +str(k+1) + ": ", dat[new.index(max)] diff --git a/google/rain.py b/google/rain.py new file mode 100755 index 0000000..23e1cb9 --- /dev/null +++ b/google/rain.py @@ -0,0 +1,23 @@ +import copy + +val = input() +for m in range(0,val): + dat = raw_input().split(" ") + wat = [] + for i in range(0,int(dat[0])): + wat.append(raw_input().split(" ")) + small = 1001 + for i in range(1,int(dat[1]) -1): + if(int(wat[0][i]) < small ):small = int(wat[0][i]) + for i in range(1,int(dat[1]) -1): + if(int(wat[-1][i]) < small ):small = int(wat[-1][i]) + for i in range(1,int(dat[0]) -1): + if(int(wat[i][0]) < small):small = int(wat[i][0]) + if(int(wat[i][-1]) < small):small = int(wat[i][-1]) + water = 0 + + for i in range(1,int(dat[0]) - 1): + for k in range(1,int(dat[1]) - 1): + if int(wat[i][k]) < small: + water = water + small - int(wat[i][k]) + print "Case #" +str(m+1) + ": ", water,small \ No newline at end of file diff --git a/ict1.py b/ict1.py new file mode 100755 index 0000000..6b3b14e --- /dev/null +++ b/ict1.py @@ -0,0 +1,9 @@ +dat = raw_input() + " :" +val = raw_input() +sum = len(val) * -1 +ans = dat.split(val) +if(len(ans) == 1 ):print "-1" +else: + for i in ans[:-1]: + sum = sum + len(i) + len(val) + print sum \ No newline at end of file diff --git a/ict2.py b/ict2.py new file mode 100755 index 0000000..566f3a4 --- /dev/null +++ b/ict2.py @@ -0,0 +1,12 @@ +import string +low = string.lowercase * 2 +up = string.uppercase * 2 +out = "" +for i in raw_input(): + if(i in low): + out = out + low[low.find(i) + 2] + elif(i in up ): + out = out + up[up.find(i) + 2] + else: + out = out + i +print out \ No newline at end of file diff --git a/ieee_dog_walk.py b/ieee_dog_walk.py new file mode 100755 index 0000000..671a5ca --- /dev/null +++ b/ieee_dog_walk.py @@ -0,0 +1,19 @@ +__author__ = 'vignesh' + +for i in range(0,input()): + dogs,walkers = [int(x) for x in raw_input().split()] + dog_size = [] + for t in range(dogs): + dog_size.append(input()) + dog_size.sort() + grp = dogs/walkers + ans = 0 + for w in range(walkers-1): + val = 0 + + size = dog_size[:grp] + ans = ans + max(size) - min(size) + del dog_size[:grp] + print dog_size + ans = max(dog_size) - min(dog_size) + print ans diff --git a/ieee_food_truck.py b/ieee_food_truck.py new file mode 100755 index 0000000..79d97cc --- /dev/null +++ b/ieee_food_truck.py @@ -0,0 +1,29 @@ +import sys +from math import radians, cos, sin, asin, sqrt + + +def distance(lon1, lat1, lon2, lat2): + lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) + diflon = lon2 - lon1 + diflat = lat2 - lat1 + temp1 = sin(diflat/2)**2 + cos(lat1) * cos(lat2) * sin(diflon/2)**2 + temp2 = 2 * asin(sqrt(temp1)) + dist = 6378.137 * temp2 + return dist +''' +18.9778972,72.8321983 +1.0 +Date&Time,Latitude,Longitude,PhoneNumber +10/21/2016 13:34,18.912875,72.822318,9020320100 +10/21/2016 10:35,18.9582233,72.8275845,9020320024 +10/21/2016 15:20,18.95169982,72.83525604,9020320047 +10/21/2016 15:23,18.9513048,72.8343388,9020357980 + +''' + +print distance(18.9778972,72.8321983, 18.97523003,72.83494865) +orglat , orglong = [float(x) for x in raw_input().split(" ")] +dis = float(raw_input()) +raw_input() + + diff --git a/ieee_full_adder.py b/ieee_full_adder.py new file mode 100755 index 0000000..c94772e --- /dev/null +++ b/ieee_full_adder.py @@ -0,0 +1,49 @@ +__author__ = 'vignesh' + +str1 = raw_input() +str2 = raw_input() +str3 = raw_input() +str4 = raw_input() +no,lis = (str1.split(" ")) +no = int(no) +lis = list(lis) * 3 +sum1,sum2 = [],[] +for i in str2.strip(): + sum1.append(i) +for i in str3[1:].strip(): + sum2.append(i) +print sum1,sum2 +if(len(sum1) > len(sum2)):sum1,sum2 = sum2,sum1 +length = len(sum2) +dat = [0] * length +ans = [] +index = 0 +while len(sum2) != 0: + dat1 = 0 + val1,val2 = "","" + if(len(sum1) != 0 ): + val1 = sum1[-1] + dat1 = lis.index(str(val1)) + if(len(sum1) == 1): sum1 = [] + else:del sum1[-1] + val2 = sum2[-1] + del sum2[-1] + dat2 = lis.index(str(val2)) + dat[index] + sum = dat1 + dat2 + if(sum >= no ): + diff = (sum) / no + fsum = sum - (no * diff) + value = fsum + if(index +1 != length): + dat[index+1] =dat[index+1] + diff + else: + dat.append(no) + ans.append(lis[sum]) + index = index + 1 +ans.reverse() +print str1 +print str2 +print str3 +print str4 +ansprint = " " + ''.join(ans) +print ansprint \ No newline at end of file diff --git a/ieee_password.py b/ieee_password.py new file mode 100755 index 0000000..55def00 --- /dev/null +++ b/ieee_password.py @@ -0,0 +1,17 @@ +import copy +import string +lower = string.lowercase * 2 +password = list(raw_input()) +current = copy.deepcopy(password) +for i in xrange(input()): + values = raw_input().split(" ") + values = [int(x)-1 for x in values] + if(values[0] == 0): + if(current[values[1]:values[2]+1] == current[values[3]:values[3]+(values[2] - values[1] + 1) ]): + print "Y" + else: + print "N" + if(values[0] == 1): + current[values[1]:values[2] +1] = current[values[3]:values[3]+(values[2] - values[1] + 1) ] + if(values[0] == 2): + current[values[1]:values[2] +1] = [lower[lower.index(x) + 1] for x in current[values[1]:values[2] +1]] diff --git a/ieee_petals.py b/ieee_petals.py new file mode 100755 index 0000000..be9a38a --- /dev/null +++ b/ieee_petals.py @@ -0,0 +1,10 @@ +import math +for i in range(input()): + val = int(raw_input()) + root = long(math.log(val,2)) + num = long(val) - ((2 ** root)) + if(num < 0 ):num = long(val) - ((2 ** (root-1))) + print (2*num)+1 + + + diff --git a/ieee_prime.py b/ieee_prime.py new file mode 100755 index 0000000..7a7a287 --- /dev/null +++ b/ieee_prime.py @@ -0,0 +1,17 @@ +def p(n): # will print out primes between 0 and n + s=[True]*(n/2) + for i in xrange(int((n/2-1)/2) >> 1): + for j in xrange((i*(i+3)<<1)+3,n/2,(i<<1)+3): s[j]=False + return [2] + [((i<<1)+3) for i in xrange(n/2) if (s[i])] + +def primechk(val,prime): + for i in prime: + for k in prime: + temp = val -i-k + if( temp in prime and temp != i and temp != k and i !=k ): + print i , k , (temp) + return 0 + return 0 +val = input() +prime = p(val)[2:] +primechk(val,prime) \ No newline at end of file diff --git a/ieee_stone.py b/ieee_stone.py new file mode 100755 index 0000000..77c354c --- /dev/null +++ b/ieee_stone.py @@ -0,0 +1,14 @@ +t = input() +for i in range(0,t): + no = input() + turns = 0 + for j in range(0,no): + pile = input() + pile_stone = [int(x) for x in raw_input().split()] + for k in range(0,pile): + if pile_stone[k]>1: + turns += (pile_stone[k]-1)/2 + if turns % 2 == 0: + print 'Bob' + else: + print 'Alice' \ No newline at end of file diff --git a/lambs.py b/lambs.py new file mode 100644 index 0000000..9ac6d56 --- /dev/null +++ b/lambs.py @@ -0,0 +1,36 @@ +def fib(limit): + if (limit < 2): + return 1; + n_1 = 1 + n_2 = 1; + times = 2 + sum = 2 + while True : + n_new = n_1 + n_2; + n_1 = n_2; + n_2 = n_new; + sum += n_new + if(sum > limit ):break + times += 1 + return times; + +def power(limit): + mul = 0 + sum = 0 + while True: + sum = sum + 2 ** mul + if(sum > limit):break + mul += 1 + sum = sum - 2 ** mul + if(limit - sum >= (2** (mul-1) + 2** (mul -2) )): mul+=1 + return mul + +def answer(total_lambs): + if total_lambs >= 10 and total_lambs <= 10 ** 9: + return fib(total_lambs) - power(total_lambs) + return 0 + +print answer(13) + +print "max " , fib(13) +print "min " , power(13) \ No newline at end of file diff --git a/luggage.py b/luggage.py new file mode 100755 index 0000000..f07b73f --- /dev/null +++ b/luggage.py @@ -0,0 +1,15 @@ +#for code monk .. P2 Q2 + +for i in range(0,input()): + friends = input() + friend_weight = [] + for friend in xrange(0,friends): + friend_weight.append(input()) + out = [] + for k in range(0,friends): + temp = 0 + for day in friend_weight[k:]: + if(day < friend_weight[k]): + temp = temp +1 + out.append(temp) + print ' '.join([str(x) for x in out]) \ No newline at end of file diff --git a/max_val.py b/max_val.py new file mode 100755 index 0000000..7f68810 --- /dev/null +++ b/max_val.py @@ -0,0 +1,33 @@ +data = raw_input().split(" ") +wl = int(data[0]) +ar = int(data[1]) +print type(wl),type(ar) +def suf_area(l,b,h): + return (2*l*b) + (2*b*h) + (2*l*h) +def vol(n): + return n[0]*n[1]*n[2] +def approxans(val,wl): + if(val <= wl and val + .1 >= wl):return True + return False +max_val = [0] * 3 +lc = 0.01 +h,l,b=0,0,0 +loop = 0 +while True: + loop+=1 + print "CH " ,loop + l = l + 0.1 + if(4*(b+l+h) > wl):break + while True: + h = h + 0.1 + if(4*(b+l+h) > wl):h=0;break + while True: + b = b+0.1 + if((4*(b+l+h)) != float(wl)): + if((4*(b+l+h)) > wl):print "brocken at" , l , " " , h , " " , b;b=0;break + print l ," ",h," ",b + if(vol(max_val) < vol([l,b,h]) and approxans(suf_area(l,b,h),ar) and approxans(4*(l+b+h),wl)): + print l,b,h + max_val = [l,b,h] +print vol(max_val) +print max_val \ No newline at end of file diff --git a/merger.py b/merger.py new file mode 100755 index 0000000..8952e78 --- /dev/null +++ b/merger.py @@ -0,0 +1,18 @@ +#for code monk .. P2 Q3 + +for i in range(0,input()): + raw_input() + arr1 = [int(x) for x in raw_input().split(" ")] + arr2 = [int(x) for x in raw_input().split(" ")] + arr1.append(-1) + arr2.append(-1) + a1,a2 = 0,0 + while True: + if(arr1[a1] == -1 and arr2[a2] == -1):break + if(arr1[a1] > arr2[a2]): + print arr1[a1], + a1 = a1+1 + else: + print arr2[a2], + a2 = a2+1 + print "" diff --git a/misc.py b/misc.py new file mode 100755 index 0000000..38f3999 --- /dev/null +++ b/misc.py @@ -0,0 +1,21 @@ +b = 28 +s = 22 +n=int(input()) +lis = ['6', str(b)] +a=[] +for i in range(103): + s += 16 + b += s + lis.append(b) +for i in range(len(lis)): + a.append(('0' * (5 - len(str(lis[i]))))+str(lis[i])) +k=0 + + + +for i in range(0,n+1): + if (i!=0):print(' ' * (n - i), end="") + for j in range(0,i): + print( a[k], end=" ") + k+=1 + if(i != 0):print('') diff --git a/monk_in_grass.py b/monk_in_grass.py new file mode 100755 index 0000000..1b3bb98 --- /dev/null +++ b/monk_in_grass.py @@ -0,0 +1,43 @@ +#for code monk .. P2 Q4 + + +def sum_row_col(arr,time): + row,col = [],[] + for x in range(0,time): + r,c=0,0 + for y in range(0,time): + r = r + data[x][y] + c = c + data[y][x] + row.append(r) + col.append(c) + return [row,col] + +for i in range(0,input()): + time,lim = (int(x) for x in raw_input().split(" ")) + data = [] + ans = 0 + for tim in range(0,time): + data.append([int(x) for x in raw_input().split(" ")]) + row,col = sum_row_col(data,time) + while lim != 0: + lim-=1 + mc = min(col) + mr = min(row) + if(mc == mr): + if(sum(col) < sum(row)): + ans += mc + col[col.index(mc)] += time + for tim in range(0,time):row[tim] +=1 + else: + ans += mr + for tim in range(0,time):col[tim] +=1 + row[row.index(mr)] += time + elif(mc < mr): + ans += mc + col[col.index(mc)] += time + for tim in range(0,time):row[tim] +=1 + else: + ans += mr + for tim in range(0,time):col[tim] +=1 + row[row.index(mr)] += time + print ans diff --git a/monk_palindrome.py b/monk_palindrome.py new file mode 100644 index 0000000..99154d8 --- /dev/null +++ b/monk_palindrome.py @@ -0,0 +1,15 @@ +n = input() +while n: + val = raw_input() + leng = len(val) - 1 + temp = "".join([ val[leng-x] for x,y in enumerate(val) ]) + # to reverse temp = val[::-1] + if( val == temp): + if(leng % 2 == 0): + print "YES ODD" + else: + print "YES EVEN" + else: + print "NO" + n-=1 + diff --git a/monk_welcome_problem.py b/monk_welcome_problem.py new file mode 100644 index 0000000..242f118 --- /dev/null +++ b/monk_welcome_problem.py @@ -0,0 +1,4 @@ +input() +arr1 = map(int , raw_input().split(" ")) +arr2 = map(int , raw_input().split(" ")) +print " ".join(map(str ,[x + y for x , y in zip(arr1 , arr2) ])) diff --git a/myst_maze.py b/myst_maze.py new file mode 100755 index 0000000..eaa0448 --- /dev/null +++ b/myst_maze.py @@ -0,0 +1,49 @@ +__author__ = 'vignesh' +import copy + +rc = input() +maze = [] +for i in range(rc-1): + maze.append( ["X"] * (rc)) +maze.append(["-"] * rc) + +def mazer(x,y): + if(x == rc- 1): + maze[x][y] = "O" + else: + maze[x][y] = "-" + try: + if(maze[x][y+1] == "X" and maze[x][y-1] == "X" and maze[x-1][y] == "X" and maze[x+1][y] == "X"):return False + except: + pass + for i in range(0,rc): + if(maze[0][i] == "-" ): + if(search(copy.deepcopy(maze),0,i)): + return True + return False + +def search(mazed,x, y): + if mazed[x][y] == "O": + return True + elif mazed[x][y] == "X" or mazed[x][y] == "V": + return False + mazed[x][y] = "V" + + if ((x < len(mazed)-1 and search(mazed,x+1, y)) + or (y > 0 and search(mazed,x, y-1)) + or (x > 0 and search(mazed,x-1, y)) + or (y < len(mazed)-1 and search(mazed,x, y+1))): + return True + return False + +looper = 0 +check = True +while True: + looper+=1 + temp = raw_input() + if(temp == "-1"):break + xv,yv = (int(x) for x in temp.split(" ")) + if(mazer(xv - 1,yv -1)): + print looper;check=False;break +if(check):print -1 + diff --git a/navendu.py b/navendu.py new file mode 100644 index 0000000..f0b3b85 --- /dev/null +++ b/navendu.py @@ -0,0 +1,7 @@ +def answer(x,y): + if(len(y) > len(x)):x,y = y,x + for i in x: + if i not in y:return i + return -1 + +print answer([13,5,6,2,5],[5,2,5,13]) \ No newline at end of file diff --git a/pretty_print.py b/pretty_print.py new file mode 100644 index 0000000..cb51a94 --- /dev/null +++ b/pretty_print.py @@ -0,0 +1,34 @@ +def space1(i,j): + out = "" + for i in range(j-i): + out += " " + return out + +def space2(i): + out = "" + for i in range(0,i*2): + out += " " + return out + +inp = list(raw_input()) +inp.reverse() +output = """""" + +for i,j in enumerate(inp): + l = len(inp) + current = l - i + if(i == 0): + output += space1(i,l) + output += j + "\n" + else: + output += space1(i,l) + output += j + output += space2(i) + output += j + "\n" + +output = output.rstrip() +print output +reverse_style = output.split("\n") +reverse_style.reverse() +for line in reverse_style: + print line \ No newline at end of file diff --git a/primer.py b/primer.py new file mode 100644 index 0000000..a61255e --- /dev/null +++ b/primer.py @@ -0,0 +1,16 @@ +def answer(n): + string = "2357" + num = 10 + while True: + if (prime(num)): string += str(num) + if (len(string) >= 10005): break + num += 1 + ans = 3 + return string[n:n + 5] +import math +def prime(n): + for i in range(2, int(math.sqrt(n)) + 1 ): + if (n % i == 0): return False + return True + +print answer(10000) \ No newline at end of file diff --git a/pytudes/LICENSE b/pytudes/LICENSE new file mode 100644 index 0000000..1e68790 --- /dev/null +++ b/pytudes/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2010-2017 Peter Norvig + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pytudes/README.md b/pytudes/README.md new file mode 100644 index 0000000..9c1edc8 --- /dev/null +++ b/pytudes/README.md @@ -0,0 +1,75 @@ +# pytudes + +"An *étude* (a French word meaning *study*) is an instrumental musical composition, usually short, of considerable difficulty, and designed to provide practice material for perfecting a particular musical skill." — [Wikipedia](https://en.wikipedia.org/wiki/%C3%89tude) + +This project contains **pytudes**—Python programs for perfecting programming skills. + +Some are in Jupyter (IPython) notebooks, some in `.py` files. You can view the files here, or clone the project, or run the notebooks online by clicking this button: [![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/norvig/pytudes/master) + +# Index of Jupyter (IPython) Notebooks + +|Logic and Number Puzzles| +|---| +|[Advent of Code 2017](https://github.com/norvig/pytudes/blob/master/ipynb/Advent%202017.ipynb)
*Puzzle site with a coding puzzle each day for Advent 2017; currently ongoing.*| +|[Advent of Code 2016](https://github.com/norvig/pytudes/blob/master/ipynb/Advent%20of%20Code.ipynb)
*Puzzle site with a coding puzzle each day for Advent 2016*.| +|[Translating English Sentences into Propositional Logic Statements](https://github.com/norvig/pytudes/blob/master/ipynb/PropositionalLogic.ipynb)
*Automatically converting informal English sentences into formal Propositional Logic.*| +|[The Puzzle of the Misanthropic Neighbors](https://github.com/norvig/pytudes/blob/master/ipynb/Mean%20Misanthrope%20Density.ipynb)
*How crowded will this neighborhood be, if nobody wants to live next door to anyone else?*| +|[Countdown to 2016](https://github.com/norvig/pytudes/blob/master/ipynb/Countdown.ipynb)
*Solving the equation 10 _ 9 _ 8 _ 7 _ 6 _ 5 _ 4 _ 3 _ 2 _ 1 = 2016. From an Alex Bellos puzzle.*| +|[Sicherman Dice](https://github.com/norvig/pytudes/blob/master/ipynb/Sicherman%20Dice.ipynb)
*Find a pair of dice that is like a regular pair of dice, only different.*| +|[Beal's Conjecture Revisited](https://github.com/norvig/pytudes/blob/master/ipynb/Beal.ipynb)
*A search for counterexamples to Beal's Conjecture*| +|[When is Cheryl's Birthday?](https://github.com/norvig/pytudes/blob/master/ipynb/Cheryl.ipynb)
*Solving the "Cheryl's Birthday" logic puzzle.*| +|[When Cheryl Met Eve: A Birthday Story](https://github.com/norvig/pytudes/blob/master/ipynb/Cheryl-and-Eve.ipynb)
*Inventing new puzzles in the Style of Cheryl's Birthday.*| +|[Sol Golomb's Rectangle Puzzle](https://github.com/norvig/pytudes/blob/master/ipynb/Golomb-Puzzle.ipynb)
*A Puzzle involving placing rectangles of different sizes inside a square. Bonus: cryptarithmetic.*| +|[WWW: Will Warriors Win?](https://github.com/norvig/pytudes/blob/master/ipynb/WWW.ipynb)
*Golden State Warriors probability of winning the 2016 NBA title.*| + +|Word Games| +|---| +|[Ghost](https://github.com/norvig/pytudes/blob/master/ipynb/Ghost.ipynb)
*The word game Ghost (add letters, try to avoid making a word).*| +|[World's Longest Palindrome](https://github.com/norvig/pytudes/blob/master/ipynb/pal3.ipynb)
*Searching for a long Panama-style palindrome, this time letter-by-letter.*| +|[Refactoring a Crossword Game Program](https://github.com/norvig/pytudes/blob/master/ipynb/Scrabble.ipynb)
*Refactoring the Scrabble / Word with Friends game from Udacity 212.*| +|[xkcd 1313: Regex Golf](https://github.com/norvig/pytudes/blob/master/ipynb/xkcd1313.ipynb)
*Find the smallest regular expression; inspired by Randall Monroe.*| +|[xkcd 1313: Regex Golf (Part 2: Infinite Problems)](https://github.com/norvig/pytudes/blob/master/ipynb/xkcd1313-part2.ipynb)
*Regex Golf: better, faster, funner. With Stefan Pochmann.*| +|[Let's Code About Bike Locks](https://github.com/norvig/pytudes/blob/master/ipynb/Fred%20Buns.ipynb)
*A tale of a bicycle combination lock that uses letters instead of digits. Inspired by Bike Snob NYC.*| +|[Gesture Typing](https://github.com/norvig/pytudes/blob/master/ipynb/Gesture%20Typing.ipynb)
*What word has the longest path on a gesture-typing smartphone keyboard? Inspired by Nicolas Schank and Shumin Zhai.*| +|[How to Do Things with Words, or Statistical Natural Language Processing in Python](https://github.com/norvig/pytudes/blob/master/ipynb/How%20to%20Do%20Things%20with%20Words.ipynb)
*Spelling Correction, Secret Codes, Word Segmentation, and more: grab your bag of words.*| + +|Computer Science Algorithms, Concepts, and Problems| +|---| +|[A Chaos Game with Triangles](https://github.com/norvig/pytudes/blob/master/ipynb/Sierpinski.ipynb)
*A surprising appearance of the Sierpinski triangle in a random walk between vertexes.*| +|[BASIC Interpreter](https://github.com/norvig/pytudes/blob/master/ipynb/BASIC.ipynb)
*How to write an interpreter for the BASIC programming language.*| +|[Bad Grade, Good Experience](https://github.com/norvig/pytudes/blob/master/ipynb/Snobol.ipynb)
*As a student, did you ever get a bad grade on a programming assignment? (Snobol, Concordance)*| +|[Conway's Game of Life](https://github.com/norvig/pytudes/blob/master/ipynb/Life.ipynb)
*The cellular automata zero-player game.*| +|[A Concrete Introduction to Probability](https://github.com/norvig/pytudes/blob/master/ipynb/Probability.ipynb)
*Code and examples of the basic principles of Probability Theory.*| +|[Probability, Paradox, and the Reasonable Person Principle](https://github.com/norvig/pytudes/blob/master/ipynb/ProbabilityParadox.ipynb)
*Some classic paradoxes in Probability Theory, and how to think about disagreements.*| +|[The Convex Hull Problem](https://github.com/norvig/pytudes/blob/master/ipynb/Convex%20Hull.ipynb)
*A classic Computer Science Algorithm.*| +|[The Traveling Salesperson Problem](https://github.com/norvig/pytudes/blob/master/ipynb/TSP.ipynb)
*Another of the classics.*| +|[Economics Simulation](https://github.com/norvig/pytudes/blob/master/ipynb/Economics.ipynb)
*A simulation of a simple economic game.*| +|[Project Euler Utilities](https://github.com/norvig/pytudes/blob/master/ipynb/Project%20Euler%20Utils.ipynb)
*My utility functions for the Project Euler problems, including `Primes` and `Factors`.*| + +# Index of Python Files + +| **File** | **Description** | **Documentation**| +|:--------|:-------------------|----| +|[SET.py](https://github.com/norvig/pytudes/blob/master/py/SET.py)|Analyze the card game [SET](http://www.setgame.com/set).|[SET.html](http://norvig.com/SET.html)| +|[beal.py](https://github.com/norvig/pytudes/blob/master/py/beal.py)|Search for counterexamples to Beal's Conjecture|[beal.html](http://norvig.com/beal.html) +|[docex.py](https://github.com/norvig/pytudes/blob/master/py/docex.py)|A framework for running unit tests, similar to `doctest`.| +|[ibol.py](https://github.com/norvig/pytudes/blob/master/py/ibol.py)|An Exercise in Species Barcoding|[ibol.html](http://norvig.com/ibol.html) +|[lettercount.py](https://github.com/norvig/pytudes/blob/master/py/lettercount.py)|Convert Google Ngram Counts to Letter Counts|[mayzner.html](http://norvig.com/mayzner.html) +|[lis.py](https://github.com/norvig/pytudes/blob/master/py/lis.py)|Lisp Interpreter written in Python|[lispy.html](http://norvig.com/lispy.html) +|[lispy.py](https://github.com/norvig/pytudes/blob/master/py/lispy.py)|Even Better Lisp Interpreter written in Python|[lispy2.html](http://norvig.com/lispy2.html) +|[lispytest.py](https://github.com/norvig/pytudes/blob/master/py/lispytest.py)|Tests for Lisp Interpreters| +|[pal.py](https://github.com/norvig/pytudes/blob/master/py/pal.py)|Find long palindromes|[palindrome.html](http://norvig.com/palindrome.html) +|[pal2.py](https://github.com/norvig/pytudes/blob/master/py/pal2.py)|Find longer palindromes|[palindrome.html](http://norvig.com/palindrome.html) +|[pal3.py](https://github.com/norvig/pytudes/blob/master/py/pal3.py)|Find even longer palindromes|[palindrome.html](http://norvig.com/palindrome.html) +|[py2html.py](https://github.com/norvig/pytudes/blob/master/py/py2html.py)|Pretty-printer to format Python files as html| +|[spell.py](https://github.com/norvig/pytudes/blob/master/py/spell.py)|Spelling corrector|[spell-correct.html](http://norvig.com/spell-correct.html) +|[sudoku.py](https://github.com/norvig/pytudes/blob/master/py/sudoku.py)|Program to solve sudoku puzzles|[sudoku.html](http://norvig.com/sudoku.html) +|[testaccum.py](https://github.com/norvig/pytudes/blob/master/py/testaccum.py)|Tests for my failed Python `accumulation display` proposal|[pyacc.html](http://norvig.com/pyacc.html) +|[yaptu.py](https://github.com/norvig/pytudes/blob/master/py/yaptu.py)|Yet Another Python Templating Utility| + +# Etudes for Programmers + +I got the idea for the "etudes" part of the name from this [1978 book by Charles Wetherell](https://books.google.com/books/about/Etudes_for_programmers.html?id=u89WAAAAMAAJ) +that was very influential to me when I was learning to program. + +![](https://images-na.ssl-images-amazon.com/images/I/51ZnZH29dvL._SX394_BO1,204,203,200_.jpg) diff --git a/pytudes/data/advent2016/input1.txt b/pytudes/data/advent2016/input1.txt new file mode 100644 index 0000000..456904d --- /dev/null +++ b/pytudes/data/advent2016/input1.txt @@ -0,0 +1 @@ +R4, R5, L5, L5, L3, R2, R1, R1, L5, R5, R2, L1, L3, L4, R3, L1, L1, R2, R3, R3, R1, L3, L5, R3, R1, L1, R1, R2, L1, L4, L5, R4, R2, L192, R5, L2, R53, R1, L5, R73, R5, L5, R186, L3, L2, R1, R3, L3, L3, R1, L4, L2, R3, L5, R4, R3, R1, L1, R5, R2, R1, R1, R1, R3, R2, L1, R5, R1, L5, R2, L2, L4, R3, L1, R4, L5, R4, R3, L5, L3, R4, R2, L5, L5, R2, R3, R5, R4, R2, R1, L1, L5, L2, L3, L4, L5, L4, L5, L1, R3, R4, R5, R3, L5, L4, L3, L1, L4, R2, R5, R5, R4, L2, L4, R3, R1, L2, R5, L5, R1, R1, L1, L5, L5, L2, L1, R5, R2, L4, L1, R4, R3, L3, R1, R5, L1, L4, R2, L3, R5, R3, R1, L3 diff --git a/pytudes/data/advent2016/input10.txt b/pytudes/data/advent2016/input10.txt new file mode 100644 index 0000000..b3db0ac --- /dev/null +++ b/pytudes/data/advent2016/input10.txt @@ -0,0 +1,231 @@ +value 23 goes to bot 208 +bot 125 gives low to bot 58 and high to bot 57 +value 13 goes to bot 161 +bot 178 gives low to bot 88 and high to bot 172 +value 59 goes to bot 128 +bot 173 gives low to bot 83 and high to bot 202 +bot 189 gives low to bot 35 and high to bot 55 +bot 123 gives low to bot 90 and high to bot 169 +bot 148 gives low to bot 101 and high to bot 134 +bot 36 gives low to bot 78 and high to bot 105 +bot 196 gives low to bot 171 and high to bot 45 +bot 157 gives low to bot 179 and high to bot 87 +bot 124 gives low to bot 25 and high to bot 80 +bot 55 gives low to bot 99 and high to bot 201 +value 17 goes to bot 4 +bot 127 gives low to bot 118 and high to bot 142 +bot 9 gives low to bot 61 and high to bot 198 +bot 71 gives low to bot 86 and high to bot 96 +bot 86 gives low to bot 98 and high to bot 149 +bot 176 gives low to bot 89 and high to bot 171 +bot 38 gives low to bot 107 and high to bot 63 +bot 67 gives low to bot 77 and high to bot 7 +bot 131 gives low to output 6 and high to bot 151 +bot 97 gives low to bot 33 and high to bot 16 +bot 89 gives low to bot 27 and high to bot 36 +bot 29 gives low to bot 185 and high to bot 11 +bot 92 gives low to bot 189 and high to bot 122 +bot 77 gives low to output 7 and high to bot 191 +bot 14 gives low to bot 152 and high to bot 179 +bot 49 gives low to bot 76 and high to bot 64 +value 2 goes to bot 155 +bot 159 gives low to bot 182 and high to bot 49 +bot 129 gives low to bot 141 and high to bot 40 +bot 50 gives low to output 1 and high to bot 47 +bot 93 gives low to output 5 and high to bot 167 +bot 112 gives low to output 13 and high to bot 51 +bot 165 gives low to bot 163 and high to bot 123 +bot 13 gives low to bot 75 and high to bot 74 +bot 141 gives low to bot 178 and high to bot 207 +bot 37 gives low to bot 42 and high to bot 139 +value 31 goes to bot 92 +bot 44 gives low to bot 16 and high to bot 91 +bot 172 gives low to bot 84 and high to bot 27 +bot 39 gives low to bot 44 and high to bot 154 +bot 170 gives low to bot 95 and high to bot 146 +bot 98 gives low to bot 193 and high to bot 17 +bot 4 gives low to bot 26 and high to bot 109 +bot 197 gives low to bot 71 and high to bot 106 +bot 132 gives low to bot 161 and high to bot 181 +bot 54 gives low to bot 156 and high to bot 148 +bot 140 gives low to bot 0 and high to bot 25 +bot 59 gives low to output 10 and high to bot 93 +bot 206 gives low to bot 2 and high to bot 200 +bot 5 gives low to bot 201 and high to bot 173 +bot 81 gives low to bot 24 and high to bot 30 +bot 33 gives low to bot 100 and high to bot 113 +bot 73 gives low to bot 60 and high to bot 129 +bot 43 gives low to output 14 and high to bot 204 +bot 143 gives low to bot 176 and high to bot 196 +bot 182 gives low to bot 70 and high to bot 76 +bot 139 gives low to bot 117 and high to bot 180 +bot 31 gives low to bot 131 and high to bot 137 +bot 179 gives low to bot 31 and high to bot 28 +bot 74 gives low to bot 29 and high to bot 160 +bot 7 gives low to bot 191 and high to bot 21 +bot 83 gives low to bot 165 and high to bot 116 +bot 142 gives low to bot 144 and high to bot 107 +bot 187 gives low to bot 129 and high to bot 68 +value 61 goes to bot 32 +bot 32 gives low to bot 72 and high to bot 53 +bot 53 gives low to bot 121 and high to bot 199 +bot 79 gives low to bot 143 and high to bot 196 +bot 0 gives low to bot 92 and high to bot 194 +bot 8 gives low to bot 56 and high to bot 209 +value 43 goes to bot 72 +bot 95 gives low to output 18 and high to bot 112 +bot 104 gives low to bot 41 and high to bot 185 +bot 198 gives low to bot 103 and high to bot 48 +bot 17 gives low to bot 69 and high to bot 156 +bot 138 gives low to output 0 and high to bot 77 +bot 76 gives low to bot 127 and high to bot 164 +bot 110 gives low to bot 206 and high to bot 60 +bot 60 gives low to bot 200 and high to bot 141 +bot 134 gives low to bot 67 and high to bot 7 +bot 90 gives low to bot 12 and high to bot 192 +bot 208 gives low to bot 155 and high to bot 182 +bot 87 gives low to bot 28 and high to bot 195 +bot 108 gives low to bot 53 and high to bot 186 +bot 150 gives low to bot 154 and high to bot 56 +bot 204 gives low to output 17 and high to bot 58 +bot 174 gives low to bot 138 and high to bot 67 +bot 195 gives low to bot 147 and high to bot 81 +bot 24 gives low to bot 146 and high to bot 3 +bot 12 gives low to bot 119 and high to bot 9 +value 37 goes to bot 35 +bot 137 gives low to bot 151 and high to bot 170 +bot 1 gives low to output 2 and high to bot 22 +bot 63 gives low to bot 150 and high to bot 8 +bot 133 gives low to bot 140 and high to bot 124 +bot 154 gives low to bot 91 and high to bot 110 +bot 145 gives low to bot 47 and high to bot 18 +bot 109 gives low to bot 159 and high to bot 82 +bot 202 gives low to bot 116 and high to bot 37 +bot 168 gives low to bot 133 and high to bot 177 +bot 193 gives low to bot 93 and high to bot 69 +bot 191 gives low to output 16 and high to bot 21 +bot 135 gives low to bot 82 and high to bot 163 +bot 130 gives low to bot 102 and high to bot 114 +bot 26 gives low to bot 208 and high to bot 159 +bot 152 gives low to bot 22 and high to bot 31 +bot 118 gives low to bot 136 and high to bot 144 +bot 149 gives low to bot 17 and high to bot 54 +bot 64 gives low to bot 164 and high to bot 119 +bot 120 gives low to bot 64 and high to bot 12 +bot 180 gives low to bot 188 and high to bot 130 +bot 203 gives low to bot 204 and high to bot 125 +bot 3 gives low to bot 46 and high to bot 104 +bot 114 gives low to bot 205 and high to bot 79 +bot 25 gives low to bot 194 and high to bot 20 +bot 65 gives low to bot 181 and high to bot 118 +bot 169 gives low to bot 192 and high to bot 117 +bot 51 gives low to output 8 and high to bot 50 +bot 41 gives low to bot 50 and high to bot 145 +bot 20 gives low to bot 23 and high to bot 10 +bot 106 gives low to bot 96 and high to bot 126 +bot 23 gives low to bot 5 and high to bot 6 +value 11 goes to bot 43 +value 47 goes to bot 189 +value 5 goes to bot 115 +bot 46 gives low to bot 51 and high to bot 41 +bot 115 gives low to bot 43 and high to bot 203 +bot 209 gives low to bot 73 and high to bot 187 +bot 16 gives low to bot 113 and high to bot 62 +bot 101 gives low to bot 174 and high to bot 134 +bot 167 gives low to output 20 and high to bot 158 +value 3 goes to bot 133 +bot 184 gives low to bot 125 and high to bot 100 +bot 155 gives low to bot 166 and high to bot 70 +bot 88 gives low to bot 81 and high to bot 84 +value 19 goes to bot 0 +bot 171 gives low to bot 36 and high to bot 45 +bot 186 gives low to bot 199 and high to bot 97 +bot 111 gives low to bot 209 and high to bot 85 +bot 22 gives low to output 4 and high to bot 131 +bot 166 gives low to bot 132 and high to bot 65 +bot 6 gives low to bot 173 and high to bot 52 +bot 75 gives low to bot 104 and high to bot 29 +bot 91 gives low to bot 62 and high to bot 206 +bot 164 gives low to bot 142 and high to bot 38 +bot 15 gives low to bot 160 and high to bot 197 +bot 66 gives low to bot 198 and high to bot 188 +bot 199 gives low to bot 184 and high to bot 33 +bot 122 gives low to bot 55 and high to bot 5 +bot 68 gives low to bot 40 and high to bot 143 +bot 128 gives low to bot 4 and high to bot 94 +bot 27 gives low to bot 13 and high to bot 78 +bot 34 gives low to bot 195 and high to bot 88 +bot 94 gives low to bot 109 and high to bot 135 +bot 158 gives low to output 3 and high to bot 138 +bot 47 gives low to output 15 and high to bot 59 +bot 163 gives low to bot 120 and high to bot 90 +bot 48 gives low to bot 111 and high to bot 102 +bot 40 gives low to bot 207 and high to bot 176 +bot 144 gives low to bot 153 and high to bot 39 +bot 201 gives low to bot 162 and high to bot 83 +bot 72 gives low to bot 115 and high to bot 121 +bot 156 gives low to bot 19 and high to bot 101 +bot 185 gives low to bot 145 and high to bot 183 +bot 103 gives low to bot 8 and high to bot 111 +bot 192 gives low to bot 9 and high to bot 66 +value 71 goes to bot 140 +bot 205 gives low to bot 68 and high to bot 79 +bot 151 gives low to output 11 and high to bot 95 +bot 153 gives low to bot 97 and high to bot 44 +bot 105 gives low to bot 15 and high to bot 175 +bot 11 gives low to bot 183 and high to bot 86 +bot 160 gives low to bot 11 and high to bot 71 +bot 56 gives low to bot 110 and high to bot 73 +bot 207 gives low to bot 172 and high to bot 89 +bot 181 gives low to bot 108 and high to bot 136 +bot 175 gives low to bot 197 and high to bot 106 +bot 69 gives low to bot 167 and high to bot 19 +bot 58 gives low to output 9 and high to bot 1 +bot 78 gives low to bot 74 and high to bot 15 +bot 21 gives low to output 12 and high to output 19 +bot 190 gives low to bot 168 and high to bot 177 +value 29 goes to bot 190 +bot 107 gives low to bot 39 and high to bot 150 +bot 61 gives low to bot 63 and high to bot 103 +bot 52 gives low to bot 202 and high to bot 37 +value 53 goes to bot 168 +bot 30 gives low to bot 3 and high to bot 75 +bot 116 gives low to bot 123 and high to bot 42 +bot 85 gives low to bot 187 and high to bot 205 +bot 99 gives low to bot 94 and high to bot 162 +bot 126 gives low to bot 54 and high to bot 148 +bot 19 gives low to bot 158 and high to bot 174 +bot 82 gives low to bot 49 and high to bot 120 +bot 42 gives low to bot 169 and high to bot 139 +value 41 goes to bot 190 +bot 188 gives low to bot 48 and high to bot 130 +bot 113 gives low to bot 14 and high to bot 157 +bot 177 gives low to bot 124 and high to bot 80 +bot 18 gives low to bot 59 and high to bot 193 +bot 96 gives low to bot 149 and high to bot 126 +bot 62 gives low to bot 157 and high to bot 2 +bot 45 gives low to bot 105 and high to bot 175 +bot 2 gives low to bot 87 and high to bot 34 +bot 147 gives low to bot 170 and high to bot 24 +bot 70 gives low to bot 65 and high to bot 127 +bot 162 gives low to bot 135 and high to bot 165 +bot 117 gives low to bot 66 and high to bot 180 +bot 100 gives low to bot 57 and high to bot 14 +bot 57 gives low to bot 1 and high to bot 152 +bot 121 gives low to bot 203 and high to bot 184 +bot 10 gives low to bot 6 and high to bot 52 +bot 84 gives low to bot 30 and high to bot 13 +value 7 goes to bot 166 +bot 136 gives low to bot 186 and high to bot 153 +bot 161 gives low to bot 32 and high to bot 108 +bot 102 gives low to bot 85 and high to bot 114 +bot 80 gives low to bot 20 and high to bot 10 +bot 200 gives low to bot 34 and high to bot 178 +bot 119 gives low to bot 38 and high to bot 61 +bot 28 gives low to bot 137 and high to bot 147 +bot 35 gives low to bot 128 and high to bot 99 +value 67 goes to bot 132 +bot 146 gives low to bot 112 and high to bot 46 +bot 194 gives low to bot 122 and high to bot 23 +value 73 goes to bot 26 +bot 183 gives low to bot 18 and high to bot 98 diff --git a/pytudes/data/advent2016/input12.txt b/pytudes/data/advent2016/input12.txt new file mode 100644 index 0000000..0eeb395 --- /dev/null +++ b/pytudes/data/advent2016/input12.txt @@ -0,0 +1,23 @@ +cpy 1 a +cpy 1 b +cpy 26 d +jnz c 2 +jnz 1 5 +cpy 7 c +inc d +dec c +jnz c -2 +cpy a c +inc a +dec b +jnz b -2 +cpy c b +dec d +jnz d -6 +cpy 14 c +cpy 14 d +inc a +dec d +jnz d -2 +dec c +jnz c -5 diff --git a/pytudes/data/advent2016/input2.txt b/pytudes/data/advent2016/input2.txt new file mode 100644 index 0000000..118bf27 --- /dev/null +++ b/pytudes/data/advent2016/input2.txt @@ -0,0 +1,5 @@ +LURLDDLDULRURDUDLRULRDLLRURDUDRLLRLRURDRULDLRLRRDDULUDULURULLURLURRRLLDURURLLUURDLLDUUDRRDLDLLRUUDURURRULURUURLDLLLUDDUUDRULLRUDURRLRLLDRRUDULLDUUUDLDLRLLRLULDLRLUDLRRULDDDURLUULRDLRULRDURDURUUUDDRRDRRUDULDUUULLLLURRDDUULDRDRLULRRRUUDUURDULDDRLDRDLLDDLRDLDULUDDLULUDRLULRRRRUUUDULULDLUDUUUUDURLUDRDLLDDRULUURDRRRDRLDLLURLULDULRUDRDDUDDLRLRRDUDDRULRULULRDDDDRDLLLRURDDDDRDRUDUDUUDRUDLDULRUULLRRLURRRRUUDRDLDUDDLUDRRURLRDDLUUDUDUUDRLUURURRURDRRRURULUUDUUDURUUURDDDURUDLRLLULRULRDURLLDDULLDULULDDDRUDDDUUDDUDDRRRURRUURRRRURUDRRDLRDUUULLRRRUDD +DLDUDULDLRDLUDDLLRLUUULLDURRUDLLDUDDRDRLRDDUUUURDULDULLRDRURDLULRUURRDLULUDRURDULLDRURUULLDLLUDRLUDRUDRURURUULRDLLDDDLRUDUDLUDURLDDLRRUUURDDDRLUDDDUDDLDUDDUUUUUULLRDRRUDRUDDDLLLDRDUULRLDURLLDURUDDLLURDDLULLDDDRLUDRDDLDLDLRLURRDURRRUDRRDUUDDRLLUDLDRLRDUDLDLRDRUDUUULULUDRRULUDRDRRLLDDRDDDLULURUURULLRRRRRDDRDDRRRDLRDURURRRDDULLUULRULURURDRRUDURDDUURDUURUURUULURUUDULURRDLRRUUDRLLDLDRRRULDRLLRLDUDULRRLDUDDUUURDUDLDDDUDL +RURDRUDUUUUULLLUULDULLLDRUULURLDULULRDDLRLLRURULLLLLLRULLURRDLULLUULRRDURRURLUDLULDLRRULRDLDULLDDRRDLLRURRDULULDRRDDULDURRRUUURUDDURULUUDURUULUDLUURRLDLRDDUUUUURULDRDUDDULULRDRUUURRRDRLURRLUUULRUDRRLUDRDLDUDDRDRRUULLLLDUUUULDULRRRLLRLRLRULDLRURRLRLDLRRDRDRLDRUDDDUUDRLLUUURLRLULURLDRRULRULUDRUUURRUDLDDRRDDURUUULLDDLLDDRUDDDUULUDRDDLULDDDDRULDDDDUUUURRLDUURULRDDRDLLLRRDDURUDRRLDUDULRULDDLDDLDUUUULDLLULUUDDULUUDLRDRUDLURDULUDDRDRDRDDURDLURLULRUURDUDULDDLDDRUULLRDRLRRUURRDDRDUDDLRRLLDRDLUUDRRDDDUUUDLRRLDDDUDRURRDDUULUDLLLRUDDRULRLLLRDLUDUUUUURLRRUDUDDDDLRLLULLUDRDURDDULULRDRDLUDDRLURRLRRULRL +LDUURLLULRUURRDLDRUULRDRDDDRULDLURDDRURULLRUURRLRRLDRURRDRLUDRUUUULLDRLURDRLRUDDRDDDUURRDRRURULLLDRDRDLDUURLDRUULLDRDDRRDRDUUDLURUDDLLUUDDULDDULRDDUUDDDLRLLLULLDLUDRRLDUUDRUUDUDUURULDRRLRRDLRLURDRURURRDURDURRUDLRURURUUDURURUDRURULLLLLUDRUDUDULRLLLRDRLLRLRLRRDULRUUULURLRRLDRRRDRULRUDUURRRRULDDLRULDRRRDLDRLUDLLUDDRURLURURRLRUDLRLLRDLLDRDDLDUDRDLDDRULDDULUDDLLDURDULLDURRURRULLDRLUURURLLUDDRLRRUUDULRRLLRUDRDUURLDDLLURRDLRUURLLDRDLRUULUDURRDULUULDDLUUUDDLRRDRDUDLRUULDDDLDDRUDDD +DRRDRRURURUDDDRULRUDLDLDULRLDURURUUURURLURURDDDDRULUDLDDRDDUDULRUUULRDUDULURLRULRDDLDUDLDLULRULDRRLUDLLLLURUDUDLLDLDRLRUUULRDDLUURDRRDLUDUDRULRRDDRRLDUDLLDLURLRDLRUUDLDULURDDUUDDLRDLUURLDLRLRDLLRUDRDUURDDLDDLURRDDRDRURULURRLRLDURLRRUUUDDUUDRDRULRDLURLDDDRURUDRULDURUUUUDULURUDDDDUURULULDRURRDRDURUUURURLLDRDLDLRDDULDRLLDUDUDDLRLLRLRUUDLUDDULRLDLLRLUUDLLLUUDULRDULDLRRLDDDDUDDRRRDDRDDUDRLLLDLLDLLRDLDRDLUDRRRLDDRLUDLRLDRUURUDURDLRDDULRLDUUUDRLLDRLDLLDLDRRRLLULLUDDDLRUDULDDDLDRRLLRDDLDUULRDLRRLRLLRUUULLRDUDLRURRRUULLULLLRRURLRDULLLRLDUUUDDRLRLUURRLUUUDURLRDURRDUDDUDDRDDRUD diff --git a/pytudes/data/advent2016/input20.txt b/pytudes/data/advent2016/input20.txt new file mode 100644 index 0000000..e408924 --- /dev/null +++ b/pytudes/data/advent2016/input20.txt @@ -0,0 +1,1176 @@ +2365712272-2390766206 +2569947483-2579668543 +1348241901-1362475328 +2431265968-2450509895 +2146385-2259474 +2935960035-2940597034 +448888033-460770571 +1993433098-1995841061 +1479295247-1481053053 +2315798162-2331724795 +553124643-558300256 +2221609952-2221736791 +2528284970-2536413665 +1003828483-1008019254 +2460073010-2461391392 +1756403373-1774263374 +181708677-181820620 +4105906368-4108964079 +2803753677-2810396331 +3872622758-3876157728 +4222455331-4230019102 +2566685080-2569947482 +2546666999-2560222508 +2563776047-2567373420 +669206125-670672126 +3047016482-3068254467 +2412767568-2415681466 +3832227190-3836056110 +1752672085-1778896581 +3612964446-3613428692 +473462452-473507720 +558414399-558825886 +174888587-188726755 +3681687609-3688894180 +482298773-513769024 +1105376539-1109259196 +2626549708-2635018162 +2221569800-2221688559 +3217908441-3218365608 +1839378196-1839704131 +4006631148-4018637666 +1033070477-1039079720 +3614366173-3619803122 +1651631132-1657688516 +3148614241-3149307836 +2922404131-2925650734 +2967474818-2979959263 +3674334884-3677432948 +2194863661-2195245017 +1723397977-1746877683 +246394156-253325513 +577459246-594741177 +410425445-412372582 +1287281042-1288450150 +2546572083-2552459138 +3284505169-3292205355 +2572957308-2615378907 +2689345749-2699114021 +3296227141-3297518289 +3695819772-3697468770 +412372583-422306605 +2699114022-2714857638 +2059138236-2060952632 +117089981-120121935 +2848444484-2857342976 +352052590-358986830 +2656447256-2685668729 +454980721-460461657 +1027539209-1041751363 +1913417-3826887 +1062494257-1082863054 +2282966419-2286017938 +394757734-421655845 +2106693263-2115236723 +1124719891-1127653202 +3292205357-3293681013 +117011952-119543627 +2181915940-2184656064 +1045705528-1078679114 +290113491-291311039 +2278026399-2284902493 +841914150-848969885 +3952731875-3959197013 +1938643863-1940674602 +1036550327-1041084034 +63607243-63644812 +3769265734-3769975585 +51653989-55144083 +1799892196-1812471751 +1371739118-1372165373 +3561636732-3569279384 +1823678708-1830435069 +4012340693-4047186502 +3697468771-3719107288 +1963424400-1964720496 +254179574-261945026 +2639565460-2643861101 +2489776747-2498561347 +1528974499-1529888310 +2272121277-2279366265 +2063178650-2063502047 +2631423649-2635927617 +1360641171-1369732967 +352866001-362403909 +2982988833-2999220870 +2226316378-2236701767 +3581998091-3588302160 +3905167888-3909688736 +2410405177-2416922214 +2221793009-2222205811 +1682009735-1689579607 +2551217715-2555588513 +4111825736-4139764825 +1495499947-1496504480 +1126815599-1132033603 +262946528-267481743 +2190431207-2194125961 +3056852838-3057666713 +3852657771-3855744213 +814188270-815660610 +1370082674-1372874146 +2698266605-2707295552 +2623491116-2632182274 +556237979-558470744 +4221727965-4242434586 +1373248698-1389927798 +3269334240-3276265066 +2266535688-2268367969 +3098582122-3101205009 +1909408103-1909548530 +2822711293-2831177968 +848969887-859626993 +46887186-54157057 +2762897904-2771117185 +289933294-290354931 +1088830930-1093432672 +2443230763-2461276873 +3160139479-3173260442 +1527097290-1531435951 +1799540955-1800006056 +1369732968-1371815843 +2622838271-2625104782 +1173393865-1173503336 +1909254997-1910983838 +1299664180-1322001993 +1688665208-1691812251 +1887810466-1890884113 +2869886503-2875645396 +582392092-606025972 +4267022320-4275265906 +3859201994-3893484463 +3589262267-3596650599 +912537182-912907636 +2221654107-2222088287 +4057523345-4060042618 +3697080984-3697115223 +970916665-977773714 +1357371244-1357771399 +300561490-351155869 +1312775715-1335513565 +117013732-119708846 +425465828-460547231 +1934707608-1943900203 +1872455505-1883131224 +1265429510-1270058235 +1351349572-1360842989 +3949672363-3965375662 +757393179-769131755 +1140550254-1155907063 +2362581541-2384858143 +3767349312-3769448384 +1010152192-1021680403 +3719107290-3724947612 +793186065-798493071 +3543437818-3570393128 +2142580414-2155598642 +570014715-594180691 +2268145476-2268275380 +682993360-688547687 +882429283-885295513 +2061317899-2062340917 +3080454969-3087996304 +1509787381-1515229305 +1792788995-1805479181 +471893034-478588629 +2469289299-2469834064 +3435184443-3439758093 +1972314440-1984109813 +897623204-906019235 +3309685433-3316891985 +2022851-2168311 +3425944138-3434725507 +1573705848-1574774103 +1843461004-1851252409 +275830302-287491224 +1099676859-1106356804 +3201885249-3216240573 +890516875-914189870 +1045475561-1045705526 +858602633-861745342 +1722754472-1729362918 +1999030390-2001346788 +2295812200-2297395314 +545671618-547361797 +1925762580-1932504567 +2469834065-2488585001 +962891401-973508116 +3056544703-3057098061 +1964666710-1968283715 +4153249699-4156067673 +2269509587-2272121275 +113577026-129098597 +2544925116-2547575012 +3930954397-3932696547 +1940360721-1941087983 +989005807-1006335777 +1715546619-1723575645 +946249856-956419020 +2580089074-2609078369 +118138523-133562721 +1418940971-1433573243 +3116049988-3117047351 +2819201530-2820204193 +609029102-631859346 +1236996385-1243667312 +2071060282-2090563034 +3275297026-3287385948 +557242553-558842013 +2340595893-2346006065 +1763694009-1772957054 +3039028781-3066739550 +2678983882-2689345747 +1496448610-1497010926 +3783756301-3783968438 +4011127020-4023009734 +2455737032-2469289297 +911816966-912509075 +2275917994-2288190359 +1405416423-1419176714 +2642680237-2644300616 +3826507233-3826769507 +3791085814-3803870306 +3990925848-3994761120 +1574446563-1576228425 +1634308286-1635388054 +3770072854-3783827763 +859626994-872001663 +1678998549-1682009733 +3615640609-3625220434 +3756046034-3759831577 +4219956234-4225730655 +1944691819-1972314439 +3232924024-3243647347 +2819804415-2821623032 +1041187113-1041438684 +1234384868-1251566238 +1707319358-1710481231 +3338081719-3342039539 +3919045080-3932932694 +1618322267-1618915594 +1196499550-1204759606 +354238054-359105442 +2788225259-2807617695 +1817797800-1818404115 +3314463142-3319629375 +3220899130-3223901824 +463163318-471893033 +2108731258-2118466370 +2531905696-2534895562 +872001665-885348477 +3618924494-3633614536 +1286808229-1287787318 +1686812571-1709789731 +1667289113-1675800071 +1288046293-1288760085 +115133053-118531268 +3084925009-3087972171 +2107005650-2118671640 +2206689406-2208120987 +2965687206-2969477736 +2789286984-2795621824 +1510800557-1520242850 +1372577266-1373248696 +3908185397-3914112662 +3027341861-3028862050 +2551506862-2563776045 +3457830284-3476082138 +2330638928-2335068417 +3754091818-3760153804 +1700898897-1708456845 +2653919552-2678983881 +1718586248-1752672083 +1909974346-1911447514 +740859879-743318742 +632094677-641123609 +2717310519-2722969125 +2429156614-2450453303 +3573769011-3581998089 +804909837-807598669 +2645933387-2650206634 +3906744049-3908084382 +1088710392-1093793913 +2945948817-2961003764 +2154975171-2170652704 +705358087-723167844 +2623774017-2637924339 +1527448631-1531925852 +541284581-550148134 +822228123-845259076 +2725319909-2726283018 +90504693-97857953 +2151018859-2156845889 +3875175237-3880661438 +2174472127-2175522174 +1053913106-1073312877 +4151957167-4159217706 +408096359-410929997 +3494935822-3518493936 +4018415387-4034413199 +1318527150-1335393593 +4094276281-4100264566 +3296618992-3305730207 +3827540382-3834020598 +1792716600-1804353554 +486286244-509649426 +2820166268-2822489545 +943117353-944243402 +4250879477-4288162587 +1092150174-1096445797 +659715146-669206123 +424405829-425465827 +2903268723-2916344920 +2825756580-2827850093 +2197813619-2221567221 +2222205813-2242661939 +1909398015-1909639813 +2085646-2171133 +3237410359-3243293444 +2488585003-2500532520 +1719496111-1733109286 +3101107881-3101724703 +4292290133-4294130012 +2682533716-2682557737 +478588631-499658423 +2056703122-2057132500 +10759205-22974868 +288949273-290120633 +3295342764-3300711505 +4144392189-4146507469 +1377845154-1383061661 +1470042236-1484545053 +2929570686-2942193911 +663447966-667304777 +2250137488-2260767053 +2916852498-2920130617 +560916716-582392091 +3826421034-3826753059 +4205391625-4209582225 +3098065613-3099195513 +1523618109-1529220622 +1280876899-1287180580 +2896461712-2914779142 +3059619066-3072535463 +3594066104-3603694944 +206442883-222778068 +4057343389-4058593137 +3040726007-3067509699 +783978732-804864426 +3782497016-3783855888 +3771309186-3798156648 +1806086747-1808455979 +2509648237-2520128379 +2655519435-2688778011 +466454947-475885979 +764443451-778431348 +942699799-943817373 +2707406125-2710335531 +3532789271-3534889466 +161216255-168066537 +3959810178-3972378256 +1216245-1730562 +820810878-827132162 +3840466779-3849871670 +241662240-244306234 +1308539-1732730 +2644300617-2653919550 +1245139600-1257000695 +472344288-476821359 +360421650-365291918 +4157074002-4160043617 +3475229162-3494935820 +4021239535-4026837101 +1122221983-1122467302 +3524503684-3534615536 +294914250-297074740 +3315785542-3320016807 +3207399725-3218904107 +3399796042-3432628902 +2415031178-2417587472 +637037746-641909503 +4125051011-4125349366 +2792226042-2796333812 +1090609063-1093811054 +3826753967-3826928901 +2845981709-2846071766 +1884551628-1888679834 +1867383722-1901804607 +1138049177-1150698174 +2489168484-2503275369 +3844741449-3859201992 +2059227603-2061190162 +2725980853-2726316169 +3950461578-3982076979 +2964040486-2971816053 +3117022269-3125872507 +4205459617-4208901905 +3223901825-3259939574 +2043681871-2056703120 +2862497588-2874433217 +1545573025-1550810115 +558470745-560916714 +2204957059-2206941462 +687956243-693820818 +1006335778-1027539207 +1683104091-1691973027 +1281662230-1286185165 +2457027525-2467523425 +3910944384-3915139260 +1812471753-1823678707 +3439758094-3449375742 +4180271874-4183028052 +3145750655-3149232555 +1063127835-1081739469 +912453784-912787957 +757841367-763656320 +970465196-984461751 +2682535644-2682561899 +1103041548-1124501094 +711829065-712418631 +786434450-810431275 +526718776-547605908 +411642224-419649420 +442563986-451494166 +3916556398-3932893207 +4178915874-4181659654 +931371848-932759051 +226571744-227466085 +586436371-589611958 +2138685204-2148239206 +2786369133-2807032221 +3902400566-3910944383 +356708623-360421649 +1195358721-1201587206 +2986693403-2997511709 +1160749272-1164268031 +1138794253-1160582337 +1316625314-1322081912 +2546426233-2547478858 +631117298-638088180 +490462991-510876262 +1585596253-1598442115 +1691404689-1708777514 +21958182-34768708 +3033283449-3033532644 +850358573-850941928 +2532323467-2533835875 +2571607510-2576905211 +3838468698-3844741448 +3633614538-3658935402 +1267571462-1273337904 +820046167-821948762 +1818557964-1821003970 +1656682467-1658689820 +3572000906-3576107308 +3518493937-3521124207 +2316622941-2320028763 +3234261481-3244439202 +1762170451-1767000441 +403695570-413282241 +1446563227-1455229013 +994814766-1020194067 +1103304248-1123109762 +1358159388-1364262240 +2643072595-2647827063 +1761152300-1771038779 +814235534-818070036 +3658935403-3674334882 +1143690782-1167938223 +956027555-959929296 +78736212-103134510 +897919912-910244590 +991162491-1009670900 +3730115132-3731119302 +3693059535-3697085999 +310695719-311355138 +3792190887-3811128942 +3236342985-3241419480 +932285275-939464714 +1690112643-1694719438 +964486517-974083673 +2886004632-2887772395 +400201502-410632385 +4151877322-4155177505 +4146634947-4148274967 +4142431183-4151685720 +108233930-110782083 +11764001-28124816 +255280185-265644134 +1604894700-1610024510 +2746388028-2755644917 +257526100-265688716 +2979959265-2981174695 +3675625153-3678243537 +946960127-957058942 +158966202-168896939 +885386378-890516873 +3944559186-3950461577 +3436884337-3440035586 +1998995929-2004489839 +1029028825-1029925818 +860116537-869330710 +534657657-536577765 +2792605215-2809178574 +83479693-101592615 +206521107-208527729 +3681963513-3682865724 +2913358381-2916852496 +3172620089-3183275609 +649130727-656267839 +1264638271-1274096286 +1029718677-1030140380 +3643603238-3653831146 +3061231145-3063632127 +2585980608-2609955243 +1316394181-1319520040 +211076367-219280164 +3240385969-3251259062 +2120060-4441033 +3278363479-3278515140 +3831551420-3838468696 +1173779057-1176512368 +4071597616-4101375293 +2781084212-2783642342 +2743354447-2760958028 +4114529275-4137230617 +3752969032-3767349311 +424150040-425393208 +26532978-29480043 +1006115405-1009958851 +2845371314-2850260793 +1267920977-1271152591 +3709512503-3716036930 +3368253421-3392905399 +2452693801-2465509837 +3534255481-3543437816 +4160043619-4178915873 +3954591115-3974152768 +677298953-691027000 +1685806773-1690772816 +436652774-450179768 +3588302161-3612662806 +83367242-100910390 +1633907668-1651631131 +443592135-463163316 +369907897-388846763 +388962875-390004346 +2306861374-2315798161 +591078-868213 +1229951959-1242298204 +3014332113-3031527143 +1171615958-1176617364 +3062064123-3063637314 +2087862269-2089342604 +1672729270-1679677272 +3733541117-3748642488 +3075188797-3083692289 +2520128380-2544925114 +1997250353-1999097991 +2326010770-2328459525 +3335649815-3359666038 +1093811055-1099676857 +1939453065-1940109461 +2260767055-2269509586 +1694740480-1710532828 +48862588-54135685 +2194651149-2194876489 +3261664286-3284505168 +712077073-718032346 +2714857640-2733949192 +3084808742-3090381388 +2326056027-2328734209 +2966286735-2970371217 +3682357002-3688783396 +222778070-246394155 +255495869-263746137 +778431350-801595041 +554816671-557769418 +2287063002-2290447136 +1204759607-1221061934 +3191695158-3195022731 +1937411520-1939682964 +3683208458-3683317560 +3724947613-3752969030 +2655947194-2686070304 +3319632926-3320555728 +3874349431-3892283480 +3524323559-3534255480 +3392910453-3425944137 +2864015808-2880343338 +3603278173-3607977481 +2221685432-2221741276 +3821784373-3831551419 +2340560220-2355630152 +117804595-135520674 +970739667-977759407 +612826307-617050682 +2420630784-2422511751 +4041221294-4053276651 +1783176414-1792788994 +1661820734-1672783713 +2285020555-2288812517 +1145717399-1147147799 +1160582338-1171067340 +2969768222-2978509720 +2241558918-2248366876 +3842088825-3849544675 +3220876335-3220899128 +3612828177-3614366172 +1848099469-1860064576 +1453352598-1457451860 +4131921387-4136290418 +1186411872-1221604187 +4271276227-4274727942 +1972041789-1977505124 +3130652998-3145750654 +4206797669-4211676679 +3382975599-3392910451 +3075497812-3098065611 +2819298198-2826283738 +1358156767-1363896494 +1209838280-1225553470 +3101724704-3130652996 +2874696153-2876992505 +1279193633-1279368007 +2044384098-2052585053 +1778896582-1783176412 +365291920-384429458 +1410453073-1423638312 +3149307838-3160666386 +3115765500-3124715535 +2524674650-2540040296 +312386716-315692662 +3195022733-3220876334 +1528945394-1531524966 +1190783271-1221823104 +1374677110-1382957599 +496392908-504137572 +3152103031-3191695157 +1706509680-1714907014 +2642314466-2645833233 +3893484464-3898889230 +3331226932-3338281520 +3421612598-3423251948 +2376098338-2382856038 +30669693-46887184 +3701470920-3709586949 +974101275-985095687 +3754694204-3762024757 +3199920021-3213832756 +3937237796-3943044170 +519102356-526718775 +3595418820-3608680530 +3132319868-3142292446 +2415135665-2422698971 +2512723394-2531872720 +2831177970-2843852399 +4067331024-4083628214 +974512957-981076935 +1939102143-1939797065 +3362465663-3382975598 +1081727915-1086599484 +62892604-66661231 +3596147589-3597403547 +2427949019-2455737031 +734503945-751972019 +4274360201-4275638496 +546152564-553124641 +1672412404-1675035441 +1799317782-1799878394 +3899929168-3902400564 +2090563035-2093365570 +2502990872-2504573807 +196879713-202383888 +1041219675-1045475560 +288505150-290311818 +2335068419-2337479072 +3115770397-3116114052 +1759780530-1779756738 +3848355565-3857570445 +2887262512-2892926939 +3297920188-3304753747 +2837362258-2846430149 +2365620967-2397295181 +2130880010-2144109636 +850356647-852183547 +2547575013-2555977963 +3293681014-3298307912 +2838677121-2848444483 +1378317671-1378385207 +3932893208-3942847442 +2775955760-2802739818 +3000621764-3001860005 +3878325586-3889110731 +1634960329-1635718125 +3570393129-3575649486 +3359666039-3362465661 +2221578838-2221700311 +307265752-314765240 +823227617-824317407 +923124066-946249854 +4151685721-4154340765 +424138334-424809502 +2057132501-2071060280 +647961093-660004652 +3307622347-3312520961 +3259939576-3281494745 +1887577612-1888900146 +1189371904-1198571936 +1234031907-1247954865 +610600287-612214510 +1630355907-1632283896 +1634415839-1636037634 +3824506379-3826246351 +3847566968-3849532976 +1588959146-1616167991 +4142261326-4149638559 +1813668039-1819668003 +269833124-284269645 +1445572315-1448859107 +3312520962-3326324517 +4134904662-4142261324 +286352057-295053323 +2093365572-2104458852 +2964496323-2978996654 +1589041634-1610897669 +4017779362-4023249218 +710580357-719926955 +3695217573-3697711534 +3119922419-3128398873 +1973300202-1979672054 +2647661251-2652365333 +1618800796-1618963161 +914189871-916240439 +70592825-75578072 +1931515004-1937254405 +2472726189-2479284501 +2073603890-2087967511 +4288162588-4289142874 +1651148640-1652304033 +384429459-393421986 +208944718-214460830 +250825858-254179572 +2845961347-2846405094 +3683052176-3689023082 +2548531964-2548558043 +3326324519-3343805565 +351155871-359398929 +4232721631-4250879475 +3459529479-3474108150 +1909441969-1909689691 +1932119221-1939290766 +2762860344-2765962584 +942511347-943894644 +3682865725-3687083046 +742172772-743598853 +382176907-388584692 +4086908517-4100905688 +2961073615-2978624771 +3753936484-3758588765 +357622008-361838888 +393421988-409475636 +4210437626-4216399302 +3866457812-3901968872 +943727563-944059707 +2919715277-2920771136 +1627803704-1630982586 +1111194889-1126815598 +1637697658-1639829508 +518330921-521079203 +558771603-558831008 +1627521188-1629733196 +2531822532-2533342258 +1722060329-1725371759 +916240441-923124065 +2267284366-2270810897 +4289142876-4294967295 +496711691-511059121 +297074742-300561489 +74957232-86751750 +67820201-89362971 +879194017-883306027 +874758234-886383957 +518363334-546855682 +606025974-631117297 +27195455-41332971 +2870905604-2878387377 +3084839165-3086179322 +4152483704-4155490661 +3992240000-3998336821 +3612662808-3613179304 +2144109637-2171654935 +2912881674-2913811866 +3683215934-3683776929 +744692065-746814759 +648698022-654389148 +770363291-773532218 +1961187739-1981201058 +833212292-844968840 +2279366266-2306861372 +1525437167-1529355367 +783203836-797187462 +743069797-747604954 +2726435221-2743671505 +716822331-723267087 +236924668-243049788 +1819907565-1821265293 +2459006570-2462769060 +261945027-269833122 +2251634561-2252542708 +3077512678-3082900025 +4178034955-4178140732 +517575846-518330919 +1833921219-1854646670 +1863586802-1867383721 +1688123912-1691016809 +3613097833-3613214641 +182210169-189009626 +299267101-339546807 +829601778-834904352 +481358143-505095971 +2224935194-2228740812 +4083628215-4105906366 +3938942245-3941751692 +983920144-989005805 +113931896-118379003 +3330676862-3358266446 +3778252069-3806861354 +751972021-764443450 +4108964080-4140242300 +1576228427-1585596252 +2268397999-2270766178 +1924059333-1931515003 +3938054379-3940855319 +4216399304-4232721630 +203859682-211512236 +1506317175-1508820099 +2082159387-2091680640 +3509536520-3513399808 +152981470-173147952 +1984109815-1997250352 +2104458853-2130880008 +2998034397-2999606176 +2081152422-2086162418 +1628568484-1631818535 +1469298549-1472797586 +2706655046-2709540287 +2171654937-2192635909 +3997842771-4006631146 +3806238246-3814481469 +3687035617-3693059533 +1714907016-1715546618 +2268214620-2268517442 +4168814485-4173314719 +4290592397-4294496881 +3026587742-3028212258 +109629716-117011951 +2227635708-2258663804 +4153336546-4157695457 +4183028054-4210437625 +1359555284-1365047163 +385317924-388866137 +956914163-980424242 +971923920-984657935 +3372104235-3387022483 +2459697795-2461023615 +4054424978-4061962114 +2531190780-2540332177 +981076936-984403766 +1943900205-1955571856 +1092170655-1096453697 +4188253293-4210273531 +1476473552-1484327172 +422306607-424937626 +3616461090-3629002324 +280581464-294914249 +1814486124-1821348543 +538601282-545721176 +4165166009-4178721021 +1988368657-1999218926 +3683738155-3686068920 +2339202139-2341973045 +1618530377-1618985589 +1061405927-1067161088 +1586686087-1588534608 +4187607606-4189350663 +1129004649-1138049175 +3769446976-3770072852 +2023963853-2036589722 +2154869719-2158914742 +4239846195-4246356778 +4051209708-4054424976 +2896089935-2914808278 +1435815375-1450285026 +145909747-170128283 +1885652106-1891564474 +1282644829-1292952382 +2286826126-2293672278 +818070038-841914149 +3335638754-3341961960 +1618857702-1619359406 +3939705062-3944559184 +2203145858-2219094358 +3769401246-3769482197 +2922943756-2925135318 +3468068444-3477636928 +3778956860-3790280017 +4073540020-4096504022 +3814481471-3828523511 +1415617645-1423826462 +3031527144-3033419898 +4062168143-4068151354 +1286492281-1286940405 +2428194387-2465453645 +801595042-817285567 +63581388-63635672 +4117266117-4119442082 +11602511-25799879 +1092570588-1093985932 +3296956776-3307622345 +2221567222-2221613969 +558232945-558709807 +3639754422-3650743589 +3437931121-3440846855 +3675035968-3681981311 +1433573245-1442758111 +1471139709-1473858291 +629519040-641689686 +4117209430-4119122433 +52713726-57736371 +2706992741-2707821184 +3602086332-3604188767 +3915139262-3922929260 +1634469269-1636558185 +2200025248-2210330662 +3521124209-3529596728 +1086599486-1093798819 +1309801249-1314575942 +3656835500-3663825208 +1519294415-1521662532 +3848027323-3849548785 +1907694975-1914277280 +1318019570-1322413873 +3338464003-3356847371 +3982076981-3997842770 +1267783432-1278940858 +1658689822-1678998548 +2857342978-2887262511 +4061962115-4062168141 +1459666268-1492181176 +2615378909-2638121319 +4134040495-4139294664 +1278940860-1279210793 +670672127-703998141 +1279368008-1294345099 +1816032308-1825117169 +5682-591077 +3367275968-3384214515 +64315567-67820199 +2502622426-2509648235 +2384858144-2400945744 +2328968349-2329640362 +3697104193-3697121849 +2192635910-2197813617 +948400714-955452470 +1616167993-1628568483 +2344207001-2347832306 +4065174279-4066995234 +2501136056-2507987954 +238478069-238584796 +2983949242-3005737605 +2500532521-2503210360 +1393768957-1418940970 +4267061677-4267804887 +1878114-2022850 +1632283898-1647333210 +2400945746-2409724446 +2869179197-2876746583 +1106490177-1115256489 +4061093101-4061131252 +2810396333-2822711292 +885348478-889915910 +1830435071-1837694596 +1837694597-1863586800 +2658513248-2682334850 +2924284916-2928154608 +2880061840-2880744733 +2598258370-2614301028 +2919390200-2945948816 +724929680-734503944 +2662412166-2665780598 +1178177517-1198965930 +1557905942-1573183772 +3563817129-3577035331 +486771190-517575845 +3645420942-3645846054 +703998143-706055398 +2004489841-2043681870 +2409724447-2427949017 +3620235480-3626019843 +1551168080-1572791868 +3438270145-3440465241 +2043792287-2048576193 +4189961855-4207923535 +1572791869-1573838792 +1560630061-1568705988 +1945995416-1972395216 +3154257326-3170804412 +2638121320-2639565458 +641909505-659715145 +706055399-724929678 +1322001994-1348241899 +178460965-196879712 +4290596074-4292022319 +951225450-964656102 +1286720286-1299664178 +4267798816-4281427565 +2473150224-2483209210 +1466959722-1495499946 +202383890-206442882 +2980151171-2982988832 +3724920258-3748749341 +3449375744-3467888004 +4793565-27195454 +2763578266-2769445414 +3551501696-3577270805 +103134511-108233928 +3985777319-3995983153 +4056112707-4056303018 +1113372127-1127291361 +3450126345-3475229161 +4289501916-4292619355 +2447323006-2456025596 +3080941568-3084548509 +3455764745-3467066059 +2180674525-2191641368 +4011611611-4029364618 +2171134-4793563 +315731014-335056809 +3397886846-3414158394 +2762557710-2767579504 +1521662534-1545573024 +1442758112-1459666266 +1415183222-1422510841 +1396869120-1432423701 +173147954-191770601 +307244055-331462148 +303700109-329107070 +3367139562-3375242354 +1257000697-1267783431 +3441110255-3441542687 +868214-1216244 +2348268821-2362581539 +135520676-152981469 +3590167439-3598674695 +1497010928-1519294414 +2990327259-3014332111 +1174787708-1178177515 +3724679263-3737472563 +3530672381-3532472131 +2337479073-2362367605 +204565716-213455559 +2725271867-2749432076 +3527158276-3529338030 +1732731-1878113 +2234307311-2250137487 +3503793539-3507292135 +2764054784-2767560591 +0-97802 +3497142772-3509229752 +2252345137-2252983294 +2511786509-2525437254 +534322385-552469473 +2032077105-2039311638 +1930871028-1935831989 +1999927802-2002593859 +2034870570-2046166201 +2416773420-2418971941 +2326019770-2327054298 +3587252557-3596385967 +3004640283-3006650230 +2504389437-2504604683 +1389927799-1393768955 +458800944-461346308 +1225553472-1229951958 +1901804609-1911376516 +628245201-636898070 +1241514379-1244482846 +1911376517-1924059331 +2179314-4534265 +2590117386-2604230483 +1171067342-1174787707 +1526785599-1531893226 +3055633094-3057199924 +1568124522-1572160758 +2966347008-2978486706 +54831687-66550552 +1550497473-1551168078 +2892926941-2903268722 +2771117187-2775955759 +1234521852-1241992108 +1691973028-1696406355 +2837877932-2849517138 +2480932114-2481698709 +2845946431-2846057821 +1233941434-1246198098 +3002861655-3005365109 +3434725509-3435993674 +2173341542-2184849378 +3896230707-3900645720 +822740965-823550270 +4110021562-4121150778 +63603171-63635151 +3132070451-3134002144 +4152899097-4154706289 +3072535465-3075497811 +2963912450-2969754776 +3143800036-3144360416 +3033532646-3059619065 +2870120437-2886869710 +3274547143-3278505007 +2749432077-2762094882 +1081689983-1081835641 +850604533-852396063 +238560784-238982766 +3023322565-3025688956 +54157058-66147301 +820647222-823031869 +2961003766-2967474817 +1576566644-1606323350 +2582544240-2595513897 +4151772914-4155462854 +71629773-74290540 +2762094884-2762897903 +3179890008-3180299038 +4012179467-4051209707 +1967679449-1971418911 +2845141471-2846053808 +2816320795-2827745715 +3780956085-3792190886 +3098898720-3099568383 +3275561729-3284901540 +1402054763-1425346693 +1070235712-1081689982 +2897914307-2900470075 +2823031175-2825449030 +3751706906-3751753267 +970815395-976275417 +47997723-60304756 +3794263864-3796550694 +2743705045-2750732810 +76689052-80924970 +2919462546-2939875618 +376886072-388318966 +1787682465-1808426641 +856379509-864589444 +2378537309-2380543166 diff --git a/pytudes/data/advent2016/input21.txt b/pytudes/data/advent2016/input21.txt new file mode 100644 index 0000000..3aab429 --- /dev/null +++ b/pytudes/data/advent2016/input21.txt @@ -0,0 +1,100 @@ +rotate right 3 steps +swap position 7 with position 0 +rotate left 3 steps +reverse positions 2 through 5 +move position 6 to position 3 +reverse positions 0 through 4 +swap position 4 with position 2 +rotate based on position of letter d +rotate right 0 steps +move position 7 to position 5 +swap position 4 with position 5 +swap position 3 with position 5 +move position 5 to position 3 +swap letter e with letter f +swap position 6 with position 3 +swap letter a with letter e +reverse positions 0 through 1 +reverse positions 0 through 4 +swap letter c with letter e +reverse positions 1 through 7 +rotate right 1 step +reverse positions 6 through 7 +move position 7 to position 1 +move position 4 to position 0 +move position 4 to position 6 +move position 6 to position 3 +swap position 1 with position 6 +swap position 5 with position 7 +swap position 2 with position 5 +swap position 6 with position 5 +swap position 2 with position 4 +reverse positions 2 through 6 +reverse positions 3 through 5 +move position 3 to position 5 +reverse positions 1 through 5 +rotate left 1 step +move position 4 to position 5 +swap letter c with letter b +swap position 2 with position 1 +reverse positions 3 through 4 +swap position 3 with position 4 +reverse positions 5 through 7 +swap letter b with letter d +reverse positions 3 through 4 +swap letter c with letter h +rotate based on position of letter b +rotate based on position of letter e +rotate right 3 steps +rotate right 7 steps +rotate left 2 steps +move position 6 to position 1 +reverse positions 1 through 3 +rotate based on position of letter b +reverse positions 0 through 4 +swap letter g with letter c +move position 1 to position 5 +rotate right 4 steps +rotate left 2 steps +move position 7 to position 2 +rotate based on position of letter c +move position 6 to position 1 +swap letter f with letter g +rotate right 6 steps +swap position 6 with position 2 +reverse positions 2 through 6 +swap position 3 with position 1 +rotate based on position of letter h +reverse positions 2 through 5 +move position 1 to position 3 +rotate right 1 step +rotate right 7 steps +move position 6 to position 3 +rotate based on position of letter h +swap letter d with letter h +rotate left 0 steps +move position 1 to position 2 +swap letter a with letter g +swap letter a with letter g +swap position 4 with position 2 +rotate right 1 step +rotate based on position of letter b +swap position 7 with position 1 +rotate based on position of letter e +move position 1 to position 4 +move position 6 to position 3 +rotate left 3 steps +swap letter f with letter g +swap position 3 with position 1 +swap position 4 with position 3 +swap letter f with letter c +rotate left 3 steps +rotate left 0 steps +rotate right 3 steps +swap letter d with letter e +swap position 2 with position 7 +move position 3 to position 6 +swap position 7 with position 1 +swap position 3 with position 6 +rotate left 5 steps +swap position 2 with position 6 diff --git a/pytudes/data/advent2016/input22.txt b/pytudes/data/advent2016/input22.txt new file mode 100644 index 0000000..31b7ee6 --- /dev/null +++ b/pytudes/data/advent2016/input22.txt @@ -0,0 +1,914 @@ +root@ebhq-gridcenter# df -h +Filesystem Size Used Avail Use% +/dev/grid/node-x0-y0 92T 70T 22T 76% +/dev/grid/node-x0-y1 86T 65T 21T 75% +/dev/grid/node-x0-y2 88T 73T 15T 82% +/dev/grid/node-x0-y3 91T 67T 24T 73% +/dev/grid/node-x0-y4 87T 70T 17T 80% +/dev/grid/node-x0-y5 91T 70T 21T 76% +/dev/grid/node-x0-y6 87T 71T 16T 81% +/dev/grid/node-x0-y7 94T 69T 25T 73% +/dev/grid/node-x0-y8 93T 69T 24T 74% +/dev/grid/node-x0-y9 87T 71T 16T 81% +/dev/grid/node-x0-y10 89T 66T 23T 74% +/dev/grid/node-x0-y11 92T 64T 28T 69% +/dev/grid/node-x0-y12 88T 66T 22T 75% +/dev/grid/node-x0-y13 85T 72T 13T 84% +/dev/grid/node-x0-y14 94T 68T 26T 72% +/dev/grid/node-x0-y15 92T 67T 25T 72% +/dev/grid/node-x0-y16 93T 65T 28T 69% +/dev/grid/node-x0-y17 91T 67T 24T 73% +/dev/grid/node-x0-y18 92T 68T 24T 73% +/dev/grid/node-x0-y19 91T 69T 22T 75% +/dev/grid/node-x0-y20 89T 65T 24T 73% +/dev/grid/node-x0-y21 90T 72T 18T 80% +/dev/grid/node-x0-y22 94T 67T 27T 71% +/dev/grid/node-x0-y23 86T 72T 14T 83% +/dev/grid/node-x1-y0 85T 66T 19T 77% +/dev/grid/node-x1-y1 89T 64T 25T 71% +/dev/grid/node-x1-y2 92T 67T 25T 72% +/dev/grid/node-x1-y3 87T 70T 17T 80% +/dev/grid/node-x1-y4 86T 71T 15T 82% +/dev/grid/node-x1-y5 91T 68T 23T 74% +/dev/grid/node-x1-y6 87T 71T 16T 81% +/dev/grid/node-x1-y7 94T 69T 25T 73% +/dev/grid/node-x1-y8 89T 70T 19T 78% +/dev/grid/node-x1-y9 93T 64T 29T 68% +/dev/grid/node-x1-y10 92T 67T 25T 72% +/dev/grid/node-x1-y11 92T 72T 20T 78% +/dev/grid/node-x1-y12 87T 65T 22T 74% +/dev/grid/node-x1-y13 85T 73T 12T 85% +/dev/grid/node-x1-y14 89T 70T 19T 78% +/dev/grid/node-x1-y15 90T 67T 23T 74% +/dev/grid/node-x1-y16 94T 71T 23T 75% +/dev/grid/node-x1-y17 93T 68T 25T 73% +/dev/grid/node-x1-y18 88T 72T 16T 81% +/dev/grid/node-x1-y19 89T 66T 23T 74% +/dev/grid/node-x1-y20 88T 70T 18T 79% +/dev/grid/node-x1-y21 90T 67T 23T 74% +/dev/grid/node-x1-y22 90T 64T 26T 71% +/dev/grid/node-x1-y23 92T 69T 23T 75% +/dev/grid/node-x2-y0 86T 67T 19T 77% +/dev/grid/node-x2-y1 85T 71T 14T 83% +/dev/grid/node-x2-y2 91T 69T 22T 75% +/dev/grid/node-x2-y3 88T 68T 20T 77% +/dev/grid/node-x2-y4 87T 73T 14T 83% +/dev/grid/node-x2-y5 94T 64T 30T 68% +/dev/grid/node-x2-y6 90T 66T 24T 73% +/dev/grid/node-x2-y7 91T 66T 25T 72% +/dev/grid/node-x2-y8 86T 64T 22T 74% +/dev/grid/node-x2-y9 90T 69T 21T 76% +/dev/grid/node-x2-y10 94T 65T 29T 69% +/dev/grid/node-x2-y11 89T 69T 20T 77% +/dev/grid/node-x2-y12 94T 64T 30T 68% +/dev/grid/node-x2-y13 85T 70T 15T 82% +/dev/grid/node-x2-y14 87T 69T 18T 79% +/dev/grid/node-x2-y15 94T 70T 24T 74% +/dev/grid/node-x2-y16 89T 72T 17T 80% +/dev/grid/node-x2-y17 94T 65T 29T 69% +/dev/grid/node-x2-y18 85T 70T 15T 82% +/dev/grid/node-x2-y19 86T 64T 22T 74% +/dev/grid/node-x2-y20 91T 69T 22T 75% +/dev/grid/node-x2-y21 92T 66T 26T 71% +/dev/grid/node-x2-y22 92T 66T 26T 71% +/dev/grid/node-x2-y23 94T 70T 24T 74% +/dev/grid/node-x3-y0 91T 65T 26T 71% +/dev/grid/node-x3-y1 91T 73T 18T 80% +/dev/grid/node-x3-y2 93T 67T 26T 72% +/dev/grid/node-x3-y3 91T 66T 25T 72% +/dev/grid/node-x3-y4 85T 69T 16T 81% +/dev/grid/node-x3-y5 94T 69T 25T 73% +/dev/grid/node-x3-y6 94T 70T 24T 74% +/dev/grid/node-x3-y7 92T 72T 20T 78% +/dev/grid/node-x3-y8 94T 73T 21T 77% +/dev/grid/node-x3-y9 86T 73T 13T 84% +/dev/grid/node-x3-y10 86T 68T 18T 79% +/dev/grid/node-x3-y11 87T 65T 22T 74% +/dev/grid/node-x3-y12 91T 70T 21T 76% +/dev/grid/node-x3-y13 93T 66T 27T 70% +/dev/grid/node-x3-y14 92T 71T 21T 77% +/dev/grid/node-x3-y15 90T 71T 19T 78% +/dev/grid/node-x3-y16 90T 70T 20T 77% +/dev/grid/node-x3-y17 94T 66T 28T 70% +/dev/grid/node-x3-y18 90T 69T 21T 76% +/dev/grid/node-x3-y19 89T 65T 24T 73% +/dev/grid/node-x3-y20 90T 72T 18T 80% +/dev/grid/node-x3-y21 94T 72T 22T 76% +/dev/grid/node-x3-y22 89T 73T 16T 82% +/dev/grid/node-x3-y23 85T 69T 16T 81% +/dev/grid/node-x4-y0 94T 68T 26T 72% +/dev/grid/node-x4-y1 90T 66T 24T 73% +/dev/grid/node-x4-y2 89T 70T 19T 78% +/dev/grid/node-x4-y3 89T 64T 25T 71% +/dev/grid/node-x4-y4 89T 69T 20T 77% +/dev/grid/node-x4-y5 85T 64T 21T 75% +/dev/grid/node-x4-y6 90T 72T 18T 80% +/dev/grid/node-x4-y7 90T 69T 21T 76% +/dev/grid/node-x4-y8 89T 70T 19T 78% +/dev/grid/node-x4-y9 92T 70T 22T 76% +/dev/grid/node-x4-y10 90T 66T 24T 73% +/dev/grid/node-x4-y11 85T 71T 14T 83% +/dev/grid/node-x4-y12 89T 65T 24T 73% +/dev/grid/node-x4-y13 86T 72T 14T 83% +/dev/grid/node-x4-y14 91T 72T 19T 79% +/dev/grid/node-x4-y15 89T 71T 18T 79% +/dev/grid/node-x4-y16 86T 73T 13T 84% +/dev/grid/node-x4-y17 91T 65T 26T 71% +/dev/grid/node-x4-y18 87T 67T 20T 77% +/dev/grid/node-x4-y19 94T 66T 28T 70% +/dev/grid/node-x4-y20 89T 73T 16T 82% +/dev/grid/node-x4-y21 85T 73T 12T 85% +/dev/grid/node-x4-y22 87T 67T 20T 77% +/dev/grid/node-x4-y23 91T 66T 25T 72% +/dev/grid/node-x5-y0 90T 71T 19T 78% +/dev/grid/node-x5-y1 87T 71T 16T 81% +/dev/grid/node-x5-y2 87T 69T 18T 79% +/dev/grid/node-x5-y3 85T 64T 21T 75% +/dev/grid/node-x5-y4 89T 72T 17T 80% +/dev/grid/node-x5-y5 88T 65T 23T 73% +/dev/grid/node-x5-y6 91T 66T 25T 72% +/dev/grid/node-x5-y7 89T 65T 24T 73% +/dev/grid/node-x5-y8 86T 68T 18T 79% +/dev/grid/node-x5-y9 93T 68T 25T 73% +/dev/grid/node-x5-y10 87T 70T 17T 80% +/dev/grid/node-x5-y11 93T 72T 21T 77% +/dev/grid/node-x5-y12 94T 67T 27T 71% +/dev/grid/node-x5-y13 94T 68T 26T 72% +/dev/grid/node-x5-y14 92T 72T 20T 78% +/dev/grid/node-x5-y15 85T 67T 18T 78% +/dev/grid/node-x5-y16 87T 73T 14T 83% +/dev/grid/node-x5-y17 85T 69T 16T 81% +/dev/grid/node-x5-y18 89T 65T 24T 73% +/dev/grid/node-x5-y19 86T 65T 21T 75% +/dev/grid/node-x5-y20 85T 70T 15T 82% +/dev/grid/node-x5-y21 86T 73T 13T 84% +/dev/grid/node-x5-y22 85T 67T 18T 78% +/dev/grid/node-x5-y23 93T 64T 29T 68% +/dev/grid/node-x6-y0 90T 72T 18T 80% +/dev/grid/node-x6-y1 93T 65T 28T 69% +/dev/grid/node-x6-y2 85T 64T 21T 75% +/dev/grid/node-x6-y3 88T 64T 24T 72% +/dev/grid/node-x6-y4 89T 64T 25T 71% +/dev/grid/node-x6-y5 86T 72T 14T 83% +/dev/grid/node-x6-y6 88T 72T 16T 81% +/dev/grid/node-x6-y7 93T 66T 27T 70% +/dev/grid/node-x6-y8 90T 65T 25T 72% +/dev/grid/node-x6-y9 93T 69T 24T 74% +/dev/grid/node-x6-y10 88T 70T 18T 79% +/dev/grid/node-x6-y11 85T 73T 12T 85% +/dev/grid/node-x6-y12 92T 73T 19T 79% +/dev/grid/node-x6-y13 93T 70T 23T 75% +/dev/grid/node-x6-y14 85T 69T 16T 81% +/dev/grid/node-x6-y15 86T 67T 19T 77% +/dev/grid/node-x6-y16 91T 65T 26T 71% +/dev/grid/node-x6-y17 91T 66T 25T 72% +/dev/grid/node-x6-y18 91T 65T 26T 71% +/dev/grid/node-x6-y19 92T 66T 26T 71% +/dev/grid/node-x6-y20 90T 64T 26T 71% +/dev/grid/node-x6-y21 86T 70T 16T 81% +/dev/grid/node-x6-y22 94T 71T 23T 75% +/dev/grid/node-x6-y23 90T 69T 21T 76% +/dev/grid/node-x7-y0 91T 71T 20T 78% +/dev/grid/node-x7-y1 94T 71T 23T 75% +/dev/grid/node-x7-y2 88T 64T 24T 72% +/dev/grid/node-x7-y3 93T 73T 20T 78% +/dev/grid/node-x7-y4 86T 68T 18T 79% +/dev/grid/node-x7-y5 88T 73T 15T 82% +/dev/grid/node-x7-y6 92T 66T 26T 71% +/dev/grid/node-x7-y7 90T 64T 26T 71% +/dev/grid/node-x7-y8 88T 64T 24T 72% +/dev/grid/node-x7-y9 88T 70T 18T 79% +/dev/grid/node-x7-y10 93T 67T 26T 72% +/dev/grid/node-x7-y11 88T 71T 17T 80% +/dev/grid/node-x7-y12 89T 71T 18T 79% +/dev/grid/node-x7-y13 85T 65T 20T 76% +/dev/grid/node-x7-y14 85T 70T 15T 82% +/dev/grid/node-x7-y15 87T 72T 15T 82% +/dev/grid/node-x7-y16 85T 64T 21T 75% +/dev/grid/node-x7-y17 85T 64T 21T 75% +/dev/grid/node-x7-y18 88T 64T 24T 72% +/dev/grid/node-x7-y19 90T 67T 23T 74% +/dev/grid/node-x7-y20 94T 66T 28T 70% +/dev/grid/node-x7-y21 87T 67T 20T 77% +/dev/grid/node-x7-y22 88T 69T 19T 78% +/dev/grid/node-x7-y23 93T 69T 24T 74% +/dev/grid/node-x8-y0 85T 72T 13T 84% +/dev/grid/node-x8-y1 91T 72T 19T 79% +/dev/grid/node-x8-y2 86T 65T 21T 75% +/dev/grid/node-x8-y3 85T 69T 16T 81% +/dev/grid/node-x8-y4 93T 65T 28T 69% +/dev/grid/node-x8-y5 87T 72T 15T 82% +/dev/grid/node-x8-y6 93T 68T 25T 73% +/dev/grid/node-x8-y7 89T 73T 16T 82% +/dev/grid/node-x8-y8 85T 65T 20T 76% +/dev/grid/node-x8-y9 85T 73T 12T 85% +/dev/grid/node-x8-y10 89T 71T 18T 79% +/dev/grid/node-x8-y11 90T 68T 22T 75% +/dev/grid/node-x8-y12 85T 65T 20T 76% +/dev/grid/node-x8-y13 89T 71T 18T 79% +/dev/grid/node-x8-y14 92T 71T 21T 77% +/dev/grid/node-x8-y15 85T 73T 12T 85% +/dev/grid/node-x8-y16 87T 73T 14T 83% +/dev/grid/node-x8-y17 92T 66T 26T 71% +/dev/grid/node-x8-y18 87T 69T 18T 79% +/dev/grid/node-x8-y19 88T 64T 24T 72% +/dev/grid/node-x8-y20 88T 68T 20T 77% +/dev/grid/node-x8-y21 92T 66T 26T 71% +/dev/grid/node-x8-y22 85T 68T 17T 80% +/dev/grid/node-x8-y23 91T 66T 25T 72% +/dev/grid/node-x9-y0 90T 69T 21T 76% +/dev/grid/node-x9-y1 86T 73T 13T 84% +/dev/grid/node-x9-y2 92T 72T 20T 78% +/dev/grid/node-x9-y3 87T 68T 19T 78% +/dev/grid/node-x9-y4 90T 66T 24T 73% +/dev/grid/node-x9-y5 91T 64T 27T 70% +/dev/grid/node-x9-y6 91T 68T 23T 74% +/dev/grid/node-x9-y7 88T 66T 22T 75% +/dev/grid/node-x9-y8 85T 72T 13T 84% +/dev/grid/node-x9-y9 87T 68T 19T 78% +/dev/grid/node-x9-y10 89T 72T 17T 80% +/dev/grid/node-x9-y11 85T 66T 19T 77% +/dev/grid/node-x9-y12 87T 73T 14T 83% +/dev/grid/node-x9-y13 87T 66T 21T 75% +/dev/grid/node-x9-y14 92T 67T 25T 72% +/dev/grid/node-x9-y15 90T 67T 23T 74% +/dev/grid/node-x9-y16 85T 67T 18T 78% +/dev/grid/node-x9-y17 86T 70T 16T 81% +/dev/grid/node-x9-y18 86T 73T 13T 84% +/dev/grid/node-x9-y19 91T 72T 19T 79% +/dev/grid/node-x9-y20 93T 69T 24T 74% +/dev/grid/node-x9-y21 92T 72T 20T 78% +/dev/grid/node-x9-y22 88T 67T 21T 76% +/dev/grid/node-x9-y23 91T 64T 27T 70% +/dev/grid/node-x10-y0 89T 65T 24T 73% +/dev/grid/node-x10-y1 85T 70T 15T 82% +/dev/grid/node-x10-y2 87T 65T 22T 74% +/dev/grid/node-x10-y3 86T 73T 13T 84% +/dev/grid/node-x10-y4 85T 73T 12T 85% +/dev/grid/node-x10-y5 94T 65T 29T 69% +/dev/grid/node-x10-y6 91T 71T 20T 78% +/dev/grid/node-x10-y7 92T 65T 27T 70% +/dev/grid/node-x10-y8 92T 70T 22T 76% +/dev/grid/node-x10-y9 93T 66T 27T 70% +/dev/grid/node-x10-y10 86T 70T 16T 81% +/dev/grid/node-x10-y11 86T 73T 13T 84% +/dev/grid/node-x10-y12 93T 71T 22T 76% +/dev/grid/node-x10-y13 87T 72T 15T 82% +/dev/grid/node-x10-y14 93T 70T 23T 75% +/dev/grid/node-x10-y15 92T 66T 26T 71% +/dev/grid/node-x10-y16 85T 66T 19T 77% +/dev/grid/node-x10-y17 94T 71T 23T 75% +/dev/grid/node-x10-y18 88T 72T 16T 81% +/dev/grid/node-x10-y19 86T 71T 15T 82% +/dev/grid/node-x10-y20 90T 64T 26T 71% +/dev/grid/node-x10-y21 93T 72T 21T 77% +/dev/grid/node-x10-y22 86T 66T 20T 76% +/dev/grid/node-x10-y23 91T 73T 18T 80% +/dev/grid/node-x11-y0 91T 69T 22T 75% +/dev/grid/node-x11-y1 87T 68T 19T 78% +/dev/grid/node-x11-y2 93T 70T 23T 75% +/dev/grid/node-x11-y3 88T 65T 23T 73% +/dev/grid/node-x11-y4 86T 67T 19T 77% +/dev/grid/node-x11-y5 90T 67T 23T 74% +/dev/grid/node-x11-y6 94T 70T 24T 74% +/dev/grid/node-x11-y7 85T 68T 17T 80% +/dev/grid/node-x11-y8 88T 66T 22T 75% +/dev/grid/node-x11-y9 92T 67T 25T 72% +/dev/grid/node-x11-y10 90T 72T 18T 80% +/dev/grid/node-x11-y11 85T 73T 12T 85% +/dev/grid/node-x11-y12 88T 73T 15T 82% +/dev/grid/node-x11-y13 90T 69T 21T 76% +/dev/grid/node-x11-y14 86T 68T 18T 79% +/dev/grid/node-x11-y15 87T 71T 16T 81% +/dev/grid/node-x11-y16 91T 64T 27T 70% +/dev/grid/node-x11-y17 87T 67T 20T 77% +/dev/grid/node-x11-y18 88T 70T 18T 79% +/dev/grid/node-x11-y19 88T 71T 17T 80% +/dev/grid/node-x11-y20 91T 68T 23T 74% +/dev/grid/node-x11-y21 86T 71T 15T 82% +/dev/grid/node-x11-y22 87T 69T 18T 79% +/dev/grid/node-x11-y23 93T 68T 25T 73% +/dev/grid/node-x12-y0 90T 67T 23T 74% +/dev/grid/node-x12-y1 93T 66T 27T 70% +/dev/grid/node-x12-y2 85T 70T 15T 82% +/dev/grid/node-x12-y3 91T 64T 27T 70% +/dev/grid/node-x12-y4 85T 69T 16T 81% +/dev/grid/node-x12-y5 87T 66T 21T 75% +/dev/grid/node-x12-y6 86T 67T 19T 77% +/dev/grid/node-x12-y7 87T 66T 21T 75% +/dev/grid/node-x12-y8 86T 65T 21T 75% +/dev/grid/node-x12-y9 92T 66T 26T 71% +/dev/grid/node-x12-y10 90T 68T 22T 75% +/dev/grid/node-x12-y11 94T 72T 22T 76% +/dev/grid/node-x12-y12 88T 66T 22T 75% +/dev/grid/node-x12-y13 91T 71T 20T 78% +/dev/grid/node-x12-y14 88T 68T 20T 77% +/dev/grid/node-x12-y15 94T 68T 26T 72% +/dev/grid/node-x12-y16 85T 70T 15T 82% +/dev/grid/node-x12-y17 93T 72T 21T 77% +/dev/grid/node-x12-y18 94T 64T 30T 68% +/dev/grid/node-x12-y19 88T 65T 23T 73% +/dev/grid/node-x12-y20 89T 67T 22T 75% +/dev/grid/node-x12-y21 89T 65T 24T 73% +/dev/grid/node-x12-y22 85T 65T 20T 76% +/dev/grid/node-x12-y23 88T 65T 23T 73% +/dev/grid/node-x13-y0 90T 72T 18T 80% +/dev/grid/node-x13-y1 88T 65T 23T 73% +/dev/grid/node-x13-y2 89T 71T 18T 79% +/dev/grid/node-x13-y3 90T 66T 24T 73% +/dev/grid/node-x13-y4 94T 65T 29T 69% +/dev/grid/node-x13-y5 88T 65T 23T 73% +/dev/grid/node-x13-y6 86T 72T 14T 83% +/dev/grid/node-x13-y7 85T 72T 13T 84% +/dev/grid/node-x13-y8 90T 71T 19T 78% +/dev/grid/node-x13-y9 89T 67T 22T 75% +/dev/grid/node-x13-y10 88T 67T 21T 76% +/dev/grid/node-x13-y11 87T 70T 17T 80% +/dev/grid/node-x13-y12 90T 68T 22T 75% +/dev/grid/node-x13-y13 92T 67T 25T 72% +/dev/grid/node-x13-y14 89T 65T 24T 73% +/dev/grid/node-x13-y15 87T 70T 17T 80% +/dev/grid/node-x13-y16 93T 65T 28T 69% +/dev/grid/node-x13-y17 88T 64T 24T 72% +/dev/grid/node-x13-y18 86T 67T 19T 77% +/dev/grid/node-x13-y19 90T 70T 20T 77% +/dev/grid/node-x13-y20 92T 67T 25T 72% +/dev/grid/node-x13-y21 90T 71T 19T 78% +/dev/grid/node-x13-y22 86T 71T 15T 82% +/dev/grid/node-x13-y23 87T 69T 18T 79% +/dev/grid/node-x14-y0 94T 64T 30T 68% +/dev/grid/node-x14-y1 88T 68T 20T 77% +/dev/grid/node-x14-y2 91T 70T 21T 76% +/dev/grid/node-x14-y3 87T 69T 18T 79% +/dev/grid/node-x14-y4 92T 65T 27T 70% +/dev/grid/node-x14-y5 90T 67T 23T 74% +/dev/grid/node-x14-y6 89T 65T 24T 73% +/dev/grid/node-x14-y7 92T 73T 19T 79% +/dev/grid/node-x14-y8 86T 66T 20T 76% +/dev/grid/node-x14-y9 93T 68T 25T 73% +/dev/grid/node-x14-y10 88T 70T 18T 79% +/dev/grid/node-x14-y11 93T 67T 26T 72% +/dev/grid/node-x14-y12 85T 70T 15T 82% +/dev/grid/node-x14-y13 88T 64T 24T 72% +/dev/grid/node-x14-y14 88T 70T 18T 79% +/dev/grid/node-x14-y15 90T 70T 20T 77% +/dev/grid/node-x14-y16 91T 65T 26T 71% +/dev/grid/node-x14-y17 89T 64T 25T 71% +/dev/grid/node-x14-y18 85T 73T 12T 85% +/dev/grid/node-x14-y19 94T 64T 30T 68% +/dev/grid/node-x14-y20 89T 73T 16T 82% +/dev/grid/node-x14-y21 91T 73T 18T 80% +/dev/grid/node-x14-y22 94T 72T 22T 76% +/dev/grid/node-x14-y23 90T 68T 22T 75% +/dev/grid/node-x15-y0 91T 71T 20T 78% +/dev/grid/node-x15-y1 90T 68T 22T 75% +/dev/grid/node-x15-y2 90T 65T 25T 72% +/dev/grid/node-x15-y3 90T 68T 22T 75% +/dev/grid/node-x15-y4 90T 73T 17T 81% +/dev/grid/node-x15-y5 88T 73T 15T 82% +/dev/grid/node-x15-y6 88T 66T 22T 75% +/dev/grid/node-x15-y7 94T 69T 25T 73% +/dev/grid/node-x15-y8 94T 64T 30T 68% +/dev/grid/node-x15-y9 93T 65T 28T 69% +/dev/grid/node-x15-y10 94T 72T 22T 76% +/dev/grid/node-x15-y11 85T 71T 14T 83% +/dev/grid/node-x15-y12 93T 67T 26T 72% +/dev/grid/node-x15-y13 85T 69T 16T 81% +/dev/grid/node-x15-y14 85T 64T 21T 75% +/dev/grid/node-x15-y15 88T 65T 23T 73% +/dev/grid/node-x15-y16 93T 69T 24T 74% +/dev/grid/node-x15-y17 85T 64T 21T 75% +/dev/grid/node-x15-y18 89T 72T 17T 80% +/dev/grid/node-x15-y19 89T 66T 23T 74% +/dev/grid/node-x15-y20 91T 66T 25T 72% +/dev/grid/node-x15-y21 90T 71T 19T 78% +/dev/grid/node-x15-y22 94T 66T 28T 70% +/dev/grid/node-x15-y23 91T 69T 22T 75% +/dev/grid/node-x16-y0 94T 64T 30T 68% +/dev/grid/node-x16-y1 89T 73T 16T 82% +/dev/grid/node-x16-y2 91T 69T 22T 75% +/dev/grid/node-x16-y3 94T 71T 23T 75% +/dev/grid/node-x16-y4 88T 70T 18T 79% +/dev/grid/node-x16-y5 92T 69T 23T 75% +/dev/grid/node-x16-y6 93T 67T 26T 72% +/dev/grid/node-x16-y7 90T 65T 25T 72% +/dev/grid/node-x16-y8 86T 69T 17T 80% +/dev/grid/node-x16-y9 87T 71T 16T 81% +/dev/grid/node-x16-y10 86T 65T 21T 75% +/dev/grid/node-x16-y11 86T 65T 21T 75% +/dev/grid/node-x16-y12 85T 73T 12T 85% +/dev/grid/node-x16-y13 88T 68T 20T 77% +/dev/grid/node-x16-y14 88T 66T 22T 75% +/dev/grid/node-x16-y15 93T 66T 27T 70% +/dev/grid/node-x16-y16 93T 64T 29T 68% +/dev/grid/node-x16-y17 89T 72T 17T 80% +/dev/grid/node-x16-y18 91T 65T 26T 71% +/dev/grid/node-x16-y19 93T 67T 26T 72% +/dev/grid/node-x16-y20 90T 69T 21T 76% +/dev/grid/node-x16-y21 87T 68T 19T 78% +/dev/grid/node-x16-y22 89T 71T 18T 79% +/dev/grid/node-x16-y23 91T 67T 24T 73% +/dev/grid/node-x17-y0 87T 64T 23T 73% +/dev/grid/node-x17-y1 85T 69T 16T 81% +/dev/grid/node-x17-y2 94T 72T 22T 76% +/dev/grid/node-x17-y3 87T 67T 20T 77% +/dev/grid/node-x17-y4 88T 69T 19T 78% +/dev/grid/node-x17-y5 87T 71T 16T 81% +/dev/grid/node-x17-y6 87T 70T 17T 80% +/dev/grid/node-x17-y7 86T 73T 13T 84% +/dev/grid/node-x17-y8 92T 64T 28T 69% +/dev/grid/node-x17-y9 85T 64T 21T 75% +/dev/grid/node-x17-y10 89T 65T 24T 73% +/dev/grid/node-x17-y11 93T 69T 24T 74% +/dev/grid/node-x17-y12 85T 67T 18T 78% +/dev/grid/node-x17-y13 94T 66T 28T 70% +/dev/grid/node-x17-y14 87T 70T 17T 80% +/dev/grid/node-x17-y15 88T 73T 15T 82% +/dev/grid/node-x17-y16 90T 68T 22T 75% +/dev/grid/node-x17-y17 86T 71T 15T 82% +/dev/grid/node-x17-y18 91T 72T 19T 79% +/dev/grid/node-x17-y19 92T 71T 21T 77% +/dev/grid/node-x17-y20 92T 68T 24T 73% +/dev/grid/node-x17-y21 89T 67T 22T 75% +/dev/grid/node-x17-y22 89T 67T 22T 75% +/dev/grid/node-x17-y23 93T 65T 28T 69% +/dev/grid/node-x18-y0 87T 70T 17T 80% +/dev/grid/node-x18-y1 85T 65T 20T 76% +/dev/grid/node-x18-y2 93T 67T 26T 72% +/dev/grid/node-x18-y3 92T 65T 27T 70% +/dev/grid/node-x18-y4 87T 72T 15T 82% +/dev/grid/node-x18-y5 94T 65T 29T 69% +/dev/grid/node-x18-y6 92T 67T 25T 72% +/dev/grid/node-x18-y7 90T 65T 25T 72% +/dev/grid/node-x18-y8 88T 65T 23T 73% +/dev/grid/node-x18-y9 87T 70T 17T 80% +/dev/grid/node-x18-y10 88T 64T 24T 72% +/dev/grid/node-x18-y11 87T 65T 22T 74% +/dev/grid/node-x18-y12 88T 66T 22T 75% +/dev/grid/node-x18-y13 93T 72T 21T 77% +/dev/grid/node-x18-y14 90T 65T 25T 72% +/dev/grid/node-x18-y15 89T 66T 23T 74% +/dev/grid/node-x18-y16 86T 65T 21T 75% +/dev/grid/node-x18-y17 85T 66T 19T 77% +/dev/grid/node-x18-y18 91T 69T 22T 75% +/dev/grid/node-x18-y19 88T 64T 24T 72% +/dev/grid/node-x18-y20 87T 66T 21T 75% +/dev/grid/node-x18-y21 87T 69T 18T 79% +/dev/grid/node-x18-y22 89T 69T 20T 77% +/dev/grid/node-x18-y23 87T 71T 16T 81% +/dev/grid/node-x19-y0 89T 72T 17T 80% +/dev/grid/node-x19-y1 91T 70T 21T 76% +/dev/grid/node-x19-y2 87T 64T 23T 73% +/dev/grid/node-x19-y3 88T 70T 18T 79% +/dev/grid/node-x19-y4 91T 64T 27T 70% +/dev/grid/node-x19-y5 90T 64T 26T 71% +/dev/grid/node-x19-y6 91T 65T 26T 71% +/dev/grid/node-x19-y7 89T 73T 16T 82% +/dev/grid/node-x19-y8 87T 65T 22T 74% +/dev/grid/node-x19-y9 90T 66T 24T 73% +/dev/grid/node-x19-y10 93T 68T 25T 73% +/dev/grid/node-x19-y11 87T 69T 18T 79% +/dev/grid/node-x19-y12 92T 66T 26T 71% +/dev/grid/node-x19-y13 94T 71T 23T 75% +/dev/grid/node-x19-y14 86T 64T 22T 74% +/dev/grid/node-x19-y15 89T 68T 21T 76% +/dev/grid/node-x19-y16 94T 69T 25T 73% +/dev/grid/node-x19-y17 85T 72T 13T 84% +/dev/grid/node-x19-y18 93T 70T 23T 75% +/dev/grid/node-x19-y19 85T 67T 18T 78% +/dev/grid/node-x19-y20 92T 64T 28T 69% +/dev/grid/node-x19-y21 93T 68T 25T 73% +/dev/grid/node-x19-y22 94T 66T 28T 70% +/dev/grid/node-x19-y23 87T 70T 17T 80% +/dev/grid/node-x20-y0 91T 65T 26T 71% +/dev/grid/node-x20-y1 85T 72T 13T 84% +/dev/grid/node-x20-y2 94T 64T 30T 68% +/dev/grid/node-x20-y3 89T 65T 24T 73% +/dev/grid/node-x20-y4 88T 69T 19T 78% +/dev/grid/node-x20-y5 94T 71T 23T 75% +/dev/grid/node-x20-y6 87T 69T 18T 79% +/dev/grid/node-x20-y7 94T 67T 27T 71% +/dev/grid/node-x20-y8 89T 65T 24T 73% +/dev/grid/node-x20-y9 88T 65T 23T 73% +/dev/grid/node-x20-y10 94T 73T 21T 77% +/dev/grid/node-x20-y11 87T 66T 21T 75% +/dev/grid/node-x20-y12 92T 66T 26T 71% +/dev/grid/node-x20-y13 86T 71T 15T 82% +/dev/grid/node-x20-y14 93T 64T 29T 68% +/dev/grid/node-x20-y15 91T 65T 26T 71% +/dev/grid/node-x20-y16 89T 65T 24T 73% +/dev/grid/node-x20-y17 90T 68T 22T 75% +/dev/grid/node-x20-y18 90T 73T 17T 81% +/dev/grid/node-x20-y19 85T 73T 12T 85% +/dev/grid/node-x20-y20 85T 67T 18T 78% +/dev/grid/node-x20-y21 94T 65T 29T 69% +/dev/grid/node-x20-y22 86T 69T 17T 80% +/dev/grid/node-x20-y23 93T 73T 20T 78% +/dev/grid/node-x21-y0 92T 73T 19T 79% +/dev/grid/node-x21-y1 94T 72T 22T 76% +/dev/grid/node-x21-y2 92T 69T 23T 75% +/dev/grid/node-x21-y3 86T 68T 18T 79% +/dev/grid/node-x21-y4 87T 69T 18T 79% +/dev/grid/node-x21-y5 87T 67T 20T 77% +/dev/grid/node-x21-y6 87T 70T 17T 80% +/dev/grid/node-x21-y7 87T 73T 14T 83% +/dev/grid/node-x21-y8 91T 71T 20T 78% +/dev/grid/node-x21-y9 85T 68T 17T 80% +/dev/grid/node-x21-y10 85T 70T 15T 82% +/dev/grid/node-x21-y11 86T 66T 20T 76% +/dev/grid/node-x21-y12 90T 64T 26T 71% +/dev/grid/node-x21-y13 87T 69T 18T 79% +/dev/grid/node-x21-y14 92T 64T 28T 69% +/dev/grid/node-x21-y15 88T 65T 23T 73% +/dev/grid/node-x21-y16 93T 70T 23T 75% +/dev/grid/node-x21-y17 87T 71T 16T 81% +/dev/grid/node-x21-y18 91T 65T 26T 71% +/dev/grid/node-x21-y19 85T 68T 17T 80% +/dev/grid/node-x21-y20 87T 66T 21T 75% +/dev/grid/node-x21-y21 94T 72T 22T 76% +/dev/grid/node-x21-y22 92T 67T 25T 72% +/dev/grid/node-x21-y23 88T 68T 20T 77% +/dev/grid/node-x22-y0 88T 69T 19T 78% +/dev/grid/node-x22-y1 88T 70T 18T 79% +/dev/grid/node-x22-y2 85T 67T 18T 78% +/dev/grid/node-x22-y3 86T 67T 19T 77% +/dev/grid/node-x22-y4 93T 70T 23T 75% +/dev/grid/node-x22-y5 89T 71T 18T 79% +/dev/grid/node-x22-y6 90T 73T 17T 81% +/dev/grid/node-x22-y7 87T 70T 17T 80% +/dev/grid/node-x22-y8 85T 68T 17T 80% +/dev/grid/node-x22-y9 87T 64T 23T 73% +/dev/grid/node-x22-y10 85T 72T 13T 84% +/dev/grid/node-x22-y11 88T 66T 22T 75% +/dev/grid/node-x22-y12 87T 72T 15T 82% +/dev/grid/node-x22-y13 88T 72T 16T 81% +/dev/grid/node-x22-y14 91T 69T 22T 75% +/dev/grid/node-x22-y15 90T 73T 17T 81% +/dev/grid/node-x22-y16 91T 69T 22T 75% +/dev/grid/node-x22-y17 92T 66T 26T 71% +/dev/grid/node-x22-y18 94T 70T 24T 74% +/dev/grid/node-x22-y19 86T 67T 19T 77% +/dev/grid/node-x22-y20 92T 70T 22T 76% +/dev/grid/node-x22-y21 89T 71T 18T 79% +/dev/grid/node-x22-y22 92T 69T 23T 75% +/dev/grid/node-x22-y23 87T 70T 17T 80% +/dev/grid/node-x23-y0 88T 69T 19T 78% +/dev/grid/node-x23-y1 86T 72T 14T 83% +/dev/grid/node-x23-y2 89T 64T 25T 71% +/dev/grid/node-x23-y3 91T 68T 23T 74% +/dev/grid/node-x23-y4 87T 71T 16T 81% +/dev/grid/node-x23-y5 85T 71T 14T 83% +/dev/grid/node-x23-y6 92T 68T 24T 73% +/dev/grid/node-x23-y7 85T 71T 14T 83% +/dev/grid/node-x23-y8 91T 64T 27T 70% +/dev/grid/node-x23-y9 85T 70T 15T 82% +/dev/grid/node-x23-y10 93T 72T 21T 77% +/dev/grid/node-x23-y11 87T 72T 15T 82% +/dev/grid/node-x23-y12 90T 72T 18T 80% +/dev/grid/node-x23-y13 89T 64T 25T 71% +/dev/grid/node-x23-y14 87T 67T 20T 77% +/dev/grid/node-x23-y15 87T 70T 17T 80% +/dev/grid/node-x23-y16 94T 68T 26T 72% +/dev/grid/node-x23-y17 88T 68T 20T 77% +/dev/grid/node-x23-y18 87T 65T 22T 74% +/dev/grid/node-x23-y19 90T 71T 19T 78% +/dev/grid/node-x23-y20 93T 71T 22T 76% +/dev/grid/node-x23-y21 92T 64T 28T 69% +/dev/grid/node-x23-y22 89T 66T 23T 74% +/dev/grid/node-x23-y23 90T 73T 17T 81% +/dev/grid/node-x24-y0 93T 70T 23T 75% +/dev/grid/node-x24-y1 91T 71T 20T 78% +/dev/grid/node-x24-y2 93T 68T 25T 73% +/dev/grid/node-x24-y3 88T 72T 16T 81% +/dev/grid/node-x24-y4 92T 64T 28T 69% +/dev/grid/node-x24-y5 87T 64T 23T 73% +/dev/grid/node-x24-y6 91T 70T 21T 76% +/dev/grid/node-x24-y7 93T 72T 21T 77% +/dev/grid/node-x24-y8 94T 73T 21T 77% +/dev/grid/node-x24-y9 88T 72T 16T 81% +/dev/grid/node-x24-y10 89T 67T 22T 75% +/dev/grid/node-x24-y11 89T 68T 21T 76% +/dev/grid/node-x24-y12 89T 66T 23T 74% +/dev/grid/node-x24-y13 93T 67T 26T 72% +/dev/grid/node-x24-y14 92T 69T 23T 75% +/dev/grid/node-x24-y15 85T 72T 13T 84% +/dev/grid/node-x24-y16 85T 64T 21T 75% +/dev/grid/node-x24-y17 94T 69T 25T 73% +/dev/grid/node-x24-y18 93T 67T 26T 72% +/dev/grid/node-x24-y19 89T 67T 22T 75% +/dev/grid/node-x24-y20 86T 67T 19T 77% +/dev/grid/node-x24-y21 87T 71T 16T 81% +/dev/grid/node-x24-y22 90T 71T 19T 78% +/dev/grid/node-x24-y23 88T 70T 18T 79% +/dev/grid/node-x25-y0 91T 70T 21T 76% +/dev/grid/node-x25-y1 92T 67T 25T 72% +/dev/grid/node-x25-y2 91T 71T 20T 78% +/dev/grid/node-x25-y3 88T 68T 20T 77% +/dev/grid/node-x25-y4 91T 64T 27T 70% +/dev/grid/node-x25-y5 88T 66T 22T 75% +/dev/grid/node-x25-y6 89T 66T 23T 74% +/dev/grid/node-x25-y7 92T 72T 20T 78% +/dev/grid/node-x25-y8 88T 71T 17T 80% +/dev/grid/node-x25-y9 90T 65T 25T 72% +/dev/grid/node-x25-y10 93T 65T 28T 69% +/dev/grid/node-x25-y11 94T 70T 24T 74% +/dev/grid/node-x25-y12 90T 69T 21T 76% +/dev/grid/node-x25-y13 86T 66T 20T 76% +/dev/grid/node-x25-y14 85T 71T 14T 83% +/dev/grid/node-x25-y15 91T 72T 19T 79% +/dev/grid/node-x25-y16 86T 68T 18T 79% +/dev/grid/node-x25-y17 85T 65T 20T 76% +/dev/grid/node-x25-y18 85T 67T 18T 78% +/dev/grid/node-x25-y19 94T 72T 22T 76% +/dev/grid/node-x25-y20 89T 69T 20T 77% +/dev/grid/node-x25-y21 94T 70T 24T 74% +/dev/grid/node-x25-y22 89T 68T 21T 76% +/dev/grid/node-x25-y23 89T 69T 20T 77% +/dev/grid/node-x26-y0 91T 64T 27T 70% +/dev/grid/node-x26-y1 85T 64T 21T 75% +/dev/grid/node-x26-y2 91T 73T 18T 80% +/dev/grid/node-x26-y3 94T 66T 28T 70% +/dev/grid/node-x26-y4 94T 67T 27T 71% +/dev/grid/node-x26-y5 85T 64T 21T 75% +/dev/grid/node-x26-y6 94T 73T 21T 77% +/dev/grid/node-x26-y7 92T 71T 21T 77% +/dev/grid/node-x26-y8 89T 67T 22T 75% +/dev/grid/node-x26-y9 89T 72T 17T 80% +/dev/grid/node-x26-y10 92T 73T 19T 79% +/dev/grid/node-x26-y11 91T 68T 23T 74% +/dev/grid/node-x26-y12 90T 64T 26T 71% +/dev/grid/node-x26-y13 86T 66T 20T 76% +/dev/grid/node-x26-y14 92T 64T 28T 69% +/dev/grid/node-x26-y15 91T 64T 27T 70% +/dev/grid/node-x26-y16 93T 69T 24T 74% +/dev/grid/node-x26-y17 90T 68T 22T 75% +/dev/grid/node-x26-y18 91T 64T 27T 70% +/dev/grid/node-x26-y19 85T 73T 12T 85% +/dev/grid/node-x26-y20 92T 68T 24T 73% +/dev/grid/node-x26-y21 87T 67T 20T 77% +/dev/grid/node-x26-y22 93T 72T 21T 77% +/dev/grid/node-x26-y23 88T 66T 22T 75% +/dev/grid/node-x27-y0 92T 69T 23T 75% +/dev/grid/node-x27-y1 85T 64T 21T 75% +/dev/grid/node-x27-y2 90T 67T 23T 74% +/dev/grid/node-x27-y3 87T 69T 18T 79% +/dev/grid/node-x27-y4 86T 68T 18T 79% +/dev/grid/node-x27-y5 92T 73T 19T 79% +/dev/grid/node-x27-y6 93T 65T 28T 69% +/dev/grid/node-x27-y7 89T 64T 25T 71% +/dev/grid/node-x27-y8 90T 67T 23T 74% +/dev/grid/node-x27-y9 89T 66T 23T 74% +/dev/grid/node-x27-y10 89T 72T 17T 80% +/dev/grid/node-x27-y11 85T 70T 15T 82% +/dev/grid/node-x27-y12 89T 70T 19T 78% +/dev/grid/node-x27-y13 92T 65T 27T 70% +/dev/grid/node-x27-y14 88T 64T 24T 72% +/dev/grid/node-x27-y15 89T 70T 19T 78% +/dev/grid/node-x27-y16 85T 72T 13T 84% +/dev/grid/node-x27-y17 93T 71T 22T 76% +/dev/grid/node-x27-y18 94T 72T 22T 76% +/dev/grid/node-x27-y19 90T 69T 21T 76% +/dev/grid/node-x27-y20 86T 69T 17T 80% +/dev/grid/node-x27-y21 90T 68T 22T 75% +/dev/grid/node-x27-y22 85T 70T 15T 82% +/dev/grid/node-x27-y23 91T 71T 20T 78% +/dev/grid/node-x28-y0 88T 68T 20T 77% +/dev/grid/node-x28-y1 92T 67T 25T 72% +/dev/grid/node-x28-y2 88T 66T 22T 75% +/dev/grid/node-x28-y3 87T 69T 18T 79% +/dev/grid/node-x28-y4 88T 66T 22T 75% +/dev/grid/node-x28-y5 89T 67T 22T 75% +/dev/grid/node-x28-y6 94T 64T 30T 68% +/dev/grid/node-x28-y7 92T 64T 28T 69% +/dev/grid/node-x28-y8 93T 65T 28T 69% +/dev/grid/node-x28-y9 90T 66T 24T 73% +/dev/grid/node-x28-y10 93T 67T 26T 72% +/dev/grid/node-x28-y11 94T 71T 23T 75% +/dev/grid/node-x28-y12 85T 69T 16T 81% +/dev/grid/node-x28-y13 86T 73T 13T 84% +/dev/grid/node-x28-y14 93T 64T 29T 68% +/dev/grid/node-x28-y15 88T 64T 24T 72% +/dev/grid/node-x28-y16 86T 65T 21T 75% +/dev/grid/node-x28-y17 92T 72T 20T 78% +/dev/grid/node-x28-y18 88T 64T 24T 72% +/dev/grid/node-x28-y19 85T 72T 13T 84% +/dev/grid/node-x28-y20 90T 73T 17T 81% +/dev/grid/node-x28-y21 85T 68T 17T 80% +/dev/grid/node-x28-y22 91T 69T 22T 75% +/dev/grid/node-x28-y23 90T 67T 23T 74% +/dev/grid/node-x29-y0 89T 71T 18T 79% +/dev/grid/node-x29-y1 89T 67T 22T 75% +/dev/grid/node-x29-y2 89T 70T 19T 78% +/dev/grid/node-x29-y3 91T 64T 27T 70% +/dev/grid/node-x29-y4 91T 70T 21T 76% +/dev/grid/node-x29-y5 91T 68T 23T 74% +/dev/grid/node-x29-y6 88T 72T 16T 81% +/dev/grid/node-x29-y7 88T 65T 23T 73% +/dev/grid/node-x29-y8 94T 67T 27T 71% +/dev/grid/node-x29-y9 92T 69T 23T 75% +/dev/grid/node-x29-y10 92T 70T 22T 76% +/dev/grid/node-x29-y11 91T 64T 27T 70% +/dev/grid/node-x29-y12 85T 73T 12T 85% +/dev/grid/node-x29-y13 87T 68T 19T 78% +/dev/grid/node-x29-y14 90T 71T 19T 78% +/dev/grid/node-x29-y15 93T 68T 25T 73% +/dev/grid/node-x29-y16 89T 69T 20T 77% +/dev/grid/node-x29-y17 86T 68T 18T 79% +/dev/grid/node-x29-y18 91T 65T 26T 71% +/dev/grid/node-x29-y19 86T 67T 19T 77% +/dev/grid/node-x29-y20 89T 69T 20T 77% +/dev/grid/node-x29-y21 87T 72T 15T 82% +/dev/grid/node-x29-y22 93T 71T 22T 76% +/dev/grid/node-x29-y23 90T 70T 20T 77% +/dev/grid/node-x30-y0 86T 65T 21T 75% +/dev/grid/node-x30-y1 86T 68T 18T 79% +/dev/grid/node-x30-y2 88T 66T 22T 75% +/dev/grid/node-x30-y3 86T 67T 19T 77% +/dev/grid/node-x30-y4 90T 73T 17T 81% +/dev/grid/node-x30-y5 86T 70T 16T 81% +/dev/grid/node-x30-y6 89T 72T 17T 80% +/dev/grid/node-x30-y7 85T 73T 12T 85% +/dev/grid/node-x30-y8 94T 64T 30T 68% +/dev/grid/node-x30-y9 89T 67T 22T 75% +/dev/grid/node-x30-y10 85T 68T 17T 80% +/dev/grid/node-x30-y11 87T 69T 18T 79% +/dev/grid/node-x30-y12 94T 68T 26T 72% +/dev/grid/node-x30-y13 86T 67T 19T 77% +/dev/grid/node-x30-y14 88T 71T 17T 80% +/dev/grid/node-x30-y15 89T 68T 21T 76% +/dev/grid/node-x30-y16 86T 70T 16T 81% +/dev/grid/node-x30-y17 86T 66T 20T 76% +/dev/grid/node-x30-y18 86T 72T 14T 83% +/dev/grid/node-x30-y19 501T 493T 8T 98% +/dev/grid/node-x30-y20 86T 71T 15T 82% +/dev/grid/node-x30-y21 94T 68T 26T 72% +/dev/grid/node-x30-y22 88T 73T 15T 82% +/dev/grid/node-x30-y23 88T 73T 15T 82% +/dev/grid/node-x31-y0 88T 73T 15T 82% +/dev/grid/node-x31-y1 86T 70T 16T 81% +/dev/grid/node-x31-y2 87T 67T 20T 77% +/dev/grid/node-x31-y3 87T 72T 15T 82% +/dev/grid/node-x31-y4 89T 72T 17T 80% +/dev/grid/node-x31-y5 91T 69T 22T 75% +/dev/grid/node-x31-y6 94T 71T 23T 75% +/dev/grid/node-x31-y7 87T 72T 15T 82% +/dev/grid/node-x31-y8 86T 69T 17T 80% +/dev/grid/node-x31-y9 90T 72T 18T 80% +/dev/grid/node-x31-y10 86T 64T 22T 74% +/dev/grid/node-x31-y11 92T 72T 20T 78% +/dev/grid/node-x31-y12 94T 72T 22T 76% +/dev/grid/node-x31-y13 90T 71T 19T 78% +/dev/grid/node-x31-y14 94T 67T 27T 71% +/dev/grid/node-x31-y15 86T 71T 15T 82% +/dev/grid/node-x31-y16 91T 69T 22T 75% +/dev/grid/node-x31-y17 93T 73T 20T 78% +/dev/grid/node-x31-y18 88T 68T 20T 77% +/dev/grid/node-x31-y19 504T 498T 6T 98% +/dev/grid/node-x31-y20 91T 67T 24T 73% +/dev/grid/node-x31-y21 87T 68T 19T 78% +/dev/grid/node-x31-y22 91T 65T 26T 71% +/dev/grid/node-x31-y23 85T 67T 18T 78% +/dev/grid/node-x32-y0 90T 72T 18T 80% +/dev/grid/node-x32-y1 89T 69T 20T 77% +/dev/grid/node-x32-y2 88T 73T 15T 82% +/dev/grid/node-x32-y3 91T 69T 22T 75% +/dev/grid/node-x32-y4 90T 68T 22T 75% +/dev/grid/node-x32-y5 93T 71T 22T 76% +/dev/grid/node-x32-y6 87T 65T 22T 74% +/dev/grid/node-x32-y7 94T 69T 25T 73% +/dev/grid/node-x32-y8 92T 65T 27T 70% +/dev/grid/node-x32-y9 90T 67T 23T 74% +/dev/grid/node-x32-y10 85T 69T 16T 81% +/dev/grid/node-x32-y11 94T 64T 30T 68% +/dev/grid/node-x32-y12 87T 73T 14T 83% +/dev/grid/node-x32-y13 85T 64T 21T 75% +/dev/grid/node-x32-y14 85T 68T 17T 80% +/dev/grid/node-x32-y15 89T 71T 18T 79% +/dev/grid/node-x32-y16 90T 66T 24T 73% +/dev/grid/node-x32-y17 86T 65T 21T 75% +/dev/grid/node-x32-y18 94T 70T 24T 74% +/dev/grid/node-x32-y19 505T 497T 8T 98% +/dev/grid/node-x32-y20 90T 65T 25T 72% +/dev/grid/node-x32-y21 88T 70T 18T 79% +/dev/grid/node-x32-y22 92T 69T 23T 75% +/dev/grid/node-x32-y23 86T 73T 13T 84% +/dev/grid/node-x33-y0 93T 70T 23T 75% +/dev/grid/node-x33-y1 89T 64T 25T 71% +/dev/grid/node-x33-y2 89T 64T 25T 71% +/dev/grid/node-x33-y3 86T 67T 19T 77% +/dev/grid/node-x33-y4 93T 64T 29T 68% +/dev/grid/node-x33-y5 92T 72T 20T 78% +/dev/grid/node-x33-y6 86T 66T 20T 76% +/dev/grid/node-x33-y7 89T 72T 17T 80% +/dev/grid/node-x33-y8 85T 72T 13T 84% +/dev/grid/node-x33-y9 92T 70T 22T 76% +/dev/grid/node-x33-y10 89T 68T 21T 76% +/dev/grid/node-x33-y11 88T 65T 23T 73% +/dev/grid/node-x33-y12 87T 66T 21T 75% +/dev/grid/node-x33-y13 88T 68T 20T 77% +/dev/grid/node-x33-y14 85T 71T 14T 83% +/dev/grid/node-x33-y15 90T 72T 18T 80% +/dev/grid/node-x33-y16 92T 64T 28T 69% +/dev/grid/node-x33-y17 87T 69T 18T 79% +/dev/grid/node-x33-y18 85T 70T 15T 82% +/dev/grid/node-x33-y19 508T 490T 18T 96% +/dev/grid/node-x33-y20 92T 70T 22T 76% +/dev/grid/node-x33-y21 92T 65T 27T 70% +/dev/grid/node-x33-y22 93T 68T 25T 73% +/dev/grid/node-x33-y23 89T 73T 16T 82% +/dev/grid/node-x34-y0 88T 67T 21T 76% +/dev/grid/node-x34-y1 92T 71T 21T 77% +/dev/grid/node-x34-y2 90T 68T 22T 75% +/dev/grid/node-x34-y3 89T 66T 23T 74% +/dev/grid/node-x34-y4 86T 71T 15T 82% +/dev/grid/node-x34-y5 86T 72T 14T 83% +/dev/grid/node-x34-y6 87T 66T 21T 75% +/dev/grid/node-x34-y7 87T 68T 19T 78% +/dev/grid/node-x34-y8 94T 69T 25T 73% +/dev/grid/node-x34-y9 88T 66T 22T 75% +/dev/grid/node-x34-y10 92T 64T 28T 69% +/dev/grid/node-x34-y11 89T 73T 16T 82% +/dev/grid/node-x34-y12 86T 67T 19T 77% +/dev/grid/node-x34-y13 90T 64T 26T 71% +/dev/grid/node-x34-y14 85T 64T 21T 75% +/dev/grid/node-x34-y15 89T 73T 16T 82% +/dev/grid/node-x34-y16 91T 65T 26T 71% +/dev/grid/node-x34-y17 86T 64T 22T 74% +/dev/grid/node-x34-y18 89T 64T 25T 71% +/dev/grid/node-x34-y19 504T 499T 5T 99% +/dev/grid/node-x34-y20 88T 64T 24T 72% +/dev/grid/node-x34-y21 90T 64T 26T 71% +/dev/grid/node-x34-y22 87T 66T 21T 75% +/dev/grid/node-x34-y23 89T 65T 24T 73% +/dev/grid/node-x35-y0 91T 71T 20T 78% +/dev/grid/node-x35-y1 93T 72T 21T 77% +/dev/grid/node-x35-y2 86T 68T 18T 79% +/dev/grid/node-x35-y3 91T 71T 20T 78% +/dev/grid/node-x35-y4 92T 67T 25T 72% +/dev/grid/node-x35-y5 85T 68T 17T 80% +/dev/grid/node-x35-y6 90T 70T 20T 77% +/dev/grid/node-x35-y7 90T 64T 26T 71% +/dev/grid/node-x35-y8 93T 65T 28T 69% +/dev/grid/node-x35-y9 92T 65T 27T 70% +/dev/grid/node-x35-y10 94T 65T 29T 69% +/dev/grid/node-x35-y11 93T 69T 24T 74% +/dev/grid/node-x35-y12 90T 64T 26T 71% +/dev/grid/node-x35-y13 92T 69T 23T 75% +/dev/grid/node-x35-y14 93T 66T 27T 70% +/dev/grid/node-x35-y15 86T 67T 19T 77% +/dev/grid/node-x35-y16 91T 71T 20T 78% +/dev/grid/node-x35-y17 93T 72T 21T 77% +/dev/grid/node-x35-y18 90T 73T 17T 81% +/dev/grid/node-x35-y19 503T 494T 9T 98% +/dev/grid/node-x35-y20 94T 71T 23T 75% +/dev/grid/node-x35-y21 91T 0T 91T 0% +/dev/grid/node-x35-y22 93T 72T 21T 77% +/dev/grid/node-x35-y23 90T 65T 25T 72% +/dev/grid/node-x36-y0 88T 72T 16T 81% +/dev/grid/node-x36-y1 91T 70T 21T 76% +/dev/grid/node-x36-y2 89T 65T 24T 73% +/dev/grid/node-x36-y3 93T 69T 24T 74% +/dev/grid/node-x36-y4 94T 71T 23T 75% +/dev/grid/node-x36-y5 94T 68T 26T 72% +/dev/grid/node-x36-y6 88T 66T 22T 75% +/dev/grid/node-x36-y7 88T 66T 22T 75% +/dev/grid/node-x36-y8 94T 72T 22T 76% +/dev/grid/node-x36-y9 91T 66T 25T 72% +/dev/grid/node-x36-y10 94T 69T 25T 73% +/dev/grid/node-x36-y11 91T 68T 23T 74% +/dev/grid/node-x36-y12 90T 67T 23T 74% +/dev/grid/node-x36-y13 94T 70T 24T 74% +/dev/grid/node-x36-y14 88T 66T 22T 75% +/dev/grid/node-x36-y15 91T 71T 20T 78% +/dev/grid/node-x36-y16 86T 69T 17T 80% +/dev/grid/node-x36-y17 87T 69T 18T 79% +/dev/grid/node-x36-y18 89T 66T 23T 74% +/dev/grid/node-x36-y19 508T 491T 17T 96% +/dev/grid/node-x36-y20 88T 69T 19T 78% +/dev/grid/node-x36-y21 89T 65T 24T 73% +/dev/grid/node-x36-y22 93T 69T 24T 74% +/dev/grid/node-x36-y23 88T 64T 24T 72% +/dev/grid/node-x37-y0 91T 64T 27T 70% +/dev/grid/node-x37-y1 88T 69T 19T 78% +/dev/grid/node-x37-y2 88T 69T 19T 78% +/dev/grid/node-x37-y3 90T 64T 26T 71% +/dev/grid/node-x37-y4 91T 67T 24T 73% +/dev/grid/node-x37-y5 87T 67T 20T 77% +/dev/grid/node-x37-y6 88T 70T 18T 79% +/dev/grid/node-x37-y7 88T 71T 17T 80% +/dev/grid/node-x37-y8 87T 68T 19T 78% +/dev/grid/node-x37-y9 87T 67T 20T 77% +/dev/grid/node-x37-y10 86T 68T 18T 79% +/dev/grid/node-x37-y11 89T 64T 25T 71% +/dev/grid/node-x37-y12 86T 66T 20T 76% +/dev/grid/node-x37-y13 90T 71T 19T 78% +/dev/grid/node-x37-y14 94T 66T 28T 70% +/dev/grid/node-x37-y15 90T 67T 23T 74% +/dev/grid/node-x37-y16 88T 68T 20T 77% +/dev/grid/node-x37-y17 94T 71T 23T 75% +/dev/grid/node-x37-y18 89T 72T 17T 80% +/dev/grid/node-x37-y19 507T 490T 17T 96% +/dev/grid/node-x37-y20 85T 65T 20T 76% +/dev/grid/node-x37-y21 88T 70T 18T 79% +/dev/grid/node-x37-y22 90T 66T 24T 73% +/dev/grid/node-x37-y23 90T 72T 18T 80% diff --git a/pytudes/data/advent2016/input24.txt b/pytudes/data/advent2016/input24.txt new file mode 100644 index 0000000..b0a58aa --- /dev/null +++ b/pytudes/data/advent2016/input24.txt @@ -0,0 +1,39 @@ +######################################################################################################################################################################################### +#...#...............#.#...#.#.......#.....#.....#.....#...............#.....#.#.....#.....#.......#.........#.#.....#.....#.#.#...#...........#.................#.#...#.....#.....#...#.# +#.###.#.###.###.###.#.###.#.###.#####.###.#.#.#.#.#.#.#.#.###.#.#####.#.#.#.#.#.#.###.###.#.#.#.#.###.###.#.#.#.#.###.###.#.#.#.#.#####.#####.#.#.###########.###.#.#.#.###.#.###.#.#.#.# +#.#...#.....#.....#.#.#...#.#.....#.#.#...#.....#.#.#.....#.............#...#.....#...#.#.........#.#.....#.......#...#.#.#.#.#.........#.....#.#.#...#...#...#...#...#.....#.....#...#.# +#.#.###.#.#.#.#.###.#.#.###.#.#####.#.#.#.#.#####.#.#.#.###.#.#.#.#.###.#.#.###.#.#.#.#.###.###.#.#.###.#.#.#.###.###.#.#.#.#.###########.#.###.#.###.#.#.#.#.#.#.#.#.###.#.#.#.###.#.#.# +#...........#.#.#...#.#.....#.....#...........#...........#.....#.............#.......#.#...............#.....#.......#.....#...............#1....#.......#.#.....#.......#...#.....#...# +#.###.#.#.#.#.#.#.#.#########.#.#.#.#.#.###.#.#.#####.#.#.#.###.#.###.#########.#######.#.#.#.#.#############.#####.#.###.#.#.#.#.#####.#.#######.#####.#.#.#.#.#.#####.#.#.#.#.###.#.### +#...#.....#.....#.#.#.#.................#.#.#...#.......#...#...#.#...........#.#...#.......#.#.#...#...#.......#...#.#.#.#.#.....#.....#.....#.......#...#...#...#.......#...#.....#...# +#.#.#####.#.#####.#.#.#.#.###.###.#.#.###.#.#.#.#.#######.#.#.#.#.###.#.###.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#######.#.#####.#.#.#.#######.#.#.#.#.#.#######.#.###.#.#.#.###.###.#.#.# +#...#.....#.......#.#...#.#...#...........#...#...#.#.....#...#.......#.......#.#.#.#...#.#.....#.#...#...#.....#.........#...#.........#.#.....#.....#...#.#.#...#...#.....#.#3#.#.....# +#.#.###.#.#.###.#######.#.#.#.#.###.###.#####.#.#.#.#.#.#.#.#.#.#####.#.###.###.###.#.#.#.#.#.#.#.###.#.#######.###.#.###.#.#.#.###.#.#.#.#.#.#.#.#.###.###.#.#.###.#.#.###.#.#.#.###.#.# +#.......#.#...#.#.#.....#...#...#0..#.#.....#.#.....#.#.#...#...#.....#.....#.#.....#...#.#...#.#...#.#.#...#...#...#...#.#.#.............#.#...#.......#...#...#...#.#.#.....#...#.#...# +#####.#####.#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.###.#.###.#.#.#.#.#.#.###.###.###.#.#####.#####.#.#.#.#.#.#.#.#.#.#.#.###.#.###.###########.#.#.#########.#.#.#.#.###.#.###.#.###.#.#.#.# +#...#...#.......#.#.#...#.......#...#...#.#...#.#...#.....#.....#.....#.#.#.........#.#.......#...#.#...#.#.........#...#.........#...#...#.#.....#.....#...#.#.......#.#.....#.........# +#.#.###.#.#####.###.###.#.#.###.###.#.###.#.#.#.#.#.#.#####.#.###.#.#.#.###.###.#####.#.#.#.#.#.###.###.#.#########.#.###.#.#.#.#.#.#.#.#.#.#####.###.#.#.#.#.#.#.#.#.#####.#.###.#.###.# +#.....#.#.#...#.#...#.#.....#.#...........#.....#...#.#...#.#.....#.#.#.....#.......#...#.#.#.......#.......#.........#.........#.#.#.#...#...#.#...#...#.......#.....#.....#.......#...# +###.#.#.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.#######.###.#.#####.#####.###.#.#.#.###.#.#.###.#.#.#.#.#####.#.###.#.#.#.#########.#.###.#.#.#.#.#####.###.#.#.#.###.#####.#.#.#.#.#.#.#.#.#.### +#.#...#.#.......#.#.#...#.......#.#.....#.#.........#...#.....#.................#.........#...#...#.#...#.....#...#...#.#...#...#...#.....#...#.......#.......#.....#...#...#...#...#.#.# +#.#.#####.#.#####.###.#.###.#.###.#.#.#.#.#######.#.###.###.#.#.#########.#.###.#########.###.###.#.###.#.#####.#.###.#.#.#.#.#.#.#.#.###.#.#.#.#########.#####.#.#.###.#.#.#.#.#####.#.# +#.............#2#.#.....#.#.#...#...#.#...........#.........#...#.#.......#.#.........#.#.#.....#.#.......#...#.....#...#.#.#.......#...#.#.......#.......#...#.........#...#...#.....#.# +#.#.###.#.#.#.#.#.#.#.###.#.###.#.#####.###.###.#.#.#.#.#.#.#####.#.#.#.#.###.#.#####.#.#.#.#.#####.#.#####.###.###.#.#.#.#.#.#.#.#.#.#.#.#.###.#.###.#####.#######.#.#.#####.###.###.#.# +#...#...#...#...#.#.#.#...#.#.........#.#.#...............#.#...#...#.....#...#.#...#...#...........#.#.....#.....#...#.#.#...#...#.#.....#.....#...........#...#.....#.....#.#6#.....#.# +#####.#.#####.###.#.#.#.#.#.###.###.#.###.#.#########.#.###.#.#.#.###.###.#####.#####.###.###.#.#.#.###.#.#.#.#.###.#.###.#.#.#.#.###.#.#.#.###.#.#.#.#.#.###.#.#####.#.###.#.#.#.###.#.# +#...#...#.....#.....#...#...#...#.....#.....................#...#.....#.........#.....#.#.#...#.#.........#.....................#...#...#.....#...#...#.....#...#...#.....#.#.......#...# +#.###.#.#.#.#.###.#.###.#.#####.#.###.#.#####.#.#######.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#####.###.#####.#######.###.#.#.#######.###.#.###.###.#.#.###.#.#.#.#####.#.#.#######.# +#.#...#.........#...#.....#.......#.....#.#.....#.#...#.#...#.#...#.........#.....#.......#.......#.......#.......#...#...#.......#.....#.#...........#.........#.#.#...#.#.#.....#...#.# +#.#.#.#.#.#.#.#.#.#.#########.#####.#.###.#.#####.#.###.#.#.#.#.#########.#.#.#.#.###.###.#####.###.###.#.#.#.#####.#.#.#########.###.#.###.###.###.#.#######.#.###.###.#.###.###.#.###.# +#.....#.....#...#.#.........#...#.....#...#.............#.....#.#.........#...#.......#.................#...#.........#...#...........#.........#.....#.......#.....#.....#.#.#.#...#.#.# +#.###.#.###.#.#.#.#.#.#.#.###.###.#.#######.#.###.#####.#.###.#.#.#.#.#.#.#.#.#######.###.###.#######.#.###.###.#####.#.#.#.#.#.#.#.###.#.###.###.###.#.###.#.###.###.#####.#.#.###.#.### +#.....#...#.#.....#.#...#.....#.....#.#...#...#...........#.#.#...........#.#.#.....#.....#...#...#...#...#.....#.......#.......#.#.........#.....#.....#.#...#.......#.........#.......# +#.#.#.###.#.#.#.###.###.#.###.#####.#.#.#.#.#.#######.###.#.#.#.#####.###.#.#.###.###.#.#.#.#.#.###.#####.###.###.#######.###.#.#.#.#.#.#.#####.#########.#.#.#.#.#.###.#######.###.#.#.# +#.......#.#.#.....#.....#.#...#.....#...#.#.....#...#.#...#.....#.......#...#.#.#...#.....#.......#.......#...#.#.......#...#...#.#.#...#.......#.....#.#...#.#.#...#...#.......#.......# +#.###.###.#.#.###.#.#.#.#.#.#.#.#.#.###.###.#.#.###.#.###.###.#.#.#.#.#.#####.#.#.#.#.#.#########.#.###.#.#.#.#.#.#.#.#.#.#####.###.###.#.#.#.#.#.#.#.#.#.#.###.#.###.#.#####.#######.#.# +#.....#.#5......#.......#...#.#.#...#.#.#.#.....#.....#.#.....#.......#.#...#...#.....#.....#...........#...#.......#.#...#.........#.........#.........#...........#.#.#.....#7....#.#.# +#.#.#.#.###.#####.#####.#.###.#.#.#.#.###.#.#.#.#####.#.#.#.#.#.###.#.###.###.###.#.#.###.#.#.#.#.#######.#.#.#####.#.#.###.#.#####.#.#.#.#.#.#.#.#####.#.#.#.#.#####.#.#.#.#.#####.#.#.# +#...........#.#...#.........#...#.#.#.#.......#.#.....#...#...#.#.....#...#...#.......#.................................#...#...#.#.....#.....#...#...#.#...#...#.#.......#.........#.#.# +###.###.#.###.#.###.#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.###.###.###.###.#.###.#.###.#####.#.#.###.###.#.#####.#.#.#.#####.#.###.#.#.#.#.###.#.###.###.#.#######.#.#.#.#.###.###.#.#.#.#.# +#.......#.#.........#...#.#.#.................#.......#...#.....#...............#...#.#...#...#.......#.#.#.......#.......#...............#4#.......#.....#...#...#.#...#.......#.....#.# +######################################################################################################################################################################################### diff --git a/pytudes/data/advent2016/input3.txt b/pytudes/data/advent2016/input3.txt new file mode 100644 index 0000000..50d7e86 --- /dev/null +++ b/pytudes/data/advent2016/input3.txt @@ -0,0 +1,1908 @@ + 4 21 894 + 419 794 987 + 424 797 125 + 651 305 558 + 655 631 963 + 2 628 436 + 736 50 363 + 657 707 408 + 252 705 98 + 532 173 878 + 574 792 854 + 157 737 303 + 468 76 580 + 502 503 434 + 467 567 310 + 911 911 391 + 791 913 925 + 174 49 532 + 796 803 426 + 800 132 710 + 273 722 711 + 388 576 551 + 17 936 676 + 371 712 141 + 692 738 913 + 745 805 975 + 381 140 680 + 859 344 336 + 109 148 877 + 835 441 716 + 355 288 669 + 968 259 517 + 979 350 773 + 134 222 347 + 614 279 628 + 510 140 590 + 901 581 707 + 958 933 680 + 95 558 766 + 676 739 739 + 890 40 825 + 280 735 297 + 593 354 701 + 555 756 730 + 39 656 853 + 399 660 14 + 293 685 48 + 109 374 42 + 260 608 680 + 306 885 603 + 49 683 810 + 125 513 512 + 706 600 143 + 728 138 658 + 410 673 27 + 617 872 89 + 923 733 103 + 462 674 95 + 352 718 191 + 129 351 173 + 648 839 828 + 332 829 789 + 947 44 214 + 768 576 184 + 672 900 601 + 98 672 738 + 368 926 539 + 271 300 372 + 141 844 261 + 731 426 205 + 734 979 792 + 16 703 888 + 133 682 323 + 428 784 182 + 398 171 394 + 154 845 425 + 643 14 775 + 695 849 432 + 22 227 464 + 490 544 485 + 474 701 910 + 902 629 10 + 996 680 67 + 91 908 75 + 653 600 845 + 439 53 117 + 480 552 860 + 156 144 46 + 492 359 597 + 408 473 614 + 469 343 737 + 777 438 149 + 803 114 676 + 78 835 753 + 567 230 707 + 542 738 49 + 286 542 939 + 75 985 179 + 293 914 854 + 234 609 877 + 237 167 880 + 151 722 925 + 793 515 278 + 350 432 777 + 883 402 581 + 621 501 702 + 494 265 665 + 167 668 345 + 853 911 629 + 747 428 576 + 703 979 73 + 938 798 401 + 851 743 542 + 281 216 483 + 772 573 404 + 598 547 606 + 275 107 823 + 92 94 864 + 416 201 759 + 331 146 446 + 200 375 70 + 459 349 928 + 615 77 999 + 748 380 628 + 624 244 759 + 934 512 163 + 964 117 75 + 515 146 209 + 917 31 218 + 694 640 116 + 758 53 375 + 250 655 353 + 153 200 189 + 259 752 85 + 313 637 129 + 361 632 973 + 896 61 934 + 581 611 483 + 620 788 889 + 959 273 754 + 677 997 322 + 43 201 714 + 181 956 734 + 147 878 850 + 139 802 938 + 542 729 26 + 531 201 915 + 412 917 301 + 845 44 811 + 489 897 626 + 378 384 781 + 429 130 313 + 583 400 515 + 811 937 949 + 584 812 909 + 738 143 205 + 79 813 801 + 599 872 539 + 650 177 384 + 299 267 539 + 506 358 516 + 425 520 185 + 901 854 622 + 84 371 21 + 931 797 642 + 274 155 432 + 366 935 635 + 331 810 836 + 56 725 67 + 9 756 985 + 58 38 946 + 385 807 899 + 336 998 3 + 243 539 893 + 792 117 272 + 345 995 452 + 717 892 262 + 311 694 23 + 737 169 392 + 875 741 379 + 609 422 100 + 644 442 916 + 832 51 967 + 230 962 82 + 380 202 931 + 308 786 903 + 556 668 121 + 194 650 263 + 732 20 346 + 528 445 589 + 341 142 684 + 281 302 550 + 408 511 219 + 683 938 617 + 679 705 763 + 812 847 313 + 557 838 308 + 888 23 145 + 120 20 129 + 450 643 245 + 329 658 282 + 30 878 700 + 698 799 335 + 698 320 595 + 875 959 595 + 50 715 454 + 856 686 269 + 986 38 589 + 834 925 69 + 263 928 654 + 430 175 586 + 99 712 642 + 439 679 132 + 639 714 644 + 563 940 62 + 228 385 666 + 758 757 949 + 137 174 104 + 859 746 939 + 675 140 592 + 324 446 357 + 471 486 455 + 450 429 980 + 955 388 599 + 914 222 512 + 981 673 871 + 941 716 744 + 55 192 173 + 98 48 411 + 774 686 343 + 689 671 412 + 666 613 686 + 420 595 550 + 891 148 204 + 150 678 978 + 420 684 49 + 503 879 985 + 95 508 231 + 90 393 777 + 17 464 813 + 372 120 26 + 513 10 445 + 258 133 460 + 392 29 355 + 116 874 635 + 326 889 493 + 883 599 250 + 913 388 798 + 85 366 782 + 422 416 204 + 533 174 93 + 168 413 270 + 617 996 461 + 8 386 1 + 613 928 464 + 455 545 619 + 424 631 488 + 142 612 146 + 921 374 324 + 744 791 395 + 923 797 445 + 876 447 602 + 851 62 493 + 23 397 993 + 232 602 90 + 790 604 698 + 855 7 654 + 350 105 561 + 550 198 327 + 670 130 340 + 904 943 765 + 23 467 804 + 906 726 948 + 337 90 774 + 438 546 667 + 134 625 247 + 334 282 729 + 619 275 412 + 377 5 763 + 250 722 852 + 754 365 401 + 558 393 615 + 974 673 39 + 922 610 899 + 99 969 868 + 89 616 911 + 235 326 371 + 252 605 907 + 429 387 678 + 564 34 565 + 436 359 584 + 125 780 474 + 842 372 184 + 785 507 489 + 849 418 633 + 962 191 582 + 728 453 669 + 91 970 639 + 48 222 639 + 41 865 103 + 395 765 945 + 551 103 9 + 313 687 956 + 952 109 894 + 612 79 518 + 392 119 506 + 106 739 427 + 941 688 483 + 917 103 114 + 326 466 604 + 393 641 488 + 128 920 135 + 609 742 725 + 101 596 371 + 631 325 416 + 318 939 170 + 166 540 821 + 460 654 843 + 672 942 330 + 620 673 352 + 288 731 20 + 263 277 387 + 259 49 434 + 73 262 278 + 525 775 36 + 867 735 125 + 437 415 141 + 567 537 640 + 99 581 584 + 468 108 84 + 608 997 893 + 573 722 971 + 497 953 399 + 201 184 372 + 203 323 386 + 2 331 72 + 375 687 307 + 484 57 322 + 311 704 416 + 720 961 571 + 444 211 926 + 668 771 666 + 742 688 146 + 447 435 143 + 394 444 1 + 450 39 373 + 150 634 442 + 422 645 546 + 132 562 281 + 795 365 455 + 921 389 255 + 17 153 85 + 795 593 367 + 788 637 447 + 292 297 703 + 190 938 871 + 166 821 386 + 437 636 385 + 160 288 604 + 334 584 837 + 701 207 665 + 470 84 204 + 599 268 739 + 634 92 148 + 507 620 198 + 193 677 94 + 301 990 536 + 874 493 783 + 932 550 497 + 81 166 546 + 633 538 476 + 553 411 790 + 593 159 316 + 47 729 226 + 619 708 409 + 38 535 763 + 421 830 550 + 400 537 641 + 275 531 166 + 247 564 495 + 177 791 655 + 959 363 548 + 232 105 594 + 919 272 912 + 258 467 505 + 882 783 365 + 916 331 441 + 70 815 204 + 66 304 470 + 2 810 372 + 734 276 875 + 771 295 72 + 455 191 892 + 765 384 195 + 758 418 844 + 38 121 980 + 302 379 606 + 116 384 199 + 353 13 607 + 712 805 790 + 589 701 694 + 540 776 276 + 985 814 61 + 996 10 709 + 450 821 652 + 715 26 899 + 628 656 679 + 322 669 279 + 144 649 518 + 962 175 363 + 839 627 292 + 931 934 378 + 588 382 122 + 410 923 263 + 652 680 654 + 25 878 835 + 640 399 396 + 492 202 511 + 510 225 521 + 15 413 233 + 493 551 122 + 683 222 569 + 248 457 641 + 100 936 315 + 902 998 870 + 975 98 680 + 998 309 653 + 605 944 532 + 530 887 400 + 572 879 925 + 311 147 692 + 425 924 848 + 453 945 934 + 492 918 22 + 434 338 933 + 288 297 665 + 274 712 185 + 99 503 741 + 868 523 263 + 828 218 121 + 53 565 236 + 15 409 778 + 367 293 444 + 352 610 413 + 892 970 706 + 954 767 321 + 75 656 414 + 823 781 57 + 423 673 349 + 817 405 324 + 768 19 345 + 302 949 529 + 654 944 794 + 262 766 959 + 783 92 866 + 772 718 772 + 629 154 669 + 723 349 109 + 914 352 599 + 559 746 346 + 492 781 860 + 103 52 624 + 655 397 857 + 680 242 417 + 183 203 846 + 714 519 457 + 849 292 946 + 605 566 646 + 793 653 156 + 111 135 44 + 882 531 191 + 920 773 378 + 911 340 546 + 23 655 382 + 656 708 587 + 43 792 708 + 673 734 605 + 506 725 943 + 421 762 553 + 471 214 572 + 195 575 438 + 114 546 687 + 121 47 894 + 744 221 820 + 58 273 982 + 759 58 233 + 770 824 785 + 857 441 480 + 87 387 477 + 838 633 28 + 635 547 49 + 329 404 47 + 534 955 933 + 661 985 662 + 199 144 713 + 228 996 622 + 197 523 858 + 64 486 552 + 859 968 422 + 847 31 648 + 41 944 812 + 625 953 830 + 987 734 37 + 529 512 825 + 104 690 688 + 602 224 973 + 592 888 409 + 241 247 639 + 290 80 570 + 483 284 97 + 322 223 57 + 91 204 503 + 257 18 464 + 904 480 177 + 945 364 137 + 199 240 234 + 231 177 23 + 537 147 464 + 683 71 468 + 448 55 544 + 264 143 640 + 307 125 706 + 674 384 373 + 469 903 656 + 538 695 361 + 461 942 728 + 430 911 347 + 85 70 789 + 422 525 65 + 466 322 776 + 49 620 765 + 832 530 9 + 215 92 417 + 965 511 415 + 865 888 289 + 993 74 332 + 685 830 52 + 11 334 151 + 98 36 192 + 93 307 89 + 38 483 498 + 674 317 910 + 697 302 486 + 267 29 508 + 816 924 165 + 895 954 671 + 629 75 634 + 591 301 149 + 368 346 735 + 916 606 382 + 63 786 124 + 916 180 475 + 466 656 218 + 128 35 326 + 570 665 164 + 181 382 773 + 256 122 266 + 130 288 905 + 288 524 40 + 278 526 471 + 39 243 476 + 951 16 522 + 662 93 522 + 378 107 7 + 218 520 10 + 654 399 343 + 674 158 351 + 854 320 834 + 722 358 818 + 231 178 671 + 862 892 764 + 109 461 982 + 943 655 412 + 745 541 255 + 868 541 297 + 472 20 224 + 163 991 647 + 249 883 588 + 232 486 162 + 236 281 784 + 416 261 65 + 377 34 790 + 357 121 610 + 542 439 866 + 860 324 598 + 865 337 712 + 368 421 977 + 839 280 457 + 140 655 416 + 962 381 331 + 901 685 732 + 818 483 831 + 13 724 791 + 818 694 222 + 746 822 841 + 829 418 836 + 335 565 408 + 516 447 281 + 584 204 166 + 480 508 119 + 713 787 704 + 626 941 739 + 206 418 284 + 989 326 701 + 636 396 195 + 397 393 655 + 240 696 896 + 166 117 974 + 72 733 210 + 797 533 566 + 729 728 481 + 663 212 86 + 298 475 563 + 590 533 517 + 618 314 133 + 422 195 38 + 195 415 288 + 540 303 253 + 446 553 859 + 568 891 223 + 432 617 981 + 519 214 775 + 529 721 844 + 786 898 692 + 440 401 201 + 345 353 846 + 296 566 906 + 638 422 370 + 15 577 469 + 624 192 134 + 136 554 755 + 182 690 940 + 77 366 923 + 284 979 275 + 157 582 373 + 433 547 343 + 767 786 527 + 983 877 385 + 581 612 158 + 365 520 673 + 436 227 897 + 458 421 913 + 579 492 760 + 818 493 507 + 316 22 867 + 114 421 939 + 372 281 912 + 415 608 633 + 938 676 927 + 965 591 931 + 335 789 34 + 865 820 346 + 406 798 304 + 893 441 267 + 166 126 835 + 764 859 839 + 629 918 194 + 557 297 552 + 954 79 478 + 801 224 670 + 640 493 262 + 750 478 681 + 534 867 654 + 980 586 142 + 882 597 156 + 277 186 48 + 448 541 23 + 457 702 496 + 11 936 491 + 689 668 457 + 368 941 288 + 914 311 464 + 893 843 828 + 800 933 797 + 951 427 657 + 754 215 476 + 148 260 508 + 735 130 193 + 390 631 761 + 288 203 777 + 273 443 23 + 189 20 355 + 240 344 560 + 157 360 674 + 921 774 803 + 473 943 937 + 600 920 393 + 611 579 530 + 632 577 59 + 24 5 495 + 701 358 722 + 703 284 820 + 625 625 844 + 649 253 531 + 447 309 534 + 662 218 419 + 762 347 627 + 947 344 133 + 581 36 652 + 222 747 122 + 238 761 162 + 72 82 231 + 717 296 966 + 563 516 774 + 273 451 819 + 956 175 651 + 33 770 754 + 956 650 369 + 146 838 148 + 588 713 547 + 453 457 541 + 979 92 401 + 967 162 417 + 144 155 672 + 725 737 962 + 779 701 886 + 64 203 120 + 433 284 482 + 911 538 512 + 613 713 77 + 268 636 685 + 445 955 193 + 458 677 653 + 91 450 356 + 747 11 360 + 728 448 147 + 37 494 679 + 780 582 256 + 756 212 810 + 556 434 265 + 280 472 983 + 547 93 857 + 922 225 378 + 754 138 346 + 236 235 349 + 718 421 501 + 80 880 464 + 753 490 286 + 616 332 218 + 338 391 547 + 490 599 370 + 35 559 686 + 67 290 565 + 30 597 153 + 59 763 701 + 268 439 123 + 237 940 669 + 451 205 145 + 302 284 961 + 365 443 828 + 225 598 65 + 437 561 73 + 248 219 7 + 72 29 274 + 577 35 654 + 537 41 857 + 956 966 739 + 545 747 373 + 479 463 705 + 112 79 161 + 280 885 672 + 322 829 596 + 422 279 697 + 804 997 963 + 907 852 494 + 321 245 492 + 298 698 419 + 49 454 185 + 169 214 25 + 880 324 414 + 816 163 425 + 366 370 167 + 729 49 684 + 460 337 792 + 719 908 817 + 825 310 303 + 245 814 724 + 877 713 128 + 488 241 839 + 499 820 884 + 918 356 273 + 69 228 442 + 877 523 698 + 780 391 627 + 838 539 547 + 512 867 786 + 491 298 421 + 402 153 940 + 602 220 539 + 638 167 534 + 626 204 122 + 77 170 569 + 342 364 529 + 74 523 842 + 416 675 415 + 292 900 918 + 335 565 795 + 145 396 558 + 320 421 585 + 315 495 106 + 618 492 494 + 985 684 702 + 261 35 699 + 890 678 100 + 797 972 693 + 782 12 675 + 991 963 24 + 774 465 254 + 409 446 291 + 920 178 430 + 558 186 476 + 668 502 39 + 897 497 471 + 927 534 95 + 465 621 535 + 971 718 597 + 440 803 941 + 859 104 59 + 891 712 889 + 7 465 712 + 928 323 951 + 938 251 464 + 939 541 491 + 376 430 543 + 605 181 684 + 849 578 57 + 635 433 572 + 958 171 565 + 525 870 63 + 198 864 591 + 466 125 610 + 442 604 512 + 444 666 55 + 129 374 546 + 893 328 978 + 78 279 999 + 852 302 465 + 378 619 123 + 97 246 185 + 374 775 308 + 579 48 388 + 497 730 745 + 142 703 596 + 387 31 973 + 861 944 602 + 894 919 522 + 755 689 409 + 592 310 115 + 326 708 398 + 53 87 866 + 966 266 370 + 925 281 815 + 864 315 882 + 699 352 849 + 526 185 948 + 58 454 681 + 496 917 237 + 556 907 558 + 815 422 705 + 232 423 194 + 941 811 583 + 686 207 335 + 637 693 440 + 574 795 385 + 531 936 899 + 721 950 37 + 317 786 906 + 830 719 101 + 360 615 650 + 689 218 676 + 790 208 197 + 621 7 791 + 868 203 866 + 16 491 53 + 952 268 717 + 956 736 773 + 793 386 760 + 750 624 957 + 184 964 443 + 454 684 835 + 439 931 60 + 293 434 866 + 990 467 282 + 664 423 302 + 523 485 116 + 127 469 710 + 625 758 497 + 514 544 998 + 571 281 413 + 458 70 645 + 526 283 884 + 77 738 725 + 802 278 508 + 782 597 976 + 385 358 919 + 710 492 994 + 750 517 79 + 964 231 679 + 370 34 845 + 951 245 299 + 83 431 846 + 384 989 609 + 447 761 747 + 647 898 371 + 95 794 298 + 644 157 625 + 663 107 507 + 572 927 578 + 165 926 94 + 455 530 905 + 397 412 598 + 616 239 788 + 228 556 609 + 26 540 184 + 208 745 687 + 877 36 977 + 64 29 195 + 936 56 807 + 952 253 397 + 62 246 95 + 923 102 491 + 576 116 739 + 919 559 820 + 882 534 865 + 490 650 961 + 441 741 975 + 59 922 597 + 76 209 337 + 293 785 447 + 338 971 276 + 117 581 939 + 210 266 701 + 108 448 378 + 253 556 164 + 998 200 168 + 969 358 13 + 606 206 458 + 752 400 571 + 796 521 911 + 934 50 150 + 96 205 764 + 844 216 657 + 669 434 222 + 242 301 66 + 471 277 227 + 732 681 20 + 67 991 597 + 784 793 613 + 198 841 555 + 109 429 396 + 219 461 729 + 128 255 888 + 850 154 754 + 809 226 387 + 719 468 706 + 289 436 26 + 441 280 688 + 510 57 451 + 417 255 277 + 670 198 625 + 791 681 20 + 803 998 294 + 332 323 282 + 905 213 739 + 115 267 394 + 965 213 788 + 125 829 635 + 90 281 640 + 103 584 81 + 407 771 19 + 205 213 708 + 380 814 704 + 778 462 872 + 799 553 758 + 402 193 269 + 403 947 198 + 814 22 499 + 532 948 570 + 159 951 932 + 505 616 592 + 507 657 785 + 811 860 675 + 831 140 99 + 450 966 627 + 939 358 947 + 182 201 1 + 951 487 951 + 367 376 539 + 972 491 495 + 758 761 80 + 122 872 278 + 933 927 926 + 835 300 759 + 733 195 418 + 347 73 485 + 783 138 660 + 186 586 422 + 464 301 410 + 479 552 175 + 532 634 83 + 383 285 44 + 436 431 58 + 535 170 985 + 632 274 488 + 338 130 571 + 176 582 380 + 669 613 396 + 705 169 719 + 856 993 121 + 133 966 370 + 914 196 281 + 798 669 132 + 890 418 374 + 955 705 442 + 159 406 397 + 404 59 893 + 526 377 933 + 248 442 442 + 471 116 739 + 292 552 575 + 676 666 574 + 511 172 422 + 796 592 548 + 697 197 477 + 661 900 981 + 526 779 684 + 989 910 867 + 482 449 661 + 891 955 235 + 826 260 714 + 652 178 978 + 234 346 905 + 935 213 526 + 329 593 819 + 651 773 628 + 879 926 371 + 868 42 701 + 13 891 485 + 130 730 141 + 454 725 922 + 586 445 826 + 274 99 77 + 282 84 102 + 318 19 73 + 467 956 769 + 90 409 641 + 417 660 846 + 417 577 381 + 463 863 570 + 46 323 473 + 261 448 309 + 499 63 834 + 334 421 710 + 392 296 356 + 432 152 633 + 48 257 572 + 130 797 559 + 304 136 450 + 285 807 671 + 715 135 563 + 504 218 531 + 838 139 745 + 938 200 245 + 866 797 168 + 656 709 308 + 213 654 329 + 550 138 928 + 454 702 780 + 881 227 940 + 83 894 989 + 903 836 207 + 134 762 835 + 592 857 242 + 724 922 700 + 612 291 718 + 874 856 943 + 413 854 568 + 843 169 497 + 815 927 781 + 236 776 958 + 990 235 853 + 537 229 396 + 706 195 709 + 13 38 102 + 665 705 455 + 655 735 525 + 490 30 684 + 291 219 12 + 657 236 687 + 814 779 613 + 957 976 589 + 705 994 456 + 276 389 477 + 968 752 553 + 708 859 947 + 267 922 639 + 34 724 754 + 253 262 358 + 693 662 387 + 386 326 592 + 432 547 227 + 295 465 360 + 604 434 858 + 627 759 610 + 676 557 182 + 231 538 98 + 817 595 122 + 153 686 713 + 71 491 59 + 197 631 744 + 202 441 943 + 509 420 915 + 572 160 162 + 836 976 237 + 235 26 160 + 729 984 367 + 385 758 902 + 190 475 560 + 432 289 613 + 435 200 247 + 366 614 260 + 708 445 16 + 367 330 743 + 397 750 311 + 35 581 700 + 574 182 762 + 930 258 952 + 739 297 845 + 291 229 421 + 986 463 383 + 875 605 217 + 215 993 9 + 762 768 136 + 960 561 130 + 809 868 81 + 843 592 612 + 159 449 610 + 148 831 220 + 42 173 589 + 152 872 608 + 895 190 707 + 675 245 822 + 671 246 352 + 401 246 973 + 124 390 123 + 461 579 871 + 874 975 766 + 472 257 751 + 421 887 254 + 429 259 207 + 472 362 673 + 392 598 763 + 459 736 45 + 771 314 779 + 734 589 747 + 206 592 287 + 984 629 554 + 801 590 601 + 517 61 527 + 389 133 105 + 862 114 607 + 238 748 757 + 915 890 653 + 984 939 697 + 532 53 229 + 822 196 730 + 621 248 666 + 901 819 307 + 809 540 510 + 113 719 233 + 348 69 692 + 842 890 213 + 821 951 579 + 529 323 306 + 89 323 543 + 440 26 722 + 802 522 426 + 756 657 960 + 93 596 816 + 866 442 378 + 828 556 364 + 96 121 12 + 317 648 577 + 253 53 633 + 544 688 931 + 424 790 344 + 458 865 145 + 562 831 363 + 893 221 919 + 840 92 529 + 169 297 774 + 838 306 682 + 441 121 570 + 428 389 811 + 344 727 239 + 196 44 826 + 229 728 950 + 357 615 210 + 859 776 89 + 935 539 212 + 884 487 844 + 31 508 774 + 851 25 109 + 436 477 675 + 584 995 828 + 573 794 507 + 599 655 909 + 303 126 412 + 752 568 805 + 987 391 459 + 680 853 647 + 778 468 531 + 415 606 323 + 490 746 519 + 373 674 320 + 200 95 319 + 251 186 808 + 49 280 952 + 173 406 142 + 421 808 498 + 550 953 635 + 314 384 519 + 383 663 385 + 116 706 387 + 376 445 205 + 430 181 173 + 248 525 43 + 274 444 534 + 582 464 599 + 858 68 229 + 353 821 235 + 564 259 256 + 510 953 54 + 713 337 323 + 4 96 282 + 711 402 41 + 337 629 820 + 185 206 180 + 385 472 645 + 455 600 405 + 743 974 79 + 591 819 423 + 741 14 207 + 290 698 121 + 851 693 145 + 739 993 803 + 740 484 702 + 304 582 551 + 132 253 734 + 770 178 853 + 835 268 809 + 759 934 619 + 984 542 238 + 835 741 413 + 606 159 861 + 699 163 862 + 96 50 31 + 814 712 650 + 818 212 404 + 32 784 659 + 111 465 941 + 895 376 756 + 924 574 646 + 341 753 965 + 400 394 948 + 379 471 35 + 171 467 199 + 528 16 634 + 360 453 592 + 820 44 316 + 591 841 550 + 724 825 255 + 356 648 85 + 338 530 337 + 637 151 291 + 811 629 578 + 709 389 77 + 208 856 654 + 781 611 560 + 165 676 590 + 657 192 67 + 737 322 236 + 946 299 235 + 410 438 205 + 789 274 389 + 834 318 884 + 107 335 552 + 283 336 8 + 755 310 431 + 920 497 430 + 576 751 597 + 9 893 607 + 570 151 70 + 514 330 198 + 481 726 103 + 324 929 124 + 594 180 866 + 901 125 69 + 528 60 899 + 705 772 441 + 156 93 469 + 701 849 58 + 66 437 140 + 424 499 152 + 380 921 55 + 825 124 860 + 424 246 851 + 832 211 94 + 419 701 417 + 296 310 689 + 127 647 813 + 881 699 761 + 815 948 199 + 176 386 713 + 371 373 510 + 356 995 411 + 97 864 476 + 267 888 213 + 656 368 996 + 921 760 863 + 208 243 271 + 241 16 796 + 168 256 928 + 213 677 471 + 829 27 169 + 747 648 351 + 339 681 214 + 398 512 176 + 251 212 367 + 313 846 267 + 255 735 547 + 271 212 356 + 146 401 656 + 245 891 351 + 334 623 729 + 498 864 547 + 857 596 730 + 482 834 899 + 400 836 434 + 78 390 440 + 398 688 167 + 63 564 884 + 587 891 982 + 594 431 168 + 439 990 512 + 219 905 258 + 550 82 523 + 631 402 199 + 148 517 112 + 743 670 185 + 605 731 534 + 651 124 537 + 81 710 220 + 520 635 499 + 761 929 500 + 741 403 917 + 68 710 230 + 278 538 203 + 235 229 295 + 470 244 126 + 448 350 96 + 56 247 75 + 861 763 85 + 571 855 522 + 410 96 437 + 196 552 400 + 651 453 974 + 458 674 706 + 211 593 139 + 388 134 179 + 407 608 180 + 640 454 445 + 213 176 407 + 616 447 712 + 252 103 866 + 242 27 981 + 147 85 675 + 314 370 693 + 256 490 434 + 296 206 544 + 531 137 677 + 577 524 896 + 61 486 293 + 677 425 436 + 605 304 630 + 654 542 339 + 863 592 22 + 914 224 711 + 234 649 727 + 873 159 424 + 826 639 696 + 136 653 407 + 436 767 449 + 678 875 610 + 271 785 460 + 569 592 969 + 729 582 988 + 326 139 391 + 841 847 925 + 425 991 861 + 642 949 501 + 895 661 827 + 979 685 941 + 724 208 801 + 439 724 125 + 527 998 303 + 150 327 217 + 7 188 418 + 52 110 291 + 59 211 162 + 989 311 166 + 377 12 561 + 650 303 503 + 427 496 663 + 419 913 81 + 364 531 661 + 991 37 692 + 773 394 245 + 459 357 617 + 949 190 23 + 544 154 313 + 629 156 298 + 338 753 854 + 282 744 855 + 273 23 3 + 908 784 528 + 889 764 520 + 65 327 55 + 118 826 479 + 285 34 48 + 320 820 441 + 652 154 358 + 373 876 806 + 543 778 916 + 261 387 788 + 695 408 734 + 956 128 961 + 750 302 195 + 669 163 641 + 197 291 528 + 406 959 749 + 835 747 135 + 474 931 721 + 374 616 113 + 385 279 59 + 85 772 123 + 767 955 243 + 782 383 174 + 253 918 312 + 941 99 123 + 234 689 235 + 950 737 269 + 145 535 192 + 13 352 267 + 134 621 325 + 897 529 864 + 373 646 618 + 597 968 619 + 876 655 663 + 83 735 132 + 866 556 738 + 580 162 735 + 437 822 458 + 482 811 492 + 401 656 753 + 615 435 892 + 493 771 395 + 721 994 734 + 243 133 298 + 526 873 809 + 564 836 232 + 768 309 254 + 366 958 72 + 568 606 339 + 775 134 538 + 255 575 619 + 997 278 669 + 957 88 623 + 720 342 370 + 213 811 197 + 931 690 50 + 838 814 200 + 776 480 744 + 638 396 519 + 356 511 309 + 912 125 65 + 939 277 931 + 305 350 864 + 20 981 501 + 78 931 296 + 66 194 781 + 572 395 560 + 453 92 447 + 919 312 747 + 824 44 469 + 367 312 862 + 709 357 563 + 637 984 458 + 549 698 470 + 248 861 48 + 603 264 145 + 379 795 37 + 607 646 180 + 826 195 197 + 562 207 255 + 426 29 108 + 945 796 577 + 292 521 686 + 674 293 324 + 739 14 179 + 544 385 839 + 236 373 943 + 126 522 467 + 17 521 11 + 111 12 470 + 232 480 781 + 393 938 941 + 541 520 836 + 705 990 34 + 800 961 999 + 532 825 963 + 783 931 544 + 327 483 595 + 578 905 886 + 734 718 476 + 744 158 824 + 80 643 837 + 118 615 866 + 59 51 845 + 56 598 106 + 676 553 786 + 660 815 795 + 202 324 8 + 349 876 702 + 421 439 420 + 717 937 924 + 223 875 728 + 236 895 561 + 302 114 176 + 314 163 38 + 349 581 456 + 124 526 474 + 537 74 902 + 618 216 612 + 183 160 937 + 945 731 219 + 108 30 508 + 935 728 300 + 854 527 753 + 87 473 250 + 918 208 524 + 554 611 73 + 545 728 620 + 77 596 588 + 751 552 839 + 615 178 163 + 993 541 716 + 581 615 625 + 788 406 731 + 655 937 322 + 223 203 650 + 267 376 258 + 321 428 886 + 379 751 439 + 865 701 554 + 758 180 165 + 880 855 658 + 53 414 748 + 852 963 754 + 324 813 28 + 535 817 588 + 364 44 581 + 211 198 458 + 193 192 695 + 61 92 991 + 205 599 445 + 920 416 284 + 965 956 500 + 835 324 654 + 627 371 100 + 897 92 624 + 47 382 646 + 800 43 758 + 804 349 363 + 766 209 373 + 299 499 662 + 685 349 311 + 23 870 624 + 202 811 638 + 189 231 50 + 813 226 556 + 546 499 403 + 476 654 206 + 781 604 423 + 805 673 459 + 26 452 406 + 278 721 185 + 364 442 550 + 169 576 423 + 808 518 616 + 841 739 727 + 380 504 391 + 191 81 239 + 895 35 203 + 940 65 86 + 311 717 120 + 77 422 22 + 318 531 139 + 613 513 219 + 650 825 630 + 45 488 702 + 470 339 498 + 849 231 382 + 623 154 426 + 23 433 332 + 810 273 385 + 835 251 140 + 83 577 853 + 125 526 609 + 174 415 846 + 698 974 257 + 280 869 9 + 436 151 254 + 603 73 174 + 782 392 58 + 626 457 140 + 629 410 748 + 40 30 560 + 601 427 364 + 532 766 900 + 969 786 66 + 558 31 848 + 8 834 70 + 915 887 103 + 909 468 53 + 738 758 163 + 805 631 345 + 188 364 354 + 116 605 773 + 366 606 20 + 346 85 757 + 447 812 952 + 51 696 925 + 425 428 977 + 817 409 802 + 911 218 886 + 335 240 294 + 17 100 608 + 2 77 754 + 20 100 721 + 984 724 971 + 446 970 606 + 948 270 957 + 765 492 236 + 527 552 37 + 365 301 253 + 434 418 690 + 501 250 117 + 416 292 808 + 180 696 352 + 657 477 190 + 568 244 418 + 716 395 525 + 725 691 472 + 611 625 489 + 584 930 500 + 600 702 701 + 202 762 713 + 354 361 19 + 579 524 355 + 711 499 338 + 430 427 492 + 680 504 673 + 284 396 779 + 544 250 813 + 247 47 933 + 372 205 679 + 458 583 566 + 161 787 651 + 438 308 536 + 138 281 797 + 452 223 221 + 460 496 911 + 401 351 611 + 191 218 755 + 475 452 497 + 72 219 536 + 906 220 214 + 959 62 418 + 225 697 628 + 195 838 657 + 411 854 328 + 993 733 236 + 846 838 306 + 263 112 119 + 158 9 149 + 144 87 732 + 87 82 674 + 283 33 61 + 888 734 364 + 718 750 344 + 2 485 454 + 337 451 728 + 341 170 577 + 651 272 820 + 225 562 481 + 472 759 609 + 63 402 607 + 731 394 506 + 744 680 331 + 697 381 236 + 336 396 451 + 360 20 281 + 710 608 343 + 624 567 415 + 778 800 390 + 422 831 213 + 453 294 120 + 28 635 287 + 788 367 373 + 213 739 579 + 622 560 219 + 296 890 516 + 733 808 384 + 481 245 585 + 58 647 842 + 60 652 705 + 2 100 202 + 36 696 415 + 151 786 712 + 174 410 804 + 867 904 58 + 885 869 868 + 99 679 864 + 396 301 272 + 744 849 192 + 425 621 289 + 805 71 892 + 92 422 424 + 873 363 573 + 480 977 298 + 263 514 173 + 456 963 265 + 636 637 203 + 902 573 219 + 414 405 90 + 314 842 900 + 251 946 787 + 562 519 831 + 865 20 512 + 560 190 301 + 915 183 779 + 372 559 104 + 15 434 105 + 377 134 11 + 178 479 303 + 503 396 290 + 427 522 349 + 567 694 454 + 630 919 58 + 353 305 511 + 704 867 137 + 713 974 740 + 911 756 703 + 655 148 739 + 519 212 406 + 677 289 620 + 983 84 724 + 142 389 335 + 841 384 662 + 807 587 868 + 888 560 138 + 84 24 812 + 432 278 122 + 656 178 215 + 234 100 209 + 239 186 768 + 101 342 212 + 264 265 666 + 575 971 78 + 655 70 294 + 616 902 307 + 888 637 155 + 929 282 916 + 639 730 964 + 438 345 192 + 468 610 206 + 51 472 217 + 423 875 674 + 371 748 692 + 793 387 318 + 642 879 775 + 499 948 877 + 930 102 541 + 223 95 252 + 588 61 258 + 439 51 56 + 495 666 26 + 262 696 423 + 276 102 416 + 656 484 499 + 807 663 474 + 876 411 24 + 351 138 143 + 312 124 534 + 336 200 421 + 687 489 733 + 751 229 941 + 322 414 256 + 440 575 936 + 373 304 5 + 689 311 931 + 854 760 440 + 824 432 463 + 302 807 159 + 842 822 499 + 751 893 350 + 205 284 474 + 852 890 257 + 91 826 609 + 806 154 808 + 947 710 269 + 999 150 135 + 291 838 260 + 347 728 885 + 481 454 779 + 518 339 139 + 767 914 644 + 519 946 650 + 561 56 988 + 485 44 40 + 42 839 457 + 518 845 490 + 121 535 452 + 392 674 242 + 502 361 491 + 838 170 716 + 828 458 249 + 260 528 618 + 359 825 228 + 494 786 183 + 701 160 315 + 568 437 13 + 577 367 383 + 65 235 376 + 134 948 942 + 151 468 204 + 67 819 813 + 90 396 447 + 688 334 528 + 706 319 398 + 609 530 604 + 564 129 561 + 932 584 43 + 653 30 91 + 262 657 302 + 389 628 375 + 9 664 564 + 764 101 568 + 754 730 927 + 650 910 57 + 51 379 96 + 616 820 112 + 100 564 98 + 688 835 659 + 720 466 647 + 262 893 400 + 425 104 167 + 388 919 466 + 257 765 50 + 197 717 734 + 101 750 750 + 412 526 261 + 382 762 382 + 209 361 315 + 470 712 398 + 447 641 40 + 390 267 438 + 441 98 446 + 402 836 333 + 678 925 255 + 835 35 166 + 471 665 859 + 390 699 875 + 551 523 235 + 691 639 263 + 879 647 53 + 331 413 118 + 154 477 970 + 389 406 916 + 811 948 239 + 408 217 244 + 868 943 404 + 349 276 792 + 236 585 481 + 320 656 546 + 835 769 804 + 161 728 778 + 948 729 65 + 835 164 940 + 692 211 148 + 434 58 920 + 524 174 30 + 572 233 25 + 50 94 8 + 554 421 618 + 338 274 638 + 346 188 656 diff --git a/pytudes/data/advent2016/input4.txt b/pytudes/data/advent2016/input4.txt new file mode 100644 index 0000000..8859648 --- /dev/null +++ b/pytudes/data/advent2016/input4.txt @@ -0,0 +1,980 @@ +bkwzkqsxq-tovvilokx-nozvyiwoxd-172[fstek] +wifilzof-wbiwifuny-yhachyylcha-526[qrazx] +jvyyvzpcl-jhukf-shivyhavyf-487[zhtsi] +kwvacumz-ozilm-kivlg-kwvbiqvumvb-694[gknyw] +mvhkvbdib-kmjezxodgz-mvwwdo-omvdidib-837[dmvbi] +nzydfxpc-rclop-qwzhpc-lnbftdtetzy-171[cptzd] +vhehkyne-unggr-inkvatlbgz-813[gnehk] +tcorcikpi-hnqygt-octmgvkpi-570[nzewo] +xmtjbzidx-wvnfzo-jkzmvodjin-447[uyzlp] +willimcpy-mwupyhayl-bohn-mufym-734[stjoc] +sbejpbdujwf-cvooz-xpsltipq-961[azfnd] +jchipqat-qphzti-rjhidbtg-htgkxrt-271[thigj] +npmhcargjc-zsllw-pcqcypaf-158[mzwnx] +luxciuwncpy-jfumncw-alumm-qilembij-318[mucil] +bxaxipgn-vgpst-rpcsn-rdpixcv-htgkxrth-427[ywazt] +zekvierkzferc-tyftfcrkv-ivtvzmzex-295[evzfk] +enzcntvat-qlr-hfre-grfgvat-143[rtaef] +mvkccspson-bkllsd-nofovyzwoxd-224[oscdk] +enzcntvat-zvyvgnel-tenqr-pnaql-pbngvat-ratvarrevat-429[zymbs] +nwzekwypera-xwogap-pnwejejc-992[lkiwn] +ajmrxjlcren-ajkkrc-lxwcjrwvnwc-667[ezynd] +bxaxipgn-vgpst-hrpktcvtg-wjci-advxhixrh-661[lytku] +owshgfarwv-vqw-kzahhafy-190[ahwfv] +jqwpihizlwca-moo-twoqabqka-512[ncdyv] +apwmeclga-pyzzgr-rcaflmjmew-886[amceg] +tyepcyletzylw-ojp-wzrtdetnd-951[mxqsy] +dlhwvupglk-kfl-hjxbpzpapvu-773[nrotd] +fab-eqodqf-dmnnuf-bgdotmeuzs-612[dchyk] +qjopwxha-bhksan-skngodkl-940[kahno] +lsyrkjkbnyec-dyz-combod-cmkfoxqob-rexd-bomosfsxq-718[lktzs] +zixppfcfba-bdd-jxohbqfkd-939[sqtor] +vxupkizork-kmm-ktmotkkxotm-852[dsqjh] +excdklvo-mkxni-mykdsxq-nozkbdwoxd-952[zspmc] +bnqqnrhud-eknvdq-sqzhmhmf-391[qhndm] +gzefmnxq-otaoaxmfq-ogefayqd-eqdhuoq-716[zinwb] +qzoggwtwsr-qobrm-ghcfous-428[goqrs] +gpbepvxcv-ltpedcxots-qphzti-steadnbtci-193[ignjy] +hvbizodx-nxvqzibzm-cpio-hvmfzodib-265[hixfe] +wkqxodsm-lexxi-kxkvicsc-926[xkcis] +bknsykmdsfo-myxcewob-qbkno-oqq-zebmrkcsxq-380[utqrz] +lejkrscv-wcfnvi-kirzezex-711[ecikr] +htwwtxnaj-idj-btwpxmtu-255[itgmd] +zsxyfgqj-jll-ijufwyrjsy-931[wrpgt] +iuxxuyobk-yigbktmkx-natz-gtgreyoy-384[ygktx] +qjopwxha-xqjju-zalhkuiajp-628[esmxk] +lxaaxbren-ljwmh-anbnjalq-745[stjqy] +gokzyxsjon-zvkcdsm-qbkcc-dbksxsxq-380[tsyqk] +qzoggwtwsr-qobrm-qcohwbu-rsdofhasbh-168[obhqr] +pelbtravp-pnaql-fgbentr-325[pabel] +xzwrmkbqtm-akidmvomz-pcvb-mvoqvmmzqvo-122[mvoqz] +sbnqbhjoh-ezf-fohjoffsjoh-233[xskyb] +jyddc-yrwxefpi-fewoix-hiwmkr-412[pdekg] +fab-eqodqf-rxaiqd-xmnadmfadk-690[sicjl] +xcitgcpixdcpa-rpcsn-htgkxrth-427[stznv] +rflsjynh-rnqnyfwd-lwfij-jll-xytwflj-229[lfjnw] +zotts-wlsiayhcw-vumeyn-fuvilunils-500[ilsun] +odiih-yujbcrl-pajbb-dbna-cnbcrwp-147[bcadi] +udskkaxawv-tmffq-klgjsyw-996[tmnfc] +emixwvqhml-kpwkwtibm-wxmzibqwva-278[zomvn] +dfcxsqhwzs-dzoghwq-ufogg-zcuwghwqg-116[kmijn] +dwbcjkun-ouxfna-mnbrpw-745[nbuwa] +jchipqat-rwdrdapit-pcpanhxh-973[hglvu] +fkqbokxqflkxi-avb-zlkqxfkjbkq-861[wdnor] +wbhsfbohwcboz-foppwh-qighcasf-gsfjwqs-480[fhswb] +dzczkrip-xiruv-szfyrqriuflj-treup-kvtyefcfxp-451[rfipu] +fmsledevhsyw-fyrrc-eguymwmxmsr-698[yzoxu] +udskkaxawv-jsttal-wfyafwwjafy-840[nlkda] +sno-rdbqds-idkkxadzm-sqzhmhmf-287[lngzc] +crwwv-yxphbq-rpbo-qbpqfkd-341[bpqrw] +odiih-mhn-anjlzdrbrcrxw-563[xadcy] +jyddc-ikk-wlmttmrk-698[lmstk] +buzahisl-wshzapj-nyhzz-klzpnu-149[pjxor] +odkasqzuo-eomhqzsqd-tgzf-ymzmsqyqzf-560[frqmp] +gokzyxsjon-bkllsd-yzobkdsyxc-874[nbtmv] +excdklvo-pvygob-bocokbmr-952[tyzxa] +jvsvymbs-jovjvshal-aljouvsvnf-253[zgtdm] +hafgnoyr-qlr-erfrnepu-637[refna] +pelbtravp-sybjre-fnyrf-299[tjoim] +fodvvlilhg-gbh-vwrudjh-621[hvdgl] +kgjgrypw-epybc-bwc-bcnjmwkclr-678[smijy] +myxcewob-qbkno-mrymyvkdo-dbksxsxq-458[bkmox] +joufsobujpobm-fhh-dpoubjonfou-311[uvksy] +rflsjynh-ojqqdgjfs-ijajqturjsy-697[jqsfr] +vetllbybxw-vtgwr-kxtvjnblbmbhg-709[athym] +ajvyjprwp-ajmrxjlcren-kdwwh-lxwcjrwvnwc-433[qsaxt] +zbytomdsvo-mkxni-mykdsxq-myxdksxwoxd-952[xdmko] +esyfwlau-bwddqtwsf-suimakalagf-684[stvip] +jef-iushuj-fhezusjybu-fbqijys-whqii-huiuqhsx-582[uhijs] +tpspahyf-nyhkl-jovjvshal-bzly-alzapun-565[sdprn] +apwmeclga-hcjjwzcyl-umpiqfmn-132[shfrg] +kwtwznct-jcvvg-lmxizbumvb-148[vbcmt] +rmn-qcapcr-aylbw-umpiqfmn-366[juftv] +sorozgxe-mxgjk-hgyqkz-yzuxgmk-748[xuvst] +bkwzkqsxq-wsvsdkbi-qbkno-mkxni-mykdsxq-yzobkdsyxc-822[ksbqx] +ryexqpqhteki-vbemuh-skijecuh-iuhlysu-842[tszmj] +ikhcxvmbex-wrx-wxlbzg-501[zhqis] +lsyrkjkbnyec-mrymyvkdo-nozvyiwoxd-978[enkfi] +wdjcvuvmyjpn-mvhkvbdib-agjrzm-nojmvbz-395[tcxne] +uwtojhynqj-gfxpjy-fhvznxnynts-567[kqpvs] +iqmbazulqp-pkq-dqoquhuzs-534[ntpuq] +gntmfefwitzx-ojqqdgjfs-ijajqturjsy-385[jfqtg] +sebehvkb-fhezusjybu-zubboruqd-husuylydw-972[ytsim] +nzcczdtgp-nsznzwlep-hzcvdsza-405[yotgu] +joufsobujpobm-fhh-ufdiopmphz-675[tsymn] +cxy-bnlanc-snuuhknjw-anbnjalq-823[nabcj] +shoewudys-rkddo-huiuqhsx-374[dhsuo] +vagreangvbany-rtt-jbexfubc-403[ynepo] +aoubshwq-dzoghwq-ufogg-aobousasbh-714[oabgh] +njmjubsz-hsbef-dipdpmbuf-qvsdibtjoh-805[bdjsf] +zovldbkfz-gbiivybxk-lmboxqflkp-653[nyajo] +yknnkoera-xwogap-hkceopeyo-628[ybmzc] +nij-mywlyn-wbiwifuny-guleyncha-396[nyiwl] +ocipgvke-ecpfa-eqcvkpi-vgejpqnqia-258[jsiqz] +encuukhkgf-hnqygt-vgejpqnqia-882[dxzer] +odiih-ljwmh-anbnjalq-927[ahijl] +fkqbokxqflkxi-zxkav-ixyloxqlov-861[nxgja] +udskkaxawv-xmrrq-uzgugdslw-sfsdqkak-216[msfyx] +owshgfarwv-bwddqtwsf-kzahhafy-216[wafhd] +oaxadrgx-dmnnuf-ruzmzouzs-794[uqhse] +ziuxioqvo-akidmvomz-pcvb-zmikycqaqbqwv-616[iqvmo] +bqvvu-xqjju-opknwca-550[yzhum] +xgjougizobk-lruckx-gtgreyoy-670[nbfmk] +bxaxipgn-vgpst-uadltg-bpgztixcv-323[gptxa] +vcibutulxiom-jfumncw-alumm-nluchcha-448[ucmla] +irgyyolokj-xghhoz-uvkxgzouty-930[ogyhk] +kyelcrga-aylbw-amyrgle-umpiqfmn-782[almye] +jsvagsulanw-xdgowj-kzahhafy-138[dblcm] +ixccb-fkrfrodwh-uhdftxlvlwlrq-881[mblzw] +chnylhuncihuf-mwupyhayl-bohn-guleyncha-422[hnuyc] +irdgrxzex-treup-tfrkzex-uvgrikdvek-165[sjbnk] +xzwrmkbqtm-akidmvomz-pcvb-zmikycqaqbqwv-434[sanut] +ykhknbqh-zua-iwjwcaiajp-524[kjlio] +jlidywncfy-mwupyhayl-bohn-uwkocmcncih-916[cyhnw] +nuatmlmdpage-omzpk-eqdhuoqe-326[ljtsm] +xmrrq-kusnwfywj-zmfl-suimakalagf-684[afmkl] +foadouwbu-qvcqczohs-rsgwub-116[oubcq] +etyyx-bgnbnkzsd-kzanqzsnqx-391[pnmlv] +pinovwgz-wvnfzo-hvmfzodib-291[ovzfi] +qekrixmg-gsrwyqiv-kvehi-fewoix-ywiv-xiwxmrk-828[iwxek] +jqwpihizlwca-xtiabqk-oziaa-kcabwumz-amzdqkm-928[aizkm] +qekrixmg-jpsaiv-stivexmsrw-672[etmsq] +excdklvo-gokzyxsjon-mrymyvkdo-bomosfsxq-562[okmsx] +qczcftiz-pibbm-aobousasbh-532[zynvo] +wbhsfbohwcboz-suu-gsfjwqsg-506[bdhxv] +lxwbdvna-pajmn-ajkkrc-anlnrerwp-563[anrjk] +lsyrkjkbnyec-pvygob-cobfsmoc-900[uyrgf] +cqwdujys-sxesebqju-ixyffydw-374[nyjvi] +odiih-ouxfna-anlnrerwp-433[naior] +rzvkjiduzy-xviyt-xjvodib-vxlpdndodji-993[aousd] +ltpedcxots-qphzti-rjhidbtg-htgkxrt-453[rjlkn] +krxqjijamxdb-kdwwh-fxatbqxy-823[wctav] +froruixo-edvnhw-vwrudjh-829[rdhou] +jvyyvzpcl-jhukf-aljouvsvnf-201[uwkic] +nij-mywlyn-vumeyn-zchuhwcha-266[hnycm] +ydjuhdqjyedqb-zubboruqd-tufbeocudj-244[vmkln] +qlm-pbzobq-mixpqfz-doxpp-mrozexpfkd-575[zswni] +qvbmzvibqwvit-moo-tijwzibwzg-330[ibvwz] +pbeebfvir-fpniratre-uhag-freivprf-949[gvxlm] +wfummczcyx-jfumncw-alumm-uwkocmcncih-890[vturj] +dwbcjkun-npp-cajrwrwp-355[kstqo] +dpssptjwf-cbtlfu-vtfs-uftujoh-441[ftsuj] +vrurcjah-pajmn-npp-anbnjalq-303[tozvd] +wfruflnsl-ojqqdgjfs-xfqjx-775[fjqls] +pbafhzre-tenqr-qlr-qrirybczrag-897[yszub] +sehheiylu-rkddo-udwyduuhydw-322[qbyad] +upq-tfdsfu-cbtlfu-nbobhfnfou-103[vpxyh] +ajvyjprwp-npp-dbna-cnbcrwp-901[stevo] +bkzrrhehdc-bzmcx-bnzshmf-qdrdzqbg-833[msuya] +amlqskcp-epybc-aylbw-rcaflmjmew-730[arbyn] +wbhsfbohwcboz-dzoghwq-ufogg-gozsg-272[gobhw] +ksodcbwnsr-dfcxsqhwzs-gqojsbusf-vibh-obozmgwg-194[rwimn] +mfklstdw-usfvq-hmjuzskafy-424[ulgym] +wfruflnsl-ojqqdgjfs-qfgtwfytwd-177[xbofz] +sedikcuh-whqtu-isqludwuh-xkdj-jhqydydw-218[dhuqw] +ltpedcxots-raphhxuxts-qphzti-advxhixrh-765[jahpi] +zgmfyxypbmsq-djmucp-rcaflmjmew-548[aeoiv] +qspkfdujmf-ezf-nbobhfnfou-207[lnkrt] +fbebmtkr-zktwx-pxtihgbsxw-ietlmbv-zktll-kxlxtkva-943[hajmb] +apwmeclga-hcjjwzcyl-bctcjmnkclr-548[yxnzl] +rflsjynh-kqtbjw-btwpxmtu-177[tbjwf] +kfg-jvtivk-treup-uvgcfpdvek-373[vkefg] +upq-tfdsfu-kfmmzcfbo-nbobhfnfou-285[vsglz] +chnylhuncihuf-mwupyhayl-bohn-xypyfijgyhn-266[pwahm] +apwmeclga-zyqicr-dglylagle-886[lagce] +jlidywncfy-xsy-qilembij-188[uxjts] +jqwpihizlwca-lgm-lmaqov-954[laimq] +qcffcgwjs-foppwh-gozsg-246[fgcop] +bqxnfdmhb-rbzudmfdq-gtms-cdrhfm-287[dmbfh] +gifavtkzcv-wcfnvi-rthlzjzkzfe-763[tmniq] +uqtqbizg-ozilm-kivlg-kwibqvo-tijwzibwzg-720[qndzg] +sxdobxkdsyxkv-mkxni-bomosfsxq-848[zyubw] +qfmcusbwq-foppwh-kcfygvcd-662[cfpqw] +sehheiylu-fbqijys-whqii-skijecuh-iuhlysu-660[kdjyq] +sedikcuh-whqtu-uww-bqrehqjeho-660[dtawl] +veqtekmrk-wgezirkiv-lyrx-eguymwmxmsr-464[emrkg] +lqwhuqdwlrqdo-exqqb-uhdftxlvlwlrq-231[ydznk] +sno-rdbqds-bzmcx-otqbgzrhmf-183[gomah] +ujqgywfau-jsttal-hmjuzskafy-476[lghae] +yrwxefpi-jpsaiv-gsrxemrqirx-100[yazxo] +udglrdfwlyh-exqqb-sxufkdvlqj-569[dlqfu] +ugjjgkanw-uzgugdslw-esjcwlafy-736[rnxjs] +pdjqhwlf-sodvwlf-judvv-orjlvwlfv-673[vldfj] +xekdwvwnzkqo-fahhuxawj-ajcejaanejc-524[ajewc] +pwcvonofrcig-pibbm-fsqswjwbu-766[myazu] +tcrjjzwzvu-wcfnvi-glityrjzex-893[bkuyx] +lugjuacha-wbiwifuny-omyl-nymncha-448[mosph] +ckgvutofkj-inuiurgzk-jkvgxzsktz-228[kguzi] +ydjuhdqjyedqb-sqdto-ijehqwu-868[ozqsj] +sxdobxkdsyxkv-zvkcdsm-qbkcc-myxdksxwoxd-640[xdksc] +odkasqzuo-dmnnuf-dqmocgueufuaz-482[wfbke] +wpuvcdng-tcddkv-wugt-vguvkpi-414[hayjs] +lqwhuqdwlrqdo-edvnhw-uhfhlylqj-439[bjzye] +wpuvcdng-dwppa-ceswkukvkqp-674[mxnkj] +qzlozfhmf-bkzrrhehdc-okzrshb-fqzrr-zbpthrhshnm-365[hrzbf] +raphhxuxts-rpcsn-rdpixcv-rjhidbtg-htgkxrt-635[yozvr] +tfejldvi-xiruv-gcrjkzt-xirjj-tljkfdvi-jvimztv-321[veyxs] +ryexqpqhteki-sxesebqju-iqbui-868[qebar] +eqpuwogt-itcfg-hnqygt-tgegkxkpi-648[ywzjl] +uzfqdzmfuazmx-pkq-bgdotmeuzs-482[zmudf] +sbnqbhjoh-cbtlfu-bdrvjtjujpo-441[taquv] +gokzyxsjon-bkwzkqsxq-lexxi-bomosfsxq-354[xoskq] +oazegyqd-sdmpq-iqmbazulqp-dmnnuf-geqd-fqefuzs-456[qdefm] +dwbcjkun-ljwmh-lxjcrwp-anbnjalq-875[hoynm] +udskkaxawv-eadalsjq-yjsvw-xdgowj-klgjsyw-216[cnwyi] +surmhfwloh-exqqb-sxufkdvlqj-439[tspmq] +ksodcbwnsr-foppwh-zcuwghwqg-402[vopuk] +zsxyfgqj-hmthtqfyj-fhvznxnynts-697[fhnty] +yflexwxoalrp-yxphbq-bkdfkbbofkd-653[jzvpm] +ltpedcxots-tvv-rdcipxcbtci-557[ctdip] +slqryzjc-djmucp-qyjcq-756[cjqyd] +rgndvtcxr-qphzti-bpcpvtbtci-817[tcpbi] +ftzgxmbv-fbebmtkr-zktwx-vtgwr-vhtmbgz-lmhktzx-371[wzxvl] +htqtwkzq-hfsid-yjhmstqtld-463[rxszy] +rwcnawjcrxwju-yujbcrl-pajbb-mnenuxyvnwc-979[gkutb] +gokzyxsjon-tovvilokx-kmaescsdsyx-562[dwlah] +iutyaskx-mxgjk-lruckx-iayzuskx-ykxboik-826[kxiuy] +vhglnfxk-zktwx-yehpxk-hixktmbhgl-891[diznt] +sedikcuh-whqtu-kdijqrbu-sqdto-seqjydw-iuhlysui-790[lksjh] +jyfvnlupj-zjhclunly-obua-vwlyhapvuz-617[pirsw] +iuruxlar-sgmtkzoi-hgyqkz-zkinturume-670[qatsn] +wkqxodsm-mrymyvkdo-mecdywob-cobfsmo-250[hgarm] +odiih-kjbtnc-nwprwnnarwp-381[qpodn] +kfg-jvtivk-tyftfcrkv-kirzezex-373[srcvd] +gcfcnuls-aluxy-zotts-wuhxs-omyl-nymncha-552[clnsu] +xmtjbzidx-zbb-xpnojhzm-nzmqdxz-421[mnkio] +qjopwxha-acc-iwngapejc-160[jimst] +emixwvqhml-kivlg-kwibqvo-aitma-564[qspyb] +nvrgfezqvu-avccpsvre-cfxzjkztj-529[lmnsh] +emixwvqhml-ktiaaqnqml-xtiabqk-oziaa-ikycqaqbqwv-746[ozadu] +zhdsrqlchg-hjj-orjlvwlfv-751[hjlrv] +cybyjqho-whqtu-uww-qsgkyiyjyed-478[szxuo] +clxalrtyr-nsznzwlep-wzrtdetnd-405[lnrtz] +sgmtkzoi-yigbktmkx-natz-rghuxgzuxe-722[gktxz] +hjgbwuladw-tskcwl-sfsdqkak-502[txdsw] +yrwxefpi-hci-vigimzmrk-646[hdmzy] +hqcfqwydw-hqrryj-jusxdebewo-946[qwdeh] +wsvsdkbi-qbkno-cmkfoxqob-rexd-yzobkdsyxc-276[wptxs] +qfmcusbwq-qvcqczohs-zcuwghwqg-870[mnybx] +clxalrtyr-nsznzwlep-cpdplcns-743[rtycz] +fbebmtkr-zktwx-ktuubm-ybgtgvbgz-553[osmdy] +jvuzbtly-nyhkl-yhtwhnpun-jovjvshal-ylzlhyjo-773[hlyjn] +slqryzjc-aylbw-pcacgtgle-782[nxkri] +tfcfiwlc-wcfnvi-wzeretzex-971[smobe] +jef-iushuj-uww-qsgkyiyjyed-556[xzrwq] +crwwv-yxphbq-xkxivpfp-653[pxvwb] +hqcfqwydw-zubboruqd-husuylydw-244[lqeho] +oxmeeuruqp-qss-eqdhuoqe-534[equos] +qxdwpopgsdjh-rgndvtcxr-gpqqxi-gthtpgrw-687[gpdqr] +mybbycsfo-mrymyvkdo-bocokbmr-692[pymza] +myvybpev-oqq-yzobkdsyxc-250[sxytw] +fnjyxwrinm-kdwwh-uxprbcrlb-329[natqu] +aietsrmdih-nippcfier-gsrxemrqirx-958[iremp] +xmrrq-tmffq-vwhdgqewfl-138[fqmrw] +oqnidbshkd-bzmcx-sdbgmnknfx-599[nzdyx] +eqttqukxg-ecpfa-eqcvkpi-ewuvqogt-ugtxkeg-128[mytkp] +nchhg-ntwemz-amzdqkma-252[kmbop] +bjfutsneji-jll-zxjw-yjxynsl-775[ndbsw] +ktwbhtvmbox-lvtoxgzxk-angm-mxvaghehzr-319[ijqxb] +kyelcrga-afmamjyrc-pcqcypaf-210[acyfm] +myxcewob-qbkno-mkxni-oxqsxoobsxq-484[oxbqk] +esyfwlau-vqw-kzahhafy-788[jikae] +oqnidbshkd-eknvdq-btrsnldq-rdquhbd-391[njzml] +qjopwxha-bhksan-opknwca-888[ahkno] +udskkaxawv-jsttal-vwhdgqewfl-190[hqmnt] +excdklvo-lexxi-crszzsxq-458[uavnl] +frqvxphu-judgh-fdqgb-frdwlqj-wudlqlqj-179[bimaq] +iuruxlar-kmm-ykxboiky-852[tijpz] +tyepcyletzylw-mldvpe-lylwjdtd-509[lydet] +frqvxphu-judgh-gbh-whfkqrorjb-101[mhbes] +xqvwdeoh-edvnhw-zrunvkrs-699[zmudw] +irdgrxzex-treup-fgvirkzfej-893[fbsyn] +cxy-bnlanc-ljwmh-orwjwlrwp-771[ngpmz] +eqpuwogt-itcfg-gii-ucngu-388[hzgae] +ikhcxvmbex-cxeeruxtg-wxlbzg-553[mvnfs] +mrxivrexmsrep-fyrrc-asvowlst-854[codsq] +npmhcargjc-aylbw-qcptgacq-366[ditsg] +ftzgxmbv-ietlmbv-zktll-phkdlahi-241[ltbhi] +hqcfqwydw-tou-bewyijysi-270[hnvux] +emixwvqhml-kivlg-abwziom-590[imlvw] +pejji-nio-mecdywob-cobfsmo-926[wrjmp] +bknsykmdsfo-oqq-dbksxsxq-640[naysz] +gifavtkzcv-vxx-tfekrzedvek-789[cnwtp] +kmjezxodgz-diozmivodjivg-agjrzm-xjiovdihzio-915[yqktj] +shoewudys-vbemuh-qsgkyiyjyed-946[nqsjd] +htqtwkzq-ojqqdgjfs-rfwpjynsl-749[hryqo] +rmn-qcapcr-zyqicr-pcacgtgle-340[znstw] +bnqqnrhud-bzmcx-bnmszhmldms-729[yfetv] +surmhfwloh-gbh-rshudwlrqv-725[dsaym] +jchipqat-tvv-itrwcdadvn-505[povhu] +zgmfyxypbmsq-njyqrga-epyqq-rcaflmjmew-340[mqyae] +froruixo-exqqb-pdunhwlqj-283[nmuqd] +lnkfaypeha-xwogap-odellejc-784[ytrsz] +jlidywncfy-xsy-fuvilunils-864[ilyfn] +joufsobujpobm-dipdpmbuf-sftfbsdi-545[rwjnm] +tvsnigxmpi-gerhc-gsexmrk-eguymwmxmsr-932[pivem] +tfejldvi-xiruv-srjbvk-ivjvrity-815[vijrt] +zuv-ykixkz-yigbktmkx-natz-zkinturume-410[kzitu] +enzcntvat-pubpbyngr-qrcyblzrag-117[oywbs] +wsvsdkbi-qbkno-lkcuod-nofovyzwoxd-744[xnuqc] +wbhsfbohwcboz-foppwh-aobousasbh-246[nfsml] +uiovmbqk-jcvvg-abwziom-720[nbqaz] +etaqigpke-fag-fgrnqaogpv-674[gaefp] +ejpanjwpekjwh-nwxxep-hkceopeyo-238[bmscu] +qjopwxha-bhksan-wjwhuoeo-940[xenwh] +etyyx-bzmcx-bnzshmf-qdzbpthrhshnm-729[hbmzn] +uqtqbizg-ozilm-lgm-abwziom-356[tspmz] +excdklvo-mybbycsfo-tovvilokx-psxkxmsxq-874[axwon] +mvydjvxodqz-xviyt-xjvodib-pnzm-oznodib-187[nflym] +ixccb-zhdsrqlchg-edvnhw-xvhu-whvwlqj-465[hcvwd] +qspkfdujmf-votubcmf-tdbwfohfs-ivou-bdrvjtjujpo-181[esuzg] +fkqbokxqflkxi-qlm-pbzobq-bdd-jxohbqfkd-601[dcgym] +mtzslklcozfd-prr-nfdezxpc-dpcgtnp-301[tmnrk] +xekdwvwnzkqo-lhwopey-cnwoo-wymqeoepekj-290[rzsnk] +fubrjhqlf-sodvwlf-judvv-pdqdjhphqw-725[dfhjq] +shoewudys-zubboruqd-skijecuh-iuhlysu-608[ushbd] +zlkprjbo-doxab-zxkav-rpbo-qbpqfkd-679[bkopa] +nzcczdtgp-mldvpe-opawzjxpye-587[tkbms] +apuut-nxvqzibzm-cpio-yzkvmohzio-655[rsozd] +rgllk-ngzzk-ymdwqfuzs-300[yhzxu] +cvabijtm-jcvvg-uiviomumvb-538[ixajz] +oazegyqd-sdmpq-otaoaxmfq-pqbmdfyqzf-248[qadfm] +rtqlgevkng-fag-nqikuvkeu-960[nqdom] +bnknqetk-cxd-cdrhfm-183[mfpwa] +ohmnuvfy-wuhxs-wiuncha-lyuwkocmcncih-552[chunw] +hqtyeqsjylu-jef-iushuj-tou-fkhsxqiydw-296[isfmy] +kwtwznct-kwvacumz-ozilm-jiasmb-uiviomumvb-746[qmjyz] +qfmcusbwq-foppwh-twbobqwbu-298[bwqfo] +ykhknbqh-xqjju-owhao-472[hjtck] +dszphfojd-tdbwfohfs-ivou-mbcpsbupsz-103[sbdfo] +lahxpnwrl-ljwmh-nwprwnnarwp-641[srtpm] +ckgvutofkj-lruckx-jkvruesktz-878[zjlyk] +dyz-combod-zvkcdsm-qbkcc-nocsqx-926[yvute] +ktwbhtvmbox-wrx-nlxk-mxlmbgz-345[lsuwt] +nwilwcejc-nwxxep-zalhkuiajp-186[bznxr] +uzfqdzmfuazmx-otaoaxmfq-bgdotmeuzs-846[mzafo] +oxmeeuruqp-omzpk-oamfuzs-oazfmuzyqzf-352[ypdzg] +zhdsrqlchg-fdqgb-ghsduwphqw-361[hdgqs] +nchhg-jiasmb-amzdqkma-278[qklti] +tfiifjzmv-upv-wzeretzex-295[itvos] +eqttqukxg-ecpfa-ujkrrkpi-830[kepqr] +clotzlnetgp-mldvpe-nzyeltyxpye-145[xfpsy] +mbiyqoxsm-myvybpev-mkxni-mykdsxq-yzobkdsyxc-900[ymxbk] +plolwdub-judgh-vfdyhqjhu-kxqw-vhuylfhv-621[zqwmy] +atyzghrk-vxupkizork-jek-giwaoyozout-228[abrmv] +zotts-xsy-mufym-162[mstyf] +vhehkyne-ktuubm-mktbgbgz-293[qmytr] +kwvacumz-ozilm-zijjqb-ivitgaqa-616[fkoxt] +yaxsnlcrun-ajvyjprwp-snuuhknjw-anlnrerwp-771[zpyld] +raphhxuxts-bpvctixr-eaphixr-vgphh-bpcpvtbtci-115[phtxb] +nuatmlmdpage-odkasqzuo-qss-dqmocgueufuaz-768[umnqw] +yknnkoera-lhwopey-cnwoo-nawymqeoepekj-680[eonkw] +pybgmyargtc-aylbw-qyjcq-886[buzfp] +gzefmnxq-ngzzk-iadwetab-638[zaegn] +sbnqbhjoh-kfmmzcfbo-usbjojoh-129[acdkb] +lxaaxbren-lujbbrornm-ljwmh-lxjcrwp-mnyjacvnwc-355[yzsuk] +nchhg-lgm-nqvivkqvo-200[dystz] +plolwdub-judgh-udeelw-rshudwlrqv-335[sihdt] +wlsiayhcw-vumeyn-lymyulwb-292[zbrux] +ytu-xjhwjy-hfsid-htfynsl-qtlnxynhx-411[adxmu] +wkqxodsm-tovvilokx-ckvoc-822[uhgov] +chnylhuncihuf-vumeyn-nluchcha-500[rcbmn] +tfiifjzmv-lejkrscv-tyftfcrkv-jyzggzex-243[fjtvz] +eqpuwogt-itcfg-tcddkv-tgugctej-310[pyemh] +iuruxlar-xgsvgmotm-pkrrehkgt-xkykgxin-956[btwqp] +shoewudys-sxesebqju-qdqboiyi-894[seqbd] +zlkprjbo-doxab-gbiivybxk-pxibp-861[azyjx] +ckgvutofkj-inuiurgzk-lotgtiotm-982[qszly] +thnulapj-jshzzpmplk-jhukf-vwlyhapvuz-747[hpjlu] +pybgmyargtc-hcjjwzcyl-qcptgacq-782[bxsuc] +xgsvgmotm-vrgyzoi-mxgyy-iutzgotsktz-150[gtmoy] +laffe-yigbktmkx-natz-jkyomt-696[ktafm] +zvyvgnel-tenqr-pubpbyngr-znexrgvat-507[wfjhu] +pelbtravp-pnaql-znantrzrag-403[cbyja] +jqwpihizlwca-akidmvomz-pcvb-apqxxqvo-850[oxymv] +cvabijtm-ntwemz-twoqabqka-954[atbmq] +zixppfcfba-avb-zlkqxfkjbkq-809[zlmjc] +sebehvkb-zubboruqd-tufqhjcudj-556[budeh] +lqwhuqdwlrqdo-fdqgb-ghvljq-621[qdlgh] +qlm-pbzobq-crwwv-zxkav-zlxqfkd-rpbo-qbpqfkd-731[ciyxw] +pwcvonofrcig-gqojsbusf-vibh-qighcasf-gsfjwqs-740[csebm] +mvydjvxodqz-kmjezxodgz-kgvnodx-bmvnn-yzqzgjkhzio-239[zdovg] +kzgwomvqk-xtiabqk-oziaa-tijwzibwzg-564[menyj] +ksodcbwnsr-xszzmpsob-kcfygvcd-454[mbaod] +ejpanjwpekjwh-xwogap-hwxknwpknu-472[wpjkn] +mvydjvxodqz-hvbizodx-wpiit-hvivbzhzio-967[ivzdh] +mvydjvxodqz-mvwwdo-nzmqdxzn-681[jryzk] +enqvbnpgvir-rtt-freivprf-871[lgqrc] +hvbizodx-wpiit-kpmxcvndib-291[dyjmn] +molgbzqfib-mixpqfz-doxpp-xkxivpfp-965[pxfib] +fbebmtkr-zktwx-cxeeruxtg-nlxk-mxlmbgz-137[dckut] +luxciuwncpy-luvvcn-mbcjjcha-500[qsvzt] +apwmeclga-hcjjwzcyl-qyjcq-704[cjalq] +wpuvcdng-eqttqukxg-uecxgpigt-jwpv-cpcnauku-830[ucgpt] +iehepwnu-cnwza-fahhuxawj-pnwejejc-940[ewahj] +pbybeshy-pbeebfvir-pnaql-pbngvat-freivprf-715[uyzwp] +htsxzrjw-lwfij-ojqqdgjfs-zxjw-yjxynsl-957[iyonc] +sxdobxkdsyxkv-wsvsdkbi-qbkno-zvkcdsm-qbkcc-bomosfsxq-536[mbyan] +fruurvlyh-fkrfrodwh-uhdftxlvlwlrq-335[rflhu] +froruixo-hjj-orjlvwlfv-387[uyawn] +myvybpev-lexxi-vklybkdybi-978[ybvei] +chnylhuncihuf-vohhs-xymcah-240[yxnmh] +tagzsrsjvgmk-vqw-vwhsjlewfl-606[svwgj] +zbytomdsvo-lexxi-domrxyvyqi-250[oxydi] +qfkkj-clmmte-opgpwzaxpye-821[pekma] +lgh-kwujwl-udskkaxawv-jsttal-hmjuzskafy-320[axyrm] +irdgrxzex-nvrgfezqvu-avccpsvre-cfxzjkztj-191[sclzh] +mhi-lxvkxm-xzz-etuhktmhkr-319[rcomn] +lhkhszqx-fqzcd-dff-sdbgmnknfx-391[ugevx] +apwmeclga-aylbw-ylyjwqgq-314[izfye] +yflexwxoalrp-zlkprjbo-doxab-ciltbo-qbzeklildv-341[byclp] +cvabijtm-kwzzwaqdm-ntwemz-abwziom-252[rdmvn] +qfkkj-upwwjmply-epnsyzwzrj-899[okhgz] +jxdkbqfz-avb-zlkqxfkjbkq-861[wptxb] +gpsxdprixkt-qphzti-hwxeexcv-947[krgwe] +nij-mywlyn-wuhxs-wiuncha-lymyulwb-968[wylnu] +sbnqbhjoh-kfmmzcfbo-ufdiopmphz-987[bfhmo] +guahyncw-jfumncw-alumm-xyjfisgyhn-500[htamn] +ytu-xjhwjy-jll-ijxnls-879[duthg] +lgh-kwujwl-usfvq-ugslafy-esfsywewfl-944[ilszy] +tvsnigxmpi-tpewxmg-kveww-xiglrspskc-152[gipsw] +joufsobujpobm-cbtlfu-dvtupnfs-tfswjdf-129[fubjo] +rwcnawjcrxwju-bljenwpna-qdwc-mnyuxhvnwc-225[wncja] +qzchnzbshud-okzrshb-fqzrr-rzkdr-989[rzhbd] +qzoggwtwsr-pogysh-rsjszcdasbh-896[sghor] +gzefmnxq-dmnnuf-xmnadmfadk-326[tvuiw] +qzoggwtwsr-pibbm-zopcfohcfm-792[jsmfu] +mvydjvxodqz-xviyt-xjvodib-hvivbzhzio-369[iceny] +wkqxodsm-lkcuod-cdybkqo-224[dkocq] +veqtekmrk-ikk-wxsveki-542[keivm] +zlkprjbo-doxab-yxphbq-pqloxdb-419[ckdtm] +buzahisl-ibuuf-klzpnu-721[stjnm] +hwdtljsnh-kqtbjw-ijajqturjsy-515[plnqy] +luxciuwncpy-jfumncw-alumm-lyuwkocmcncih-474[lqpco] +tinnm-ibghopzs-rms-aobousasbh-506[sboah] +pbeebfvir-rtt-ratvarrevat-403[tdokj] +dmybmsuzs-pkq-efadmsq-300[msdqa] +ujqgywfau-tmffq-dgyaklauk-970[yxmid] +ovbunmneqbhf-enoovg-hfre-grfgvat-481[efgno] +hqfxxnknji-kzeed-uqfxynh-lwfxx-wjhjnansl-957[nxfhj] +plolwdub-judgh-edvnhw-pdqdjhphqw-985[dsxhg] +nwlddtqtpo-awldetn-rcldd-nfdezxpc-dpcgtnp-353[dnptc] +bwx-amkzmb-xzwrmkbqtm-ntwemz-amzdqkma-668[swmnl] +bqxnfdmhb-qzaahs-rdquhbdr-443[bdhqa] +egdytrixat-ide-htrgti-uadltg-steadnbtci-297[zampy] +gsrwyqiv-kvehi-gerhc-gsexmrk-erepcwmw-880[bkwts] +nsyjwsfyntsfq-gfxpjy-jslnsjjwnsl-749[lvzus] +dfcxsqhwzs-pibbm-gvwddwbu-246[dqbem] +mtzslklcozfd-ojp-fdpc-epdetyr-613[dpcef] +gbc-frperg-ohaal-erfrnepu-351[reafg] +gvaaz-cbtlfu-efqbsunfou-311[dvnmz] +ugdgjxmd-tskcwl-umklgewj-kwjnauw-892[wgjku] +iruzfrtkzmv-avccpsvre-nfibjyfg-243[jzoyc] +shoewudys-hqrryj-bqrehqjeho-296[heqrj] +hwdtljsnh-kqtbjw-htsyfnsrjsy-827[dntpc] +zilqwikbqdm-kivlg-uiviomumvb-902[imvbk] +rsvxltspi-sfnigx-wxsveki-984[sixve] +surmhfwloh-gbh-xvhu-whvwlqj-387[hwluv] +ubhatstkwhnl-yehpxk-wxlbzg-137[raqjb] +oknkvcta-itcfg-uecxgpigt-jwpv-ocpcigogpv-596[cgpio] +amjmpdsj-djmucp-nspafyqgle-470[ztpqn] +zixppfcfba-avb-abpfdk-471[abfpc] +owshgfarwv-jsttal-vwkayf-944[smcyx] +vjpwncrl-ljwmh-lxjcrwp-lxwcjrwvnwc-589[irbxq] +qvbmzvibqwvit-ziuxioqvo-lgm-amzdqkma-928[hgfln] +lxuxaodu-kjbtnc-jwjuhbrb-147[bjuxa] +etaqigpke-fag-yqtmujqr-440[qaegt] +zekvierkzferc-irdgrxzex-jtrmvexvi-ylek-rthlzjzkzfe-633[gkyzp] +mfklstdw-hdsklau-yjskk-kwjnauwk-762[vnfzg] +pkl-oaynap-fahhuxawj-oanreyao-706[mdfpn] +hwdtljsnh-hmthtqfyj-rfsfljrjsy-359[sxziu] +fab-eqodqf-ngzzk-bgdotmeuzs-144[kxags] +tagzsrsjvgmk-tskcwl-vwhsjlewfl-424[ejuah] +kzgwomvqk-jiasmb-uizsmbqvo-590[mbiko] +qjopwxha-xqjju-oanreyao-758[ubmon] +hvbizodx-xmtjbzidx-nxvqzibzm-cpio-yzkgjthzio-889[rmyqo] +iuruxlar-kmm-jkvruesktz-644[kruma] +ujqgywfau-jsttal-vwhdgqewfl-710[hbdlx] +jlidywncfy-wuhxs-wiuncha-yhachyylcha-630[hycaw] +lugjuacha-wlsiayhcw-dyffsvyuh-uhufsmcm-890[juefh] +hjgbwuladw-xdgowj-hmjuzskafy-398[wqigl] +yuxufmdk-sdmpq-pkq-etubbuzs-456[wldkg] +vcibutulxiom-dyffsvyuh-qilembij-110[jdnmz] +nzwzcqfw-clmmte-dpcgtnpd-509[cdmnp] +aczupnetwp-nlyoj-nzletyr-zapcletzyd-665[zelnp] +htsxzrjw-lwfij-wfintfhynaj-kqtbjw-knsfshnsl-983[kytzm] +enqvbnpgvir-onfxrg-qrirybczrag-611[rgnbi] +molgbzqfib-ciltbo-xkxivpfp-159[biflo] +plolwdub-judgh-fkrfrodwh-ghyhorsphqw-517[hdorw] +gzefmnxq-omzpk-oazfmuzyqzf-872[zkycu] +qjopwxha-lhwopey-cnwoo-naoawnyd-186[cvyno] +jyfvnlupj-ipvohghykvbz-jovjvshal-ylzlhyjo-435[xlenk] +ajmrxjlcren-kjbtnc-jwjuhbrb-329[klcuz] +wdjcvuvmyjpn-ezggtwzvi-jkzmvodjin-603[gmveh] +muqfedyput-fbqijys-whqii-bqrehqjeho-192[vdlge] +ktfitzbgz-xzz-ftgtzxfxgm-605[izfql] +bknsykmdsfo-oqq-wkbuodsxq-458[stifb] +slqryzjc-hcjjwzcyl-yaosgqgrgml-314[qymir] +gpewwmjmih-veffmx-xvemrmrk-126[itcvu] +rdadguja-gpqqxi-ldgzhwde-297[hnvso] +lxaaxbren-mhn-cnlqwxuxph-251[xvjuz] +xst-wigvix-fewoix-gsrxemrqirx-698[xireg] +iehepwnu-cnwza-zua-wymqeoepekj-108[sdnmj] +oknkvcta-itcfg-rncuvke-itcuu-hkpcpekpi-908[pgfbe] +enqvbnpgvir-ohaal-hfre-grfgvat-351[hsgdf] +ixccb-iorzhu-hqjlqhhulqj-647[hqcij] +apuut-agjrzm-jkzmvodjin-915[jamuz] +hqcfqwydw-rqiauj-ijehqwu-530[qwhij] +vhehkyne-ktwbhtvmbox-lvtoxgzxk-angm-kxvxbobgz-683[tsurp] +gntmfefwitzx-idj-knsfshnsl-723[fnsit] +ajvyjprwp-bljenwpna-qdwc-ujkxajcxah-563[yskxv] +joufsobujpobm-dboez-dpbujoh-mbcpsbupsz-259[bopuj] +xlrypetn-prr-nzyeltyxpye-847[yeprl] +zuv-ykixkz-xgsvgmotm-lruckx-jkvgxzsktz-696[ijlfz] +jqwpihizlwca-moo-lmxtwgumvb-798[nkzsr] +jsvagsulanw-kusnwfywj-zmfl-klgjsyw-736[ectrq] +ykhknbqh-nwxxep-nawymqeoepekj-758[cfvdy] +kzeed-gfxpjy-tujwfyntsx-385[aunmy] +slqryzjc-qaytclecp-fslr-dglylagle-184[lcyae] +laffe-vrgyzoi-mxgyy-iutzgotsktz-410[gtyzf] +gpbepvxcv-hrpktcvtg-wjci-stktadebtci-141[zoqhx] +yaxsnlcrun-lqxlxujcn-mnyuxhvnwc-641[nxclu] +tagzsrsjvgmk-kusnwfywj-zmfl-dstgjslgjq-294[gayon] +kwzzwaqdm-zijjqb-xczkpiaqvo-902[mkgjt] +mfklstdw-usfvq-ugslafy-xafsfuafy-684[fsaul] +zvyvgnel-tenqr-ovbunmneqbhf-sybjre-fgbentr-117[shfce] +emixwvqhml-akidmvomz-pcvb-amzdqkma-720[relbk] +rdggdhxkt-eaphixr-vgphh-hwxeexcv-973[xozyv] +bqvvu-zua-iwngapejc-992[nmdax] +bjfutsneji-kqtbjw-wjxjfwhm-203[irjmx] +bdavqofuxq-nmewqf-abqdmfuaze-976[vgzhc] +vdzonmhydc-okzrshb-fqzrr-rzkdr-313[rzdhk] +sawlkjevaz-oywrajcan-dqjp-wjwhuoeo-836[ajwoe] +fruurvlyh-gbh-sxufkdvlqj-413[kftmo] +fruurvlyh-sodvwlf-judvv-ghsorbphqw-569[tadzk] +sbejpbdujwf-tdbwfohfs-ivou-dpoubjonfou-103[rbqio] +oxmeeuruqp-otaoaxmfq-xasuefuoe-222[ozipy] +rdggdhxkt-qphzti-ejgrwphxcv-921[tusrb] +dkqjcbctfqwu-fag-yqtmujqr-882[kzvuf] +gzefmnxq-dmnnuf-mzmxkeue-248[menfu] +kgjgrypw-epybc-aylbw-kylyeckclr-314[mlvhs] +bwx-amkzmb-akidmvomz-pcvb-abwziom-148[nmtyw] +ckgvutofkj-sorozgxe-mxgjk-xghhoz-xkykgxin-670[gkxoh] +zhdsrqlchg-fkrfrodwh-ghsorbphqw-803[cjybd] +hvbizodx-wvnfzo-adivixdib-603[xwstz] +tvsnigxmpi-gerhc-hitpscqirx-204[icghp] +jrncbavmrq-cynfgvp-tenff-npdhvfvgvba-741[ybszn] +mbiyqoxsm-pvygob-psxkxmsxq-952[mjfnc] +gsrwyqiv-kvehi-veffmx-gywxsqiv-wivzmgi-282[bdrgj] +clxalrtyr-xtwtelcj-rclop-awldetn-rcldd-cpdplcns-847[lcdrt] +ahngzyzqcntr-bzmcx-sdbgmnknfx-287[fmyqt] +zgmfyxypbmsq-aylbw-amyrgle-bctcjmnkclr-340[mybcl] +fydelmwp-prr-nzyeltyxpye-717[gfjxa] +rnqnyfwd-lwfij-rflsjynh-wfggny-xfqjx-931[fnjwy] +zilqwikbqdm-xtiabqk-oziaa-twoqabqka-278[ftonr] +bjfutsneji-gzssd-uzwhmfxnsl-827[sfjnu] +ojk-nzxmzo-pinovwgz-agjrzm-jkzmvodjin-733[zjomn] +ygcrqpkbgf-dcumgv-fgukip-570[vmhxn] +dzczkrip-xiruv-srjbvk-jyzggzex-945[uzneh] +bkzrrhehdc-bzmcx-lzmzfdldms-287[eclvd] +ziuxioqvo-kpwkwtibm-lmxizbumvb-564[txsru] +kzgwomvqk-lgm-lmxizbumvb-122[mbgkl] +htsxzrjw-lwfij-idj-xjwanhjx-463[obdze] +gntmfefwitzx-kqtbjw-wjxjfwhm-749[qzutv] +htsxzrjw-lwfij-jll-tujwfyntsx-671[xugan] +ymszqfuo-rxaiqd-etubbuzs-118[ubqsz] +vdzonmhydc-azrjds-lzqjdshmf-989[dzhjm] +dyz-combod-bkllsd-oxqsxoobsxq-354[nrmkx] +pyknyegle-afmamjyrc-yaosgqgrgml-626[zdlfg] +oxmeeuruqp-vqxxknqmz-oazfmuzyqzf-352[rnsyt] +qjopwxha-xqjju-pnwejejc-654[jepqw] +wifilzof-jfumncw-alumm-xypyfijgyhn-604[fjerw] +vagreangvbany-enoovg-fuvccvat-533[gncot] +avw-zljyla-zjhclunly-obua-thuhnltlua-669[wathd] +ynssr-lvtoxgzxk-angm-mxvaghehzr-345[vopnm] +cvabijtm-uqtqbizg-ozilm-xtiabqk-oziaa-lmdmtwxumvb-928[imabt] +frqvxphu-judgh-sodvwlf-judvv-pdqdjhphqw-751[azovy] +qmpmxevc-kvehi-jyddc-fyrrc-qerekiqirx-282[ygmhv] +fodvvlilhg-udeelw-pdunhwlqj-153[sndmo] +gpsxdprixkt-ytaanqtpc-gthtpgrw-765[tpgar] +cvabijtm-kpwkwtibm-bmkpvwtwog-174[wbkmt] +vetllbybxw-yehpxk-wxlbzg-891[yekxl] +nzwzcqfw-nlyoj-dezclrp-275[zclnw] +qmpmxevc-kvehi-glsgspexi-gsrxemrqirx-828[exgim] +xtwtelcj-rclop-dnlgpyrpc-sfye-hzcvdsza-873[xmpon] +jrncbavmrq-pnaql-jbexfubc-793[bacjn] +ohmnuvfy-yaa-lymyulwb-266[yalmu] +nzwzcqfw-aczupnetwp-awldetn-rcldd-pyrtyppctyr-613[pctwd] +vqr-ugetgv-uecxgpigt-jwpv-rwtejcukpi-752[geptu] +tfcfiwlc-lejkrscv-upv-rthlzjzkzfe-607[tcfns] +hwdtljsnh-uqfxynh-lwfxx-knsfshnsl-229[xtngb] +iuruxlar-igtje-iayzuskx-ykxboik-930[kmghr] +xjgjmapg-ezggtwzvi-hvivbzhzio-421[gzivh] +gpbepvxcv-hrpktcvtg-wjci-hwxeexcv-349[xswrp] +tcorcikpi-eqttqukxg-gii-hkpcpekpi-622[ruxyk] +ygcrqpkbgf-ejqeqncvg-ucngu-440[gcqen] +etyyx-dff-qdbdhuhmf-729[wskto] +tfiifjzmv-upv-vexzevvizex-399[veizf] +houngfgxjuay-sorozgxe-mxgjk-jek-aykx-zkyzotm-566[aimhd] +hcd-gsqfsh-dzoghwq-ufogg-aobousasbh-714[ynfie] +foadouwbu-qobrm-qcohwbu-zopcfohcfm-792[obcfu] +ynukcajey-oywrajcan-dqjp-wjwhuoeo-680[jaowy] +rflsjynh-jll-rfsfljrjsy-489[jlfrs] +vkrhzxgbv-pxtihgbsxw-yehpxk-mktbgbgz-917[igtvy] +hjgbwuladw-tskcwl-dgyaklauk-294[aklwd] +cvabijtm-jcvvg-zmikycqaqbqwv-772[vcqab] +odiih-yujbcrl-pajbb-vjwjpnvnwc-849[jbcin] +tinnm-tzcksf-igsf-hsghwbu-220[bnamt] +pbeebfvir-wryylorna-jbexfubc-637[egouk] +xmtjbzidx-xviyt-yzqzgjkhzio-265[vxsry] +avw-zljyla-zjhclunly-obua-klwhyatlua-201[sjayl] +dfcxsqhwzs-qvcqczohs-fsgsofqv-246[dosrp] +rzvkjiduzy-xviyt-xjvodib-kpmxcvndib-291[cwzla] +gcfcnuls-aluxy-mwupyhayl-bohn-wihnuchgyhn-968[hnuyc] +dyz-combod-lsyrkjkbnyec-bkllsd-domrxyvyqi-328[vtxzd] +fruurvlyh-mhoobehdq-dftxlvlwlrq-907[jlves] +mrxivrexmsrep-gerhc-gsexmrk-tyvglewmrk-152[wzuly] +votubcmf-gmpxfs-pqfsbujpot-883[fpbmo] +bljenwpna-qdwc-anbnjalq-329[lcwmy] +xekdwvwnzkqo-ydkykhwpa-wjwhuoeo-550[toavy] +yhkpvhjapcl-yhiipa-jbzavtly-zlycpjl-201[lpyah] +xjinphzm-bmvyz-wvnfzo-nzmqdxzn-681[ykfxe] +pbeebfvir-rtt-ybtvfgvpf-507[bftve] +gvcskirmg-ikk-hizipstqirx-750[iyquj] +yhwooebeaz-lhwopey-cnwoo-oanreyao-108[tmuag] +wlqqp-jtrmvexvi-ylek-nfibjyfg-581[tnrhf] +tfiifjzmv-avccpsvre-jyzggzex-477[mvnjr] +xjmmjndqz-zbb-yzndbi-811[bzdjm] +qjopwxha-xwogap-nayaerejc-160[isjqz] +qzlozfhmf-azrjds-knfhrshbr-573[dfmys] +vhglnfxk-zktwx-vetllbybxw-vtgwr-vhtmbgz-ybgtgvbgz-761[gbtvl] +etaqigpke-ecpfa-eqcvkpi-cpcnauku-336[eyxtb] +lqwhuqdwlrqdo-fdqgb-frdwlqj-zrunvkrs-933[tvijl] +gvcskirmg-tvsnigxmpi-gerhc-gsexmrk-wlmttmrk-828[szawg] +irdgrxzex-kfg-jvtivk-wcfnvi-jyzggzex-269[givxz] +cqwdujys-sqdto-iqbui-270[siyeh] +bnqqnrhud-bgnbnkzsd-trdq-sdrshmf-807[dnbqr] +rgndvtcxr-hrpktcvtg-wjci-prfjxhxixdc-193[yjsht] +qekrixmg-hci-xvemrmrk-282[mreik] +xcitgcpixdcpa-snt-apqdgpidgn-349[mfywv] +wkqxodsm-pvygob-wkbuodsxq-978[ysamp] +aoubshwq-qvcqczohs-kcfygvcd-558[ytvls] +tyepcyletzylw-qwzhpc-opalcexpye-301[gamdn] +tfcfiwlc-treup-uvjzxe-607[nrthm] +ubhatstkwhnl-lvtoxgzxk-angm-inkvatlbgz-865[tagkl] +wihmogyl-aluxy-yaa-qilembij-890[emvct] +bxaxipgn-vgpst-ltpedcxots-gpqqxi-hidgpvt-245[pgtxi] +jfifqxov-doxab-mixpqfz-doxpp-obpbxoze-107[ghpyi] +gvaaz-dpssptjwf-sbccju-fohjoffsjoh-675[pfzwa] +gzefmnxq-eomhqzsqd-tgzf-efadmsq-378[qefmz] +emixwvqhml-kivlg-zmkmqdqvo-876[dcfin] +fodvvlilhg-fdqgb-frqwdlqphqw-725[qdflg] +laffe-pkrrehkgt-rumoyzoiy-670[dyjut] +egdytrixat-qphzti-tcvxcttgxcv-245[tcxgi] +htqtwkzq-wfintfhynaj-xhfajsljw-mzsy-jslnsjjwnsl-645[eynzi] +vrurcjah-pajmn-npp-mnyuxhvnwc-563[npach] +ejpanjwpekjwh-acc-klanwpekjo-576[jaekp] +kwvacumz-ozilm-kpwkwtibm-uizsmbqvo-876[mikwz] +hjgbwuladw-xdgowj-esfsywewfl-866[byzdm] +pbybeshy-wryylorna-npdhvfvgvba-351[stmxy] +qjopwxha-ywjzu-hkceopeyo-654[tysoa] +lhkhszqx-fqzcd-dff-vnqjrgno-417[fqdhn] +rgllk-otaoaxmfq-fdmuzuzs-768[vkqac] +ohmnuvfy-xsy-omyl-nymncha-214[hmtfs] +enzcntvat-cynfgvp-tenff-nanylfvf-455[cuimh] +sedikcuh-whqtu-sehheiylu-tou-bqrehqjeho-868[ydaux] +tyepcyletzylw-ojp-opalcexpye-145[wciks] +udpsdjlqj-hjj-frqwdlqphqw-309[gbpcz] +eqpuwogt-itcfg-lgnnadgcp-vtckpkpi-388[gpcti] +rkpqxyib-pzxsbkdbo-erkq-zrpqljbo-pbosfzb-133[bpkoq] +kdijqrbu-sxesebqju-tufqhjcudj-114[tdbva] +gsvvswmzi-wgezirkiv-lyrx-irkmriivmrk-412[twsrk] +ucynmlgxcb-qaytclecp-fslr-amlryglkclr-704[lcrya] +xst-wigvix-veffmx-wxsveki-100[ocvmr] +surmhfwloh-vfdyhqjhu-kxqw-frqwdlqphqw-829[hqwfd] +xmrrq-usfvq-esfsywewfl-528[alidm] +zhdsrqlchg-lqwhuqdwlrqdo-sodvwlf-judvv-ghsorbphqw-777[rtnmj] +egdytrixat-xcitgcpixdcpa-rwdrdapit-uxcpcrxcv-245[cdabn] +yrwxefpi-ikk-gywxsqiv-wivzmgi-152[iwgkv] +qcffcgwjs-foppwh-obozmgwg-558[zotsu] +veqtekmrk-gerhc-gsexmrk-hitpscqirx-568[nczdq] +gzefmnxq-pkq-pqbmdfyqzf-794[jxrmh] +eadalsjq-yjsvw-usfvq-ugslafy-ugflsafewfl-632[fsalu] +esyfwlau-usfvq-ugslafy-vwhdgqewfl-684[flsuw] +ktfitzbgz-fbebmtkr-zktwx-utldxm-wxlbzg-683[afwhg] +wihmogyl-aluxy-vohhs-uwkocmcncih-292[wzryd] +bkzrrhehdc-idkkxadzm-lzmzfdldms-677[oxwvn] +clxalrtyr-qwzhpc-lnbftdtetzy-249[zryvn] +rgllk-fab-eqodqf-vqxxknqmz-pqbxakyqzf-222[qfkxa] +xjinphzm-bmvyz-xviyt-mzxzdqdib-603[xnhfs] +htsxzrjw-lwfij-hmthtqfyj-wjfhvznxnynts-385[zreuy] +myvybpev-gokzyxsjon-oqq-nozvyiwoxd-692[iyzuj] +hcd-gsqfsh-pogysh-gvwddwbu-480[mysuk] +hcd-gsqfsh-foppwh-rsgwub-428[kvtfs] +frqvxphu-judgh-exqqb-uhvhdufk-621[wtgmn] +vhglnfxk-zktwx-vahvhetmx-vhgmtbgfxgm-345[hnamj] +tagzsrsjvgmk-usfvq-ugslafy-ugflsafewfl-892[yckbv] +joufsobujpobm-gmpxfs-vtfs-uftujoh-233[foujs] +zsxyfgqj-ojqqdgjfs-zxjw-yjxynsl-593[jqsxy] +bnknqetk-atmmx-qdzbpthrhshnm-131[ecnmt] +hmsdqmzshnmzk-dff-sqzhmhmf-859[dnxcz] +hqtyeqsjylu-tou-udwyduuhydw-348[uydhq] +ktiaaqnqml-kpwkwtibm-zmikycqaqbqwv-772[tlrsg] +nzydfxpc-rclop-mtzslklcozfd-mfyyj-nfdezxpc-dpcgtnp-951[cpdfz] +ckgvutofkj-hatte-gtgreyoy-644[tgeko] +iwcjapey-zua-paydjkhkcu-628[hntmg] +bnknqetk-okzrshb-fqzrr-trdq-sdrshmf-729[tuzoy] +qmpmxevc-kvehi-yrwxefpi-glsgspexi-wlmttmrk-828[hsyvf] +amjmpdsj-njyqrga-epyqq-qcptgacq-106[bhysd] +dwbcjkun-ljwmh-mnyuxhvnwc-641[wuyrz] +gspsvjyp-jpsaiv-hiwmkr-854[zthel] +gsrwyqiv-kvehi-gerhc-stivexmsrw-750[whgse] +xjgjmapg-wpiit-ozxcijgjbt-889[ytsop] +xgjougizobk-kmm-rghuxgzuxe-280[cwrty] +zovldbkfz-oxjmxdfkd-oxyyfq-ixyloxqlov-653[snkwb] +qczcftiz-qvcqczohs-gsfjwqsg-142[cqszf] +krxqjijamxdb-mhn-ldbcxvna-bnaerln-771[ravbt] +pybgmyargtc-bwc-bcqgel-860[bcgya] +wyvqljapsl-jovjvshal-shivyhavyf-773[vahjl] +pbafhzre-tenqr-onfxrg-bcrengvbaf-221[zyaro] +glrcplyrgmlyj-bwc-pcqcypaf-132[clpyg] +dpmpsgvm-dboez-dpbujoh-tfswjdft-545[bdmzf] +dkqjcbctfqwu-rncuvke-itcuu-cpcnauku-700[cuknq] +ajmrxjlcren-yujbcrl-pajbb-anbnjalq-459[yslvg] +oazegyqd-sdmpq-bxmefuo-sdmee-fqotzaxask-586[vfmnu] +ugdgjxmd-jsttal-ksdwk-632[hfjix] +aietsrmdih-gvcskirmg-tpewxmg-kveww-vigimzmrk-412[kfcim] +drxevkzt-jtrmvexvi-ylek-uvgcfpdvek-685[vekdr] +excdklvo-bkllsd-nozvyiwoxd-250[dlokv] +uwtojhynqj-hfsid-wjxjfwhm-281[fqsmx] +plolwdub-judgh-udeelw-uhfhlylqj-205[ludhe] +oqnidbshkd-dff-zmzkxrhr-729[cvlkx] +bknsykmdsfo-tovvilokx-bomosfsxq-328[boqly] +dpotvnfs-hsbef-qspkfdujmf-cvooz-tijqqjoh-961[zmnyi] +gspsvjyp-fyrrc-gsrxemrqirx-490[rsgpx] +gifavtkzcv-szfyrqriuflj-wcfnvi-uvmvcfgdvek-139[zadfj] +gsrwyqiv-kvehi-wgezirkiv-lyrx-wxsveki-490[alpzb] +ykhknbqh-ydkykhwpa-zalhkuiajp-862[khayp] +dmybmsuzs-yuxufmdk-sdmpq-bxmefuo-sdmee-fqotzaxask-586[nwikx] +nwzekwypera-bhksan-nayaerejc-940[xnmta] +wrs-vhfuhw-hjj-zrunvkrs-283[hrjsu] +ajyqqgdgcb-pyzzgr-amlryglkclr-782[lozts] +ohmnuvfy-jfumncw-alumm-womnigyl-mylpcwy-110[mqrgd] +foadouwbu-suu-obozmgwg-792[hgkuj] +wdjcvuvmyjpn-ytz-yzkgjthzio-109[jyztv] +ucynmlgxcb-pyzzgr-qfgnngle-210[iftry] +ymszqfuo-omzpk-oamfuzs-pqhqxabyqzf-872[qzfmo] +clotzlnetgp-ojp-opawzjxpye-769[pnhtz] +mhi-lxvkxm-yehpxk-ftgtzxfxgm-657[etajx] +surmhfwloh-fkrfrodwh-uhfhlylqj-699[rkslj] +iruzfrtkzmv-tyftfcrkv-kirzezex-841[emztq] +bdavqofuxq-nmewqf-ogefayqd-eqdhuoq-352[jpmyv] +bdavqofuxq-otaoaxmfq-xasuefuoe-326[aofqu] +gpsxdprixkt-tvv-ldgzhwde-219[dgptv] +pbeebfvir-rtt-bcrengvbaf-897[enlaq] +jchipqat-gpqqxi-bpgztixcv-375[cnqyt] +glrcplyrgmlyj-qaytclecp-fslr-pcqcypaf-574[clpyr] +pejji-oqq-vyqscdsmc-640[qcjsd] +houngfgxjuay-yigbktmkx-natz-xkykgxin-774[mszcw] +ltpedcxots-jchipqat-gpqqxi-bpcpvtbtci-219[isgfv] +gifavtkzcv-tyftfcrkv-drerxvdvek-659[vbdyz] +vjpwncrl-mhn-orwjwlrwp-641[wrjln] +vjpwncrl-ouxfna-bcxajpn-511[ydzfw] +rzvkjiduzy-xviyt-xjvodib-adivixdib-187[idvxb] +tinnm-suu-twbobqwbu-272[datjf] +apuut-xviyt-vxlpdndodji-941[zrtso] +jxdkbqfz-zixppfcfba-mixpqfz-doxpp-jxohbqfkd-705[fpxbd] +zilqwikbqdm-lgm-kwvbiqvumvb-876[bqpme] +jyddc-wgezirkiv-lyrx-wxsveki-256[sjntv] +ahngzyzqcntr-qzaahs-zbpthrhshnm-963[fzvai] +ksodcbwnsr-qfmcusbwq-suu-qighcasf-gsfjwqs-350[wyezk] +atyzghrk-igtje-iugzotm-jkyomt-462[ksuli] +dwbcjkun-ajmrxjlcren-yujbcrl-pajbb-nwprwnnarwp-563[tjsqg] +aoubshwq-dzoghwq-ufogg-aofyshwbu-896[hwcmz] +apwmeclga-npmhcargjc-njyqrga-epyqq-rpyglgle-340[dgtsc] +apwmeclga-aylbw-amyrgle-dglylagle-210[iumzy] +ydjuhdqjyedqb-rkddo-sedjqydcudj-738[ycbmx] +iuxxuyobk-xgjougizobk-pkrrehkgt-sgtgmksktz-644[pzsmw] +bnmrtldq-fqzcd-bgnbnkzsd-vnqjrgno-521[nbdqg] +wfruflnsl-gzssd-wjhjnansl-177[wtmsg] +yhwooebeaz-ywjzu-klanwpekjo-680[eowaj] +pynffvsvrq-cynfgvp-tenff-ernpdhvfvgvba-663[vbduy] +zilqwikbqdm-ntwemz-uizsmbqvo-356[yhenq] +jvsvymbs-zjhclunly-obua-jvuahputlua-721[uajlv] +fhezusjybu-rqiauj-tufbeocudj-400[ecamb] +ftzgxmbv-wrx-xgzbgxxkbgz-293[xgbzf] +chnylhuncihuf-xsy-xypyfijgyhn-578[jigcy] +vhkkhlbox-pxtihgbsxw-cxeeruxtg-wxlbzg-111[hsuty] +foadouwbu-tzcksf-gozsg-246[ofgsu] +xzwrmkbqtm-moo-nqvivkqvo-434[moqvk] +gvaaz-cvooz-dpoubjonfou-415[mcnzb] +pbafhzre-tenqr-enoovg-grpuabybtl-169[bktjl] +uwtojhynqj-gzssd-ywfnsnsl-723[phguv] +dlhwvupglk-zjhclunly-obua-klwhyatlua-227[luahk] +vhkkhlbox-vhehkyne-vahvhetmx-ybgtgvbgz-215[hvbeg] +qlm-pbzobq-gbiivybxk-lmboxqflkp-809[blqik] +forwcoqhwjs-qvcqczohs-ghcfous-792[mtuqn] +eqpuwogt-itcfg-dwppa-fgrnqaogpv-570[gpafo] +lxuxaodu-bljenwpna-qdwc-jwjuhbrb-121[rbqfd] +ykhknbqh-xqjju-oanreyao-680[ahjkn] +ugfkmewj-yjsvw-hdsklau-yjskk-kzahhafy-918[kahjs] +gbc-frperg-fpniratre-uhag-fnyrf-897[dskta] +myxcewob-qbkno-lexxi-wkxkqowoxd-770[spdoc] +cqwdujys-fbqijys-whqii-huiuqhsx-998[uhebs] +ckgvutofkj-igtje-iugzotm-rghuxgzuxe-774[gutei] +excdklvo-lexxi-psxkxmsxq-302[ypsmx] +mbiyqoxsm-dyz-combod-mkxni-mykdsxq-zebmrkcsxq-692[fnhpz] +zlkprjbo-doxab-gbiivybxk-xkxivpfp-809[ydtxn] +wdjcvuvmyjpn-ezggtwzvi-hvmfzodib-603[vzdgi] +njmjubsz-hsbef-fhh-bobmztjt-649[mxkjw] +wsvsdkbi-qbkno-oqq-ecob-docdsxq-796[rglok] +htsxzrjw-lwfij-gfxpjy-fsfqdxnx-307[uyteb] +wpuvcdng-ejqeqncvg-yqtmujqr-882[svamn] +tagzsrsjvgmk-hdsklau-yjskk-ugflsafewfl-606[tysrn] +kwtwznct-akidmvomz-pcvb-zmamizkp-200[skpom] +dpmpsgvm-dboez-dpbujoh-fohjoffsjoh-311[fknst] +rnqnyfwd-lwfij-hmthtqfyj-xytwflj-567[gzkol] +zntargvp-pnaql-hfre-grfgvat-923[yijbm] +dzczkrip-xiruv-treup-tfrkzex-drerxvdvek-347[vrmsu] +ajyqqgdgcb-afmamjyrc-sqcp-rcqrgle-522[cqagr] +pelbtravp-ohaal-erprvivat-715[jnbmz] +irdgrxzex-sleep-ivrthlzjzkzfe-113[bmsnw] +eqpuwogt-itcfg-tcddkv-fgxgnqrogpv-804[gtcdf] +cvabijtm-moo-ivitgaqa-226[darfu] +ytu-xjhwjy-xhfajsljw-mzsy-zxjw-yjxynsl-281[wzjeb] +fkqbokxqflkxi-yxphbq-obxznrfpfqflk-809[dcasb] +gokzyxsjon-sxdobxkdsyxkv-mkxni-ecob-docdsxq-276[zypso] +ibghopzs-suu-kcfygvcd-402[cgsub] +tfiifjzmv-srjbvk-uvjzxe-581[sovtj] +gntmfefwitzx-gfxpjy-xmnuunsl-619[fnxgm] +lgh-kwujwl-bwddqtwsf-vwhsjlewfl-788[tlejf] +hjgbwuladw-wyy-ghwjslagfk-164[wgahj] +nzwzcqfw-ojp-qtylyntyr-431[ynqtw] +sbejpbdujwf-sbccju-vtfs-uftujoh-909[kujit] +vhkkhlbox-wrx-ftkdxmbgz-241[uwzex] +lahxpnwrl-bljenwpna-qdwc-cajrwrwp-381[yjzno] +lugjuacha-jfumncw-alumm-jolwbumcha-838[uamcj] +gvcskirmg-glsgspexi-jmrergmrk-828[smeyi] +thnulapj-ihzrla-thyrlapun-955[ahlnp] +sno-rdbqds-bzmcx-btrsnldq-rdquhbd-937[dbqrs] +vdzonmhydc-eknvdq-dmfhmddqhmf-781[dmhfn] +iehepwnu-cnwza-xqjju-ykjpwejiajp-368[jepwa] +dfcxsqhwzs-dzoghwq-ufogg-cdsfohwcbg-974[gcdfh] +sbqiiyvyut-tou-jhqydydw-608[okbzs] +htsxzrjw-lwfij-gzssd-uzwhmfxnsl-801[nmtjq] +hvbizodx-rzvkjiduzy-xviyt-yzqzgjkhzio-213[zivyd] +ajmrxjlcren-ljwmh-lxjcrwp-bqryyrwp-745[kheat] +vkppo-shoewudys-tou-udwyduuhydw-556[udowy] +dpotvnfs-hsbef-dmbttjgjfe-gmpxfs-nbslfujoh-363[qapli] +glrcplyrgmlyj-djmucp-qrmpyec-158[clmpr] +emixwvqhml-xtiabqk-oziaa-wxmzibqwva-642[rkpba] +qczcftiz-dzoghwq-ufogg-aofyshwbu-298[lmcuy] +cvabijtm-zilqwikbqdm-akidmvomz-pcvb-nqvivkqvo-746[ynxzo] +pkl-oaynap-acc-wjwhuoeo-134[jxlai] +xjmmjndqz-kgvnodx-bmvnn-rjmfncjk-291[njmdk] +ejpanjwpekjwh-nwxxep-nayaerejc-550[lisvd] +htwwtxnaj-htsxzrjw-lwfij-hfsid-htfynsl-wjfhvznxnynts-541[hntwf] +mbiyqoxsm-mkxni-mykdsxq-crszzsxq-770[zhowm] +rmn-qcapcr-ucynmlgxcb-cee-pcqcypaf-886[cpaem] +rtqlgevkng-ejqeqncvg-fgxgnqrogpv-466[zktns] +fydelmwp-mfyyj-nfdezxpc-dpcgtnp-769[anfej] +yuxufmdk-sdmpq-otaoaxmfq-pqbxakyqzf-742[ohxti] +vxupkizork-igtje-xkgiwaoyozout-592[bmwjf] +veqtekmrk-tvsnigxmpi-gerhc-gsexmrk-gywxsqiv-wivzmgi-802[dglps] +nsyjwsfyntsfq-uqfxynh-lwfxx-ijuqtdrjsy-931[ymnhu] +gifavtkzcv-avccpsvre-fgvirkzfej-841[ypigz] +krxqjijamxdb-kdwwh-mnyjacvnwc-641[krnma] +dszphfojd-ezf-sftfbsdi-805[fdszb] +xmrrq-tmffq-lwuzfgdgyq-372[fqgmr] +tagzsrsjvgmk-xdgowj-vwhsjlewfl-788[gjswl] +lsyrkjkbnyec-mkxni-nofovyzwoxd-614[knoyx] +dwbcjkun-mhn-bjunb-173[mykra] +vhehkyne-vtgwr-nlxk-mxlmbgz-319[eghkl] +bkzrrhehdc-bnqqnrhud-bzmcx-bnzshmf-otqbgzrhmf-677[xaszn] +oxmeeuruqp-bxmefuo-sdmee-abqdmfuaze-248[udtec] +jlidywncfy-mwupyhayl-bohn-uhufsmcm-500[yhmuc] +xjmmjndqz-zbb-mzvxlpdndodji-239[djmzb] +yuxufmdk-sdmpq-omzpk-qzsuzqqduzs-534[ofrpg] +tfejldvi-xiruv-vxx-uvgrikdvek-659[cnesm] +yaxsnlcrun-ajkkrc-anbnjalq-979[nmivs] +tvsnigxmpi-ikk-wivzmgiw-880[agunv] +mrxivrexmsrep-tpewxmg-kveww-viwievgl-698[evwim] +nglmtuex-yehpxk-labiibgz-241[begil] +zuv-ykixkz-ixeumktoi-igtje-iugzotm-aykx-zkyzotm-670[pjybl] +forwcoqhwjs-dzoghwq-ufogg-difqvogwbu-272[xkwoz] +ajyqqgdgcb-qaytclecp-fslr-bcqgel-886[mkvsi] +myxcewob-qbkno-mkxni-mykdsxq-wkbuodsxq-770[zmijb] +uwtojhynqj-kqtbjw-yjhmstqtld-333[jtqhw] +wsvsdkbi-qbkno-lkcuod-dbksxsxq-406[biaoe] +gpbepvxcv-rpcsn-rdpixcv-advxhixrh-895[dcwgp] +muqfedyput-isqludwuh-xkdj-mehaixef-712[betdq] +ckgvutofkj-inuiurgzk-xkgiwaoyozout-956[sazyo] +wfruflnsl-uqfxynh-lwfxx-btwpxmtu-541[fxluw] +qfmcusbwq-rms-igsf-hsghwbu-246[sbfgh] +ynukcajey-nwxxep-qoan-paopejc-602[htmbv] +ujqgywfau-uzgugdslw-jwkwsjuz-138[newms] +yflexwxoalrp-zxkav-cfkxkzfkd-705[ctnsy] +vjpwncrl-lqxlxujcn-mnyuxhvnwc-953[nawmz] +willimcpy-wuhxs-lyuwkocmcncih-786[cilwh] +mtzslklcozfd-clmmte-cpnptgtyr-119[tjkgv] +xlrypetn-awldetn-rcldd-cplnbftdtetzy-795[tdlen] +vkppo-rqiauj-huqsgkyiyjyed-452[yijkp] +vxupkizork-lruckx-jkbkruvsktz-124[eumyz] +diozmivodjivg-agjrzm-nzmqdxzn-915[otpfl] +owshgfarwv-hdsklau-yjskk-klgjsyw-918[qcjim] +zuv-ykixkz-igtje-iugzotm-zkinturume-202[plvqf] +zlilocri-oxyyfq-bkdfkbbofkd-835[bswmn] +ziuxioqvo-lgm-amzdqkma-798[maioq] +xqvwdeoh-sodvwlf-judvv-ghyhorsphqw-517[hvdow] +ovbunmneqbhf-enqvbnpgvir-onfxrg-qrfvta-507[nvbfq] +gbc-frperg-pnaql-genvavat-351[pmzkq] +eadalsjq-yjsvw-jsttal-suimakalagf-580[zjghy] +rdadguja-rpcsn-rdpixcv-apqdgpidgn-245[dpagr] +tbxmlkfwba-pzxsbkdbo-erkq-abpfdk-523[vifrq] +ocipgvke-uecxgpigt-jwpv-ugtxkegu-544[abfsh] +ovbunmneqbhf-zvyvgnel-tenqr-wryylorna-ybtvfgvpf-481[hxymg] +pinovwgz-xjinphzm-bmvyz-agjrzm-ozxcijgjbt-681[cqlnu] +tinnm-qobrm-ghcfous-220[hyczt] +iuruxlar-yigbktmkx-natz-ykxboiky-748[kixya] +bkzrrhehdc-bzmcx-bnzshmf-cdrhfm-209[hbcmr] +gpsxdprixkt-tvv-uxcpcrxcv-973[xcpvr] +forwcoqhwjs-rms-hfowbwbu-974[stzrm] +zovldbkfz-fkqbokxqflkxi-mixpqfz-doxpp-cfkxkzfkd-705[tsmfo] +vetllbybxw-lvtoxgzxk-angm-ftgtzxfxgm-371[sbemy] +hwbba-ejqeqncvg-tgugctej-232[iyrqv] +vqr-ugetgv-lgnnadgcp-wugt-vguvkpi-596[gvunp] +xgvnndadzy-wpiit-yzndbi-343[rawyd] +jxdkbqfz-oxyyfq-qbzeklildv-107[qbdfk] +wlsiayhcw-luvvcn-mufym-656[jbvne] +surmhfwloh-fdqgb-ghvljq-621[ymnve] +mvkccspson-bkllsd-vklybkdybi-432[yscux] +dszphfojd-sbccju-dvtupnfs-tfswjdf-129[itbfs] +lsyrkjkbnyec-lexxi-crszzsxq-978[sxcek] +qlm-pbzobq-mixpqfz-doxpp-zlkqxfkjbkq-211[satyb] +bknsykmdsfo-nio-kmaescsdsyx-744[tspif] +bpvctixr-rpcsn-rjhidbtg-htgkxrt-713[rtbcg] +sebehvkb-rqiauj-udwyduuhydw-140[udbeh] +zhdsrqlchg-fdqgb-hqjlqhhulqj-387[zptrs] +qxdwpopgsdjh-rpcsn-sthxvc-635[nbixj] +pualyuhapvuhs-msvdly-klzpnu-721[ulpah] +sbqiiyvyut-shoewudys-isqludwuh-xkdj-jhqydydw-894[dysuh] +wsvsdkbi-qbkno-lexxi-dbksxsxq-614[onzwh] +ydjuhdqjyedqb-rqiauj-efuhqjyedi-894[ocdpe] +kwzzwaqdm-ntwemz-wxmzibqwva-434[nwzml] +qspkfdujmf-fhh-nbobhfnfou-571[zpyau] +bxaxipgn-vgpst-tvv-detgpixdch-583[xwiac] +qfmcusbwq-dfcxsqhwzs-xszzmpsob-fsqswjwbu-402[lstrx] +dpmpsgvm-dboez-sfdfjwjoh-337[dfjmo] +dzoghwq-ufogg-fsgsofqv-636[gfoqs] +nzwzcqfw-dnlgpyrpc-sfye-qtylyntyr-509[milhd] +xgsvgmotm-pkrrehkgt-vaxingyotm-176[jubcm] +xgsvgmotm-jek-cuxqynuv-644[soxwn] +cxy-bnlanc-lahxpnwrl-kdwwh-fxatbqxy-485[zamhj] +irgyyolokj-inuiurgzk-sgtgmksktz-982[vzkrq] +xgvnndadzy-xcjxjgvoz-xjiovdihzio-733[ozhyu] +gvcskirmg-nippcfier-xiglrspskc-334[bastq] +zlilocri-gbiivybxk-obxznrfpfqflk-367[ntyda] +pyknyegle-pyzzgr-pcqcypaf-886[nxvzy] +zhdsrqlchg-gbh-frqwdlqphqw-361[nqzts] +kyelcrga-cee-yaosgqgrgml-808[izdqr] +hplazytkpo-prr-cpnptgtyr-379[prtya] diff --git a/pytudes/data/advent2016/input6.txt b/pytudes/data/advent2016/input6.txt new file mode 100644 index 0000000..84ff7f7 --- /dev/null +++ b/pytudes/data/advent2016/input6.txt @@ -0,0 +1,598 @@ +jtfxgqec +zxoeuddn +anlfufma +dxuuyxkg +ttnewhlw +sjoyeiry +rgfwwdhw +qymxsllk +forftdvy +rzmnmewh +hogawihi +mtsyexba +mrjzqqfk +ypmkexpg +pjuyopgv +rtqquvaj +evubmlrq +bqlrtuce +ndidnbps +vqukosam +mzdyfkcd +rrbwdimb +uhnvxgly +aaimxpcv +acxvinqj +muaeikzy +lhzbosjd +fflqqiit +unfhzfrs +gmwoyvob +cculubmy +zqbugcwa +ijouicwt +bildjjww +ugksmnps +ivawibvu +igzteede +foehssxo +pkeevvlt +xumuixyw +okhhtycj +xhblffye +iqapgjqe +lkhpntum +wuzxgwow +bkkpfguu +bnqctsdi +cwncjrwn +eivhabsi +bwdicgfm +kowiourk +dhbzuztx +gibitfxo +wmrlhenb +wfzmjvwh +zddjirfg +fafhmiwf +ddhvufhg +qdwnlzqp +nhsnngut +uacmfgop +morcixux +sfdxrgqy +tezzvctv +dnnmtkfp +dygdzcib +efurreri +npvpklix +svpbdgyw +mcntltzd +inwkhxlx +sajfgeoi +nwkqrspt +qtzqsksv +mtncajjk +etarsvxr +eyaeeauy +gqnctylg +uerywmma +hjrxhtjb +zdsdyfzp +zhgrrhvd +yvxqyalf +rlgwftff +xczvgpzq +yydydclu +rzltbrro +jforpzau +zskadlfz +dqbqdsgv +bcwjltvc +byfoamgd +cpefdmso +ocuetyke +vlqrfnpp +ggikwydh +eakpyuov +osaguhlz +ylmrfvee +nvdvqpzm +pudbbuhh +bwmqdpyv +proscvgy +cetkcpjw +sbhcqeya +fgnyltmf +qcspgopp +bdhnemmy +tczkhihl +yduxunvr +dtxerncl +xnxeaayt +rvlcbgts +vpavzjqs +oueloufw +mubbhyna +nptmeppg +ojjfbuzz +lusboycs +gurmmorr +kefddaka +cpvpszit +bfvthzpm +owgcvdjo +simxphmv +rxedvjyw +hmeieuxr +vgqhcapz +vwtvbain +aobnhdsx +hkpshsjs +jxgegczu +xbsfxesk +pqhifeaj +triurorr +rnkufaxl +hmrqfoaw +veghzoxa +zbvgbpcm +rqrnbylj +txaawlta +uuksnfel +jqvycrvw +cdttmdpc +wojvbrzp +qvnuinon +gnpguyvh +cgbkpzbu +pdaqhlan +muiykslt +prvzlunm +whhcrchz +cahjhrkl +zifdgfpq +wanlienf +sfrnozvi +mwmykvyh +fbdfzgut +wfrviilb +ucaopfgo +fjhuikma +hdmizjdj +xngpfwvn +rueojtjg +xvtssxtx +vvcgzidf +xtehcxki +xksbfbso +osnzpqmy +isrnjkxh +utleakmz +dthmtbdt +plregxuh +amoeprsy +tmyhzhqd +csxqavbe +jmojlysw +slebxnbl +ldzryqmj +ajejyudk +ynhgnjhw +mdibxxxw +rvtcmesd +jmnwqddq +hppfoplc +nrcbjynz +kcqnjzue +mthvgjxm +ykztdbcv +etqqnhuz +tezkopgq +fwhwkqmz +fozpkzfy +hbbtlcog +hdvjqwyh +xuljsrvz +abskreoo +aedeydgc +dcyigvqf +ntpcvvgk +iiwgzkhl +zofhlqlx +veumtlae +qibdapwq +xpgpwirt +wvnnautq +wfhlgmdg +yqcrvdgx +srdufrbu +vycrvkpx +flwxzkim +enxayqxm +dgpntiaj +qedfutmp +vfdovine +dgrvjfjt +dqxxjahk +hnxpblyp +nnadwbsc +krmqqgwf +efykkzeb +lkrmrwqw +vfzayrwt +chopbnyf +vbydrtln +azmlestl +sqcyddvi +zdcubjok +afshwptc +sjgpuoch +bnfylydl +rsyxsbzi +psyuvyzx +npngqypd +xejayhdk +aqfmvjfi +tpffksph +uekwkjnj +ljsjimwm +hbgzjlig +ngssshxx +icitlosb +unxryqyt +nzpujfti +lupxnzhe +kxglfnic +ecewosbs +htlqxpiq +clqgnyfd +yyiozvar +mbvjgmyc +srhwhlin +casmlryr +ebuzskkp +iewhdqtr +oyidcobe +avptvltf +mfheqaxl +shqnezrq +xrpkzuvb +soxdjwba +aitmzlds +rpmpozpd +ccgxauky +gsstsjyx +bzeolqal +vfhddmuc +wfbbmqfv +pumxmnhj +qumdxkns +xymraott +uthlccig +ezpalags +giftxymr +ujjacleo +cgwgmktp +istetgdl +azedmaao +bnlfwyoq +orcwhbek +amswhkum +yxupesxu +mlzvqsrg +solkxzby +tbaxnjdu +xwbsiquk +hsftntsn +ajraaorz +mwmycrff +ymnbrbpj +uyfscatq +kzkgmbeh +libgpgnr +kxlgthxc +vzjbobyx +isqessab +ehursvof +guwrjnbi +xivkphwn +rurrmdmi +nqijeuzq +jambocej +qrtidktb +sbzvehmq +aikgzrsq +lgydnujf +twafyzry +nxhtklba +xhyaqyqe +xgvdfcrf +wdieppsd +iabrfmdm +doijaavc +oxydttkg +qsqiofwv +titrvjym +mwojqcku +tewiyhjx +jlqbksqd +knycvoks +tmcbnvhv +ekksoxmz +mgvommal +hrosnzeu +fzeymbek +evqxcukn +ilkpvdvl +rclpjbkb +tdpitlei +zvvzuucc +pzdgwnfz +mralxxlz +wywkawzh +hmazaakd +llltvbex +ihsmefpz +rzzgkjyz +srjqpeoq +jrczcdna +uuyskwop +yeuiaepa +vzppcwnn +oqhxixdo +xkwpfsij +cmsoiogl +ngbmaeue +lmqttyrj +yhgjxfmx +lwfgjnyp +ibbkjgra +gaxsotzr +paugisvs +pcqqauqi +pweuwnqs +jcbrscrj +ovtsgcnh +oscsgtqn +hkpwmhwk +pmdgwclk +owmskdhh +qutyussr +atdkvmzl +oqslriwe +wafjwfxp +ipcqlsxv +kzurbnoh +lfhfzwqo +ucybqwrj +tgnblzgm +lhwlniea +tlxymfbu +bcyvlkvt +glpacpjk +rjagzpnu +fyjpvhaq +cjtzwtdu +dkaqawts +pjoovtlv +xsnwqixw +swcftfed +cadigksp +fnsmxccx +cbxmdxvb +hpyqnpjq +jzpvphmo +kdkpubul +kiajwwta +uyeuctbe +yetyzqxw +fgeemnbl +brprbvgj +xszwwlea +ygunyguo +jwplrcbq +fejndxnx +oxsmkcqm +ldwkbpsk +cmzuxrst +jaoadiiu +oxcpkgbc +nyulhuci +bdwfqtkv +ehxvnzyd +cizuemsb +lbqyqduk +kqweswcd +tqnicuzh +utyaiaeu +osjdgvtj +qmrxcaoa +qiltxgvv +qklfgyss +lpjebmuo +bvebkous +yifrmeoa +jzgntlep +wadcknde +kaikclag +tucuhehr +bvwhuwzn +uvlecxgy +rzyxjhmo +dyyfwjgv +vocjkohi +ylyflktq +raltxpqg +eitypruw +pfbmopgm +qerushjt +xykophcv +amjhrlhi +uqkjhdhn +kkohprfw +hvsmtnfd +uxgiqmqc +npxwplcj +ltchgces +exiyyief +ysmvbqso +zpyvuhqz +lkvwronk +vxilskkl +cxfypwcd +jhrczkmf +rdedtejq +gmxcrlzi +jumwfmnn +gkynzdtd +dfdkxggc +yldclxhz +fsxvbwyj +ioiupzio +lxyqvncv +rsgsviny +osgcimej +tecqrgkq +tozohtwt +kmlowfrf +hhpiukqe +xlxlkjwf +ntvtoexx +zzvsvdow +yluidajg +vumkynvp +vaxipwwg +pqymmoif +sgjzogut +jppwszzn +gvvaibqu +lwjotuil +srflotab +ibnblmjm +kvcsdivb +wqrpzmvr +gcmqdezs +vrizdyfo +vtqnsjbf +jwocjmvb +fjkiiowl +ctjhmmrq +pcckqfki +wqolxgfg +gbsdyrbc +giqmfqwb +fodfpvyl +nxdzwvzz +hpnatltw +adjjyhjd +aoguhvmv +yyeanoir +baojaygs +ovkebbjb +pmykvfex +zeooykoa +uuozuxjb +kxxvbhbr +jxbchjlr +qhiwdonk +dnvfwwfh +kjfrlslh +wionbrdf +qgkjarob +kwplsxso +txgelygh +vlmziqwf +wbetqqkp +qfkocear +wrvonhyr +sbiqrcri +lnwzitce +bctyrwph +kallfwzc +zfqwanet +bevnljjr +kwqsktan +gjviqwlu +zflsnpig +wzaufqvr +uvxhutav +diejbica +ojciaexn +zyjoxrwi +djkodeiz +gsinkcqk +jkonssuq +eychyabp +fkcogwnr +kkioyrnn +inqxlztu +cqnbxxks +ipwmpdmm +moozfajm +irjaimrw +ojihmanb +hzoszxzc +ajjvxqqi +ohkfkijd +nlsahrpv +zizxtmxa +gjtnrurd +pyqghfuj +fltnnyfe +goxagvfp +nplhpkiy +dlwgyvby +fzrfhcgh +zaiuostp +jdjojfkw +thksqbjh +qopcwnht +ewkljwho +qguaeaac +wxzzxgcc +nlnuuhdu +ihtzrqay +nmtdbkhp +yasxhulm +drzjobfy +qpgcjdxn +aegbxmjb +bbuxsffr +zevjcgzn +pgbqezxk +qdlepjko +zbtzvicm +ssjdcggg +ugrtxalo +tsbvnppt +rboleppu +gywfqiwz +skgzeqhu +hzuggbcf +dkegaxap +zijcjrkm +jtfkeoog +fyvtrvig +gophbeoj +ieatnihe +vlaauxgz +mxnheqkz +mftwybny +ebawojuj +dyrvecbs +lrrcwang +qswijdeu +wkuszdax +ecaokzfc +pmbznspx +tjqrztdv +mwdxruge +whutfdqy +zpfwqvox +fkqapoid +bodleqbn +kpxiuodk +johmsncc +enhamlol +yhtydoss diff --git a/pytudes/data/advent2016/input7.txt b/pytudes/data/advent2016/input7.txt new file mode 100644 index 0000000..19f8fdc --- /dev/null +++ b/pytudes/data/advent2016/input7.txt @@ -0,0 +1,2000 @@ +rhamaeovmbheijj[hkwbkqzlcscwjkyjulk]ajsxfuemamuqcjccbc +gdlrknrmexvaypu[crqappbbcaplkkzb]vhvkjyadjsryysvj[nbvypeadikilcwg]jwxlimrgakadpxu[dgoanojvdvwfabtt]yqsalmulblolkgsheo +dqpthtgufgzjojuvzvm[eejdhpcqyiydwod]iingwezvcbtowwzc[uzlxaqenhgsebqskn]wcucfmnlarrvdceuxqc[dkwcsxeitcobaylhbvc]klxammurpqgmpsxsr +gmmfbtpprishiujnpdi[wedykxqyntvrkfdzom]uidgvubnregvorgnhm +txxplravpgztjqcw[txgmmtlhmqpmmwp]bmhfgpmafxqwtrpr[inntmjmgqothdzfqgxq]cvtwvembpvdmcvk +gkxjhpayoyrrpcr[mwyoahlkqyhtznyzrm]mvmurvsrgjunjjepn[mkoumuohilpcfgbmsmh]hpwggyvjkusjxcyojyr[wqxyuzbewpjzlyqmkhw]nniczueulxtdsmkniex +vuzyoofrvaanszwndyt[mzcbhmabgnetrpje]tqnygwhmwrbyosbke[gehqzyhlnyufknqmueo]ngendggbjcvazwol +vdnploylmxnipfudw[pbkxlaozhqhlbzz]kpxnzwjhybgcenyw[fpukiqrjraomftt]rosyxtsdltbsmhykxu[wrucjfwuyypmiic]ydnbgvicfnmwzuatudd +lknaffpzamlkufgt[uvdgeatxkofgoyoi]ajtqcsfdarjrddrzo[bxrcozuxifgevmog]rlyfschtnrklzufjzm +kajqeqlafxtmzirn[mkftybdukmghmyoclxd]plvjnikiozkikifpodt[cmufoktkndkhaeqbztz]drjixnnsdxqnrmn[cmzsnhlirtskunngcee]upgxlcjhmoethppx +joibiixuzgtkjquor[xmnqotlqrhpvlglwaxe]kjmfrpihitjydwda +kouyuiijgsmpzynmt[xvwuujrfkqjmtqdh]ukjscwcnwktrfvrmvew[quzbelbcfxknvqc]drtrmvnabjkslahadad +hhlcltfpiwfjhguif[rpasuqltkbudhwjeew]mkcmvbxqukjczex +xxqceycviwyzqxekn[tiidftrsnlgpesxlf]obtbqfgogpwkoqow[dabhpdntfvbhgtmupy]hbvtghnycgyywavqbtg +zlqdqmuxebccmndzbl[ykefimjzdqdmfvlflj]ptlphteflzxmolkof +babzuaikmedruqsuuv[emlhynmvfhsigdryo]iyblsqlpplrlahtwr +byddropvzudnjciymyh[jcebyxyvikkshpn]ggmrxgkzsrfkfkzo +ektijwczwnlancuqfv[luqhtfgwmlilhwnk]gxgivxlnerdhbhetfz[bzczfdorrsptzikjmct]mfrsvxgxijtusmvjd[sbpnwycbrykuhsinudc]bmpikuskzlxcoidp +igefoemugshofmibco[uhahihzaglmzdpzjvfp]tfbuuhoughgismec[inbtuzxnxekfkulodyk]fxykxfkfnjvswwc +onmmhtsykubbpdiqvjm[kbfbiyjyuzmemaomkwa]prqwqocsihfnslooel[hysggeprqecalydywlk]taghiwhgnujsduhnffu[ibpvowghgttfsvt]wcajwcxhcriflxi +evvhkvndeoxrrftqmih[ckxjgqvpdxjvmbwsor]odolgenlgaxujvqg[qyrnnrjgxskuxycoip]jvtjgwaaywdphxpy +fffaewoawlzsmnqo[ubnpbqpxgenzjiytml]ztberlzwpzdvofcwo +vhrwunprhbpclog[vqtnbjndcwpuyen]vzuudswovzmjviee +yfeztpcfgazkijht[xqcjocbnjmvvrzg]maisokokpukpstgpj +neudpatmnjayamydbrd[heckokdparzefxm]qulfvfivofznkyvkwq[owjrktbaejpffqef]oserqezusmubsertq +ykgyzyqlodjvgqzmzy[ewsxadkknhduejft]yysinlpnxpaqdai[hqagzwigkpvzsje]auibbpljfmkoxaskuh +kntmgvoypnpibjtp[ispxkdofjsdufpivwrj]ndecwlfcbjtrnrzw +pvjsstffnygbjafe[ztrjbalsthujslnitl]xjsoqghvrjncejwww[khwjgywxyglvhgz]kaxctpvhleqfmlm +ovbgzhzmenxocuvdhwk[mzfbtwpwnttyeykuwzo]qrmyqzvxetjbrhossb[tjvdprzdgjgdvjygpnp]bgkkrcsrmfrsrtahxus[owipixzcqisqapz]fsbkjqgxuimcbur +mbweohfcgybqcqnl[yafsvfrduertfqze]hqaodhzkmhzmlrxuc[bytcgnvzvoovirqwn]njivpwgkkqvgowpenh[erodavzscuubhea]gizvzrqjzhkikhb +azrzthfimarcdbk[usfjkmhedaqpfnisek]yqowqlqvlranjjvbauq[korlrbzcgrneashdrrq]fjicirnofvlrlnnkeqb[ktlfmzrqxcntvasev]urpuwoiogtcwskygxz +htuzgcmjixiaofnm[mbmrnxkedkrjqwff]srvmeadhvwftjmx[vqkaxjmugwdmwcqlg]qxzxczyoqnkcaoqmsd +qywanrnotepsgufhr[hsmvibiybrxwabambm]tdwinkqnjvirhgx +cfurhuhjrbxqoefybl[kdcazzlfacaurqguqkz]yufsmycojcxiiomwteo[zcnzchsersrsapze]bhkpjaybdyilwdomfr[ddbxqanevcpjuodnj]ttmxojmazfqzqxlz +xfpeuaftjtjzzyrlw[vxklxjatlbpevalmb]klpxbsifaszxapsosjq[kjzdnfadnybfnfvm]kodbuiigbiqdbarr[vkgxvvccoyknqcg]yusyefeqfqjkcmnrfd +welumvdtzozzqkc[xunvcqdbwitokoerg]euvhbecekwaszsmxu[xrffdzabspotehwg]uqzwhrvygasatdaphac[xexwfcsgfyvciqdu]kioaakhmpgudcsrgnqh +bvirojodecjwgsfr[xezdftvafflhsabc]dlsuqqzkekwsmgyz +xxnrooghjqtrtkmhr[xhjrmkybtnsrdkp]krhveuyzhsnfrkxq +fzgdyuackwckqwg[jcdyvdcmrqxizkqxhke]gkfhkoqwqvkfxgj[wfxghxhkbhxhfnscjy]tdpidwqwryxlubtg[ptldartinsqinuymsc]tglyhrzvexdqkkxrer +qjmlxlnqzipdflotzl[mwewadvcvkoqjlvlruk]aciqxygnygyordpcvc[sirhqhrjopudmfub]kxexybjqhmqmukxmpug[bbvccqpfdebfmnvald]lgqcpzwrjzlhdcalvxh +gytjulsxixxkwhtwts[bmwcdokbhvwmzvpths]amvwsotxkvsjszzk[rnbbbelvqlqxdckpgf]mfoelmolxsbibcyss[rhqarjczvrulkfd]smrmbwtejyrtbuxw +yzlhtplfmpcelnlnfgo[czpwiwgzcuyingho]biwyfjhjxyaougycvdk +nyqhnhedzzlbyucj[ahtgwmsprvxrhzkb]jutcnlfuavbirrvbe[oybwrlquyqzhlekfj]ngfnydtkqpdyusyk[ojxstfhzjmohguhnq]tupjbscsqbvxtrgah +pktcuxqmiitdhfgja[urxogoqmprdhdod]rynibylhjlnummesvrt +yetjrczvtanwejhw[fzqzeqjxwqqvpuc]nxjwkjqetsqmfxvjyg[fvyucxjhkszsvzhg]pashbrmyrjwpsii +wrckfismggcluob[npzqpmftqwrntqh]jxusszbprbpawih[fpajhvucmcqbcodx]ebyukjvtjancdyauw[qowzzdtnwcttqmj]szzphzxntcrdllh +tiuxthoqxxcdjolpw[xwmkhxrufrnidpzcmqn]bgtqysjkqdyoarlioc[xepsnctwhctkvkcoux]ytveeannchgdrwy[rqulamirtszjpur]pqpdocnfwnxcklwdkj +knhexvmvgxbxazws[pgqvyqcafalkmitovbo]nkvxvhujdjntxkwvb +njgihlbuvtogchsr[krsfdyuxkjpbtyqpth]isbqmarqmczgwxcavcn[vbnyzzkztdbmcfwuvv]pcadjqqhwticmggako +lbjyzlehzcbkfkaxxbi[thjzncmjahzoioaxkec]odpqwbtyioalhdpln[adgbscuhmxwnocaf]zkkncvglgshdpdvyd +hkehqhsovznpvbswih[opzxtethoiygsform]qqfpojzvraiqodrcxl[ovbkowvnnmmrpxkxgb]pacjulmvfjulpmusmb +svagyqkejbghvrwjr[zhcbaehiqhsxkeggjae]kcpnpfidebpzbmsprow +rxnqsxoxnfpnorci[zmwairvwgjnwhwllby]jtfuevbybpfyzck[pzckttxojhgqbame]kksmvjkwxluybydp[rvtglycwefrngwlxuok]nsnbgptselpykejj +avwfrsrtlqyurykdh[ogdjcdswzzgdzccjky]qqlcnsnrnhasqkdv[dgycbwlbkblmatzzj]dshdkjbwaurjngilk +toverwzrqnnonuvckoh[djsmkldxbwjbhgjnhj]vnudkekbeegljwxwsmw[pkxakvorxhwibjiz]yefrfdpzofzprngi +ljiwgubplllnvaph[yuzecfphjkuhzsvbn]lcnyltmstziygmmbqq[xmvtnprtazfzedzril]tnbvxnqbjsguqckia[kfgbtyxgkdfzfvl]zvbvxbhntspktdyuia +rknzylpqhgyblkqyapv[rlsevieskysudpz]zrqytaurmscvewhx +ygvvlhyvybzurxscqxn[wpejtafceksukwwjpj]edsawjqusqcncfpne +whpfhldfvqdkdevzcy[xetsfwodsropiymka]dulqatggkfpfjay[vwgpvysckcyiwloy]tvcztqlixnspgnvtzyw +nnevzrqtilosoamp[korgdgnaogoonln]ojjmrvbhjjylrnc[dzpncsqmuzsykyyxlru]ruvcsmwpqvsgkrd[ivjfkyskzxjlodhrcf]gaohcofquvhuyyu +awhprneuruwjztxtmwf[wcpcdlweyrmpkrvdyjh]cdaonqghxbsvtnt +ntccvvcydxruscdr[wjrmhzszobaebuu]vrbeofykukjwjphhp[ujsccnrjhwpzbhbssn]macvtmbchbanwchh +fadqomfsupaiapqufz[znkymlxtlllwvnp]nbhbfeabfhhnlean +mwjhskllhfkyzfgmse[ldegjvgoybxqqjirkul]dacztqtrjzyzezf[hrekjyxytlgnexn]xgupvycugxrwncruiua +ooldrugmiekmgizgzdh[ozhtqqczghctjoevzyx]ztoepnjmqwxazxspeeq[vbkkeecbzyjohddlal]zjxplybtpamkpsbtvb[hcmmumzyeufosnzrm]fzqgpczaiwqzmhaxurj +snwnqixjgwhcrpfeun[mvseymbltdzywnw]xbogzgtddtzzadgsrin[sibgoazaxuyfaaf]tdtrrjbxjzusuvzogpa[etytgiqwoyxevcq]ifanoaaqoldczzj +txwincbntmaddlmous[qnoqrahfvzcyknc]lyxgbednzodetdivvqa +laqkpspaxfqdpnrr[sskaqoytvzoxubh]viaivwettzucesoz[lfyzcvouvgaiavpxnqt]lqoedmocedvtgehdeok[gceosyhfjabmrgdhyve]fstmrfbyesmoeuzjzd +ubmtbxlcwzyjxkq[bdcpucmtupuahyhrg]qbacwmgpwrgwehhcley[vjrphfuixndpcqvlrx]myyojfenvnbulfpfvm[ebskbwkmpfpicpii]jqcknedxkvofewgb +qdltorftziarmsmblzd[jkdgiezykxormlrhf]dudsablawcevrgc[udxosudcterktvqs]mmgdispwsohszhaijkr +uqtanrclojcfacvbcq[pzkjktkncsqosczeqt]qlfpmwxfgosekmasaj[jtlzdjlllfzdbph]hrexthazwiykycquzf[mkunxvcgzvxkiisy]ckkkvrtygxrdkhl +ruotffmomhcedick[dmnfkrkkwmcpclit]wasvoffbvwbqxzqkry[lgpydbqfvzavjjjh]goxeyzauaitzyuoyf +avbqacrbszphimkgl[leemowpsauxeytdcqlv]drltanwwwpxqydt[fkckmeonkmfcckcdyiy]vgrqluieesnrxehopqk[qpofuybpxohvubnbo]nkqkzyumipccfhhnptm +bcocswwxbpcrscral[zrffpdwqlffhxdbocop]fsnlztdroztjsikft +pjxihfkytmmrowclw[savrpenougddqkuq]kfqivyjzfrpfwlftnq[tageosesgmlsmshmv]gjbgdqnwiwnltear[uoxbvzhexqonkbu]ivryntlnapjjlpgwv +vjkvkjxswlamgvcw[ybrhbbrbjzojpwlvl]btdqklkxxdhnnfiqqmv[fqksqdobgdlklrwnuc]tpdcfuyvmpksrqallb +xzikvuztmnvdqqf[uivapwxumjyrgvcboo]lavrjlftjbexetfuf[uwnhovxuzlhdndhkg]dpczhksmhvlrmcj[ulcbhpvovdolyarz]ojjkmzerdytbzvp +hclgiouyfswdbwnti[nnwaflbcxvbbthsl]pxjjmisxbyiwmuqr +fwfkxuhyfdnvvwqezf[dmeokyoipdwltkpg]ddnolvbvgpusjsa[vpoclwplrjknllhryu]rmqeqgagcqmofnps[yvhjhsmgddqtkde]kjijabccyvpsrszs +jjtbppqfxshylfxwgk[lfwaleyvjukiuzpozij]ukepogmlcsxhfcx[prcunmlrcsvxdjd]mgerqzbqgxqexiqlg[zrmwvhevfcweixuex]fxdjurxhhfdvuikdn +eawekhvzawymmdzms[kzhfljimwaqrbvv]dtherbwgzcqrrbharfa +eyojauyxcrmzoqcqp[wxfhnyocnlbdajjwdzx]uywdludrfcaregojvlx[yrnenbzjowzhlqzkuk]iapeyfowndzpwgtw[nthkukeqpebwhdxekte]dxktirqzurivkqegnsr +azdmtszcptojcctn[iusriojbrvjjlydv]qizrtjmzmjbmwgod[hbtonbvuffuhelmdip]kwcfekfqlhqpueir +ctfdidpiwnnprnvnutp[lhlgiglwifvarkhbwuw]isarjxgvutokogi[etyigiqpfthpahnmd]izzwglokkvycageup[tyvnjnuluevhadlop]awzveqfsbhbgysco +hpxtzoultqvmtkffpb[dokdhhnjxmscoplm]rqfnolhnrxvnozjdv +dgcgifmrdaalcgcezk[ahmebeklyswhtnxlht]iayodwnhtczfccw[epxnlylxxvjpntgcj]ikqsmqghefhjgnumyn +wzmjnahgxidsrxhm[lcuntbdddrdpcrop]sqjwrkyelgfgkietb[olqqubshqcarkfa]xpydoavvjjzewcsxc[qzspebtniqsymfjik]dnqzxclkluzfsawdfxv +audcrjgzeftljqzw[fzzpqcdxsxiricuds]eyjqrmfwcagyffagqc +btxzsdjmldelvkj[oecrbttgfarihfju]xmdesiupsithszyf[hnsjqvzgoqhkkhoat]qgxxglikazknfcpjelw[qqbnfchiuduqraydibc]agtolrvhctxlheezjxm +piqxruewvmckslykyi[wkvxhrntyrrdgknb]kjbncjxnwqcwvzbpuv[olvhfqgparupktaw]xyidaraeyxgahwkf[yjmpgconpxpeemipaev]spapofeonejskpgt +rwsucmdalgforpx[fptofnnrzpisayej]cyjiuvtyykpvyzpqefv[qpsoezjuvbfbtznfa]iuqyhjibfpneszazjs +tllzzoxwkvksmvrzns[fgnkysetxkybvch]storhozyqfulmet +oacadxafckiudqmfhjo[fsamazbypvswtsgpk]eicndqjzospfxycc[prckjeeekbnutohbwk]ivsbxexsumtllceon +jindledcszfmvquq[eequkemziiktdwwgd]vynsulrblnbldpv[hvehmekmguyhnyr]fpmkwyfzoemssyvh[qwffpztdkkedfipnpm]gmlmkucisbageapvts +woqmosyyvxpfmlnle[hacqqmceujyvgpn]xfmcmokpdozknvxbju[fnrvwiakrfycqwjwo]rxilhfmwmbwbfuha +rzxpewtaxroblzseavt[xnzgqkjlrygoawr]eyhljysneggmabio[hxchodkaancmpwhedyz]okxucbjgxqabvuwmkm +quyfvhjxjrhkxzlgxdi[izgyrfkxrtrhhjqhxh]qoqndbfnisfqnmmn[srpfccbxhvercnc]bnhnfogyaghasifuj +uwpvnobjjapdodvuvcn[tcyadiqhfgvyivfrj]gbxojvfhftssxxw +wsrkdxhlmjrguuusl[bcojcehodsomathk]alirscvtcximlmc[jqkhsmycbmeeobrg]bxkpialtvbaoyyi[sdaazhnofawrugjugkk]uxchzsbcbnaqcpuh +pfarrugbwahulsa[ldhddlvlbjibnvuv]tilarotebpmswyzf[bmpzdqouxybpyquaqx]djzgdyihpmokqwd +zebobuzzdhxrqhrdx[qtxuxqkcskobopgreip]mafakpzsixxtswgbj +ritgoytjhsvejqx[weinhscatdjtrox]wnctxtienkdruwuek[jajgbiwplipjtzz]ziycfhrkulmibaonfr[cukdkfiyvtcwkvmd]zrsfspitfvyouvyp +lvqriqiwhkbrhcqs[djugxnocofekdjwmqj]thmudyjerpzhkdba[oiugxdrwlvhewjjr]blqbylawoxakibn +inbcozwxxvvidqiql[kdcpnksdbyrejmqo]uondaihvtcuvhdi +myokkyhemawvwbkp[dednvcdwlebnmrqvwv]ctcymbkrzawvlaago[lwspfpqgqnoionz]spabgsgwxprvjhvkokl +rexffiwfnspzpmyn[mzvgqvurfjkidzqriqo]mxiihzysexwbttajwz[uunfaunxxyqbrotibf]yzrzzdxihtaxttejgr +afzicsjqtkrxnijyac[ktvvxpacfayamavs]cysvgudsuvohfgfqq[vhexzvcyislgkcux]zrvzapbjmazvhuoqewg +nnooizmnmckfscw[hkuowskeopjsjmwe]jhdbueqlfgpmdopyhm[rvlidktcaoxknsvl]gildtxkvfhnatfxeh[infjbdnojldommqhxo]oxbcsksyguwkkdugg +mmqtlyvushtqihwafvk[mjnrjvhhalkwttra]xufqefhpncyugjddb[kxtjxxeugowjxqxbbr]krhojliwfhavzttfzsd[vgswlmisfnxwythrhi]kwtmlfbkfjtdsuqfxc +lzaluvqdvzusmrpv[qypygkxwzogwejqtax]qyiumeiuoxfxbbq[xscktxkdyhwlayq]gwvtzqrrvjkhovkukm +eslcdaqtfkucqxp[fcyifagugztsyggmk]fetbnjgqbuilwypcdhw[wspzciicbcfpuvfcwd]jzvppaoudhtpznrpqe +rbmhgksoawmvqryer[mshujkyqkoixutlh]qnilyertndnhfbtuhot +fmgtjtptpcgybdxs[oyozzxvclbnangj]znafmnkbhwvijexm[vmeeytrraevvvrnh]vpmfldxpxvruphurx[xpvudayopdhyjkitfb]jvzzhipudpokyuz +tnntncwjwkepyjjj[rhiklabfhxebqoxjjd]nccutnmjduptofslfw[ztvcsayffkslzawquzf]bzicdywymajrjihcc[eaxrssfvhfvbswpqley]itikrgohakoqnmbxv +oxpnarespssxlvbhe[mjactxdxwrjxjoa]aodrhgqmztemdxtbelo[vuslqwnngueagez]olwrulgbcmflenua +gyccymmdplnqvfj[omhfidjspyequep]zntmrvroecllhmijfr[xnegyunervbkkskdxft]cmafcvmcdrqgtcg[gexcgkvwzzxjffe]gldghyxesjixbrogla +gggmbiorxhmyikn[mdgbulsydzjldhpa]uwtdwcegkdlnznn +bnhgjjhtffydhmndkp[lbqolggwsszlyozg]agzyenlcqvnrogy[ekhcwghezpmzaduqr]xzyeaxduqzjrygxneu +yxtilzostvugtfnm[pjktbtpemtuuoew]ffjbtbdbhfzsgnxh[zutqqcmomxqjevc]ckhzcprrfbfitcbfxgd[kxquqirrvhqvddtkb]ijupwzfwguufapi +cyctggsonxaxixcm[tohfyqjcubsndzbrzq]opxdpwdklhbroyhocip[endamtsslfqyzisyaxo]xmptlehqgsuvsytou[ereduvwssofzjlkygd]zkprvanvgbjyggvn +nxktelnubcljypdxkv[xrtzoweqclflkhbwit]eotleemqnyazcjuxgwa[snmdckbgyopkpxunfdt]kenywhabxxddwxwww[jnblykmfrrqoctwavdw]yevwnyhtxqytkeeslmm +txszmuaoxjkvjehv[keshifysmztfwbrnx]izfqdrtaovdmzsp +wmphoqhrtbhtijxq[fbwpvxocpqqtnokrpcq]cmlumbobzfnypghr +vtdxqtvthwjnvkjpsee[kcgyvjhwmqwzbyx]kaezesxvcerwqsp +teqxlduxiirrgnx[zucffwlweaudpri]mzpjffiywjcbnuku +jkqdvfmtbjnmklnmx[hmqoinkpzysxsrktpuo]eguyzxaqkkxuesxprk[hxgrqyycjsnjhrfmfns]pdugqdkbiygczaxy[vvsuyjuhjomhrpfyoea]pdhrjxlxyjiyjyualnj +zojzbjfulrbujunusw[fnunifmehxzbamnfkzd]cbfvuivasqkakmized[vbjpvzpsakndpemroh]tixjxkptjnitrbvr[bxenidaryhykquy]qtoafogjffdctmrx +rwvwgmaqhgqjueicg[bvjvjxgigxyvfixtg]wevbbttexalqtfqg[gurskiiyupflaaoia]weyshamkcasglulxb +xcwjswerfgbbupnrp[tuseefeiwixjqlvp]guyprztjuwxbhxkuhz +inmddvbxbzcapnrjjp[isuwmmfkbawoysuawwm]crqwcnynpuxmpnc[vkryjewmwncajmqnbpt]chngmwwggbyjilmizz +yuihdfbeuocgylfqfr[dvyzcvwfzdmdtlnnl]vpmklsowcbnqhuvl[ayebixlsvkdwjoreyj]ixpbtsawfzyhhpfyes[eviatjhgsxmourwmj]xsodwoouovxauxrknau +fpwvuyqazkzihhw[xrendoqzmhewvop]ktetyabvmujtvffcc[hzyvkrirmjmlrflal]gswncgkujekldvblnw[lfbtpqdmhqoxmegdlpb]jxmulcekdazqavd +hkfcwyjikyfztomcqdh[caeeygfgwrhnlpoboe]bhldovhzlzfkncre +zlbhtywlmsmufziawev[tudpnzttpwgwfqsyiip]gsmtnjikkghasjzbkza[qptaxafyakibdukwgz]kifbubdofpdqxrukibs +lvxbdcwgasppyujx[oqfwissnkbkakmhk]nygncthwjgtvbwaz[veaazsfwgiqduizs]eytzwauysufqsexgt[toakaopkjocdxtpxh]mgmjiaktsovemtzl +xnlqcpdgtkdgnkonwgy[fvyzkqcirtbmfvqsard]rnsffvvzhiikmotoh[bpnyaghincndggsxz]kqjcrdmvkuzeihsmbd[nmyysycixszjrzuxlu]jdswnlosdguqdpja +jdnieroqeduzimxg[apihtfappedmfjwmebn]worvqicbopocech +xyixktzuhugnowdoaz[muuaqgkhheqlkto]tfwvgrwlwrtwozv[nugeofmlhsleukl]tmctqkiphuncroetpek +ovnratuwxpwzcykzpj[foqxyrskkmesltfrwg]yxodjprqnwqemak[ymbbzjpeiqdvdbjlqql]vubqbfvqtpaaejhbjf +rfizkxgnhnvzysv[omwubvxihthnhpfb]ghjoyszouqkvjjcs +vblsthcbmwurcllqht[fghsxxtabklblefkl]blbuqudblkhrokps +zybpfjpahsyjoroypbv[pspmqreykvjrracm]cmtnycrboclakxllp[wedfbvnkdzkjeridt]jzdanlfyrkymuvuf +hjvhopnvvbonrcih[qynsimdpflcjgfvxii]nibjddllyxyeerekprv[ooqcghsavzxkjwhowg]mlrfdizdusszgvjezqe +xxmfnrvvmxvkwcnk[angqlvvvnhhzdaot]xbvxgrukhqkzmjnzi +jtzuxzfnmgmwaxds[exfqygocnapdnyelw]lfvjnpnvewjdldvreg[yjynstmasvuydtzygci]elujbvkkjtnppkdon[ztvmfprwdmypovmh]fcourzlawmpneezhq +tlgpkpcocdfhyiarw[ehknakogvjljkshok]uckpkzxzzmbeslzpyw +mistdegjfgtbbrg[vyzjyxyagemysturc]xympgroewkrbynfj +zeabxmbyoklbutcx[xurfybdchenrzbh]mzjqooejqhutzmbs[kztnsmrisqgcwhnaua]omvjcovqwrcrkjkiexr +oxzletzsngrttcx[pjehxfxfphgfvjktnd]ivupaueotjstxizzjn +ptccmbzycmsydavfxij[lazrpzwnahixpisflpi]rhdvbmwoakmormp[sqsictutmqpipuv]baevorxifbunpxn +flencoljjwnpxse[ptdpigwlfeocmacw]sjuqfwyfdtvmxvl[dwkmzdasdrqgwhgq]idtqdgvwtakvgby[dpsntznqveznfgthmds]sihygmmnpyfzryj +rkjmrunjubfjyjxw[zgweuykyhuwxchxn]beusqwafaiqyiusis[ivqowbexdjlfbjruek]lghaaldsrtqosxco +rklovxjiopapoesl[elwskjmfpdkvhcih]dhkpeigfdcuiikkjw[hqryzvjfoyhqartgew]krpfhfwhjjcyscepd[wykceqswokmkhlsjmyf]dzuspslbrocmmnm +fryazziglugprgfcrdr[moxeblgwqeuvghns]wxibobcvcgpfygza +vnzccxmthrjglqjgiuh[yvuwzxakvwndqxv]vmwkikpdygmkwaurdk[rmqjpvepubstccus]dmrozydiidfceyw +wqxkqopsmhdejcrg[jhknpshwohpnpje]lmtxmkyuyjscmzm[sfsrvcmzctxgzhvink]wpsmecgomyvnjwvbtcx +itcyzdttzvuvqhkik[cescfxncujbknhub]fqsotealuatlwsbqvxn[xwnqysqjyvvzstlpsjp]diyqmxuikszeiejxxcf +aourqwkobsicfstqk[sgnlfieszqpequnh]fkghwhahwnrwwpor[xuaemetxkjaaduqbi]kzwlgxlfvyzoror[ridqaivztpdxzeacj]wpphturgkbpsiwkel +xolzcpuajnkpzoyae[aqcqprvtewmdlwqaleb]hkyjxrqsnndxmeazhe[dfgwjdrpebilinta]ofoggmssczeecqss +swdxibbsmxkivtpx[ztynvlvmolopmji]bdqgjtkmnjlmsjru +hpaiepzmwathlnj[gyupkpzataikzmrud]zwewwulioarborcbp +yohefxiskmqbabbnz[bcyankaddygkumqv]uxvzlfsmushpfgly[htcgkbbcvcqznfg]byuxzaqjrzfldmava[rhyxlnukijhyjtahjps]vqmfvcgpxvjdjvgnch +bozraaeperteyeqyu[dthgzhkjgalzoumuc]gtleiqtncvkdefzv[rsjbjasnseqaeqdsn]oyyytssftyvpssr +wmpzdknivaejaoourhx[gcbcoftyaidwkmcfpfc]wjgdlyyfmcbcmuhb +rfjmjswzmbdqilrwoi[wonhehqoslwkcuzb]mexwmjiczvztuvufbmp[wmlyprqcdprmjmhpukn]mjdqgcsbqgjhruwr[wyvwjsqvmybbwcfrnyh]wbjdjkgqajrwthha +jafuyjvmvnlcyct[mryfhcxsflxqszhupfr]xnifqiwhdkwwcuvycy +kbtwugmbfxmyakkrg[dvvyezeuchxtharp]crfckkuqyhwknfkxn +acmtosqnsqsxkhdrd[jkapzaeusxzibvctt]uscjxyktvaphdkkdaw[tpsekpbdlqmiuoj]qcaudtzfapwuvjzxfxu[zhbsuykivuwguukvl]cqkrjlgbidtjkihjft +lkjjcjauuoogrerw[flrslixtxcaobepjz]irjuforfcjxqakzhlnt[viebkwhwfmtdvbj]emjfmceqvgerepyzpzu +zazhycdeclmwotqqavh[atizwuahmzwbwqao]wafplpfraqshiwrqvn[hoyrsljedqmcrdux]bqnplwvwfsndbxzvd[seixffhhbexvizfz]wrlkgcnfyjyurtftfv +eqeeucxhyzpfiesx[ibdpqscwudjrphylb]ftpdqxskecdumuz +tuaigpyydbbozvymwzi[omnxnrlltcpbzbch]ztdoamraigkkptodpa[ajqpmmnlqllnpdjqz]hnnxyynvacqsvxuhx[qoizstfmkzklrtbnxnx]nwwwmbxyxxaaodhta +fkmisjreyrynhqmnx[kdzbuprwdcttzsiusk]avrtoelpvextcly +dcejlfebrjejetdjmzf[ebtugaezmdvkxdl]babbgplruqqghxseeuj[kdjgtrnnzwffvxa]cevstjlmpskjzeeidz[gjckmdhojxehxuc]nqrngirtlagbwojukb +falbwekyijnufsyrgqm[lgwnlauxjymmzavcws]davusoovwxmwgjo[gzvhlcaikjbuttssdq]wpdnbuvbqozxqvua +jmhaipdyjojoexmgaf[yzeoffzdsyntjpawdah]eknpywjbojoskyiura +peipgvusywbfkfb[dpdvkejzvcnfxubljtf]sjyxhekgywleihjz[xpebncztvxxonwuqt]eitivylwufensob +xaeemympdbdanfy[zqxxxfkqlmqymzx]ssixxpwgisvxftal[twffyxxxzzfwejdo]gawoyoyptgwsuncuds[tnpwtclzavxnshge]rxiwzaghvviuddux +ndmojeftchotsyrui[onrnsftjvrfnxdub]bjbtbwpaxunibohp[vobbfwfgnztwfwk]sakgxnmssejznuym[lrkjfeagimaksllzkw]tzjhoqgstnhiwtfwxv +mkimrczxipnfjoenfyn[cthpigbgurreqaqm]bgvcttpetrjjcrn[wghqiaakyxmldcp]urwutrvkaukluecpf[vcrgtzezdvtjdaqn]avbpyjtujtvmsbkl +kffuasdfmyyckbvcpi[mtlwqooxmdztgraecr]nxxxmblqjctmimlvxyj[kbuygkhxdjcpceg]ezcpukzxpntqfrbwf[lhldwijzzcqidqamcb]bjlitvbbanxtbiu +ktlvgmzwavemrvzlc[guvmortwepibtzbvoe]iomcuyiybkjctwmk[mpaujwsppiwqfnpczk]anomefvhsofxngylnj[kvfesmnytlnjpxldqiw]bpxaqmkkjkqedkjinf +aycmquumrixcpyhx[iglewlmfellbvdk]zqfiuckeyjomazh[wdtngaffbtofmbva]ayjshpmiazzlcjowue[xhwfuanyynpdsezcodq]okoqtpvoyxfqiutag +kxymotzfhlhhbdl[tsbdokfypokswqetm]cxjtuubnqttfiapsbfy +hqjrvqgcycvhzdtfc[gshyzjzeiuyrrfiluow]vufgsnuaifsevwbts[zkzfgyckxtaorpldyls]hvjyzbdfqyykluj[pfpowxclncoirdu]ymoaujufohlhrawpmz +ldyqqxpficsgnsm[rvnztmernrjmvhls]ttduhtgvvmjkiil +zwmxvgenqqbbqihujd[oxtwuouobesowqrao]gnnxgbmaeijeyeh +khkdmxhvmdwdglpqjnq[zpcmwmjvuinqcim]ffzjfwsoxavawvusc[bentinefxinnuqkv]szerswbequtjacvwu[qttnymrwpyhamlubtl]vqnaphbflnmzjqei +fhqsbeixwxbkrnyx[tjmtuauoufrvtmsnvod]znpzvpuvhncqtjt[icgckqkrkwgojirrq]ckxpkdfotnzrfzyldrc +urwjarigxmgmgswtn[xjrjsopzksvzmgjhlrn]pwjsqoxtlshyaxf[axporznuyfctqhi]gvhznwrjrxljgmotleh +quiqiilyzwmxyzbfgux[ocyzjvkyqaqfjoqag]wexivvgdhmslykwwgp +bgsppuopeqshvdhrxt[yfblnbsqkjjueioisq]lwvpnboqojguqaulrlo[wnhlxlfouoglnqxgnev]iyqqhnmakvoxztpxnp +ofswixrurgvazkn[jukbphamobnvueqdqnt]adfjlvakayvrgkmtwka[gmxkfhlglhaeznpff]rrwqdermdneysymehpc +nazzydfglbansumot[ncsbwulgursrszyknha]urighqhhyroexekp[szxbjnxkasvwpwua]hdnzceosfcqebtprxxo[zwnkfvufmgdtvez]rrlcqspkcptjvulsfng +vsodrkskysfmohw[hwrjtzyduqodkdjgj]xhiosvwdwuwvqwwqm[bwfslhlgujojxxsrhys]micvbxdgzihqzltzje[tggikdhiylakwufw]nntlstxdwwmxmjz +ggwsdmfoilqmywvyktv[nqrfwjbmiipttqre]dpfehnkwftmeabpk +idetgmlzizlewzpligc[xskqctlxfifwpgtxje]lymzlbqpnmeylzwrq +wsnxdpcqyfleebzsp[jtdmlqmyetpcpqjzsyi]pitazjxjvewnjho[gqesisudfglpdolhn]jfaziwwwlpxwxhqfynx[cxwejyufcjbnvkz]ywcyufkunkitefy +zoabcbmpdbfhiyzzrb[lindkrkqwhhouvhhvfn]qlmljywcpqtuytbydxz[ktyjpegljuoftdwcbza]mcgddpemsqxvicvm +mxgthmyaupkuhkaolg[wiakwqprrxxrmuilza]pmuhwmouewzzxkq +jdbxzpohbifmjlbesm[vqetjjqcvlniokar]pkdspazyhqfyvovxhmc +aistnzrazhwdybv[ujwpnuzlxujgyijesso]tijdkwuxuyaotgi +mvgtsndmrheqjrwhip[ohfummqvupizjumgvv]kczjngcfeuwozis[izjdzfhsafujllbgqz]smvuowfxvapaqhrm +pcuiwlviqnyoachj[dlgxxylhzwhuvowtr]piyiyrxcvrbtcdn[kcegjaozyiyibnh]uwlkvkmzywsidhgcej[mqgatgmrdlffpjvp]ybsaqisekhdzkgzj +voqzvcjzjclcqqiqqov[wzvjezqkeougixj]vqhvqanaiolmhkfpy[cgjtaytywwwoclclru]lrmisugdvvvkfsspfi +xqkhogolmkblkxxje[kaejzosqwxresbgogo]ggddspicalpocithils[pztbyhclifuodlwhxda]cauqeecfiwpvyvzehjk[ufzlxamwsmaxvsol]mljctouodsupchz +kcepuqpreuovyraar[aiwdwtperlwlvbqdxi]yqavrluyhkhupxxz[vlxuuotzuvlfvirqo]vaewvboqoxfnggrrnw +gxeijqyqnnjzxvigef[prwrvyqyvxzojonqm]grlrsdpfhvpfjwrxr +yytzwymxwisswxc[terkcypwqvvmdnirqph]xdsjnlpajeicsqd[mvawtnvvnbocxhdx]gbzyqvwonlpeuzrstep[unrdpcwvbnhnhjsr]hwuzwmraiplzplhb +lavqcyjhwczvpyzipl[iqiuwaywidvolykuaq]nbgqhocjmvsbivzt +wdwtvakvxdapqpaqwpw[tbhryfzypcqkmvl]qkocobnvijyumdif[tgzmvdqrflqpajv]iztejfulutergziy +ksvcpqqpigrddnva[fvmdashpahovucg]faznkbnixlfjvjyhg[klrcqpbyyqexneuw]ogvdntbaxvikxut[pgbnoqdsjbhnnfsglz]vgmdegzvdtyirxq +zrqbhwbscinzviqqbvw[igtgietobqjhjgu]jljelzghzqbmlkehrbq[tvrrrmcbuigfcfff]vfwgfvlphnwunvair +wubsdikgqcdnnxao[fyobcpzfxepbhmtz]lgicisnssdefoquygr[uodoaghwyeovgwqd]qkaorrcwuumonbh +kzjnwgqelqkmltc[mfqrapsousyrctoxlpl]khapytvlssxxwgblc +oemekhuucnnkpglqn[grxxusqubxdzqyl]kjdmapmhyszfhemkjdv[feawbayehptooegn]kgdwtwvnavtiduqxwo +royijobmlxsglmfotr[uazprkxsqtgqbdeb]zztikniqfvaxifmhupo[uqtzaxenoirdmlyhwp]htfohllugfrwalhn +bgwuvkhyegrmdoffuw[uslzpejoesttiegxavn]ebebdisdaubdhbebp +aggmxhtosvempmory[yxtlfxfztmwdrvxtvi]celvnswiplhcbolxw +irgchekfpygvtxnu[rkmlwzeasngauzubwax]ujxwybzbmghcbglye[ryciioqcnrvzfoj]tsfhnuhouhepozzjabr +nugltbtwohjpvwm[qumtmfynkzltsysg]hrrhwgzkohqiqaa[atmtoaosvluzogrsk]rewpjesmmmiengjek +dfwxiypyrodbpyp[bcmienuitbibjciawg]wetmqwsernpjyzfiqg +agxpdoozggfgqhpkups[wczujtsywkrldyoxdu]stxeteqmxajruxhxxhd[bqvzcgcflltfgfulcp]vdagkanezojneoe +dvqelzyssahitfpag[grtomzhszpfebiev]kccedawmhuqkcrcrk +xdiqoofhceqxmqs[ujdcazesabclofy]azfztgulqnhfzfcfc +dlkchoeimefcrsuay[zopdjifnlcgnmbcdu]qdtevsrixomqydittn[ethvxsxqsiduxvzp]ufcyoijlrdwjiqy +avzbzzdookhhinbstmt[hbetohoiyzeetxtjwwh]muuhqqyoenknrosqc +ziaoosrpsgpmwdigl[fmgyicpxugwcenlnnia]ygcbciigvnqojgkrq +eeclprewfejnypima[wuxinonqndaynnneh]warzohigntoyvbhdb +bsscuanhtqgprwnq[sramwctkwarfhzewlyr]nqjbqlpohnbaqkxacfm[tfhsdqtivgdnvplvigp]jbhxkufifdlzppfso +afkhlbzuvhwkqgtu[xljjasobpexxunibvi]zwsvpnaotvaghchckmt +mmuvtymmslzxuxsl[bersttslewqgxvjgo]ipahuxiewzsnyhcgm[klpdvclduqwuaqzmda]xfgdcmvzzkyyhslmh[syfmraupugxlkobew]zxgbdgwwjnoietp +srithuoihefavsxwgny[onounhtrnonigjpukmi]ucbyzheogikvqdhh[eqhrgtujasnhhkoobni]epijlgdvxvymfgrv +ntbtfdqgcridugyoj[slmqwvjooruxoayeuya]elddyfwmkdaqrvj +eagpolfqlnjahgrp[tntebocuegsbsjgkf]sixfopuzjvwqbhatmn +zatwudnjplfwjaorjw[jqcqbirzvohixpl]fmlqzcprruflyfnxk +fjbespfptraaisobk[dehykwsvkxiiehy]owzcfcbzmuszaui[vxtmjuyctrexdcai]gtafjdieoegejbbxx +uznhobovgxlnclgsb[sgkamllpdkleossp]qwpimmrdmsizeea +ommachltlnpcqsk[bcgqymqekxeduyteuc]sqqksjfqwcelmvxvmil[ivologuudhoyoljbpgc]jxuxubuvsocambjwrxl +xigypxktvvgvvzpsmws[fefhqqoqufcqiicnj]nrvcqtvpvsyoefeyob[kpvzkboogiefpjei]yvmewqmkwqivsdfl +bxfnfdxahjhmlyhviht[yagrdqoiwsjheeta]dbmekzhawtetapagtn[mwsgphhxnszvddmmmuu]myknrzpfuzigvva[rubuxbozbbkjbfmr]ekgepgpnlzjbrhux +pxgynehaeperkzswyp[ctfzqifislcdqhign]kwjhjhadvkqfoprosyn[bxbjfjduweqqxshqrw]uaznlkxmssfmfzm[xbxwdysgytptaphpwse]ugekghaaepncbpgckzj +fkznfudbiblxhhze[vacqcynzyiecofd]gxiktkcknhldckcp[hcouamymtafatmirx]xteiephuffemzeel +oyokrsrvnjyehtinvg[wjwwwnyeucvpgszc]odoytwhhglrdodya +ouasmyefboyrhlawsju[vvnkfdgkrzdizes]pusbufkrcycpnfrtm +ljqkshuoyqbvfza[awtsydwgfkavhcjmpx]ujlnzhofnfrecdqnrd +msexjvtxzrrrpxltxy[hpwhplpjyxwwjstedb]lpluzxqfapmpwfncv +uzdzpjkqdjwtzflxaur[kjsxmwxaswopwyxw]lpztuktpdibkbhtqs +bsghlbjkrmiwwrzfzzq[whofvbzzqaacwztf]ikkrevvznotvczoqnei[xzvrgqliulervgi]yseqpdruqmaiouwkj[jlczdjfmsjpgvzguh]waxydchzmoughmr +iitiwhnalnlosnc[xpmwkcmbgrwisvoy]tfctoedzsmboegtjo +ttqdrjzymuagqqiz[ckecwxlvhltgosighl]oiknxwhvpoefazvvkn +dgzigyfngxcqwapqbfr[peyzbevhfbkconp]bbhycxlmzysynrcdij[qqsodhjuujzkehoeawm]gnlyrbnlgybeaaqyrzg[pouqbmatsfczqqrrkep]mdqnfjizjuaydagu +nzojrnbfrxvappppu[gbhscjbspyjsviyhv]crhdedgpszdouzio[unnohemwxlecqsrhtez]blgpnlvjkmvznlm[edemkrkixzunqjbbw]wrofffrmxakiqwt +hshucyqrhhwjdbyvil[rgqywsctjhucvsvsymw]xujmtuifweuvktqc[qwbxmhqfespgrzho]goevsvgqvbskpciebr +dvdjksdazrasbbmdp[ramiuseukzwtkycxgc]ycppxvaitmsvdoy +xtxspkgfoepqquwnf[viivstflpbvqrhmyt]gormtajywcijwfbpmo[jnkgkcuhodivxggiw]fdpkuzlipozqwtiwiq +kidemeuvfksjsfhy[ocwffrbmscxzyyax]yuljtvukgbwalmfsfc +fahhvpvwkkvltklj[jxnxhkvasjqewonzi]ttivuutjsoyjvfcpj[hpthotkiyjsyfhvk]kzendnponmwgjpyz[cruaaebmvuijcothir]cjqnlrjthvxeqdndpc +tsgjzunbkpizyqeqr[wqaqjinfxbszyik]iwbntvvubmiilra +dwiccjrwocgangcqdy[artytxoxbrrodhnrzmq]ohajkaeutwggiventwt +ibtdoaidcrtbsmhvksf[akuyowgcojzfdwraota]haaqsvxhxaixwpuhck[mpwpofhciwnjzqatql]krgajuglqvrzbprtta[xeehypsucuajhon]pqqtmsrbsbdiwtxnpv +baslapqsocqdaquvh[pjlzuqnuzytylre]gprhwiieirqfbbb[ytvearxznsjbbxhlf]mnwxjcfrvimrjpu[cvimuirdapiosohzulh]wmthcardkqnwpnypl +dmpkayksbmxaxlrur[eeswdwprkphnaqd]eikxmwafysjqxxszjl[plcixcgmkbxzwzuhkp]hqoxumhablcnmoip[bptiogxgjindjhfrn]xxwatfkthcjwqyhnkje +uhetvfadhbxpshtnf[maihnisbzjjddvdbh]khnxpuugcpiiaxdtl +ehfeojfzbyhhvhm[dnztraunljulvhnzfo]zlqarmjvifwxevhv +onjqzuwqztqelqhq[wwnytdpcnjphrjetxxa]gqbvuasgighpykjg[jrrtrvhhjtuzxiekcoq]rybavgoltejwzpx[uamnezcvwqhbtnpv]gfwaifghpqmdbtuh +zbvlbzrwsnqtmxvevvs[akxdycrntehyhlsikqs]nqmrgxvxheqeinnb[tcaxyyaxqqyavodvqmj]vsllwhiddpqnylo +zgegaqeqwyrhclzdlv[yhtevctgruszsqbcb]vygeingtolabpgyojf[bqsvkrlaqaughbr]zspqjczelulswra +yeunxsaihaavuoavjp[frtgjtmwotxdxcapfsh]pagxqknufbkcxlnsyv +vbvnrdomobobrkd[bfluwdqgdzzswav]ydzrlrtgohvqbwoto[czodsaxtotxohnje]nqgrqyggewjmklzthpm +gkhqhprnmrtdejox[bvuuhvpvdylnnpbc]spjvarmyzcxldjf[vjotgcqnfrkofqfpju]rakmxvjrrocsemy[wclvowuqivvtshwlvl]vlbhrxnfadktffqwdts +eieofbvelgfaaif[szerphlnujlfnltmlp]uczsdquecftuxywcon +fjikwtjhppqemms[drckbokfgrthhjj]eccmyomrlztemnjlli +ycvyiclwfsqfimqbqhr[salbqbgedsalzeukosi]vsnlwynocjtwfwykobz[gigasolhbyirzzgl]nlzlwbirifimfjs +xgtkwdpokjwzsxmpgl[yfafhfdemntzpbf]xqqpbpmldbmxqkgzepg[fuouzqrvwysplja]jpvejlwtvcepklabv +wwdngfpfaihzehky[ezwobhuctncfsxw]ujzubptpqmfbmtptv +oqwujxuxffauxup[mnhbivdelqlevvxgvyj]xmgntwppomdgploofgc[hcgxkkuysqfsjek]bufawargqfsvcxqor[vjzndzuanzasgnkpn]svvtfrrflvtvndqliy +sxxmkxkpzxtirrrkdu[sboyccxldcpclvtf]ygzlasdynwvphqjps[hpicrvgduavhjhi]vfdlyivngovuvzd[nqqzqbitpvgzlopktun]bayteidfcirbklhufdi +bepcfmlepfsqmtpzypy[alucbktkeotktgnwi]xuurpicvnelquvcxpr +igeoujaqikqpdbqhiz[pefrnbgmefclodb]lbxfyjpyvtwjsoe +npfgcmpnsucijsoq[iczfocvqgerjglu]gniihzzfdbddgfvwopy[chvpghdnjjzqblg]lgdxocvckvfckxgjkj +bvbuayzjrgreniq[vvkhefnfscetxxbpsk]mmvivsvdwravbvtrt +xuglkaojzufpbpondc[twaikvgetnyzpiavz]saqkbnxkrbpbyfsc[qxztmpswmpvpvisgv]anzhylixdnapsmiyik[hgwnmcxtzpksgqeuurn]yzhtwfrdfyuvsjmjpa +jtwxrqqqyluqufdf[tvkwjeghpejhivekqx]dcucgeqebqyhbshshm +ahhdycrszsrwjjcvojz[fmrmjimjzxnpqiybvp]ltbfzymjiujtryu[mxwaqromkutcwbwcg]hasstnwcybuhlbmp +hylwpmuxubrhdotqr[luufwrmuemdaqekttwi]ucyndgpufbbqbbsq[lzdvdhdfbvgakrqbi]tnciwujbyekicxguct +elcdjqojmcwqmlb[lvvuaudbokptcauadl]qmuukgwvvfpipmtd +ydpbccscfptppbic[phdmkbviawxqqyqevaz]oekifajbuhythyqyxt +evbrgexbagkpwtf[ywfmvfpvkfgvwwpf]ktbfwirdfcftcxbqw +tvkdxorbjljqdcsbp[anhtdvpapvcztmuybpi]igbiinywiyrlgunyvjb[evwzsfjmtgrzxnzkxmp]ycxgvldadmkdukwni +fxuwajvzdihghvdn[xexunkfzvyhstbz]piyivjleyasndgnny[pdakxjkrgcpejwnnujm]wdzqcrxrzpauwfmq[nuxflgndvxrxtrnjw]dkaggsnracnbfamlb +eqzmvcfzysxuymgypzw[dawchbjtjthjrwuc]onmnmwdlhucoaisobj[olpmwxvcemhndym]rhrzrnsqnmcqvoa[fbjcmnqxoclntvcvf]cjbvqfninuppvovkmqr +pzcplrtxsmrrnkdhb[fsfhbmpmoltsrazzmsc]lqxfdwwrojxmcppnck[jwmdfvhfkirltazsho]bupaelpproqgqltj[hwuvzedqqeozddnmdkf]mmppkwlljdxrupt +vdjlufjqpvyqgjx[omlvdzxsozlbrbkklh]avuprbrimlvpsfljr +ygbspsbxxswmsnm[xfqgducuqczosts]rcrilaqyhaqdzms[cnwbokkgnuqyybrtnh]lujwyrdmobhojwyss[qulylkekdvrzrdbrbz]siwhfcfwuijumpal +njzcgzhcswskgakj[yylntuikiucfrhp]umnlawqvcmsumomzor[wbkwjwbuinyfhcl]tdpughwogvaadspwsp[kybtdwntcawcvgg]xgmyammydawidxd +ofoexaumaogmrvfxva[ythshgunuchzyqnz]myhfbnqhkusbyaujqfp[ydqvapsxvatmnsqnotl]jsjxikgtoscfartj[rijtqnjlysmylrpe]jehdtbtjovixxcynhbo +ydfknwggrlosjxqy[cyhmgbqtompgkdoy]gqieuwyrjlbwxeyn +qnsrnssvsajezhc[modvjehlkjvwncl]optcxoazpnhamypkhj +optmucfvseahsayg[szijefttdjukyusqmz]xvdbredkrvydzjsbzhm +pklknlqabxqxkvs[zmcklqcmqysvjltw]sdfkabzheilcunm[woirucskjhwztjwa]avgmygopoubvkavsk +ulmcnycaeendwbjh[kbndrebyibzcijvgdk]ovyfstjzcawsgxjabc[wdtmeoiuiwkdfprpbf]vguvqkvghenzvvfi +khtrfyldigxwnrked[vmiucwzgenhgmchjz]ronhhmptnvkesvj[riapvohhcegxukqfklj]bvbujrwmkmnvbjmwi[vhheuhbyrifhvbvhmr]elejjwfebkwsgasxu +unjjhnpqehrjjcpzit[teuannuieyuxhrnpwt]eqmvmacjgajwwguysyk[nmmptfvozrpcnkiizs]jwrrglfbjgmampxzcxt[zksvtcdsnmceaghvco]pcxxattwhdmbhnkph +borbdeklgxlodif[giciuekdouebfugvuu]jwnlmqbvdxdhylnfk[asjceksckpbptsuj]btiwucqbgxqsphyj +pyuiibzuklinyxdxg[prbgjhutocdedjn]tvyzieshpeeluitw +mvrpsasuenekvzdu[djydvckfgunrkzgkqv]jhpxgayasabadnezx +rojzzwfajnxyfiima[qmcqljyjvpeccoemb]fnabwwocvkdbnymxzvl[uyooigklptdmxde]yeezkyxrmkoyqmxm +abtrnotnozgmsiene[rvywymbjmrszznl]tsqcnkliijzsataue[jrhatzsogcwhymmq]dczjarobvhaucwaltmi[zqwdgmjdumbadsjmqrm]aphemnpmxcaosmmbap +pqfeteyvtwhdxtr[yirceemqqrnkyfz]finsowielugfjti +xvzclksfiyvugkjty[xiufmgdubbhqoqkuip]qntnenloqobxvrfjfim +appwubxanahxahxqufu[lyujclxejirymgf]pgltzcbuirjhdndtsy[sxqixopfuviugyixptr]jdmjidcsiwbhkbn[zqdccjffpzqhaeow]bpyxcppnvfardsolbwg +zwsdevjtorapcmdkmqs[entskvcteinmrfm]dyxljfompsvnhnrsfoy[skzzszqseguhsajvj]uzscvlvhvjvzezqiy +enfsjrgrrbzhwkrrdb[baghohbyndbmgeta]vaekgqhilbkmxqfr[xzsirhckgfgtofahx]qkylgrvrqyknaju +ricdzabzcnzvtkxjigx[ahylbnwxznaqhjicslf]ujhbdkubrzyxuvagpkr[sauwmblnmphxaltcgan]ljculzlcjdhkhrjhy[krtwaopxtqcjcquq]gslqucmuqlkcwmibtb +rwagfoioguhsuxmnb[oqlchsmzdbbdiqs]itdkdkowiytntppqbpl[dkhveketihenwpjm]edkkekflzcsxrtbkoa[gcgunowkivsaizrergr]aykccxvaazjttbix +ydonpbxrsrisnwzezj[tvrolgecurxoaqygrq]elczpgdzfqzbxcjdfas[bkcwijdelhknclfzsu]dgrvkzdsngxaetjoi +nilekuwvaoeaohrbuq[tmmlftxmdyjgjwlcje]gnpgjgowjlkjvdxaaq +wyurocurtxvudii[boyyycdxrqrfebzxtsk]zybwccrrhhygcicgxtg[chcumobehmqmtdc]avlvrqrttfvsrpyqux +ukixopxocpvmxvkshjq[ilowajeaebgshbmcwc]vkgphlquuttcjdcaeaq +hhqnyfyenekjnnzh[nzsivysdmzlxujnen]tpxgxxovrrctyzo[hxooqqzuwyezujqff]ufzjddsqmdynyxktvc +aqgjlpapbewblghv[adxjmrbdowkfeuk]xwacrdlhqqisjbwgs[kmqrxtckdseljyzd]wywbycffohlnrpz[fgbdpzjxfjslaqeyvb]lzdfadvckypyddtrj +ynscfejmfrmwegxawe[wwavlkfjotnrilho]intmsmrthguxgbts[gjyywgijvhtlcuslhh]suvzwdlryrrqoukv[dvbgyhfbogftrzkof]ttxugypmjcpwwrj +glveidwbskfsjrpeivl[pntgsktknixclajqmli]vpxhkfquuqueaetktv[atrmrgcsygulmewp]tbhyqvdbmmqmjfp +asmieghesyynwrr[kwhopbocvxcctveyo]tyutaxdxwlljoau +hjxpjbafextgvdwyc[nubigljeloajrggv]uhnsrxgsxuyresxxtj[mhmgvlgvahmzdpxq]iiwirmqjgsfmaya +eezdjzjjufxtobmln[jfhatwrfnoxnubhvz]nqmgjykvaaskoobuspz[eyzdfdrftbmhtsqvb]daqsijtchmoaemot +cjrqdikuxpdlnjuw[kglodmoueecqfilsbc]kqppmkhtyvhbtedew +lelpkfweqesqgosa[wyjxoguthueknybtks]cfprlrhaaevwnhk[jdjgafghmtpklneklt]answcorhdeoofdxokhq[kwjmwtzeztdxpwo]ryengohbsahkqaqaa +gvtxfgnkdfhcpvpbqfw[fgullkfpxeqpxfeikv]pazghcjqpedihht[lpbmxqpmtsmhhvcftfe]cvuibwkuvzlyktklddy[nfxhoodduthgnhouwfc]hfcmvjxjvgdrriqzi +nmnznunznzhpiqf[kzrnoanvyrslaiwesyu]ztlqljtilulefcfw[ocgvakqhpjrmhqrpx]vsplhxhzslknsqx +bgzebaklxfotapk[qpkeedrozcythyekej]kchtifarcnclbdoey +rhpspwhbsfjhdgnmbx[gvmhqbwispuioyaadyd]aqfkmehrkqucpmckl +tnkbbytrqdxplxc[jrwexnliwrdpjxsbxs]pkatqnffpinqugyemu[eprydvhoczrmzsoov]edyqemyeqhauvmz +nmnoyjnhhpjzofxr[rhbzfdxnkxkmytszl]idjiytwayqhqpsto[lwomwdehcsadyzonfv]fsqqortykpqakaylth +bmcsapzfpbxulpxy[qyswwftkevpybymc]xyqgfdfoubxdnvsiuh[vwtoqdicblmfkdmkgmc]dkkfvbjicanywmqcryb[xnrvwydbdyssdwuog]zxaoerbwmuckyvijjl +ekknhqyoxhdxdhoizw[ohhmxdxypqgovswjxle]gghvnqbvfolthycesco +mwscyrzzomgdszdp[gaxvhxahstexdkuzal]hovwgjwfeuasvkgefjg +ycbhyiqhyaxieqyn[xsezcmhvbgccguwf]xmxfqnvysvmamhh[uxazcglqdthhxpzp]osyxegeblucpdglg[aamfejvkyvnalveud]xqflvtznebofhwf +gnzdxwwwisiqjsis[rdsyakldyidetzsaj]qocedtmvtnfsaol +zirxvihavvvjmxlk[eavxbjgywyjaccuy]fwckhphelbffbpsrwqn[rcnwurjglsqhaqxhx]tcgwbzmxszrspwbpn[nnaiywfuvjmnnjbngrx]nnwzgnsynyjhodjjal +yaklwokpliqzznn[voahnvbkbhdcrta]zpsfblandylkwetzblm[cviucbjqjxojxvfrbh]wxnmcgyslfyhjbb[xoeohbbquuflfczzrfx]huozeoewsqiqizrkg +qqezbweffsvlhdv[nrwlstjmcfdeoknejxa]bjbzwhrpzwhdplgpxzg +geqomfoxmohwtay[htuvkkoolcdjuwfkfi]ufnbtalpwnzxwawdo[wljakfwmzpzfawazm]glsmrgivnyqbvze[dypzcqcwpnnuuio]asqkiocooybnwotvhxv +qfveyucsvamopzcevpj[jhontypcjxiqmok]ztqopuugothlvqkyjr[gtwslgehaoefonk]gbzpfggosbzbwbwfnj +qgbbllwmdxvjbbdc[wilthdtqsnyidowz]fvsgrterxkfxytjo[vfbhaunwhnkucaa]nrmiutcaqjmmlvf[lslzfrijvupqytfsps]faoczeuslsurgnnj +mghuczcknredmulpm[kxyvogjbjkmfhvs]xuuugkpxisrmoqzrktn[kkjpjmjafktnbfsu]iixqcqwjcusrddz +acqlidiaismzjcv[krxwrizrblelrinmqt]dnhtoxugsddidzjpv +ruihphiefqxdtzoilo[harngompsprwsrfv]rrdsqrfrwmwwtxfdanq[ufqijmrzriucjhzjovp]tuptegnjeqzjxcqp +tdwxbgepspoqbphu[mvxrguzfqwbklaj]vrmibeoheitbarzdtw[piisgameaaskvbp]kouiijuqjufvhmyx[jwpqpekhyvbdvoyh]ivcmbeitdnzxalei +wvwhsvattcfkxsjbif[bkesznrpxrlcnsmhbxv]rdycrgrtwazfqlx[genmoutcoedshrn]ucufntphttrvzmgt +zbjsdpihltflxiyza[chbfofonfnheqku]lttrtaddrmooyaftzom[rpzbfrevbvvnqsoqta]vxqkgztdjwnyttshfq +blsbpkqkhwimfjxa[tysyypqpwfsihvpumwk]adivipxtgjemvvvdgip[etebetmijxhanxcndzx]bswwmsrqqpdrvovbopg +wljuhpitnutdkehqaqy[dudxaqawkozvbzjnl]oxcprdaaoaqrmku +tsvqtnchyztmsrkepo[sbykwhwpipjcnmsny]jkbriyxmedpdpxakjvq[hdbpjwvsmeagsnqf]fovyworeftotyou +tfgcfmqoawapbyqm[ezjehtzzfrelhfu]awpuzstowgckfmgrbh +uovjidiphghdzzjb[dtdrzwcusjtvukuw]ulkcrugzaophsdkgp[rovxtnfmskkldle]vdbtxyoyinruobcdfbw +ivdfqkjxsocxzmixvki[zbuuqoctjufuuge]xpllugxiqunyuelezg +oxzelsopvmbaskzk[qjidgldtzyxafqk]yruckjcrisxaytxie[migurcagcnpcxysz]mmbalecstoccvznciuz +kgtvaeutmykftmfxq[qkixsghbrdvmdxdfds]xcgrbqxjovoxdocf +hugtmltsmyjidfr[qvvenxersilqpddsa]rlxwylthrhpizeawuj[jdspbsvecihzguv]sudnxjqwbctujnisgm[pwesrolivyjummxqe]yxmwuojvnocdfgfdt +cngbxpbauezgfsoew[joasdwsddgnfaxy]qofsdoatlhczeekcaoh +rtzafrvbouppejhjya[pernxzuagmhlccktw]htuaplcqixyrpiobrc[kovyuqunaiajujoom]rbkzijvudwqfhgam[hhnhqfqzaaocgkt]swpxpivnbadljnibjpc +ervsgqmmagakjqslfzy[uvmkslgagnkyvxszev]eceaiknzayfbftt +zwzczkexxkvpobp[fbkdnsksmqwjqev]molinnmafhfqgbc[xokcwrgmanamiher]ymvfovgayderspzxqxi +ihpvknksyabxkbl[xrutpjyzjkmmglvvu]qjpmwlweqpzbuwwa[rcptostzorolknz]vsvkprnzbsbkkah[kppazroehhzhamfdeb]mfzzvblmbedqeui +xtliiwhelmircssh[blziuctnlnbddxzgryi]ndebxzkwjrwvlnlo[zzmptzhnmcvgmqkfive]ldkndptftrgskfi +vmcxolggxdtaawl[jrsapvcqpvpwzeyo]lsvrlnyqstxynwoluww[loswyflsrvkjqgjmyji]hvbkkapyfytegkbcvob[udbougwmipihlbqeyf]pyomqdbaiyqfwdngddp +fsckaqoorayphqddex[gdhcfnmxahimfrk]pscnlqroybeacmzl +faksrtkmppleuteolp[arpyspgdmmikuaxhf]qlfkpqvqsrthgsaa[isronuepalcjkfcsi]xoizuyhsovksivz[hctljitxdpncenbya]xcdavkilyghdcuhm +sdeqalvkcrkrinxry[xezvqhybsiwnncuafq]wgmtvsnsbilzxdd[exabnsnnyiyrxkdd]wmtluopjkaunmyyogc[mcecujbnhewtxxny]fasqbsmncghkmvv +imjsjagosjsapla[tulnvdectjfkpgfv]cycdjsngozzmkznmjro +yzrtsvldibvyyvtrh[wsessluyckcgokgkqb]zhmcpufpsxctxoyag +ptgavebppcdhrnhq[tttuwdmggqvjsyvqncy]watzcvwamwzegnlqyvr[xjgmshogcojhnjv]xltnwtmlptyidcevaw +pzgrqoktlayqnrett[hjjxrqhsnzoyccaaq]brpjabtdfxnygqiaarg[rkqavgkgubozgownwml]wjxgbervjemzngf[sjvmflnoffnnefafiw]qyjfcbbzkfpxjeiijwf +nfcostvpmrtsmxgi[mpsolgbkhgeaqxr]odzagbxqorrcvgbtqn[fflhwjduymmupdqtrzz]wckttgyhhfqroael +cmbteyhpmjucbdu[pwwwivojyyhfhuxrem]bwkmgeggapphrfd +kvqmdfjgukadbshzs[fdbbocfncwrodlocm]lvaxzdlzjfqguetpn +oxsxjgrrwiwscddy[cejrtbzlcfjvfawlck]wcbfearmyztejbvphuc[qiubscyfrbvlkuptpf]zrpobbrogzuycnopoit[enphqttsdcbavwzu]clrymfxpyjrbbbjor +hhkbpgfivocwsgt[ibvjydpzawdkukunm]gurrtsurksvdcmtim[sorhhoidukufzlzwc]iwioespgpdqtnroyq +iamtdgvqmstvcco[hkpcvfwrobdkuxoc]mvhkxcbpjljjqdo[jycwjtxuauhgwwr]wdaorllxaauagld +pbrmiwsixlfmsdwd[eogkhrzicmhfgpp]vynfbrwtkfevbzbske[jevcdynwfstxudo]qrvvassoiwkskcwrh +eurmgfnrxqchakry[xaketetlgzadzwpzm]eypyfdyrnmlevmikrkn[suyrnrkrprufjpxro]mekswuvazvujealz +mbrseqfrpnyimus[jzjzsthgcwtrzyc]fdrztnqjfeqfqutk[fvhqfugjkfthjoffols]iuydpdexhtvrhbthmn +wpdjebvrzmivunrvwwu[wtvseusrowyuezwouf]qhrauglncxcamzwfjz[vcobhfnmhhhhpftxx]rrqqlthgismiahcrm +qeljpmnlnlgfbwlw[gzrcgmwqbugtmvc]mveuxatewhiuxxy[hdazkerrbjavygs]hmoechcirywzjscbgs[eunkjyiyldyrnzz]kqceecablooujyhpo +pvttquyqcivwqyb[qdewyprgoyjzstop]rniodvvcjaprzwhrugj +yoqoqchbjoxlaujxal[qiovqowowzwjnqjnmv]zeujymywxrcdyxt[biudovwqwilssftvaji]cvllvfrnzvbpwqoq +dfdmogzbwoqcxxjt[wjkxgbiadsjhasw]nahghhzvcmxzsuezbd[xldtozzfdfibzyfir]naoyetzdxxhsuayxhdv[bgnjxcjigctspvtphi]ofqodixdyoyllqwmm +whnoowlrfbusppnmx[iqkoqqwuwpjymrfgmef]mwbcxqkekmkjuyec[ehjhwneoswbhfistr]dgimikumgypgcfgkhud[wcfspumwevprqkdkra]lkrqeomimrcuuutma +cwfwtigiptyuoscgqjl[xfsopbkdejtqyfqcr]xgoctctnbrpgdpetx[jrvsqxlosucawqmm]xybgpxudsdlmuzkkk[pvmkpymwtmsvblad]tuadmrxepxtcfxnj +hcrioqzpglfeqhk[atmukocquibjcdk]zevfvsavtdplmavzv[tqgaubxkybftifxnox]uzekdndrbdsgpuqdpc[ivnsdltuqiukdag]zujjefxyclbusavtb +rubuyuyswgsvuryuhg[bggufeqnvnmcltkxdn]pdixuunidafnnzmvy[qmewpxbpqxfakkpjq]khvqslqcodcifoku[vgvnbaunegtxgdogryr]uyvkemhfsxruwonkyy +wavmxyhhhthnxbqeu[zbvfbagorkymbgt]cxdkxjdiwemkbqcfs +qcynqcmhyzosgclnlj[dkwoyvtlgqwferyplhs]ixqnfkjsytvyhwk[mskihexwsrthrwoxlkq]ybcepjxrwbfpwbrj[jtikhwoljzhnhxtd]bmbaqxydzmnsbbui +tikuebtrsggwohnoc[gmsyovowwveyivxom]loedcvovnwjlxrin +fkabwdkuftcibicsnpy[chlyzxtachvkcehii]efjkasydyavlmogrn[ljdwiemzattmpezhrk]hfvbegnrtuvvxrfpmu[iobgqgzwgicgdljml]sxehdovgegoxgfuoz +jpxfbgmxcedzrhcw[awblqyolqotobty]zghskkdwhirzeabi[bpfnymgupwpyvtqno]rzxgvoakkarqzckqlm +tpriezzqcwdapzmqi[uhbvdbykbjjugwx]updunlgopgmpuxhz[ppvimkoubpzdrdpnqs]nznhmtrcebortfmub +yvhtcgpickhpkugv[peidlppzxitabkhqxqk]tewdgsemxtpdzlbp[cqlkzgucaeogcphup]sowzdzofzfxmuqm +obsasbvikoqimtvhwig[zvnaytcddqphbstv]tfeurtvgujjmdqt[cjlpuwqhembtpto]qtgtjmciifvrjqvpl +qqdcyxwbsygmkhe[bohkfvniilpcnylq]jsxsgqfvkcqgtlx[coqishgebcdedju]mvgfzpuqgdqqmlrahuo[skcrnqfagotgitdh]edhqioatknhvqgtksj +ybmxgdftqlhmytcftg[leyqniwliccsyildw]mgwbzvbnxtmpeeh +dldzrldldtqrrgeyy[gkwkejjgjmkasiszp]weovrlqtdhoefbf +dcqsumoaiclldoocbu[rxmnzngtpqbvoaekut]qucfneogbyxmtnzjjs +snvaekazpxnocmvoblf[ahgpcmeawumtzplcib]qvhpmwsttfbqebklb[kunfihiwmtokswlzbe]bjecsktfdhzxuzsekj[bkgmlzkpwrmuacgdbqo]nubfdchpgxxdron +mshnjuzlppnyjksh[xkxximnofpivappllvw]qtjwjjyhubwlnjac +ckilmywqvmrrrygjg[xvwolhywbdouyxttxlz]bwkzfunrjefbxctn[azmsxgpkdmcycberi]bdvvzbhvykxyyle[dkaxgvdfddserbyfii]juehqvwzulaosay +dgrdibnxjppdktgoit[vvozfezhcvfpzpb]ympljeoeowdprztyw[ggojctjisspsgwkboj]gkmmhteczsojypwqf[tyqjmwiqzswilwt]ohwnrsiggvwhsxqrpd +tnvdozwrubciyrdex[niwiaiphjxqouxf]uotsxpehznazjut[kyutlrycvciunrehme]sndicjrgcqnujkq +wehiywednvqcusqc[edielesexiqqlslgq]xgmuihvoesidict +jqdnckyvwyiermwlxu[hmaepthcfvaggphmk]ybzjbirijyxypoatll +pxwtrngnidzoikjacbr[hmzpszagpflytcnl]nzbzixygkdfeyxcvnb +exmklubmftcstgfar[rvqpqfvlepfefek]kujnqogijggldwbdhld[coinyznostzlfsppvqk]kseichzhzxmxvyhrfqt +lstwjvommzlmudvdq[iemnxpjcvfmcdmsjglg]iozkhciriurjusbkwk +vlzeeygnjpkujryahx[mmzjlmzzcnioefctryn]njdpfoaoawffveissqo[jdtrzsflacqptpj]hosvbnjbhkcrndipsbv[bzexrmoxyqlxeqhrj]mrhwasnckclqoeqkj +pwpdkauxzallkcbpo[qpuxtpxjqpjpsurunws]hrzxcfelkqidswszccx[fuhnomwpwgiakrkt]omgjstlmqqeqpngtt[iyqymggrzzleeody]blvqxngiwkntvocjmo +wnwvwnqfjujvwvk[lexdnhmrokvkufsnqmo]xpfgqupyzrotwim +nbynnmofuvgajvkuwxl[tphszshufggusga]llbdbageokodcaoqehm[reiislkltazqdwkeedw]ruuynjfntbplyyx[vawvqtvxkqjzkqktoh]tjxdobeddpkmlhtx +miahcruksdynhluwp[ytjrkwguartqhts]acubeswyhngxcuongsm[qieirczwzpogxrgsq]pkjvlwwoigzbdetcxom[girgybnrihgankqadyn]iinsphjfseslwef +zsukwqwfvhamtzv[odtezxdtbxbbjxizth]knevuvdvkhhoxxvhqeq[dcuzmnxphpypagsip]midveqcwlvktcaa +kzxcbzdabbovirtmgau[uswizwfejwhehvr]klbqftcmdrqefgel +zgqspbdsiaworwaddt[xobuokktkigliim]kznrswhwmzuxpfesmd[wvemizuoujudbnvub]urjofqtkkuzkytpfsrz +tevwkvcsisbfatbi[zbfthmfwgqkdqgpomwb]azkhhgkithojbelrs +btbwjpqtashnwizlfq[xhjvuaewdpuetpqi]gzshtumvqhkszakb[rqjnrhvvpgqkquwzz]bghhfjxukqknaxtnn +ianvqljsgiwwwpygbj[scrhaeddnjvtginln]jlhwjpdlnfeveigqprl +jtsgfzkpclhjbovpi[ixaehuixnpbzgmtmm]pvrxiwkyrvbajrb[cjlelxhejwwnseumy]ikdowirllxmuglwdz[lzovvdawkjnghbyehh]cngbbbeqmaaqokewt +qgdsbxninirijouefg[klekiewvjtcdxfdila]kzfwzfhzfoujtmrcuje[llkqwuyfoqjysyyc]wsmwhuxbtzurkeid +txhobmmzrqlghsu[pakgwjuydphidahute]crrzoeehbiysjafngkv[luptkawydmuztmcblfz]kprmziqnzkhpxfabhb +rvufkiktbvnotod[jphkdlpkjeigxjqgjn]bmknabjinjeuiki +zwwxudbvwcsaruswt[zfjkmmbzxajtwbdj]eepmwkbkpmbkbxovhia +ayzjygofeezlymze[ajmtrzvtwrplgzk]vwgedbdzfcdvlbdbd +kyaahofyiptqlrdvo[nksbtkzihbjrafkedjr]xybomxqdnsfmxtelvzh[oaapzcjzmyhpqai]qbskvazcpbvjnfdhn +zzddqjgykejlqow[surormryamavdrflsu]ovbhbhiofkemrmbq[zuxaxjaolswrzcglt]plirqfvhirouawm +aigjnupodnwbobzvn[mmmbzvkaqyljfdso]udnugxtjwkzrqgxie +ogwauwxanzadkougje[eqkqpzxvqvjoouh]lfkrkwwpjipktlcgvxs[guxerxzsvgztktamj]ggvheernrbzepvlheex +zrpijmmyxifndxz[edeqiujkuymqywq]oxvkgxekhxlsvrrivvg[oehkqqldmldngnq]nokjsnpbyixvzimmbw[vfzdizgbrtprjkh]eeaxrkybwtpnfcyq +pgmrgxidmtrmoqxnrv[bwwiifqqpkvpnqsrt]xymvgstorhhhlzhukfv +nhhmhupflojxmwnh[xzlsoqntfifjcapmwn]rpviveyvhkhswito[ryeeofttqkhkbmokmi]ebsnrkidkxzrwwbf[lizqaxlfqjlrglxg]gdpmskujkulqitskwfz +limvjkmdnvycrab[urpwsqwsfgftgidxbc]yfgcsvgurtsvkjqvxp[cgnqmeswvibvvoqbn]vnykqwjdflasldqdtri[pfbtzcegiuitkjopm]udmsysvgvmtdebl +copajvuuvljurswjhlv[yrmkyjydqjdysdkldln]wgzfebnjrmuaxbqhr[myrpufkfkowxvwbt]htntuquzgxqmwnjetpf +ohtwpsadxznphxkjidu[bdpmoqxtfwehcigpw]ztrgpyoxyuwugnqdwh[axurupvztacpqrourzd]ixcwkdcvbdijyhz +guqlgnplqehqvzldn[sswhwgukeunvezgbws]clkdyxiebcedrnhrb[slmbnjtbhdnjqkb]kdhitjgvqotodlgqus +zbqynkvuyzsrnaycxa[xicrbiytzgwnrzg]bnchnjvqnvvamulteym[vyobaxgfdudkusb]utjdxdutkirbrcnru[nziciprzormocagfd]bhewqskrdgmwxke +qxrmuodvindqvno[tadfrqogkqjqhzx]yinnblpurapwhewsown +cjxdkqnspksopxpkee[knvnqkjekmtdnazd]sihvdgnuujsadypbjfu[hpxlankhthglgho]pofexznitmwezidwupm +kvnnkdxlqbpnjph[qrgzlftpjiehardjfcp]davsfmgnxtfqbiwrou[pvtpamwiamcejklvb]vchjfnblkxebwsbqqlq[jeeggmzmoogpujvnwpc]rsqkrddlpieuthtjk +syuaknunjsepwcxotfy[zujyunuzyvehhqjf]wyfoxvcfmhqxhvgjn +utkiczwafvwtqukzo[difdyqhszswzosvyqb]lhkisgbqynprsae[veibfwkkeyjcaxth]uxdekjckzkifulxs[jrjgwyduwrlgddnw]qdyhsivqjprjbstf +ulpgdxuwfjglisvwhgf[evlwiyunqxabguz]wkgdyfouunklxvcom +xxcuqshmfgedytfdt[whavzobglhuethmyjtb]htuhmvdgyvcswufnixa[cbkipdlosqgamuz]fbxdzemkfnaofqhy +fmnzrstzqotjqfpswhs[vbqaazsgdkzowgy]hljkdlhlivihlhww +vxnvfwncvtddmxn[qdztvykawmixzsmhbf]hrummwvapcqokkxtyva[dlxuybkyamqjorwk]yhecpgjzirblrgpi +vrbwcrefbfeyheckd[tfuieucjwqdsyhbhq]nbvhmebepywyrkmto[rncncajyznsqjmvsv]tfxqlxrorzfnapste +vmemxnbmynxzogwcd[qbvahclyysulqgltzeq]ujwzxcermwzdixhxzhv[ovrdvzwzaowbpqha]xoabyrojezmgwaqd[todpqenmramguxrjwi]sabztynxcjgbuqxmr +lcksticedysidnlkxq[bfltyxyfbfvdmrjajpc]puqmhazeoztndtjlfw[iqpueljanqxaepulk]rydqkyqdiaiicrmerda +vuobbnewwsdcmeu[ufsyoetyczrvixkmxqk]byuxuqzwryfgjtfdx +iprsucnzcpjjcwxb[roawxineaovtmlc]thtfcccdiryzdxc +clnftfuslfkusrc[jdjlerrcdkdroeua]dwnvmspacjkuubvuu +frdnlaqcbvkvyggwbzl[kybcvggyflcwlitzxo]zthkkszsnajwtfdw +fvqsnmfgbpixbyryp[eadgyuttmxhlptccb]phksccteigdnbldmtsb +tiaezunggkakzbv[tkmctgtihulchag]bkiatejazgeozzfih +ckqpdxyowthtfkrqhma[sicmvwqvsnoftvte]lcosjiegmeilkkzwcj +nvazrbkmooazozl[jeznxzzyxhmnopr]bxltiqjuxqjcunb[aixtzkozgngkwhlrj]frctkysebyvixjadkv +tstprjkgjvpbqptc[xthwfmchopcfzrjin]lyyobeeuqgoevymyzd +vzqsdhcylskoxrip[gjgzmmhryphljuzbxzv]lqhdhhelntgqsjyj +drkktrcuclelctvphj[lgvizjvqzcpdlvtgvn]houegqpucrquzdp +bjryqckxvymkcdydn[nqivnqzbjhreueaajna]fxpfigwhtxixllsir[pkushhryhehrccy]xishkltxvbfsxhkling[kulvofivcvexawp]soiyukxfuwwdgccug +kmailxqkywaagznq[kdwonyaofeekdeppdtv]pnthputkjvdbgyru[lpiwcpmcudqzcbvzggl]pbznywxvbckrvapuql[rbfkbmejtuayrlh]fykknsratzeksdgm +vsvtjxjkmzzcqsiu[pwsgmqzkemnofmlsqz]rbmcsnujrpgnpao[intigncrzlaxkbbnvzv]jdpakshhywqkdtpzsfg +fqlxdtfrxlbrastov[sidhdltoumwhntbjbb]xxpxptxxuenjeqexgn[niaxbptapvcsoax]mwfkjhzdxsfmpdd +zwjiosjujxsundbpr[qtakztwdxjnsnbj]hstbhwdwjkfujcl[zlavkjuknwcrshv]azyjashinydxtglzap[soonufsmdppzwxws]eulwduyyqxwxwtxvf +euixknsdzvnvairuenb[lriewvmalbssnurfbva]dvkofaligokdhjdfhmc[cegqoaqltfwtkexh]jcpdqbzoykxsaewvkle +jlvzlamdbscjkfim[nogqesekrawfckn]pedfdrkstthxprlzhqp[mgkxjaxugoyetlbybky]owtfewvpbwmiobnt[gsmtvavsebjcytbl]gldttejkthcainnw +vleehsdlxbcduyk[epbegqkqvpbetnqqur]utbvntyotvbehdw[wokifkvqmwgzhqi]gshozqmbybvdpzw +psberheospownrstmdb[hobixrwwbcjzlkrhyg]uusuyjsjdbjdipw[zfcosustjcjhunt]azpzempiylqhxzfdgd[okrowkogfwtccgrot]ezvgnigzhusxnyb +cawisrurjjercfxhg[anmauekxeejeiximk]qxxixahhioggyzxgt[ckrftztwxaprurc]cqgqlcuaxlsqrslm +mztqprjejzrfqcknl[hgvormumunnhyinact]oqmfdxtlqwvkcbnjq +ddqxshliyzpwmxfz[efqwuxzhnnnwvmae]jsnnwmmkbppdxqzuebu[tuqnsjbhkznrjeaewy]qgxdbtoafuaopmrrc[rrztddfevqzsszvama]laovqbyjxvhpqei +jftpvubbjalxusud[gixzcxhftfszswi]pzsztljzizffceb +hnqlzwizmeivopno[ybdwictmpmudjoelhe]tmqlhikpqeasdgikoiz[ooksfcddcpwmdbr]ickslqdrtjybyhooipk[mqbxxbyvktocntv]kbecbfiqbywiclxoa +mxaocnceliygtnt[chgbrdkhugvdfvt]bsscipyhkcfsekr[nuzlhwyhkmxuxclzwk]nuwnoksstdpfemu +yuptzkxnywmlcstq[azizdckkaibnwtjh]kesoaxduowrjwnnuuhl[mtzhwqznjijbgfmncgm]adqfnionvyioeoh[rgctldknwjmedqrxfof]wujfhdmcxyoudxjew +aojnbfwkkmhzkrlvmls[bnydjrladlbfsjm]ppferzjwrjmvgdq +pvbkgycmswoaofxzt[jqpftuvzelyrqiur]jtvbpwgglokuycce[odeunkfjfnhsdgk]xaphgtoqxoxeiaprz +hiykncscrcsfznwlsa[idrrvtjpeljmnuzcwg]tjlkziajdeqsakkao[xuojrksmvmablcz]jafrcrvnbkhyjjng +yuykiwvwvugeegtbkx[gtfoajutbcxcorxnp]stupzwvwhfaloddsotp[gqurzoxqyhksfkie]itbshgnwomnxpqz +vbpomdpserlvmieask[tqjuggfhprmneivw]djxlzdgolqmhkao[cpiglqvurgbaxadba]cwyeykmfnszwyhlaf[teqhpayrwdnxagiidq]ptvnkeifvimgqbfqj +wnnkshlawsyprxvsgy[bvhyqlvxtgwttgvgmb]ajkhvejrdevvilqvm[ujtzkisrhcwjawkpp]prfxzvzmtcccialpo +uyhofsbngqurnhro[plqzlpngwhzhfiarqz]xqajzmywhyiqamuyhof[zbgmoktjsjelnkb]xfypsqvgzjtgzbyubbo +svtvybgrxkankzx[fuvinmadnipjxrtj]whnciqgscsntbktd +ogmihypeokevbjqtvb[cuogkytvglrpvpkcl]cpfkxrmfqcejxjazd +enskyoaaijegndjox[flvbziostlkjvowo]oskdogvvipfdkvwxus[rhhyxymeviwltjpnws]nwvpwwvxzxnngtn +kegxoylxvwpmgdrin[mmmvlxpcthmodjykqvg]gpyysciahkottruuy[hswsbitgguxjpzi]zdforhdaexvaskgkxud +qeezojkbjgqstiyvtkl[ubhdzobsjvakjhri]krfizmrhuqhwkzzl[kkrkurrvbsjbzru]rdedxlmltkbyrfl +jbdkqtpbpekdupxqmz[emavdfxjrmcupcagh]hucmtkkzbozsefonohh[gykdmwpdwcggqozmf]xypzhnaejxoovwmey[ygpjhlilnooukjlpie]qbnlaggaqpfazbzcz +mrxhbcizrazzesmtn[nkskrvdwnxhsksugs]dhsgjqblxzzvfehk +mgriwdwzebmpsyeisz[iyfhezgmcpwvqmng]jfdmdkcnpmfaxdwdv[jnatlhvlqgotxfoet]toyymdknbbiljioo[endxmgmktdygkbem]xtxirnbghkbhgyt +iwkcwctaiifccyvx[dhreuhwgdcxdoaesacj]krojhzfgsypullwh[auulusartlbzxww]wvtmyrlsuoaqshxs +qwlajgzkuijkxyyobu[gbblqehetozmviszvb]itpdcmwthdsvqebfwig[odigspkfzgljypqzck]hhekbpjywzgbutrsmjh +cynmrmkfvmoebkgez[jzaybzotjlunvvfqot]tiocypxzwggoxmcmx[gwcvebutfmbpxuqh]ggqtjzmrjurxqcdxivu +agxxvohnbvmcjufyjdk[qlqeonouztkfircb]wggnpwpnjbhmdsdy[omrwycukclrnonoo]cqfgbcjzejfbiozco +drrgfvmqoumkispbtyp[iufgziylbvyleequkcc]rmukeddqyhuqevq[ruluasxbpvhpooctqf]jkjotjldovfjhsvtc +xxlahrtevhandbwroy[pcraznkocuurcgsj]pjajsaxktcpdvsbyyzp[tgmvgtqdcjkqsiqhi]meyzuvytavmvqvwkbt[lzpuiedmvmzcttntk]wlvylpwgbphxadzzw +dvuxzjrjwvnmblmj[vfbseaawbpftutnh]nzvmqwsnulncdxujiy[scainwpdjofjqjtoaaj]vhtwsvzjcxkcriev[hwxjhdlcsoosbgei]znobbrjigcpnsekcp +aohprtieaesusqzct[rxeifkybhndprydjfd]krwfcrwdefuwhwl[qncjqacmkmuxnwhpgjf]cyrismwksodxfswc +wmcyfvxwfnhneauhgge[jrvogoqcmfoltzs]qbaegqpmphkondsxcvh[ahxrnnjutnixwos]exmftfnqdjormjpl +nleqavohxgdpbxemz[ieaoydhnfcxrcnaea]cfnacaezpqaxeaef +uzqtoyqmvlugqwlyitr[sgxfuoyuymvktnvbj]xcyadfqmlxgmzqasbp +vwtwrwthqnkdhjlq[ilrhmekzbibtyrdzefw]oflmshlxwclsrsn[betodlpmjiqvzkmxaj]pnwzfzthqidonyx[swqvtscumgjohkuy]yiiohppikeskcygdht +zpmeptspcezjvhak[uyjaxzismpxzmqs]acvugzigemnoelhes +eefdpemsqjhxthkhbfj[gsvbehxnyhhoehtmala]cwqtbyqnndgjfdab[snsdcfxtdcpmocaig]lbzzubcayijfxjvq[nnglxyyepowuzcfxfc]exftztcstqqkjzxgcfl +kbfpnwnlptrkchm[jvgtlrciswdwjpmre]otpqukbkhqgxzhl[xfygtxgedseyctuf]sywdtsfgzwqtzipzujy[rigonhegruewmqqknj]hqqjsjjilqwbcgjz +sgnkiiabcovqzfpnn[vkygnyxpngrdlzkcy]dfgbiqmwnuixulrubdm +vacsabexiddvjpae[uvxtrszpciapnxshb]ghuwfleiiwyxvnfh[nlyyctrjyodrltml]oddtljkktizflewj +sjagfvgzfirwgzfncvi[escyvycktqqteujdf]tzscvdivppgiunla[gnmeersqdxblaqxdxx]orweuxmleakfshe[cnagekzxxornsztbjb]yzvsmxolljxxxtabjd +jyrxuhirgsjwvdb[cgyfsvjjyjtgbfh]mtefdrhxxvxhzdfzvt[ftlnxxaroyqzurox]yeeggfwhkkdqdmwdjq[qojfuvhtfvbyiiqzjs]tzpetihzcsaqmpqrfa +bjaexsnawropmbsyqah[axjgbptxigrrcqefs]pbizjcylfxsjztupl +mkfwnwfmaxjfvbd[tbdqrfncqhqfolrohlh]vufbysbumanpwsvplk[hgccgaugrrifthwqmn]jqfuefpubmxlljqwasj +sxlxlxhmodwwwlxld[emazxtunmycokpo]zmtpdjhowqqognt +tsqdulffcaxdqzhreo[dhxegtmgfyqeggmanm]cbfkamkmmudpqqe[lguxotzyuadywbg]bopsbcslvtkabqmly +iqvjzuupdyywqsnfml[wmrdmfcjcvntngbbw]ctoelddeeyheejp[mvdgitdtomshgeyfrl]cqxjyvfoikwebiho[rkltpvwgobbhvocruq]xdkwjfechyvrlbpxet +xdoqpyeckdlaiszs[rukukzfdtfzmmnk]aqpqwackscsqlml[xakkukhjyrloxombkn]ocqtwftdgowrrtr +miavqilsngerosmmlh[yqnwyxkptnrgwuh]zmacdwkbtmeiogmw +tirgarumxgeguzenzic[bnvitcpldegejsk]ncqjdmckryasjokmrr[wokprgiunqngvojn]srqqnuyooampjrzwo +wsqnzcgeghjpegehafn[khldptwssfvljpvt]etwlcnkuxlbzymrlsmb +kiquxnadzdgxxpex[eynkhbuajcefvhzxc]bjcsllfwpvuymnbiqr[roiyobkmmfomhnflpr]wftiprlltbfjjxckzhh[dpehbckgfqksmudek]hyiqoytirusiqmkjqio +galgxbwpysunvtadi[tixmvajxwyaqbkkbrtn]wiqwynobloyzexeb +klujuavsjcsvjju[wewpoytrayrqrhsqnm]tcrlmzsqhdoqlnyann[gfnbvifqypvxipyoun]dilnsipmuhjesppqju +ddesjlkpijlflrolxrj[mtouorsfscxfdyrwac]ppyvpitgkmchfjhgup[qtunszixycukqwhmycc]bqoxbvbpayesttsz[mynsuxmrxhmhjuupfp]bpvlqetvfwvddhh +niibfqknwxomycwayj[uwpbncnbnbjdktrfp]xticnctzogcgummf[uymncaoblvekoeq]kycgfcxwpluejthfigz +zvdnfqgnpxzckphgak[cikazwnixzopcdu]kqghwzhlhshodbgwyaf +dlmkotqywgjhwbx[xbmqztdikktzmoop]iqzahqdnhrjsscw[vtbnldlnlyiemtkh]zgubuvnujaavugb +gukffymwcehuzqmm[whsnyfteuuztughezd]unjohwlbznalhzziio[vtuadjvxthrwsvbumqp]vnialcxezvuolabtlq +pwkslkjhgcpcwehque[xrjuhatdqjzppuz]mjwsyqiidzbigcjkqc[nluvxxbfpmaljcjfygd]naiapmpcpdqatidqrv[uffwdvbvthmlhcfkkge]cnlmdjwaoubyedma +ehnjnlgljdsybmrkvha[jqaqcxtwzfbynxfzlry]kknsqtggstgkonnwqbw[zfhbcthldvkqzeeamv]ztsziucppbuckie +vbfpxyrslfviwjasotr[igcqcyzanjkknjrtec]kvvpsdwqsdmeophr[nbaybnnckjgjvzpqbz]wjfvxaecmhtxpbrild[fyulyzxzafftwhpz]unojeclbmzclhzx +pkgmdwbjrzzgicfpsc[mqfflkezdwpwykan]ochvvwteukpmhrhxjdx[fcskceneoiiylbmn]ixkkydgafasxxogq[erqgeoxbdrizkacisih]pcbrdfjopcdentkhyht +yfywjwtlknqfoubst[xzlppjcjwgkncwa]sbsifrdawjsphpziem[xmxeveuycvhurgnf]hntcfimfscaohlvwpu +ngarjrzglcxqbjqxo[qyybkrmiohhwlalfm]evhremxjrjsorhhsm[csawqocrcoxsupodwd]lnwsrxgoexppbnmlt[frvavptmamvyqclcwwu]uxbegecmhuoipnlvux +gwlyylsyblqqnvbj[jzzagfujmvwcvhlnhm]bgqddudaiuchcfh +mvijkuegdrpnmnb[fibqrzhhvjjaleraa]fcjabpshhhkbcmcr[yodmibpoadyyjevu]orjjwjrplvsitmbdca +tddarkqzgzcroswo[yiizkkpjcrnwlagt]qnbzxxdgzgnxygowzw[tghcmhqbbtkddvp]runjmyflfgzyjajg +znkhgknlwpazsethi[amnxbwdzvbtckymm]fuagoeyfosfplnvdxy +exrrjmkvsiplddrfk[lirnsrcctykvjrgu]dgwbrkchnkuochq +rpsoyrvptolnlxr[xalcytpzlzithaaujb]ihcahmluroytiem +hzhjvwoiwyajqkwkmks[fpmzbcuxxqarjimbpbm]fholbzryqsprgswx[tslkyxnthjytovov]tlgcsrdfeyhbfdei +ogfidlqvtruzlqiqx[cqknmhfmkbzdzdnrn]ubszlidbpcietcbpib[pdcpbucpspopdcgmn]ohhqskqdwcahmkslps +pzorygrmbbofzzzlhr[djxceuyvowbcbyrrp]cokaahrpabxwqccqaw +wqkcjtsnsnrnoguze[qtkujvopoiwnsnyj]wjpnbkzsrkdmjwhk[myorbznqrnieutxbt]bivalvvdqsjssmgoin +gvswtukculoxwywlgvc[rxhwthbnvgiszqj]dlxlwsnngfxtxaxra[mmibrdioonvaptadxnq]zblqqlhosassxdsmj +njwxcxsbmlqnujsv[zrpjfusprxajnokgam]gpohycqghidttoylbyu[jvqgapignxfrqlo]lfrmfxebbwhrukamfc +gkbgeoxxwwajzwloo[wglhbpldleateucgvnp]gebfovxsodntrawztcu[luvrntxtspjxpci]qutrtvabsfmedptbwld +walfhzzejzgjfpsx[yikqqzzxxwcvmsrpi]mokawvbvxfshenhrgyl[qzhowtlxzlhjnrvos]uzedstyhtxyodwfxngz +awoizwpnpjoinkj[vrqxkukowgftublkxq]ojorrutzzusfsiq[jfpjktqlszpktiaz]eknozpphyjgvjock[nblfkbhtcbiywbgqx]ybfsrfiqqhuwwfizjpn +kzimhyucwdjwzsxueb[ihapqjxphsmmxpx]rezebnatvsijssj[avjsvhfagnqhqda]wdropwgmvfbdhxkyz[bxstvyjafvdzzhhj]mwioxpzxyxdycwmotv +wdgbhmdblqkfgcbkqij[yecckefvryjvkdimdj]owpkgnzzbkmirdvij +vvtclwrmitixpftahev[qpwnsefletbjzuayn]fdpsflowuakwchowud[ilsvarhwqwjncud]tdabbnvupamppngbxet +yajftdfqbdgelonjdak[cruzjzvtanizzvynbw]vkxpoufluztpjhb[znuobtwgeitdmkclh]fyagithnpbhoypm[dftlbnxeuoasdurqbk]rpyzntgwhlojjxuj +ozyzmowqiyoztwjqign[repdsdluemsybnljcsc]qvpndzlnkqibgxtxt[vvktkdwnendwgsmmaeo]klrmgwgzfhttmbhs +nkuebzwzjkpebvqhbm[pffmbiwfocdszvehp]mvlvhepzzgqzegswk +jrcergxhhyywczqsiml[jvqkldlewhqxtqyxlje]tjxhzshbfycmdsdld[lazzgyvnsjasozw]ewmpsrjofcfvzyws +jmdoaouxainwodpyklc[qduttzgoerzgvkhdah]xbhooltfzxprajhre[ahtslpntzsaogqegun]dmcgjgeqiiiuzkydjap[vqwgftbjdxftggd]qbovldiitpdlythgrq +essziziabrdbohunp[ipgvyhitrfwkdon]obxpjfscqsxzznfk +swwyhoqigjoshxypupr[ljqjnmcmfoznekdz]vlfdlqwurtizditszb[hnmvrsihruqihuyjxm]kakjymekxbirxmf +qjfyellapmwfmyly[kunxkuvvwdgxsefm]sdpzdyvpapvnfybmkrh +yofobbkttxblpfbuyee[pfpmckdnyfrownjfup]siyloupsjrixrhwl[wyhppbrjcvlqzhgtg]zvtbzjswfqjtikkpdlh[rfphcxkyguxdyje]yillsqvxrnswpwzau +lpxrtppstnwbkugxfj[gmioyrpgnsqtrkh]cqvxtvzwgvaotzwjij[yqqrhqvlqeupibi]tzkunpenomvrkwpbfd[nngwswtnogzzuwb]vvfadzquqbhqgrh +jkujtmmvicmjbxukil[bafidxizxrpnanagh]ysakzpjpkpmyqpotfgw[zbpeepkvzafmbnf]fjssjhkidnseugzc +mlyzeywblxtjlvw[ghktomogaldxwtljod]ijjkbhgjvsorjqh[sbtijfnepdpmzskwzrq]bkwjgvhycaitsow[zvvorhjhrttukklnyq]ejyrfajqucpjfky +fzobxvurbcyszmbvb[ndqmlifmppvhmcfjmhp]ecuketkngdpmhqdnte[uwhufpdalnwarrqqnmw]wcgemlenpitwqztxgd +uybidfvdwsftvochwe[sfehkmzqoqiadkky]ytfxldmshamrzftqlba +eikkyfkguyhyghs[bacnjyjwhljzbtfrejv]hwiyjtsgncwtvqqf[avhvopepuinywcbw]yqlwlhnpevxqseqawt[tlkkrddoxbowvgpsxy]iencigijldepvgsbv +nbflbqiqkunampmoo[rnmxqissfolgstsska]kjrmmogbujwwefrxng +tuqhrszpjlxatqml[hxdnhgixlavniikr]sdwonwuqfyfdtukyvcr[skyxxmuzalmqetltb]ubhcvwrpqkfagxqddxc[otpczwgqjycfcjkbn]mgvwealiwijddyw +xtfpwupdjzgbiguw[ilxpnxsmicnhciwzed]sxujrtrobjxzbnl[utaftqrponqfxollpo]umcdnurpmduumbiqw[fsiplgyzeygxdam]lrcidphtbpgeioifwa +hwcoshevixvzeohpnnj[omkygcmnmivmzxtul]vmagndyfccnvivsj +dadyrmuqtnaavsg[bonytbjlittroyfwdkm]tuqrsrjkovehrcuoq[nzxtnakmzxfxpjqs]pcvsvijqxlhcxxfe +fubygknvjuwgvgshymj[puqpnkunirqntid]dmbnbjrijwpphajnwa[wlzffvubhjxaimienv]rhmuvzdefpbvinbn[zebucojhlguuusjmc]vlfivdncfjszmtglnq +hnpjvwcaeveaegzetm[yfhawojltwnwkwlphlr]hybipxasndfbtyqz[lvcbmzffftidyscecvh]vaxlwmjbxmsawhq[etkzvjppzikagthunsc]yeoxhcxatwxwynsomaw +ebzcmhhycomllbjvvw[ginoigaubpravsyzv]qsjnhtstgukhonvnrj[ddhwvakrvrngudjyk]govlhgeseypwdml[upamuhmwxzyechcxsae]adgykulqufpnvyhkoz +dsjnuwymuydynpsbx[srhehfurrxstlvh]aizdwywdkydydqhrrm +whnypyswxdvibuaf[jprrzmmgtuapbsq]fnezzlbhdnyyzyfsgdo[zbkrotmyfemqlfhj]motfxyxhhfcvbsmqth[haplhxagaiyfbbvw]mqvuamzczqzzutalvm +qejybnzauvklezaxat[lvcyutafowlbxiyjvry]nlrivlmlsrwpmymaki[pqynpncxdmchcdlcey]kivqpctoajqprslcya +bbqtegzobdomeyp[moubpdrdmsilsvduug]kmpsljwwlfsfnxisn[jupswttsazzstqcxnns]besgduewpkaxdgfpy[sfsshbcwxpznogtpl]ggdynqzbpgfkdna +pchcgopdpykzejlzet[jnemalefeqibkwkztf]jcbzvnhvgvsqrnc[krgonprelrikhqbm]avtigocdwcmhqlanl +igkahohuybjjdsvk[ddpqgrxwizhtypk]chtowtzshvlozhf[xrolpgignxavtcjmaxk]buxbbdgppyjqurfit +qyegpxetuwnvtxjcl[haodzsylpffsytbkbgd]duofhwftoyanbkrikbk +bxjuktpoqhnzhapoboa[ijejsuzsaamipeuqe]ugfhuvymiejnoyglivi[nlfenjfnxuofpsqv]gmsgugkqcnenabl[ruapmdnisfjitrzmnr]jxojarsmfmrtmcc +hzkmfirdfdhysgbag[glregrenstflcrd]dczcchuaisyvpofbdm[ofnuphddpiimwtljk]eamhpkkwyyjcudoqjlp[iqxmnhhruhvwykr]yghmonjhccqlbwqfjp +coksvymgefyduvwqyb[omlsfgbrafolaxqrarl]ztlchazfvqvofntyqn +kojebokyfqpifeqr[waveewleyvhyyxbbwi]rlftzvgorbwdeboixif[lqiyszzbjnbllhmn]lprxnkmtivebztmvha +ugmzrcwbhsctsaetwa[yoydtlzukeyfxiojis]zaddblqtllumigpup[fpgfbpoemablmbovgai]lxvlbchpysxadxy +dbuzmvrmwlyahqjxd[ysbljqipyhbtfxfsz]zzbmobgoogmmqfxuw +aofdjmsgbgwrrbfe[vcnkrktlkrjgpqwo]crnyyvrifvccdsffj[sivwwrcsqlsncytebdj]zxwovtacgykwcqu +xtimiqzhzrpmdzoeu[dumiqkncikqwlpbzuwc]ijgoorzwtoyogahbzw[sndiwpejqbzbksi]bqissljfewmhthzfr[fhfvptvkrwmsvxembv]bmcylnvgczaoykwxto +smbefwqfowpnjrvj[jsrmqvxzrlockwrfdkn]xzbebsvxickulfvcc[bgqnrsyhahbwlkglwx]zcqswywwfxsgdytwwrc[kbjybpynqssoype]kuvceztxgdxfzef +zptgyycvygzcpqyr[zopbfyswmfcyqnzw]czjhcywofjoemnmgk[hkfjofyhiklfjtys]cgguodgbyzgilgjr +azebcnxvrxgwqftti[jbjfvarjyawqoms]iumqfeogzuwcdsipoj[zqbzgzdbrhoahav]rpbmxhvdzkvffnegip +rnkbchnaplcaugzser[qqnwunmwppjnnzuw]frhraurwhtayoegoa +djdnoqvailodztt[priqsqdrtywaxmepuvp]lbflkgxysuxjammwj[vgxrcsygyqnaaxso]nrfpdwfnmzznmvigdzj[vxindvfzagauwfaflar]cxemhrdhcsbnuanr +kxryribjlgxthbcrd[occbuoecgilmgfcrotq]dnrojjqevzdxplwizr[xeytpiswulytyma]ppjdfxllbqsijgg[nmjjllckovlktab]slbrqhmiouzuqqdsyi +ojnsmjuloqvprufj[tkpxxbbgmagiatfiwvt]ddgixitcijsibqydznl[pcugesshfvmbqlshpr]ecdnyhjksojvcbwjmwz[orcodadsxpbwlqpjy]bxrtwpebbnalwwaajzm +jdvdquoycomtlulxi[vilkkewafttknrz]unvacfrcqrhhguidtl +abudfhatbaveagp[uwlypdgoikgmwvqly]djhbjwumcgercmstac +owtnzftxhxmhdol[nctmtlusvapfjbmj]hsulaqofhhlydjdbrq +oyijndyohfltcvf[lbupfppgfpfvhcarwjr]tseynqkdfvlkzjcwfhy +fdtdkedwxvfnnodin[beafbnlmeuzyeghzlnd]rpxwxuejmkfvafyzkfi[drhznurgrbstytrnirr]egmxcqmbxkhisxp[dtgdbnxelpnefhoi]fhecbdfkbdrgrgmyx +gzlnfqowkbyqmibsg[lzywadxodwavkhtxu]wpccrmtyleifychjr[spglwgrhypdouknj]sndgxjpilgsfyxedpw[uafazaaiwyzyhxrinje]mpfezcobffuqliauwnc +ufrgsazkacoofwcupij[asrwuqgfertmqhum]tufxgwsknrocnry[kpwnjrbysrpfexnh]uiyxwhevpcsahwrpt +mwpyjvycgsamjfo[llbftirpmajykidf]xbplgjaytbanccwggq +zhnceamqyoqjxafvep[kmvpoihyjubmolutkba]shdkiobkihapietwdln[rzsvvyriruxubmzw]lnjwcdewziosfrh[yyfcxuivqytghxbans]cgruobtjvdavlyaswzv +yfaeecsnjninyyq[izsyflxexjsfczjw]ajzghdmkbqourodqkd[efbiapsnvvshxkszvv]ahyleppbvgepnpsndws +nvaxrowtfoihltgbnh[oicqahjzhoqawldc]xjmimdfpycnfabpsmi +ecbzvkvwejugizqkkau[ilkbcblyfmwyerln]ikxgldlxptakjstofw[lpplocnwmlkwzxj]flyizzmlmwycjyid +rxizygcwbwfmudujg[adxdzbnomnidudamavv]yqcigoejcfahjqioc +oplxtbvzxwqmldl[nzhtesvtcuuhnuodbek]xyywwnhnfprudxp[qurogpiljgrtzlseble]garylcclffgnjoabqny +axstkggsonlnbwali[blveytyeyryrrmeyenh]xcgepcxzqgkrnovmw[rfgktkfrsvorqbinnc]atmhkdbxvrsnyix +emawdiuxcsjsczh[xxemsxaurgebphwq]siacfvvocetalrm +hoqezcmfxcbyldzbdgj[ncczfgmdqzsslvwuw]wbywkeznhcuvhyxis[giyuqsdztfjzibzuu]iicxqdsgpkzuwouu[fbbiakfcdmatawdhu]rnfjechuwuvbkjes +pxlkjszedeyandtg[vzmztqfouhicjgyhn]ghdgurhvaqyjvwfzoi[hdunjbenuuwsxgoh]jgzxuctibegtzxrdi[vtkikughinykgouumj]lwkhwpgybfxftojc +inkbtzwtccdnerpdx[mzwxeqyfiflhakjodsj]mnsglzqiugdvutbs[dxcjbamluuvpfajhbk]durhitycearjavxqbo[boldvrkzywpxpwacs]tjgqrsxrpmaaqzn +zetkijkpzfjwtkl[patsujyyufdjfjdlyin]crskagradcyyupn[qmfftenpdtzmolxplis]hwdllotorjkqtag +gfsmrmrrhmhumyqjsp[otatbgppuxthhvoviri]ydqdfbezsnbqiulb[ryqfalrmrxsencrv]cobkfmwofrhzaofnwu +extvjeumduqukszdj[qqvnhgfrlpwquqoqim]aqopphxuenwysihpqes +bkfftlgxbfywpkzn[stxjgnocrsxcnxnl]rmauhhaigkbagyiw[wqjohxfdiwvoebtpzf]aqypecqnfkrapjq +vfisywjwfomqnxdyt[tflglumsfyusvtsu]cjelvptmnjpamqfdoj +vpzyomkkfpuizfab[nymsqhheiemwakf]nlsaqwycgasqvto +kfsphnukvapezubfa[rvpcbqzzfmhfoafgg]thmzksirdnczecb[idnjlzzhtswtdkpjkj]laekyuhoaphgcxiavs[bsnaphjpbybtsccdtv]aejpyabhmmijvspvl +wplvbgumtphjdcyoz[itxailnslkhdprewbx]uciulwglmwuhmbiai +ktksdqvsrshsvggve[grfqzwaqjzafpouzx]erfxekjmzygkxknwpd[bebppmnerartdednzxd]bdtlnylaxjkdiuz +ixjuswimkhrepohn[llzfpekerkwbmbdjx]wfencfejxqugytmc +vzofsqoquvdpcmd[zrzxijrndisptemytlz]lucezitrkbsuxtfcsxn[rhcovsvwnjqsycbblp]nsgbadwkfbyomsyufn +opxoxtwdyxabcjqlsp[jsbryhbfmhvtjciohd]bqwushnbkblygsnugyl[xigxexrxyphtraydo]xdbmkyrxlyoboshb[antssfzqawswqovigu]dnxnfgaerzwlippmc +dukgppmqemezybpyj[dzewikpugbtdzixqjc]mqeinaonmeaisbfsr[hmjrbimmfceegblerib]agmofjqzwimbwqja[odsegwxtsuasjpkqn]wikmfsuuhxcshqmf +pwvqcqktvvsfwzoskb[ijshyeopqvhobqwvnj]txalkphvegektizxygy[daifwzdfnajqdifjsm]jnqzrunzmgzpeqwvvl[gzncgfsgqltttcvedxa]cbfuzivokyoadqac +gsgjuwftbhhfikewzd[nzsndocppxqeccyxhwj]kfqzfilqmjpkpersl[iqydsbvxstcexvu]ltownmcrtkdleeqit[axjmjeddwjwwkajy]bunnjmdtrwdckohsbh +vhukbemzjwjjywbv[ueidxjmdurwauemunrz]amqiepbhdmmdzxhzs[ysrgfjmdlkrycxx]qevervspvsigsjafp[ylfhzzhmpbvfwlqwppw]jixmhgnhstfzqem +bjakgnakukatldw[iwlecbanzufuuhfpv]rftfqqralrxmruo[awkuqaoypgaatlz]ayfnqvewpbtkqfrmzph +wtngccotjxnlpag[zzzqkhkhspyqswml]rdhwakgcytjxptgeno +qdsjlfoqdstuwmize[wgchicxbtioiuywxubv]ocaxcmnefuyrocckw +jxdgkwiboqykzgpl[sylyvaoismnuimyms]yjeljspizddmqrts[eddmtxaxjayqyldrkab]kknnogloewbujcwwqsn +xeszwcfrudkhwgvhlz[gfzrcibirbunjbftwj]ngkygalyrekcbduhltv +vbugbnooeufxostaeg[kqkrqzrfsppmkyhht]zdcedlpugauoquq +ewpjlfbltsqhfpxgm[fvmecdntimvzdbnpin]biasqqndykbxhormg[tmexezovdnezsjdpu]tetcfwyrwtrqluenrr[pqdwbntptnnjzagxvfd]cakfqmnzrchyjif +btfpfterlwsvxom[shuzfmaoxfjtkes]yvsxvqtlkryepfpz +jcghfctceivcaiweue[eftngalnwvhjjsmznr]fawobojxajdxwqqzs[ooswxgrpxwyohdyruo]nmtyadyigbjerrgww[kawttctyrgxigajaicc]hmwgzbdzmeoyths +xgztroshpxqwqrsig[albtlndeyhthxeysq]xssxdcyjkygctnmt[kusgxaspwbcwxdiwanr]qgxqzkufuibdvexiqlw +aupdftbvutytjjx[jgqshwanddjcznrt]bjiwzvzrgpjhphjmazs[zxqiwfrsraampecpqr]trtnmysitgttyqibzpu[egnarxlbujtfwducwub]kpooslliceekqkjspg +nrltgwhurffmbzkvik[pfytsodylbargsdnkfg]cyftawynysetaggk[tusfvggrehkdyqynsn]fsdzpvhetavusseeep +rishwwchkjtvjkgcvym[clboufuojnycwdykmng]nrzsdoqccrzoqosytw[mhacptzinfmyruq]ruobszhillkzobd[vwgzdvemczewlfdape]jpjduefvxvkgdku +upnzmqxezzcuzpzi[sfbzitvncxzvdsan]bxhuatpfqfbbymcaqg[itxiiqrgfdiqhqfqkgs]gpykhbwfsnltkghfxh +bxjrsxeqhqtlklmzwr[okufumtxukxzjmrfmyw]vxgitxdacjxfufuujg +adiajjvqyjwyntoub[wcxqhnhrnuztvwqlm]erfjdukzqyrszhtax[kzrmzsgszhjkgfkmvg]tutivtoomopkzuhz +jmfdcptafqhalvgp[acykarxccznwnon]qljwybbiabdhpyf[bzdebbpnzrhbxng]fuxeqebhacjqgono +qdclvvpmahtnmubxknd[olhalegsarjferqax]qprlwnitnszmduzhu[qctlsakxesqxuczbqj]yteehljxvedbtiex[dwigqthtobxjrdcgtgw]thbbpflwfpvcxvskpix +awrnjmsqjoktdahkeqz[grzlijsrdqkvxmoa]wzgzmyxsiqybpsrxyjy +sinwoqzusuveolw[gmiafnhtabdkfxyfwz]kwcyzjfxiznfzlmfsd +crmcidayayyyyioqinz[azvxsonkimgggddb]yorlkxpvolfjbglxvzw +pknzemrnlhfrajkog[frkiaelszmelrcgc]bsqoeaktflqoflqz +bvhbloqmuktajazwuk[yulzhoaebdclieex]rqtszqjfacjvsjq[vrybeabdclrxhxp]cmvixojwapyymzqa[wsgbuxnmfkfvdgdf]uhxbtdorobyjptfx +vmadexpdpxtzmepfrh[ztavnqbmxjvtmhjb]lukmdktfzxmduxk +cjfvizczqyqtyzswz[tmlhxvszektensftbc]eavgloujdjdrksy +ceuagjmntpsfznxkei[ydzsscglmaefrglzqw]rgbhuylnwnlthnmm[bkwhkcvwglgvlqsqzez]kckzcvjoakdtivghu +mxiknolwiwwkfxzq[ecpirmmrhbcnsel]mwoacrqwpkzjgrukydd[ckrpozlopnumxau]zlujhgccbrayveinccc[apicjpatyfymmqpm]yvxsjjrfhjhrbgqm +kdagqbilqlgxsqsydu[bjurycpobwakkhdynbm]oiigpwlkpppteqlqph +upfwmcrlhwbjrpspnb[qdhwjtfplxjlgshw]apoxxaxjxnikymhmavb[qbmshekxmrypwmnftyk]hraxfltpaxhwphiw +byigpthtxeetehtygs[dyjvyqzjnitdakuqdx]hfesbffgslbplwug +xdgznsxshfuvvhy[gwlfajmssomjseg]unlmteiufthtldgxw[xsvoroqswoitjkdlool]bvpsmfjevwvsdzryycz[rfajwhdmwspvwpy]zizcfstjmmrkyga +iuywcnjjgghpmpj[cnccavsvbpousjxxu]hncnlufnqhnkyfdbzbj +thjipbjkfgddudxs[spfbsnppzkkrjocz]rhjypobsmegxjxbnz +yiniphjdjqyhbwcqumk[vxctujvgetvbnin]oznxmbhfgorugvnbqhm[tpneajssmiyyciuv]doipfgzftkcpfgkqjg[ntoauuoaetjmwcdgl]muvskibkdazqpzle +zatpeicrnqvfwhzevir[achkrxpoddhoouvw]zqomirycphnjvvnnmrq +gyewjnzbzlphmcl[goentnfvtqkjbhengqk]issvkihotsdxrtrcge[pjjynwjxqbgdazrar]vfdodmebolxxrtblp[rnafaodqrqgyudz]bokbyzqkrlatadrafic +fcrqnhiztsbrqbfpmu[fekxlgvgnvdrgpewsh]mlvilpahenxjdnkfd[ekrovnfkukxcttdybv]igiafsaabmjtesxoez[poymdoqpgmvklnplxs]qvfvnidapmufkipfcaa +dcemjkltlvmtwmofo[kyaudzwtxgzgmfmxzm]yghjbhjodvfcesp[jwnfoviyntxidpqlnpj]mqlrvdrlysriwcvkx +vziylsyzlvipnsh[cqfgzfmbmnmpgebrbh]vkrxdbgfihqjbka[egmgpijxkmdpabo]blbwhpvabwahytns[tsrrxdxqiyuiysi]hwrcfdlrnlrqogzjphb +rkgwphaqmotuuygbi[bpbbruvyanbcjfhfp]aanaxgqysluifteswxr[fbkbtztunqaeegygqua]ssyhyfmomjjvgao[snutrvblikqraplvqpc]aqmgbfijmnrlazy +qyxtxwfuyatwfkk[miumakzwpbjaxrqssh]lxzwtxthscuobcmqdo[imxykzorfeucoihmte]xxfwdpaeravliey +vunybsvbkzmwaqulat[uensrnacojplrywisqd]ivuvkgwszkrlrkfnne +otlulepkuriopamwh[enqkhypbjtxousmlvtf]atumpzporzbmfxc +axcaovnvmcsghqylwi[ruleoatoxsimpta]hlhbkpdtzetwpdsmrh[dzhszusmrmytlspbf]wugvqdtzbapnfnqmj +inhfttxwgfttwid[elrhovmfckezycyi]orzwappwaaqffsetsc[veggwpvoxfubwplaqb]indtxjyutvbzuulrw[btlasmpvwtjhpwhu]sxogdkhsqgtdleenjn +vpwaegumvoaxdvx[xzzubnmcxpipvhqdcc]deqghyudmqkokmasp[fovrmnguzanmxhuaw]hthncgthtpecouvybk +scixwaywmasqlyl[orceqekzfxviuhkaad]qpqjnkswbgoztrreipf[ylmiivwsnskbpquahom]qazoofovxvylyzov[aigwlcvwrhyelwwunw]masxonmxibbgdpnx +tsddqheerfdpyey[xwfsqaquovppcqej]tahlfpvdmdwugtef +eixnvtawreuhmftwc[evyrbnlbkghbgcdh]rcepebeinmlmxuu[djpjavkjyzstzysv]nhbwbzyobrsjzeer[gnmuhoyckprysxjoabe]mbznbasseysitcdsl +ayerjogfkvbtcmgaq[ypxqrsfznolrfwfjlyi]pxycrizrpgzrymalj[lptbdsejlsfritmojo]gqfsrlirmuvqmcffvit +gwsubtcbyclfsrzrqwe[ozgxofiupxoobtettqg]jcfmhhbeqwttvotop[ytegfilkxzpbnnmxvl]engbwytwqgfnscmuet +dtbijivxxdayheh[oysdmyqutgglmhs]pshfpdqvzmkyttsztp[bruwawtcymsqtpixsy]vajcsjaelcehuha +hrowrexwdkjaxuu[edhgxzoepzajwcwxvie]goqjmpzfnhapvckyad +klkfnhbjcsvetmgls[ogbrnnzixyzwsul]epnzozjdzuffrtuipyy[ohjtzufdgczsegdop]iwlwgkhuwektdgkqb +exgfmperyunkktocei[ajenbklubiwdguvzay]dqfcyrzkxrlarscihrd +amwaprqbaslfaemba[vrybktqzolkxsykmb]uppwjsgamzzzzdr[hmawicwlazgpebkfmj]vqbzilrohqhydvrdlyd[fsocktbxlwkkqlrvcq]ebhizjlhessodzfcumv +bwsdcvuawqxzlfr[xumvqamkhmeaojhmz]tfljemjnnswaexn[zjobasyqwzlyrvr]ciqqmfkvbtrfmvaib +ljimrxzjagtjkono[gqqmbamscacuaxfg]okynonzqyielzjbyj[dfqemwwhgzaeihmpqg]uqphfysvmmjgszshcx +erhewvsixvvxcjrz[eyfritdtwjtdehuhsi]rpjpspqqejjjqnqx[cemzcwmjisxnepo]thkimqfwnfqxteknhu[kzbbxfyrvdqcrzway]hnbffqdyclalrqrbz +wwderlwkzxrftov[zrizcsrhfncxxhipgmq]evrhodzsbqxtqtsdxp +mrpnopyfrbcspgrly[ooyfmuwumbdlamnpeed]zorwgbsvgwmfupfmd[xfvegbcyklqjzodcv]xujauhxtvanvrivzmme +egyjwwzzdhjpwanajg[vnanejmhmsxfuqx]kapnbrddoomlbvel +yfyhrkxnnoanzrlcdjk[qbuntlfyfapkyzmjzp]darztduyenjxyhum +jnonzlgpufyjnmamixf[ilkmivptsamagfx]rvqfxkybopuhwajawqc +rjomaggyirzljvf[xueoknoqfpbfyrp]vcsijujfuhtxyiz +buzpfyqcgoaoqfjeflj[pahnywsxbhzyurcch]oshukcataepznwjjton[vnumrerfgrawvok]qyywuqlucfzwpnunhdb[avdwhfwkjowovjgtkct]iperivwvqtuepmsj +elziwqlyknthlsh[qrkhzurvujgpcml]szsdkjevjgxkffjhbxo +svkvkdnnljqwwoda[xwznynicehzqeeurqbm]xcdbvrwhslvqnbwtkab[nwvkvkvlfbljzkuvixy]pauwjcnjdiaaxihkan +drywhovxupgktbdzbho[npczquslwmmbtfqdkmv]xnqswspesaincxxaw +tidyrfvdudmssoznady[krjhxhuyysnzclehaha]qvqakaxmebzqeckrtt[rjllwmvyrloyfyvyo]nwawencbmnhjuoulnp +twthnuwmlfzvujyqx[ojbeeirfxaxwqwpp]fttuhnhfcpftnkhyd +vlwukqnxcgvqvuxfkqu[qvqzcsatchyeejylo]bqsuzlobnqtzwlfeub +ceeceksffqchnmvj[izuzaozpvkmrndrc]uzubqdxupnjukurd[vuozmmzihsdnvvknl]ejerkicmcnifawbqju +ayekndnigdqycrpnlx[xxykzedhqwwnckaqu]yphmzyprhhzeowdaoqw[irmlnpnugysdornrtdu]njtkadbeifdveunhpfz +cpeszbxnhskirxolfov[rqxzblndfgzvcast]fhwjntsvomzhpms +iqekaxrwfpgllwdgbvy[wexszmqervjoletnghi]jdcrafwyovopiurtsnf[odjyasbfoogcbvfvzzx]itngdpzcuibvjac[cceirisjlxqbfxk]ogyythcefijdyfiymv +kjilxivdlgapzubqvv[kdflzpupfrwemledtt]mazidupukldqsfbnzo +gkdgwdphyrnqcciqx[xyrdtyvqjpyqzqne]rxczahyeiwdopuik[azamosvzssaydnafs]cijixpozetemnhf +gsbgcxxrcsfhzbnrzc[fqbsuahvhspgbco]ijeencjmsbpozedvkxp[ogxizvbeztjbxjmrz]qszpgaqlqaniqmr +xojjfjndicsbfkuk[fuixcydcggzgkupbumc]pdmagdpsiiilbqzp[grppnkoycvmqsbetpi]xrrdnfessbzbkyjczu +pvxxauchqzwtppcbna[jyxogwglsdoqqbx]tiashymveuqfzqdsyi[fdkkrkhptxwyqkr]jqlvtibdwcxmwdfojnj[agoafviidlyogjezhkt]oeipjirampmhhgm +scdzytmxeoaepuxr[urolfouojzzrhmon]frebdwuouxgsqtqw[sgdlyvwltjrgtwhsp]xbjfuzrxrdlecygz +otgklupktkmwbtavac[wyvprsjidzacbdtwgb]ktrzyvbzsnveqhr +oepabzcnimrxthgu[ebsvaioyvpgawvxwlv]gsyvwsmuadcmjfta[subtakwszcanhdsstd]otmqooxijiyokuu +tumtmxzsvomlsgstv[gdjdgawczfzbzwt]ajcpjdjlvrvlivvb +leygxteqdwiqyxf[xswsevnmiejuyzpwf]ufuucwyuoggkkggm[yxkivwuqyqzcuuspecj]zlxqdstoausbpeki +iikdzjucbifeolwply[mmtddfoasesrcmxc]tddkgqcvngvdvek +vnfqehrouoftynm[syrugqbozyvlzlq]ytuuouulpavbrfq +ausrmizadkahfrh[beowyvexfyonqjtstme]celvylbfdvpqpqkreb +ytptllepvyoythdr[estilqmvzfdodmmybk]buehrbcawkbmemftkw[izepojfemxcrvucath]gjfaesekjmixzrcdrh +evdtdmaowwmfwpwulz[bwrggzenbjnqsyku]qgwcrqfgfnfjhyjyn[ayqqzteezuhmsfoz]joqsyzyllhqzlkrebaf[aahixqinyxxycwcy]kxcsoruengmnfzuj +yeadegkqhjjdeyeg[dvrhwoumlkbffoca]vqrrypwcbymobavcl[qccxmwheinlwnxqprop]phtvdrzuntnzeqp[fjdaddrcssrzlokngyw]rtsmqlzjpordish +gtdwlzyrtbnirzqgijn[qbjuhyhlzxciwzihtn]vgfezhcijflxugrod[amfxfhfpiaqeegvk]sujqwinnjojjjkveufj +mjrvqtjwmmnjifhjj[jywhwpwuhwhjuhozphc]vkyewhwcvwlilsxiy +ouyfkgjxhdictfuoim[vnwqzszsvlucdhhtvtt]mlyaasjkojbxosartom[iopppsiygmpiceaoii]plzvnvscipkkyhvyma +xfhwixrqfffxynxmb[nzxstdnckwqfeytf]hpndwxudqblkjnqhgzs[kvmiharowcqigkgz]jcvujbhlqglxgkcgv[cmuxxdzwwavcujsbxl]aphgbxkiomeyzcrz +trhkvukqejwkgbjz[hlljygrisvqzdgln]ffruvyhhxzxpbtkzou[ljfckzfabfallju]cfbupnmggpzxzklfdox +wbqwyyrcpigsaergmh[zaapwugxhbjnrjlz]srbswjghfprtpbteb +gvqstfxraflbmnizmtp[vqqpwxrbfaglxpwzafq]cphvveovkynmudsnl +yzymzczvyvccvgsex[enwyuawiydvyvydy]ywmzufzgdvszexk +thtrxdiihhwqgrnkwt[trgnqhnfwkwmttxlu]owngvlipscuztlgi[ciurpcebccvhkyk]lnuyoiyzbgwobagu +psttgjvwniwynersrs[oamyvshfynaslrqu]lhidxwfyxnteooqqzs[pnxwfetkofgdgeigll]skkakydgcmfyfuwyfpi +mylmuolvzqegvsrys[slsfmaklnwmlbaqqib]ilutpaqqvgbkexrhksq[qnouzvltrmjvtstaubv]ystsornebtqdepbfn[rwzptvhlfmsvjgp]vqdaqpbjownbtlz +xfugcgbismoojdaiw[nuwyrjiqrcddsckgka]rmwpvltwfpxcuoq +trmkejgqteugbyplxr[jxnfhdtqduoudilvo]gfhvptjfzqolpzn +brxbyjkpskhyxelqzc[eherfigxymatyzc]uhnpycfyhuexifmhw[mqtufbhlvchtjfyqrie]wstbnihxfestirjqg +gmsfaffefdwpylycgu[ycffvzzgcpfnnevwvl]fxaevbvraehcyaxkjhi +wsqshnuceysksrqsp[azogmtnfebuahmqf]ovupfnvnzrdeljgict +gproaacfmidokatbox[ngntwrnzmhuqttk]ertfafnfchokaiuf[lbacfbidrxjrayell]fwzbaikmpnudlqwgwak +csqccwbysdzhoiwq[kqmxkcgwmkhsaraadtl]twmikglnikmbbvulgam +xmikhqxprkkpbrbm[fcwmsjyxoigmdezpgr]qvoohhzozfllrxrmvw[uldnkzvdedrczko]eoqubtfldrkdokd[exvlggwmmfnavdyjq]wcdyuriygbvdtsmwx +yzwaojjbgvqouerlqj[wupouzamjgcxelugdwz]gudoblwwedojufgbl[hlnmcvdsgitydqaergz]liauykhyeanfbqnz[kxznetqxvuxlzovyqx]fthhvuyqixukncruvxd +pljzzzfwedxoctvarjf[preuhfwjhyatfkeepbl]oqvbccylyczavpve[jttaesjxfofxudw]syndrygyumrahgypl[xtyiwwkrtspyhkppx]xfixdfntvxpdsqqryrm +iibobxpwfctxezwbyhl[pxqibtdzredjukbs]xspxwfxzwkmtbqbpp[qtoqwbdslluvfxxrte]rztobibnpprgbkvd +fzycsudjxxyqsebqnf[xdhyyrilwqhohrjop]qjoukdgrtogqcjvi[ujgpjsfipgxsdkajlmj]ugeeytrhbcaqjvfys +rjnxaitoquekpqa[hizdsfyfinelugp]uzilarrjtcouqxw[cxouglsexamjmfxkem]ugfeendmvhsamxdsbkc[jevmalycyvinoivws]mrchcvmadwlpyym +cxgdigdcavedxkwoz[ixkshnjpohrhzgclk]ljfstqblntfdwxxr[nktbospjrfsmodi]pmvdcbwwsuvfvhkdc +xihpbgawtsjdaemqsi[exappnkwhzpuxbtabo]asygirvecghmzwek +agsrysnebomkidgddk[scnqmapfnvzwdldlj]foufoyrxgsrxphsmg[ekpyrgsshqxveoui]igrrpyodnkfuszvphq[ldvwvfmkzabivyqida]tqgcqaqhiugqginmgdg +ftalokkmwvnmychcxe[qmkmclrthtqvrzpbbnl]sebxgmjvtzpgwwa +sflfifzvrstqwxv[ehloimnuhsnlfzclo]pidzhpgnlvmeouhdblh[bymcgygrripjvluh]qwtfcwpwyjjzsdbg[gsieausklaxbhvv]mbwcknsmekbsvzxy +tcqwxtntpnjmyde[tzvwggjvmousnkgr]vqcrulftlhwcxax +vaxpbeuoxndqnqfqfrw[zgmekxeilvdxhis]kdjynxgskvfsllrlrk[adbeyrhbylvxmauf]gujqnzsnrapkcugkh +zyaiyhzzabwxdktkcak[gvocmwficgznesg]syhzrwxfixdzdcn +kdvtcvgdauvuzuoaqjk[bllhxeuwtzeumulkr]xfehllnbstqtnpi[tszagvpenbqdvjfymzn]jnmvkrfkdugqvrk +fbuyhgbwosevmlfzfa[dumgjdlumtridjl]ipaiotiwbvovrhfci[rtzswwdbazbrtzunsv]kcfoduojhpbocsaocd +zbrdkpydedtihdrwth[mtmszuqzjkbiqoi]cxvnykrffutmlpv[mhenchsemaqeakeh]blxmgldcgsedeyerdc +rfybjscluiprxixzds[owvvwlwspqmwwgzqe]suohwxrmpgtwvkn[bhkujnvspuwsortys]thwttaamaopsuynnvxy[vscgitzsyujngksy]sxyttonsquzryswvjye +pvdgotkcfqvayxluj[bzefwpnkonqpbzshl]tuhxhtjtcxdybbi[vgivnvqwthkppdhjo]xthnruhpxrvubxpc +kmevercvnugttmuxejw[pgkmrkfsppeomnpj]axdiwgeroyrbnnamw[cdjxejxqcvciydtlowb]hcqdkovuniidorztqb[ckexdghbagizrztvkct]brrudblfaephsdveu +tcnppvakkkcvlyadeh[afjjeqqnialrfdapylb]upgmkjuhcdqmxbtf[hztsvlwpihcduoxd]incybyshqjvmqia +ftxxajvfagituqlel[wxzqvpqjzkbagapyi]rhmjkhphhyogbhvhhk +lbaxvfkxgpjlgnbiv[epnghhcmzmlribr]bzfkgixukpjlkivvvx +kqhfbwargcfljca[dajwcxdpnzupgtj]omzbajtlbnvzsfl[lgthltbhsaymfcbyjio]lgcriypdynwkmaxg[zrveyqlcymzdaokxmcx]xrvsydzwqcyopjjkhz +zlmqfywvqzlvhdjx[opyzjeyvgrpuficjptx]yekbdsloensbtwcji[zzdmocooaokswkhoh]xbeqovknhbymfkwoils +zlmikilitbrphmeql[fvwagtsyxxlefxij]lnrbggidsccigwmavw[nvwngkikedakbjsqg]rcsrtdkiulovdlybyt +evfbszgzwvopjmrw[apfxqhohwsuyqqndos]mbbrkclcwcxyasw[vcebwhalumupkiixf]zsjlvlvifmyslpo[wornduwuvfwacvyt]orhbyltvlclyqtzh +wwiwutciwsouadnf[fcixatjbhsjkvqyqhan]zavxccqxwbzukmrtf[uzzmdfqjktviijwx]bxelmiwiltaouycvz +uxhnypkqwipstnqlpx[pfmrltrkbxxjrohon]qcsudiligpjjnuzz[dgwmslhoedycdih]klilxgivqifiyrxmdj[rafcmynfdpuaarugr]wzlinkrbastxbytrqwv +gwcazcrtdocwtnxpw[uyrnqhfkhknvpvqk]lxctiwkoxodvsoxont[gxcdvbggzpkaynquk]tybqiclmwidzuiheat +bycgcwgekvhhvrrv[yhbjxdhpvjxvfvnxgye]zvvgshtnnkfybapoptj[arjnewupuqezonqpnan]mjrpprtoiciensf +dqktatenwybipsoxyrt[alessjzyowtyhmt]rvtajbosmcsskpwkxf +lhagnapuxhiursmf[zthearqsonwszumpkwu]oefbbresvhnetbr[vuqhwuumioepvchm]habghujmnhqwojlbvw[gdxupjwwasidgxe]xyvxxbxukvlsvys +wsjmynhruoauandx[nmacrlctobhycjl]odtmnavnougxrqowzgp[vhfdmwhldzrsccqh]kzghmvmscrxeqamakod[wsjsdpifbcprlmrkeqe]tbuiskombxnobrr +rsfuxbdhguqrrje[lzmgnijeavfojttt]tvugblvtyuqohoink +okydhbqlqxqojgnis[ebtctoijhlkrfbfggs]bvduavhztxbswbdtvz[kvaqznxwglyszfwvl]rirzscsulgfrlwki[nmpygrvpsbulgnzdolb]ubayxfezziquxwm +epgceboifjuwmbtkx[mxsfqiocoaleeng]ihrcmuloriwkcahbaov[evwextxmoifutiu]ddjqvwbhontlwzmhg[cckszbzdjrwbkxnj]mkffonctplrjpiqve +mzkqsihkkedzlvju[xyjsjvzuhhkruyg]pvqumdhbbzmmcmlw[pjzhzzmtpldqcowxi]ociobpshmzbqflbgxo[hcwbiqmukroioqjxs]bczktiepzmlaaeku +gamdwrspfolycty[tktugqpvahqrxmfhu]jrzxddrtbixcdqlqplm[vkowvisvfyatzyom]jdxopjmaxksqyknrtbr +godrfhnofdwcebpjwr[keiatgzgdqjbtfr]uqadhoarbsbdrevh[tusewuvtmgaiafj]qkumgsziwtssnsyjct[gmnefsbeuqiacdsdllh]zrzhjvphsxsucwcd +afcgjmwkvdmckrklma[cnhrelyjocpgqpsni]rdkjzzbvwfzophp[cynhzryouowuuiy]jhdacyayikwftlmreg +mmmxtororwxeiudhzh[unnuvhoroijqxsnhzg]ouimxyccojgnskozz +xvjgurxzdtbaiul[zrmxlqiwyvfowgndigr]wbpakpahulbkvnweala +pddiluioyvdczutysfr[dwcqglpljdixcntp]mezezfcpwvlzrsslah[ikozwlohjgwdsvwaf]lajbzlbaklmgaluaio +qnetjiacxiotczgrlqm[rccudkslumutqlqk]naqwcwlrtkqcwcjc[bdedocqcutdkkbg]zrktdueobyofamj[vhwwecprhkldysvmka]vhpfiiadtjiegkprmw +jwpmijanukxpafd[mgouzietwniuyoeozh]ojchhetiwykmxcu[msesxkispnyyhthat]gkclrzdrfdhfgnieke[qubdzcgsnogzgrrhr]tozejglmfonjlmghsn +fmbbyrmspjegfiko[sczruvfxgqvogvvrr]mmthznzttuudwccw[nlugietncjawardjjio]pdjbzwndmymhedtzgp[fmcknqodbiisnzndwo]wnschxicvsccasmxbnm +tjshdtqixcnucvkhgc[mxoyuobnokjhede]qhqoqocyqutowhqh +ojqhxwnehyfhdvr[zwolerhoxwbjqdwyv]iwzswaejrzxowgmgqu[sfszzoxjmdqxkikleoq]nartznqpcaoncpzz +wrzjdrigefohesrxdkq[pzxvrzhkohgqabojcrv]tottapfprfycyjoi[qldiorpimokqzoimuj]rlogwbnqbnqrydjp +qhczurgopvddfumdkwh[dxzqerqfzfvclmpd]bexascwtlizoacpdrks[eqkdhaazxiyhisbjhkz]shwvmbnwoqbqqgjr[gqwhrpwehpqbqwtrnz]rskgbfaeulbtkuxzij +ojqzacqecvtaikbi[dqfouvlvmbnqfpg]udjpahuaagajsslu[hnphkiftfddfjrkasm]mdwjcylvlvophtv +flvgaovkteagpynv[szzperfoebcvyfkdmi]siwkxshdixitmgudlcj[cjaclojgffilrfk]wlfygguppsesoqqd[syxnwdheseoirapzsq]gtqcgykzckvsuobv +mdiwtzfahcfddvqvjil[vgejbnbfzjgjqvqjguh]xlgwswsnxqrrikunty +dmibswyxlxxadenxit[indzvmfqlsazkqpwler]zfgzmwfrysljdinb[zchkubvcqkchuhqqozq]fdxxvatlwlynvpcc[jpdqlqfzwikvmuuvvif]qxayqjtamrjkmmajfw +cvuhsnxjwqqvqnktov[isynyancutzzaegsu]wafqfzxamdssndcezf[mlcqpcptyvzubjsjjtw]ttwxrnsjspbgfpdpuyj[vcbtyvnkxvhjxqxpnrz]cejbiqkdgdoocfp +xmrgmkkhncmoxsuhwxt[knratlhklaubcmanoe]kwvoawpghbndceos[rpgghgrmzrvproskz]ililcrocksgedhjuhjr[osfcbrqhtkhyktkfxk]itklpoezpplrenxtqv +mznmrotthwphvnqgrca[lzmbkodxnyqcihjwsp]tzgxczqosvxpfwlrc[hbedolihyyunfwj]izdaufruczpkxqj +bzaknsueaptjdcsw[mfyqvkzdxuhedeo]khaxflvucwkbzgutsge[yqjpgywasndedvwsd]zmivwoqmrqjfkvmhr[asmmexyekrgrfhnfm]ggjhdjwdeczhoiipfz +zirtgiiqekqpqny[gmyxihpinxlvrahsuj]hvgcviarxrtsofvcf[akymzspsfehurnuz]kitiugedgszjjnq +oemqvouptnqauewn[chwelvewqnrwatnami]vsxhrtilwgaulrhrzq +qpncwiwclnvcawai[gjrsbjrryhbwoviv]estrqlcofuysayrezlq[zmoixozgmgsncdalu]lnfbogvznfmxcuju +dwfjbqqfnwsdodul[ehyolwsgpgsdxyitjqd]bqxqcfhexqxphqmxk[nxsjycrzzkicjqb]pcflghwqinnnpxruuqv[ownihwpcnizyyifkihv]cexjgqqhswpnrujgj +ruugwpvhjyjwecfchn[ihtbgcwirdnuyjbx]jckbhwdmpsyquwckj +eshkwnhkunybxdctmj[dkefiycsvmzhnjfea]knmcagrgdhctbzuj[weikvdezylymclftryg]wnvhotwryuerqui[epyensfacxyegnzdvz]wlgztwudoejbtqyu +avuqgnzautxxbrteabq[ybapddktmqsaijqx]pccadttkazpdxub +tvejinpchgummbg[uahhifivytznhms]xbsdcxyaiceykgjqjsd[npkermlinikufcunxro]fkbdthtbgjtorrkjpcw +guswezvvjvnrgcqnb[ovvonjqfigdbfwchq]rdkjkwyvkalcjqnj[awcsmucmugnmeiugm]ugdrjtgsrgppconirkz +zahfosuxhtuqptoaz[qhsqtkyovsddgol]kxgccetcutyrcethsil +ytuxuxgzsvcecwamt[lovvgqqzfybywhcqfce]juvhcgndgfkwoynthrh[ruloprfijalospov]gdcheafirlvghthb +jxethomfiwzhksww[vzcelvyiqjxayxifjkc]gnzrlibobanzorykii +pjlywpqlpzjdabozer[lrehazdewzhixga]zdvzuirkyorztrwy[fikcexbaiwtnqbt]fobmkmgnxfmaftk +taagvqjyhughwmkkvl[hkuztqckzdhnktvn]gsabfglsywphugckyd +oshqjstzujgpiwczrj[hduptjzmswqkhbdqgov]hqmsoxukrfovbeopbg +xgsjpvidzwicmsb[bunafjgrbtvqbapoopk]mqfyvvahpjyfoalzozh[mmfptgqrojhicfncbmd]saxxjfzzjihfmllsgcs[wyqlxccerdjykocqy]hzuwvusymrxywetmna +lgieqmfglevrbdvnn[yuezptfbplhkimfq]rvwssgzdwlgpfqf[qkegiqztcofvvtrqzcd]wqfawsobdysrfqfqbv +ccauaprhxrjdsbrqzz[sskvkaaspuldccrg]wjortlhzgsgpwesga[waszszzivlptpedsdx]iaklpnaaeiswyzgza +mskrfzoumbmanthiths[jcbxermcqmrlsoe]dmiodqzankfosysgbpu[hqzvulbmguyvsqhvjuf]yiqcoarpbavqxsiwtv +cknpfcczfjvmuifaii[oygofisiwuhemyz]tedofahngltwsufvwe[leioechdfhojycsimh]padlduabrmtbncr +glqxkbujgswoysb[fimbwphbpeelcwdi]vpzolyuuqulcdplfr[psxblsccqodbrbs]jhrmzsgdemycrhzsm[gmdvsnwufhcgjqvof]psvervlisrluzisrw +cxrafoyokflthjcy[wupjgniyzvgwnbgseu]jayoymnavgydhkpc[yyfumpawulrxokrcxw]ggfmtwrbqvjhecmn[zwtrupxseojrhqtwe]szlvbhlihmzeemcdvs +zkbhccweyvajikkoxfy[fszqezsvtctafsv]vqumsjdlyznmzrwib +fnzpumsusucgyjyqe[fcfhmlxixcswtijzx]elgibjruhpsnyeikpev[cxasrzvzoqqamrwxeyb]hvqjlnkfttgveuxzoa +aqdyrsuxpeazhvpmv[oudjrdigbhovgnproor]zoqmqtismbzypyrssu[mmjhslzqmbfrzoez]pavcrhmjsnjudxk[usqrdmdxetgysgrnyt]tmhronwzwrzadepjt +oxjgsxwdkvbtwun[voxemrcenvrllxim]xqpqvkzffsowfrxcvt[vuhmfghljhheozjp]iagixberjizzwukbb +hhmnefofdypbkgy[piopbixdrssyawazfc]vfvwwevieiyevhciymp[tibldfadnlohqub]ifcjdjqmznrpnez +idzefrctgukgftpkvt[xhfjwjaifgstqulkjsg]eppjpjpgvlurphg[ljzttsfemjpjlgmhnqq]gxuregbxdtglnnc +swtdvbcjngxrzsqvmya[oscfcdxmjandmsdni]xlvamtsetxkjlmafuq[ndkesmiexgmkuyemqy]tjnsiobklvqxvkfg +ciyxyauiynetvuysnqs[ovngnnbrpiavswcek]rnaeejyiqnynqkpyloz[mccrpfjqimexuyd]nnbignqcpdpisjkzdsz[vrvsahyhkexkxutcgmo]kctxzgiznbtghfsyl +hpkxpqeyumhouklxoai[qxmisohfibgoaqnkcu]czzpaxszfcimeqjjk[grwuxysxuwxcwftda]spkpkckuiswehsh[itrxjgkpkowcbilvtgp]guumzewmubuuyfafli +rivqomdhbrkecpbb[wdohqrdyvioabfbf]dbllzrwwbfbgdqktj[dxvafeshpdywcxl]uzstsjlisdrnfisduck[cjazhqptbxcixsf]nslumhmpbmqpivn +qtjhnrwzpqaqpkdz[iocymnvkcvemkfiyt]qwrvnjzeopltnpytb[trvortqtdqfpmrwbcb]cxsunonoahemdaoywu +eghqxxqrjofvlwtclmt[czflqhgwqesbeja]dkempvjqqctfbjtqr +scoquhherndelmwbo[sshazaphvblvxlvcvi]wcvdremsljdidzbfo +hrveibqmirdtsfvvp[phsldxexzafxwfyync]sotdtqgujticqic[osvepfuzgbcarhiupj]ydjbylbekezrtykjysb +nlgdecifcwmuayibgrh[kasewwljltuzeobe]rmiyqugsqioouoxmbc +hivavjyoxnbcjqgfkcu[vsgnoayjlewjsmfoge]rqctposdtaxiabiaps[uovebqmxopsmbzmbljz]ltpiruahxuaubqzsa +pkpapgycinrwpglmkx[payhdtzrixoyoeti]vvudfhjejwfzqbv[udswjrppbnpeojfbxi]arkpkevytpytwlrzblc +lxtzohxiknrbiydkuq[tjzcjzgasuadhqmrenb]dwleahtmccflund +biokgvnjswuselhtuzi[comxhmihobxmgfua]elbjwejsnosujshbqd[tkwacudvjplpqaicmb]zadsfcvcemamozlimw +pnqaihstdftozsriips[lkhdtkwnqrypfpi]peindlywisgzfcfry +fkdpjbqytvzvjnws[slqefmhqexwhkkdhv]jjzqnutkhosrpvj[wjvzprupaavpuzmc]cqkdwaosyntbuyxhk +oevqjtpbljycelre[qsjbtmwnxmimbtaf]simiksrgdafhjktu +appbdxfomrzhtlb[njqrhqbvqvdvgackwi]cngofyjrrwisczz +xucncimruxvabncx[gbubelyrtgutkqlsh]lfneuteufvnubxnnnce[spsauokwxkzlghxsvj]ticuuxutrlrqmlqo +suzaytczxhxstoqodm[efhicwilrikymrvbe]diqcwvsagtjadurtkft +escgmnsjlkclmkff[anasojtvnzzmawcboha]quxaypktxokdtjtvw[nnansptoensuvdqbqh]bwrvzncyicnclmkv[zklwtdlwbciplfuts]qsslygkcepyvfmrivlv +kqdcsjdbvgzfpolkvr[nzfpjesnxmhradmeqh]xekfptpbnohnrdwe +ytrjotkxynxsdlfdood[gfgsticgrqrefsbhd]dqrqmdqfitiqafmp +dkcpuvmrctwtwtjveoz[hvqpvkumjmhbvtvnoy]ppvruhonlhfwltmp +igkkzzqtjaczvwimgs[nxzvgepflgmumbr]xwbqpfpndyvaxfufwj[dylxopnrjlxdtvhoj]keepzdtkjrcszilhk +kudscwhbhmiqkyu[npsoiozwddcysbw]qontovsowstkobmfx[vpypckodavrypggo]utmevbjiupwbqimzixo +rexmfqfertkdkgyw[fazktroqmzuqnws]ssxqlyuuizozyafaa +spaelxckytsjxewny[frhpgodqzkobawpe]urcygtcihbnpayer[ndhguaxbiqxmfgu]gyqdqofuhthgqmqu[xplcrhabqrvxtixlk]xuclgwuisbehygf +nepcketqyhmbolu[klkpcndcxovtxgenahq]khcemvzgfitmgwboe[adgtmqlirrrclbpmimx]sgepebeedqtakqjg[wrdclimitkqejwwt]wcjuedbmdejtknxo +poikpbptymruxwyo[vfhtxmdcfhmqvkbhfi]bestifhuiokqtqqzy[ewngjbizxocmhgf]bttdzjlguaddgmktnb +hikyosezhctnprla[hnfrgdaujrsamhbfpo]wdpzglchlcxleofyqqu[yrpkmzeqrspoqfx]rfskxkbijoxsgucfpb +zkkfdqkjmmxurilkrka[rijqjdcohanebspyh]srjevlnrwkaghovhus[kgrgzuklkakvzlexl]tgnqewvicnfyocaxfu +bafjxjjsbkvwpbbu[ytnoocrzdceohcjzsmb]tfxyycvigweydqtt[fzgbgfqzlbdngjhfko]xxytzvgkqwrjpmwnqrj[hsclxpgznrwxorrf]jnjjvlzeymalkrw +pvdeombqyhdeuracbsw[ogombzjnxmptwfwe]jwhfzfxjfwfkersx +oqdoxgqsnzsyoiozcv[njjfqdqpljgsqjteq]xzyxqhzwulwjggwr[vftspkxrvlidhxpz]wsluksmzthfzialzbn[rnpnecucmnumicphp]iucuubcmodrgbezfi +fhqgtjwndbvxhjnay[zhjyasrxjhshaibeee]gpnknolvzigrufpsy[uvkhwcshsalizlhln]miqggogcoalsnsg +kbaefnclkfuaacyaqw[kvxkjtmhrpmfybabmrn]bfcgpluqgcvcywfilgu[itxwxuzuhirpwzjn]sqssnjplrwtusvkoq[xtswpgursrnfolfp]msgvzgspshljqvy +fmtectsgyckgsxhtq[tolibcypycluxqggvf]ahsxzidiygtnpqth[fnxqvonhogepgcnm]qalfxkdyvzzwqav +ivjntbzpeqkwncmju[tduwafmzuadkrarv]codtenbkheubswo[imscmiquwvjkktoqwhs]gxcioexacilhqpbgu +nrxlalqatettzodgrs[zmscgfitelxpimva]ddcjrltymmxjejsdjb[yxfjgjwdazvgldbsl]xsqeusulfsqplrpet +yachjgxyuilhkuxfy[cbmlgjovjsjscrb]qqhzalwoyrshsmaejb[jfwwyvjdgqpjunys]kbrfaibdtcknzue[jguruergvdgbjkv]tgsuseeylzhplgrpg +haobgfarfwwsnsmt[ebkldjwmfkmsyjl]nvlelqzqjlqqplbrtwd[qvitfazopoylebv]jidnhpalxguenkeons[syannxpoqdjlsehj]nyoqfdaqlfexszfaf +lkblrelkqvilunrpz[pqzkriftkhwruzxjp]uthvsrxlswtiuej[rqxmpszqrwyrrpj]idshhewuwwdgdys +jtxtiohfhiutnkxrw[xpxcqczqpekfmusvwr]sbqsrjpvimcbpapxp +cgbufgextzfgphjmpa[jhcpgxakwxrbedf]jdckfachzooibtpgde[upjxjgkbcocrtcel]zfuntskkkaqoaawlft[atvbrjlpzjmpqla]zkznozcvzbtilaqu +npxehvadmrbadkjf[udleiusfgbphbicllz]hcffuslnycbpubqfmbj[omluucjltknwiebdefp]gbmwvqgieonzfwrclse[oelxxcfbljsyeijeefl]jofvmydknyufeyi +xsusetwokemyldccer[lptgydchemsqljaxypo]ejtlagjmhaszjzqsnn +sgodqumychhkvnk[roubwxyrgybcnaqv]rzlmvxkwxfhzhrgvjra[kwvngfedqvvuishjoji]qppuwczsfqqxxqsepu[zmdxnkvlrnkfssv]afnapqutdqznltezah +pcnanwdmzpshbmyw[patcrbtvevbtanaxovb]stuyxlurceqhactp +aivddjfrbkpvmlsooj[hvrvynurbxihuelkjl]rpixqxbknnktowmkdo[pkmxpdasehhkpyy]odwdkfrroynzswerbs[mfvmvxovfqegtnxllpa]ufboctmqfwfehmfebkf +rtbhehgjnevzmmqgep[yzodzcckeqmwpbook]mldhiwfaxrnljjovg +xzycdgrfzcgzuebvi[hugmldunkbtdxeli]qugxgdvvfygluodabgq +uiocwjcjawkezsthdj[azmygforvoiglqaobez]xliasvcjctalzfdr +svtsxepnrxkgyomsjt[dglqtylczubhqapb]kzyrpfjigqwaeavrus[wizgslqvgqbogptg]sdufetznpmxchfpy +aqkjwedsgvucjvbu[kjcxtyswlcfkgimqqmo]cefzpwaqfbyvfcqc[dfjrksosggnnulxe]joaumybazgctrshh +whzvbjllsrxgfnqi[jhgsvmmydwgwdjglx]ebshecvmjodytfhpsw[nmcgzfhovcwodbtif]ulsnbqybdkszugxd[yfocxkmabsdnelad]wggxekhcisugatilgp +muqhaqwwzuoaqfyonl[cdiyytjrutnggkpfc]cwpbjzjinvmcfxilx[krzhyrpnexotxhapzkk]ljkitrakpbxghpweviv +tqwtflnxvucqsgmd[fzflzmpqlsnmpjixres]ipfqmaohkqstxofevcb[gmgkfolwwihufdpze]owpyncadwgzzmqyv +ixbexcxmoqpehwqabi[txmhelnipufwbwjzzj]mvmhtepvmvxpssr[wydqdqbtpbkrrexe]fqlkemrbdtpswbcqy[butplvsurilrgfawgco]tavqvajtocbvjevsil +vwfkoxvaofxskyhbjqm[puvnruashljbsqbscf]taievkrmmgnxdpa[xrnlbvjmvidvnkv]gxudgkdjkszrjyfuy +itnjahxgfxgjnslbe[hbwbbpvylfbyqbgfpvz]suqdsbpmptbrujuf[yfkvqhmseaimirlwamb]svktdnbormbmbsnilnk[xlybsibrczhbpnphw]vcslptwylljzxjlvcn +lccctefsdrcdlkw[hnwxoelaqsswnrlipk]dxslofpdnwpdqqtyqk[lcptfiqjgjaakmshdu]ypnniarllzpkrinfo[zyrdjbowiiytfhb]qstsanwuwunmeytkmk +wtxasrkodazruvnr[bewsicxijbwjblgjj]hnhtxsccchhcycbt[gycsmvclfyjlraerprl]wowibzopjcibenefiti[uuxeudxwqtrswbxuhxb]ttsgxsgkbamcaocut +ntvwumbkdxpduiy[zkhhxzidmtujaytpsnc]hzzwgoqlwyadsvaejhy[bvbtzbhaqgusces]zfllkpmjpdddzkqdm +vzwgoqznxdvefgbqkjs[swckbsoabtxlkhbksg]zqjsgiodujmdfxfhiax +movhrjexteijabgzjtt[qmriigrpvzoanmnmvsw]nwmdizazbepnduo[qxezsdcvcwdfhfmna]igkggjfjshvekgaapss[weeuzvhhvucaytq]pwwxdlihtxesiffju +xkluztptozcnbvh[btptpdpiztmrhfijfk]ffjcwrplvkhuuxugg +hhfzzjrspqcimcn[kjdhabulyhfjytno]tcbttnaialvktxqqsfn +xwrxducaozrhxme[magpnshvryqtljmijqs]oxusvmrtigxebedfk +fzuvuhajudnlxscbofd[otmsbqkykhucrldvttx]blmfnsqkwlndpjqf[yqpwlhlpykachcqeesu]injosnmllqisgwqxfuo[vsbfohlfrptrxib]zqamtnzifmehdxxoh +rperdjgiisvvnnkqa[wtgzipvjvnuyvtqt]llbszshmkckrtmk[qlidltzjvjtueyy]vaqxlpwkvspahufb[oatmkdkqqwucfodoilu]axluymagirjmerkhzu +whferflocizjrokfcay[mmwecazbfcqkomqmtte]xzzqnxyjleqvfhdollz[qefcdifayasgncsitrx]eqcqtehhaetqlkl +punmackiplnvsvaibb[duepoewfezjbmiprz]xeqtdtxsgdpjgquefny[enprhqhpeyfvjodhg]dqcbffvaeznzycitoz[gilxojkhxhttizc]canikhdckixnlnhm +eiphpmokjfcyqttz[gtmpkvnsrbwqrdgkhw]gaedvjkebfmagujj +vyrzozjvlflremttj[fmzcdwwhgxetugth]pahbkmcxhcuuexrqo +izzyhwipmlykvvvmcr[fewicghbzxsojowdhg]mrzrbqtuvxaxzef[zbgnaaslocwtcne]mbzxovudbgkiwpdevin +usxkkeufvdoggas[dswwfmzmseduqxhtvwx]zgqaeauwnbvslksyovd +glfrqjuwkvdohyiwdt[pvjouwyzevujmgejnf]lrbkapwbsrreomofbo[wkjravacdyfclczuosc]mwmhplddwqgreyyzcko +dkfnlleylbdaajb[yyintvqizzzxrfcpi]tngxominnsczlht[upwicgefegpbmnrr]fxfefjvyqvdcrmglrx +rshswtpuebrupwdzqd[ksbhjfdzcolihpty]vxmdecfcljflahiuy[fdyfjnsmcpxgnbhzz]abuwcdidsndgdnsy[wpaglfwmquxtdvcq]odgxpvmwhlwzudtqpnz +rplrsndfombfrzzlc[uiugcytieaoqilk]ntvrfovdvzuuonp +mqzpzeudnxiqahnska[llussgmurjghbnnoole]eusafrqscbpinpaov[msdqfnpwmvegogpxo]inyrlydjdbqpztebbib +qmmliykhvnkulamtuiw[udnzzpmmswzcavkuxv]gcewrmlypdeocvbyjj +uiqhaiqjwqofbgqto[gkakppyupbxwnno]lcwfhzqpmowkejj[rtandvdifasfywsle]rlfkhnelytlzutfnv[fuoanrlavgjygzqhsde]dwfddcgrxzkgtcm +bzgyinxpqvasnlb[hvsierfmklqiivawit]sqkqdyuvutegxzrkgyd[mvittbxhbtklpuh]afvaocxcbvrivxvuv +rlpdcdvetmwhoeh[ustdwsmbojqbqwc]bbqvzwlscykctcgoho +tahntlhdicpdnnalpp[fnmwvddaoxkmjqst]xixbiyqgxypqaedxnem[smuvqxwgwfubhmuw]lthrcrcxoimmqgk[ezaxxdumdwigkvu]crowudsyxfforlrayi +hpvryeheavhrkjloujx[mhehgywzdejsbfuwey]pkrgqmqmudayqmyv +umowweqsyinygfe[grtfniugpboogtgpv]ttgtktqopjsywulprqx +csjlkynrlvbgwlzg[nsvnttchrhqipcn]xariwkhwfjfwehfswp +cacydzczdaqfshhr[jzgqrfcnbqshdzqfnmo]dnlkizppyuvnyrkuxce +kangosnlzmgeaiknm[bfajqjeohycglxswlra]tkqftnbkfagagcjvi[ovdubgbwoeqefrw]qvklbmsmtzwxwpuywel[usjzhltvradirrddsf]jmxnrjffssgjlfivba +snomixyfcqkpwktt[iyxjqorsjqjuunteqt]tdbqjkrsdgdlyelcw[cfebyskawmwkgraytn]gsqrexnbkrwpcmyrft +rafnquyxsuwvjgoah[bhcqlwyxonwuqowofp]mtdaordhobwntkco[rtyupdiocyhxkfsbv]cunuqryocxscununa +dexyukhtvmozlth[omyonfjhuzikquoivfa]abyszyboigekahfgl +cfaamntsdtevtoou[amuzpgjthvqzhdqn]cyadiddxurfpdakbwk[uyqjkkyhdalczourhr]zxhnnyzahmknirc +zoqdnxwmhiwrqaejekb[qglzymehadgnhyoaf]whivbjvmjxrrrcju[xsiczgkcermegfxz]yrqdhyqsitcbuwat +terznkuheuiksxrak[mvnbiknrfabvjwdkxn]cwddjxvgmetzjrkzea[xziqxlxbnvhkmqbos]fhxfhmqgpuadsubh[zeqlrmsxwvjemyw]nsfzmxgouassmcs +ybeezzeojemnmzgcpdl[rjzpwdnraffmmqenf]bmsevuoarcwfysmav[yzvllscuulqatcxvl]vlmyukjcnfybkwdwp +fnoorwmtmzwvwktqbo[ajydafoskqgtidoz]rkvcabzlcpxvxkjlu +faikhkzhlrclghufqs[flkmuovmqyqnkfaf]asunufsqzdxoudiaxxb[hadjusanacyvrjedrms]kecxdaaazmwrysfyqml[egajblaxnaynubwlkzq]wmjxhcmohmeoyoukz +lifjpuhsmpcwminulbp[ogsqhmitayjkvhxn]tpyrwhmddljxsuf[yvbworbmupysruqu]xcibjyvqwkwawzdfm[euriftllunddsasont]wnpqnncbbjrnzzwd +dtwtsjecebuxxscwdej[gxutszjzoexdwwpxfxh]qfskmyjabemuxxl +fjqeekfbyxrfxhqj[udaboiljhhoqfgv]vuoyvxfoxuqtrfyu[gdykotdfbbpwmie]rgszrfktcxyuhvkv +xyqqdpygmeowmpkzxdd[bjxnjajhhffgsjtf]beeakoraqizrvllo[ttbjhpxiaijuyfunqd]hbxswggfvnjhzyymmxg +srtnhdjdniufgyhgehw[vribdcfzbbuksonm]zyhzrsjuveucsawn +uaolqhuxfyolzyzxesi[olnhuxcyyzywhqjkgcp]lhwtpfmegcpmuohh +ztblwjazkufcifqu[gqwhahvnajlciqlab]yhloiuhbkwzmynun +fylubozznhbgqgl[jhujcfrttvwsynxbv]baddxoctavloxqy[ymvtyrqgqmuedvtviis]iunkknlhgoauhckknz[qluvgkvaqhrawtvvl]gbjvfrdirkhuifrss +xqujempeigpgeyifi[gmuequihzfuppqz]vtejaedoorvisdogx +fdmbfvtxctvlsqpdg[ppfydrwmxhonatvil]jswiuniywrjammkuq[tcggdwprsapeogozg]gkaplvlfqulngueiprd[jvdyisxwrzgzanqjnby]soovzbtczxxxfzpj +mlmotkwsacuwslthc[dopkkfjvrkqlmluai]ziyyyuqwvtjieocc +unqckrsxtyadoeup[rcbvmphhdlbwbgzti]nxtsjyxkihfnxzgx[jeznsoqhajzekppvfgl]xhvbdrqswazjzsr +qzonssvnqehuodjm[owetefyiumtshqqa]garcprzmvvujvlu[ufjepcondnxhcraknvp]sdwmafrnzdhabbr +htlwjrpzxlqzaqyhhj[bhnrcyoqmpxkcwtoem]mwvnohqdiiyjgmr[vpmbiueqcsixwyxvqbr]ddqbaqtkoeiepkx[kjvlejrlcgogwewymqy]azlvqkhibkvpvgts +fasqsusdjdurhzhmxy[beuhgugmlbobevxa]rkszfjsnzbqweycv[pobeqlhcuytqqgtkbp]ugmqmvhkunncokeqv[xjhcfliwmotyktlqaz]kjkawayleopewbhamo +gjukuffemjaastxdtl[enqvehxspvgyaxtqo]fjtzivcxhwmgsgcf[eldofthqgeifmmjpqvp]pzmrzoktfngiatmaasl +evswvustuzguawqg[eekvvswhthiuitu]gnkkxsqwsofsoioaan +slbvgfuwwxdaekfjdz[nesgfzgxxsnrgedtlbr]csmhdgvsclsflwxq[phukwbprlliaewbqjrq]qqnfatzpalhuuchdl +fcichhbnervkoyzgou[jqivwhooetniapnts]cmlbezxzjrgotgrkv[jwtovryqdnyurgdlh]iqrnakzkquqvlud +twywruqrxmlimxi[cmbuaiyisjfucji]hnmqevywynqocxi +uensckwobqnhwpmy[laeyyzcrkqwjwwtb]ztujdcvfodwlakjxa[hsnxusbqwxwijgveqo]dsflajtdxnptmvnm[zvrmewhwiyqzrdsri]udvmuglxpkdnmzbbkj +jzgevefvzpmbnmwbuzk[iyncfkotavwinyt]efxtuwuclegiaksqhw[drfnvjygczdpflhr]ecjtnayoruhczrtiwa +qxchkvrkswtdgxesbq[zozvdyjglsajwsymn]flxwmludxuuufikvwcm +bvkauvycxhsfedi[etgucuislswuesfqudn]rxppectbqdozxmjlcy[bmqpcoljmvtifmx]dbdtweevpzvskqyefwl[uqczspdraplmucwfyp]bpufbddjskedwxltqgx +lsccsgszfttmtbm[gicwhuzfyjzphptd]mktodtjlpwawglphs[dfsjbfnwfxxinue]nldonynzupojalctsds[hbimwpgmfhkdtedtig]oxxqsccdbnpzeikwj +tlmxbhbpdjnagkuuurd[fxcuxmpnkvimfevb]fmtxsequpqgukvgo[cvrjsgzyirrqvgag]losjdyginsppgle +acealhqzrrbnskwla[kpxiuidwwzswvvt]tlehlrejjirrpelcpvs[hicuazvidjdnuozqg]pljbbpztpxzqubh +qvgvyjzkfkqecyfi[mtsswvgnyvbjkbdd]rcfpqdgxtcexwcgevf[jnutyvnxznanmkwbor]uitbdmbrvsczrqtlzb[deiyfcsvhwqkjyyraoh]mgsivfzvqzwerra +xldbwzdplokritegpot[dkilyibmiqqhittcbe]dvolajbquiegpyzm[tiwarbemwlmwpty]nsknuzyyjfhrmaf[yrutylvvvkxpleg]dempcoygehabakatfsw +xdtbsxcmwlyyewdci[qxtgtieblptxcrxjc]lfnfzcyzctxxwpxanp[zakzzhdzbgdmsuhu]gtrnswhdqhuhmkb +jiwoxrumnfbjlwkmhr[puvnrkflogcazwtbc]zlebejqrzictznzjhj[hxbveahojvbdqaa]etrqwrobjqrxdyqzdw[qpkcavbviaajsbzw]yybkscfwkadoysg +eteufxuerkogooqtds[tatatmxkqhdvvwwe]noedcedzspeyqfmmd +cthiztqbwlgffekx[btugyjtwojnqocop]cpfwsoehhnfftbkup[rrcurvtjybfngzr]bftefflqsiacppggg +cpbomncsxcooaynbyb[nmnxjillbkzozriaic]foyuenlrilyaaiavd[dilsdxhwvvuiyrpoe]jlnmynnwhggznnly +emnwagolpfpzcpps[uedrxoasfqlnnynlhtb]didvjcpvkjnxeyxtvv[xvrtztsajljmixymooz]zuayhoxmtftlkidfrz[rwmzeoprmwvixth]occafpfaspkktqvsdo +lodlbpyfqlpambnb[ujkoamorycpjdahia]fzcrwltfqghqbhvxn +nizwzpivrpafchpsxh[onyomxlcatphdydyb]ydydlvlpsnrpfeyz +bbnkumpfxywuaju[urgqyoeidnzcrhebv]ilnwwmvvjgpoyvno +spdalcbxoljjsnnp[fztxwiuercdzikbbk]akolwywqiysxpubgu[zbwzwtpyfmicoch]bpzsdwoconslujf[uiizmxhuylhilnor]uhrqppehrrcztkfmkv +rgddxscswnskqpxpan[mffqrbysmfatawfmxg]nbkentnrqlfynyy[voxcdqkhylzufrjekdd]voveqepyrzidwkscp[nfjvzhhaapnsvlgvq]vexwngjkdcxbwkidns +jpntpuayoxlduqww[ezrqmpfomsfilulevvy]cjrjefmcnbswkrn +mjfyrlfzelvjonnn[ulcbojuiaahlopwk]idenqpkorklddbnaz +bhgshnxhcgbestmfnxv[mvebmbvioqohanjpog]mntsrtzfzurcnqxpk[bdcahsyheihtumq]eickztygasboinu +zlplqtceqgefnke[gmqhyjmtykiyxnz]ipfqojghtbsioksptem +lbbcqgzfdgerelg[wwfafbqlxcfomqyu]watztxtiqwqrgqzjxan[gxntmrjphcqsuvbygab]wirbojjuorwzwudlblj +gjlljqgroftymgt[qbgnlxbwcxykipz]iihojyaziefwjyy[jnsmszgytndqggahn]qzgxgpudmhmyktg +mzujymrvymlfuefmc[lowenpwwbljiuaex]zdoohchvifnhbln[kmmdgmmzpajpbpses]begvpvufpiiknphagyl[sblceylkgsmpmkkptpj]igmhiscbofjridkibs +evlnogsloknvghdj[yxdrizzmnnpledj]mdphafqgsjokxfxv[jbjwluoucouakaef]iddlilvtxhmmzvhecf +xkifittdfqhyilxath[qutqagtwjergmpzwozk]ommacqhnpzvalxyyowc[hotsxrwsqfgvvzpvn]xjpysvdceyiarwla[pcmqagoxtbiqvnk]xjyqptmlcqppwvun +fsnqlrxepbchttru[wtbshrnrkwfipibyd]ugokorswuuvhmionq[tgbjfinuwfidoojqcb]dhrycpbrbgvwkqoa[aedbxtjjmhbplwhtkp]dipkjoflmykyisfwh +qjzrvokvqtakxgqlhcr[xcsezvnaaqddnscyx]yphwgbeecgofsdoqkj[nzexfrstzntliwfk]nmjjavothhltpfzl[tqhxmitysrnznelkr]xzrteqpmzxxwfjmlm +pjuefjhjpzypafnrz[icmlfeeurgsdrgpher]filoaxijpcrlhahuro[zldzwqaxyaazvbxnqp]tkomnofolyeclyxbfk +ypcbanszbtapwax[yubwfxyblmrciwhvnvw]bgjciiddgwsgzqnzaue[qronyqcvzbelsywyl]luzqvtdkvasryrk +pazfsvlvzjrhffpsckz[ymankdoapvwotrpjm]hygkvlsmknzdzwe[nmmponlmpmyecec]xlyouznwjdsvfve +yoktdgyjyjmxoppisp[stjvdedbirzwqtpkb]qoqkdqwkpprxztgfc[tzahjyjnmnekwyokbn]mkcaateraenzzfs[cpgyhilznfdeyxrbtf]iylvsbxcjpflwyaqjde +rvdotzpukiohsaz[coziezujbxmihzmjetw]loneukwuckqfvqkk[ynlwusyvfxkihdo]lezljajvdrepwjtxrzf[pzaxvbabpytdtedu]kzypirxlfccdorpe +wncchvvpgqpgsfwtkx[jgxqaowxpuyccvaof]suhckeyiuukphsc +bmmddzmbntvifwvjqke[kthmploktlagqdcp]yshronrwwxaumtezdwy[wyayyzswlygqljv]cpipupwpvtulpwmhfi[nbyjveyambtrzyg]taywpwuagvmzbyea +dlzkgjhjrxhnvcu[lqykoztnlcoimougo]ijbtwesjymwjwtbbp[efdwxnuattyhuhy]zgsccjbflsvyskyjd[hndrparcadyfdmr]pkwhspnypwejvpbb +yrudnkhmryctzxj[myculukcorfjveashn]nwqjutgwzwtrhywn +sirwvtfdtmwlslskjqq[umfkwtinqleedyjk]krukyaewjyaxeddj[houzkplzbpbwyondki]vlcccazbpfsahmklsn[bcmdxhwrdchlquvvxtm]nfqvtnzbgotzxntk +jlmjrojhqjwsjjlfx[yfpgrcpmohvwhkehp]xynfpofzesitrdia[juhtudcvapywgbirah]yabzjurgykvqxngvd[dustqrmgsyxfflxddxg]moqtjnsqgjzkqne +jjcphhlctetsmrzqsdx[ptzjefvylkgmgdx]xjdygmcoebrmuqimky[gdzcbodwmtanfpjv]yljqodfuxztqciwxlkb[qehknsdvgdaugohfbrv]uvnjkrhhqhdgolm +suabenrfopqsqowfvb[lhtpqqyzelakwktkvvp]dfpptubztvqslbifnht[rygoefoqzmcwipmedoq]fgluhxtmnxivcjb +ekrrmuecrgdhpeotivv[kxkzwxjbtaizqpapb]hkxxbqllizgoifd[ndwtymhzmjkwhfsqr]tkjeezcokycysbq +vahyryyfiekzmnaghy[dunuoyampibhomw]fuaolgtksarnxqzgoat +opqrpddoyrgpvkt[xtylkrcogeirwiwjff]qddhfndaqfjyccjsasl[kdwqztteysjdealp]jvpfwepmuknsuvj[osyjycjxyxxhgwtozzu]auholwpmxhgvqhl +finznvwrtmxdkynqq[znzojlzkdfoyeqkb]fnjmchixkxmxnyb +gncexwppmxqmkhbhzw[tgqrfrdtfrfmfwegl]frqkfwbxrdlfcnfaf +mgnaaimzjhippkz[afphuskevlwqzleiodn]emvyyesllcpoexkxwkm[zvfxpqmdtquznpumg]iegbxiqmjunxkqmwgjh[vmyqsqvwmbrpyoqyeo]yddgqlqdekpjdamz +sqnxywmlpdbbuzqdny[tnljzbvgduiqwtkopc]cgjtjcdqvcrhnlrr +pwktmqciycemwmznvg[hondgdpjvhllgez]zivqgvlldyvgdggevtr +mnjcsuljiknowfdt[tnqyexaahpngwzxd]vbvowakfzaiwvmvmr[quqcepdcnxpfdymyby]iosgerilxasxtlfo[vgmkhzudwsahzfhlz]sfyqfjweawnpedhpa +auzadgvorufbggazq[wtmlikewnvpjxwl]pzwshvhfhmvhpzn +chzpyezzzomccxuy[klzfwlherejbxiknft]mepqrextkfdsymvehyf[wntgvziaxrikkmpe]vhkrbfpcwxiruuunmog +fdhxyylnqyvixokzws[rznpbyrsiqveane]awaconkatxjrzoyqny[zubifcnqbeguvdb]pnfgvufswpgouet +gdplslxmkeqrgpxmz[jytqvvijffchjzdwio]lkoyipmcdnvrobi[odvxcudnmizlalllpk]ndzooooetllelopjq[yxswnbybqkmogpxqxi]hhsiadkfchzmirqbe +nasgwopoiadqpopnrhm[zddbvnqepjjpvyns]aygazvcnfsahyeia[qyxrvgubcntrfyb]dvbcycyrjglftqip +scxtjmiyswclsrpfei[evcovzgqegkabyoj]oawbgsmtomjgrti[xewhzbgjxcnziin]vrfyzfdadraakih[veeypcuhjtrlqfowk]oyyftetquzaitaoaaw +csjixpasemetnrfr[kttugethsxnxfvx]yfvtbjpvereefqqk[ejitlxyidfdanuhn]gnolniwucdhifqwmwhj +ctrzppadihbcdxudtac[pivsitnhbimfsmou]jtyycbiaszrwrdjs[hyewishwbdqkztij]vhbnhuxwwswyhfeo[gxnszwutoqkeqrf]ldrzkosuqpzdbwtvfnl +oyvvyenuvstzikxbjce[xzcmihyeisrgffhni]ahxuncdxhwfyrjmwgg[ndrpukceoakygxmx]ihiodqfxvxdovqjz[krbqfwgtncvhlqohl]oyvbwcqvcmnjnayq +hstvsaoodhudeeraito[tqjnoxrjifgfniwsgns]jjqyywgpzztmfuyufgk[eegjtcvpnwbtxdlhxs]diraujizuvxirqg[avmxgioohhmrvbdfexf]hcicgciithjpfab +guvkwabdcrjmfosxrrr[rwzlclrvprmdczgn]fiajsksyzvriefwxnon[crkryjxcpfwkdiay]ktmmtsjuktyxezk +lqhqiadjoeveajfow[piesytfyuypdnupgkbu]bcxjuyihjoupntop +lvcibleskyhgtpjok[kocymbjktkqgknggsa]dbhuuykasimgnmboohv[okarperllvkzvumc]ceyyisdbguwrmoqeynj[fdanqvyulqipsrheik]ikptohkxtqtzvjmgu +siewppymykincvgi[qziquwvqdandeqs]zklhkhtusfbxcfke[jninzudoqzyohyjnnb]jnpphpcygdyeapndhph +mqqkmtrfuxsrblh[fgjebegbyiskwwreznr]ejnuhhgmcpecrdozqk[fpalqibdtrcsfwrzwcq]kqpfqmuniiqfodatmq +ghvwdujlylpycugan[eizafobyeauiaah]yaovrefpkcwrzialc[isvfdvszbgotqlh]twwumygawmuvgdq +huzpfcgpkjqriwgw[wwfnkoxpidpovtfqqms]ezwghdwtxviubpttfz[esnueoxpiupdnfch]qedrgftkgeajzihb +eylwwmjbkagljlls[wehomzjfgwrnqkso]ihgiziijkisblrjlj +cjrqkcwraqtnqzpqhe[rlfsrayecejbfutd]diyzyuauaykhkicopz[lbnawmlieyiheut]wawrxpverseykyblnmj +tyhvcqtbzdnwnuswbtb[brbsvmujllkoygmcrf]ssuklhhyuxxpnrsot[ilrnjgerrsibiahxb]dxsfzuyxtbtuqhcfk[jtfttgsgymzuaytbczs]bzkhccldohcveqxkxg +wmxhvjtzrqofvqyq[gtqsuhzwzcenscxy]tiijmhjktmwptpl[xkjvinezorywsvgd]ourhlioqvpbruqgqwbm[ripdkceifjkebzzxrmz]vyejqgupwfzqlzk +pzkxeampgfrxvkjwmvx[saxmfjcbvylcmpohx]dtbrookfdueiaiaa +haibhyxjmwuvaqsqi[mqpydjhhspstfsik]kyhqgiczyzsjdizggfo +hyutrxovudlcgtqaasl[kvdhdnugzqqgqrtsy]wjkjumtxyjtbqheviy +ruhifdjnynmaztrd[umltrgurecjqdispa]jziknahqzbwnfaf +vmftilsfiabxujkooz[vhuwubvqoswquse]kqrncdsyxwcqswtt[fsfotdrzanwngvf]vmcgykukxchqvbzqy[xamdrmnawmxwnnh]gemqmkhhygpnesfq +tpfqkyiuhgsltihph[kpmygovubzuigsb]lnebyuiwfqmmqse[jutxvzssuzgrawpgg]nzvgiiwwbohkmcfuwa +qqzgpzdgqomdudpe[doaqydguparcbevug]bdthytdnxltpngtxs[yyfajendprpdsrz]xvbnyllrvrbhtrrm[fhgitqxewvntdqaje]nddihvrjhegbvvn +pinazwykcazurbz[sshvvraelgtrfgf]sesgkbttlqdppow[xbviulglabpfqjxix]qbepfhuupbjfhtrtgb +nyyyfbgdbctjxrlsm[qnkjtwxapqfahaxfz]ynhenrdnuiygrsi[acibrssqmqnuijw]gkktazvrgsbcfkrgnlv[heqzhxymrbkyatmmp]npwpezwbiozxuwj +jqdfkwpptvhyadpunwv[ifslbloolcaxrmewt]rzxpslpcbwdwnjgjmwa[eudjhujzjvwwpxhre]zssncqczbrorpihra +wgrqmickpndzcsxnpsy[orymsnwemgvgdvqc]zddumfflitisvohyx[lhobkuefqssrljzsxzz]nckmxedsmroyysnrn[zccppgwxrxxhaunb]uyjmcppwnakgxtjroh +xuirxfixfstoyav[txtxtanvbjlwzhjy]tzxucltxuiqiucmzob +hqbnuolwklisljo[ccppvwpiymlirnpkbr]pnckxiikjkmguai[yzynhfcpxpaazwrkt]bxwzqcnfyzsqinty[fiochkeecjbsjckgt]gwebbynmsanvompl +laadegnpzyzcuihz[zfattroimshqjstf]khfqzmasvpzehsd[ngwosqahikiqbbnv]sbmdllqrgaiwplbffb[ethsxhjrrlupxsgmm]vqywfmdgzdvsion +nuttuucwnbwhyoousle[xoqhacnfwnnjopnhy]shxrsrcumxshluuj[opehhbczseexgtyrgqs]olbetjgecbsrytnzjsr +wpkkpcplocnofso[xossadjiikfergczau]qiwuqiphcppdsrutxp +okzxvxmfocsyoybgvs[zusjjfchztcjrcy]vpiipcrozcdvszecivv[kkglnuxxxpurhihbhxr]mmqtmmbuprnemdrpbdq +niphkdkxnrcxhtmnr[jryypjuaaorivctdt]ovrwgrysibigupzm[rxvrnwosskfagouo]grctrjnateekgzt +feecsvzxdnklcxlfy[bryrwvhvpgqdecftxhj]dsplaxuyxllravxac +lfgubkzkoardzdf[qiagyqufzaggyaqb]yppfmghzluleefukte[jvaxizomwbofkvledjk]svdgdodidnfctqbj[ztgyesrfvsdhpgx]vurzpbpadhrdrrdiza +urbxbghjweuedbtoo[ylydpscyumfpxuore]ssbkrwxjmwfwjqaljt[uwlwfrvqhozzerhtoeh]cgnzbzgqozoiyta +hienhuwpcwfzagmibf[khfdoplbvoapbgbj]uqtsfqxtpasqtuwuc[fguibihgiebfiftg]jgcqyaeharvpvyy[cxqfeehtfnfokke]ihtuaduxkbjugie +vwbsvafxdlwwrizvqo[uhzrldkjlgudrtjorlr]azplsihnwmvcusfh[ososullwghqsuxm]uhwdrftzhfnmrroqp[rdjlbrqexvdjzol]sjmefswddwxnnmnwi +pjdujpcohrebenyig[dmaoaiofisjxiedobgj]bddiakgyfryqnye[aeppppahgwqdgulj]iucspvoyfouwezd +zhkzmzxbizaiadjmohb[lujcebxtusmzjnfggsc]tjlquxvqzaqzpcynsc[yvcpypqprtubhiskq]aeunhwiwlifwsiddtdd[ybtelokgzqtdnvbzh]rsysmzmnehjxazr +ciqrfxmwewtudofpi[pqwishdwbtrjostexu]vkygjcmbnllgtnmyjfs[zaptpojmomjsvqkme]jyrfxswxmmmhdyn[ruprqcsvyzmkeeu]upmqkqfsyquakoltryp +ptvvimfpvxpdvqxnr[cbayjdthgudlsfqv]brgbpugjpulmcet[vzxqjdzvvujbumsr]qscfpzftpppwfibgs +pmpcdmrdmricooy[wyopcogjkngqewnyzh]cpcirvlqmtgrjoso[gzpklputpgckxfzuwx]eilnrzxsajqinlxpzy[igkgvmaezsyfoukgkjz]vwrrhaemgouxydcmrom +fbwnbgvlxrdsxcyzvey[uweuxgyvdzucqbpee]xiayhjagtdzgtxlhge[ldcgqzmbaevwqkvut]ztivhyevetijjby +iwtqydhqswrbcqvkxqk[ytzedtgeyocjray]kctyawpureoyejf +urbtdgykoerwhomda[tcfwziwvqgccvskcxnb]fevulnobgppmxruzw[vwbgppwwwqshlko]ioatlnhkosliptztwoa[aeavbhpnhgdlemsox]owabiqszcligpdbz +tplrqokukffrtmlcga[jyuxtvhfudogzqx]gjugdhbfmwxnjtmrh +swbwpexnuxtttzhh[xspyigzqwuafmarjin]qellirwonukbbvdizi[rkkwqekeufbvhzu]kwuzsqbisvinzxq[nfgwvgerkfwmgqgyy]ozjbmbifoxiqrgemvv +geibbiqamcspqflbo[vbdzzyorxegvqrx]rktukmmbrdynjrnvfkp[djqcdeqfeydxadzbkj]hqijcjkzfbturfhy[xlmbymbynvokjtjrclw]ssbgszeektjtjabcp +zaqgfhshahrzkbf[gwgqdumlqyhzbhbfoxr]bxsxoyjbvcxqjnfhwp[kxchpftippbfhmtmoi]ecozcxdwhecuexkf[ojtinjhzgcvxuxen]chgufqbtfczbvqh +uwjbtudngtnhenh[xmszyblpzsxgwirizr]qrlknnfyxgttgzlsux[egetldzejvwkagyk]dcapecjizydleytc[ohboyhszqajjzudxfbx]qavyxwvktwjjmyx +srpwicpxcbrydmvhvxl[zcoxgycbwkpxoyuy]yfblbajikrltjcm +biqevzvvrqzgaffnhv[dsqfbbwkjeczlbrnt]kztaqzzzzlxvaqhcv[mcaircppwyjpyondde]yqsxkrbdcdxrwvjsgo[fvtjtxwmxlnadeu]bqhllahkduvydrvb +ukbmjszvndgzbuq[ckmrzogujmemwsfwh]wdscgknyvtgsegsfuaw[mugogalgcsllfilvfv]zshfxqsdnmjebzgdbcg[erkesgwdhfgpfgrxhro]yezguyhbkkcdnphtn +lmcmocgheniqfzeh[qomoqrujzxhiicet]qplxjgcfhyhmrzsnif[jodkvnzlkjtimlkr]gevkbeqeoxpbmompr +fkitsqnkdbckyose[rnjpqsplojfzysplipn]tgjlgivockfzsnu[qmwmetgfapieyyij]gzhptamokjfcgxwr +nhaccjkfkzhqjxlevlp[ztqkwewvjykqsmsq]qmvkyshwzjuqeqgv[vlggwfdxikilhmmyz]ogfjuhopnhsomtuupn[ctyoshqlieonmdainlb]yugmxswctqtktale +yxbeuvultfhddgfxmkd[auylpdijopmthrq]dxoibfjfqgkvjui[vxbyklblajmpuvftws]dyfpmoiwlgpdzft[hpkzbkcigqespcnmby]fvvzvkzvcrynkwkhxo +jjshxelsbssojrjj[ivrjrnasyhnoxmy]xkpwivngxdpbfkel +tyfsedpncmhyrqtfgz[yjeggvuxhkgyfqxkotv]bkmhwmqbdhbjbpbya[hzxelmrqeehnyiot]chumeedtoybuadxhjx[bhskcnreqqkzriifpak]raipqqoxsewtwfbf +vvlpzpyycntnurr[jthqurhuorgdlgmtcfo]mflrxkepbinrwldxkt[mutqsvtyzainkzl]oghwiiyeejukmsbdivn +yunriwucdmubfnb[chsacprfyhickht]wiwxpaiqouzqbqn[pivpthswenluzhuv]qgzsiwitybdzyha +wzekjsiosuxisuogprm[gsczvyeycmgtppfofp]wcjsdjdvukwitiiqswe +xcexnnqlzutjelywcl[jqmgzsbaonjghgdqes]euslsftzmsrewvtygv[qljfgeahxazzlokiol]jrmgipsfxcxdlpkvmq +aukotsjedvizsvki[pbzfgdfkdkipigwmtjs]uduwxmhfhbgmpcllnf[xqqxhnslpvmuxoldolm]wxsdpxxmcaljhxz[emxctxhghajgmeeqk]ztpoznxoqsqidohorpm +pguuvxbikezqidtdurn[yxdjeqvznowhulg]muodbbbogoowckahla +okojbvhagwjqahgrrdg[hycsxepwykzdypwi]yomtukpjmggiphyjk[culvswlfcoeuaqcimfq]wdrtcuygpmobnbwyoqj +mzujjrundkzwnbj[qxnoeqduajlbzgahwb]ydeomokobxpwkyrzxf[gpildviabamrzjdgl]elokpqxifyyffld +mpdksivufhrmiftntyc[klohhshgiajnhyolcm]dxojhbryrmjdrbqf[achjadgbqremfnln]esfqacvhywzqvlgo +dwdewjxlordmximnhc[yhpwdgvfznbqjug]qefwqjonyclxccnhxn +ssnfdxtouzqeruefim[ptumstdxyfllldiu]otfigtytzmgyvqsxe[vgtvvclfpidmglgzcup]njpcrqwyskhajmb +wxrleulxjbkjssjns[yrvfgegncmwvdgfrpl]vtavixuclgdhjhwhmsh[rtqlhysweljhuqet]kvzabqkrvpaqegu +tzdyticygcaeykyetwl[cxmigrcjvrnhnewd]udfdtdieexkukpkzy[zawjrmdumuqqcoou]osrlhnhlhmqvhxg +rclvqrclhowiewpb[afudkrtbhzghwbcvkr]qdjjbvapbhksrjxt[atcxukkeqxgbwsfsem]vthozywiqhoyozw +fcvwlbrcafnwtfkwl[bsutzlujekojshbsah]wpxtndvqbcwrahxiosq +utckybdjhftkvzuk[qlponosvenyinmpil]mkmpnlhjwkquokgf[ogtzeotwzkmjdhoz]ehpcitmbqyahzdij[agqojjcxeartdrsncnf]dqhohvvtpgakncpl +kzysopdelhivngw[trvtmyvevtslrvp]qphggcnojdcxper[yrpxdwqkodqwwfpquhc]ikrvkfrlvdvqzkhnvop[qwscaveveqqeolhu]fmathufisqcrzzvqkw +spcwfvqrcdbrkzha[aacdfqguimzfxnuqc]vfjayebjpgkyarfwuod[ooejtemreiraorzuvkw]sbrgkqfyzrmowee[jguejbpfuatokoot]uyffbleqofaudlj +iuiivvjgrowzxjzdwe[tipvsdrrvbmrnkqnq]wpxqhpqjejxviejj +gpjhvftuuheinlmsk[yfgionxdgbfqodg]uvlgolalqmssslrqrn[xupwjjmnkisumruwg]ujpdcjhxrwuqryfp[dloaihpfoadfqpdo]ahuhpmtxnyibkaahe +fybvgfiffkvwwycnivk[dwdzeostavtfscfi]unnydzkcjwijumjdbvn[pomamdfqmhocxigktg]iaejpuirmpkkfvkejj[pivxukllzqqugad]bxouayahmwtxkqut +xdiuvigyctdfeaejx[rjyvmnwzclqxyhnno]rptychqruugkewjlbr[ttbftbvtxgjbqkx]mrylgxklxlalaeuvz +pvzfosmraqanadbjzzh[tpdyvjvjytynaonz]xyceynlcrcoamkoyggl[beyogipinpnhdbwegxk]nltqaqbofjfihfo +gfzfnhdazwovhqic[fbucazkpmigvubskbo]tfingbmegctkxbnei[qzzdlcbsvanckje]ydfrszjgtczjfwvfbzh[soizdivaorxfooy]ykibkbgwiurbmdvbbr +myghtswolcjafngtf[zutfrslrmtbxdzpzrbr]lqwqsdxcbzmfdhebdt[eaphviremcedoopgotr]klqdporitfjgvfdcng +zmpfcgnflxuqojtdzz[npdnxrmuyupjonu]dapxpbmmdmgibovzotm +hsjsadzjikypnqwl[vrftvjdeihxpipdi]fuxpptfybkuqfyjh[srrqywcihpnwwipix]eldexczjxodugqk +movlksoriejyxitxg[iaknxaszidebdyfxw]yysakcbvsslkhvwb +rmbwwdeselsgwowqdtu[wlmcyaelhocbtxv]yqimqwiydexdpyoy[oezsqbrkwrxxzti]rphzznfghptscxc +wjrkcdugygvotpovl[bifcvrbecoinaniafdp]gpwjewmcfaefgxlghsm +qthtijcolamzmodd[gfdgnvtlfuftsthhb]kyueaoppjvhsmmcpwn[iydmuycwkbmgwgf]bpdtbvrsxighdlqyzi +crtynoguhgrudlds[ijazuftctmjhihyg]zulfosdztpdpcsg +toqrbpaosoikfdj[guigmlanmpgxecbf]wslmvwzngiqhpovwzl[bzkjldxxciuinqxuaxl]pmafduqjiwelgrgqbf +vmqbwevkxcdbgrmtga[cshtkthlkgkqprzj]vbnpasrruwnckpirekk[egnsvjilwzsigenp]boqzfygrbptkyyvsy +cfndlwialijdidbo[ncypuoyqemkzhwoio]mebhpaowwzrzfarmrw[wgjkjwbohgrovurdcf]tdaitjcszcmisetz[esfxareaykafawe]achdtioidaxwmeguzu +dwelecgxyuvkntw[hcojsvpvyhsjezu]ytdjhxbjjjzmoxl[ntxoufciycjooraylrw]jsguitaddluldwku[ashlhstdjokagrfpcjv]qhkzhcdlqtgibdlzaxu +prhhogdhsokjknsxoio[fykuuabtpuqrbalv]vvyhpipdwddipihiz +xevwylfessbnioftxs[cvlubehyimgfkojldu]elqdlwnniimpsdbonu +wbfbgkeoweyrwisjx[hypdbiwtphepkmbdns]kvzvbqoouuwqfafc[butwiexkmurmlqxnlxp]vriycrdqonbbniewds +hjjreepqrxmrqbru[ipklhtqsevrqhilueo]vjkuyooudgwwdgpsj[bvtocxerejwvjyiply]atrkpzpzwoeoepnfj[dskzailalbbwgpx]qsqithvqbksqsss +rmicaeebjkhedguaifc[ibtqvtfcjjxidapofor]tknwydhzhvxnlmzkuzc[tapzhzqftotqrxupea]oqmetuqhmbbayqk +tsisneonoiivusbbr[yyjkxfjhhcexydhzgy]ksawozycbypmfwaqrmj +dbhzicyfmcmemujkavv[cyyzbusshtktlxuytjq]jqvoffeifohsjljfw[ftmvnjkjszltbksva]scbbarilanrtgbqgp[xcswrqudixdbfetmd]oerxhemedytqribhj +hnvwwadnhpiqzpkv[zozlerifsscpzjnqys]cysfhjxrfjvdzwwp[trflckrkwxugpwsyw]vltvkkfzqjwzpyk[qlxpwwgtqkqdpkdkqza]jkhoecssazokxfmb +qruxwdxoktymrlkoduy[znhmihomcayftfi]iawvdksycxnufbjrct +xkoknpwqhxiwcyskvn[pelivfbuweedqcuq]aanztpskjvvzlza[bjxzezpsagcgeyxifa]snqbrmqezeryvdb +jvodylhbqwwiijcnymx[iivesedjbqrdqqhqvpn]jtgdnsvhdqknztknb +mkdlnadkgkbtgvp[nnkhnvbpxoufuacfig]jqiilqtzqropmlxsc[kqkhzwgjpzpinaetnl]zozxleefishfngcut +plpqlkcayycnmqgg[srqmqmdornbtapklsa]odegnymijiqxfilwkm[dtdaizmqpvdwwrtc]hgquqndfvfhihcu +giejjddslecykts[ghjozfrjgyhmabf]lsiybqrbkmcqyefhv[pzmshjajpjgcbhneq]ljuhamojviphgceydd +crqbdqgrbqtgzhe[dpsviouwumjphhygivq]ugpkrsusfgbvzckzxra[izanoqmcpbrqlbwb]uqieftfzzafyhav +scdhccmlmbtewnhk[ujyejnmxsxvwqiz]ffzgxtmsuvhllqosd[xyluxilcsxgvcieiaz]ljohpjpzvfynvpk +brcgbwwhkwsvvpxxssk[euzdkcxqaptnxnrvavi]qzxjsccldyywodhie[kcyaexzhlocdbqwvnov]ckecckpbgdynsowa +jkxcumgjssmfevqfjyh[awomrgxjdcsmundgax]vbukfdztnqmipzx +pqjjqvhovocfxvtf[ygrdhpwgfcjsadv]kituhoohxudiehn +pbfgqgpgmkhchvh[aamlyufgsiqomrqd]ijpgkdykzqtvvjwog[hthjnricdullzfmpasi]rtkatzcpgsuxdqgfz[qudiysxyalvwskxxyo]qkzageunrxavmzjvj +xychyhexbshcocf[bcllbjrhshfpjdn]kqmvakytshsxiww[rcxmrqbahpuufrejx]bbsdzdqgawawxgzpo +srjbwqvczzuazrukca[rlcrsgjwunveouh]qzdpjacdwfzlssyxs[zhdfdosmhidpshy]zoedlfourwcznkg[irkyiphmiftygrvywx]mvzarvhbbezltccnr +jgqzrsqsbaeukqkzgu[yrsxgxriwpyrjlpvlk]yerlfdummxyjxyhjogs[srtpykziynkajtcp]spostopwxfdpasgv[wyxnlteivwelaysj]nilrixjiorcdoujxd +vtfrshcfcxnqjxt[qkqubplofpdttcpz]uvqsxsmaeswbmflq[pmqoilwznuphmnohg]wbowwnpffruiwxsxt +hcxmpqwbwnuddxrkx[abqlynebkursbfmez]aakfxjescmydauthh[zbzjjailduwjhce]esjveeultejuzcuqgzy +wyinzojxabrhxfrng[begmgspqgszayonfel]xbshjcyftuqfdhdgpv +vuyhwnwrhhghobnmsso[ypxmxcajtvwbzqd]mxmglbocflgqykybs[vroinedksynhimkfhec]vtiiamzjlkuyytijwsx +gucgfzgzaxpbfgrvrb[vzdpfjzluengblwm]valkcmtjmckwcif[qfddnijruoxnmvsqwb]hocgykbffrppoimgum[vkezmfvuejeykmuhsve]lugcuflbptxqinw +qiyibgazdkkqfobirh[aszmrilbdvrvijmz]smojvlwxevizbbnf[shfjrfteigwnaiqkp]bgkrdeuduyafdvklqd +euxkocmwyevgmpflmxh[yakuknewnjdpnhdbwo]rhqabxhqikqgekoiyi[kqgtjqrfsbfhfwtthy]dhjlubwnkogyqqeiva +ymkslptxydufplr[giqbnlqqatbetodn]ompzqbzmjrtruuxkxlj[jhtnsfsnukqcpgvcw]mafbvhnkkfjzpwttq +esksbtqfptuausafh[izxuyluohauavcizl]tujhzjaelyhxbabqr[jcteeownyxliuzkej]elzhopaawvtxacfocde +tszapaduhtauqdfvf[xowocbwbgyqyevuym]fongzlnggdhnhqla[ulapnnawghssfirg]ekgcajislaflfkila[rmmkmlsexgtgxlqbpym]ffqzfzcnmuifxybwsmd +uvtutbniagbgxyelg[zqfuzzanfygdqab]utuvbyknohhkgyfer +acqjbcjhbbrpjkpm[whoaesoequjoguzcz]alusmcqapkcgsbkref +rzuwgnempzphmgnh[lkundnoojtdrkti]xxvspbgofdndkrx[hgfxulqnzphcikwe]tmyxnsphrrngczazivi[wgtqdnjtltyjppzck]wgbdjvlzooehfdvv +lopvvqqhsgahpzi[ppmazimecryovnvxm]ttkkqyvsrwtayjo +zvfttfwzyzswyodn[dudhsomamquabhgy]ghamazncxlbnklaaobg +cblrbaialhexeka[rafddyqfimdmsawwue]nqfmlmidvhbpdake[jvczldxdtinugiizhfh]rprwwgnzrelfwixrw +tjbvzxfyokuidnlttlf[wsrdswnysiffeztzlv]ftuhyupciyzhcmold[tkphlnqiubjhxfmlvx]yezxjbnhqlpzhojdt +cvzxdelnjskzuaj[yrvavspquyeuvnkm]dokeeqzqpgrzhkfg[jkjvoaajttsrgzgqdhr]ngpbpvrzwefnskvvjp[hwmxtnmjsovbtfslro]qcyeeupaeuvnpqeaq +rosnzzjlyykxaumax[mtgxhoxetcskqfezo]teeffdnqgiznghb[ewspwrjvfhrnpvjhb]obzkpfqoexkbmxqzg[jrsmxennifwruawr]dxephcphlpxfexlde +tvybshujicnmxpgkw[liwvwvadpytofvtzmpy]gxiskdumjsbdoij +evohohxokbgyiqofbp[qluawmvnvrryhhsdrp]varshohxapbfbmkcdy +vfdixowzcmduksfbi[vodkriidjctnhkcswl]fwmbsatwpslxgpsf[slfpoidaqgbpemyap]jwawlwemapeplxhxiy[nbksmqpfqjdojzhorhz]tsjjvjucdmvkfjhlk +gvbegqsytohfannfonj[wnrhcgdhbeusykvxp]agoufxlccgsxbpuwzo[wvxazyhfneyocjtllv]geitasndyjkjpmnynbq[yghoooleyzscxpthkm]zpnikfbcjvnbwalmd +noeqmknutcmwwmtk[hpfdivjpmbdwtrd]klmldkobucpwfrwsv[iotftpgwaksfazjeqy]ncdrncsgmjwqmmjlsy[qwcpmhndndiltvi]cbpgvhlrizoebrrgg +zhdejtnnzgmzgyn[npxauoqmjbyviwhqw]rcsyhvgbblnwosstr[yacocdndvalyrug]zabsoslxjggivnnp[pzpjpxztpiijeoloon]jbgkfygdrwqvbuxlwqn +wycbzoymtglyaqpk[pvfqpjodiuhufhkfje]gmmpbbyayhlytpce +gwllhhyjfqdxindt[ujepssulchcxjwbcduv]raslrbcyvxgueavlmkb[woylgjdprggsgzwuct]eiknvynbmazkxyny[yfialkiqtlmqulr]asgswneidhdmgfiknbv +kjxsymaugpdzjnnn[kqttktvhxwntaoq]cqmiytzlkquqoma +iwzchfytihnzqhrihf[mfhgrsnvlvdywbkhdjd]oohqjzdjtvgaalomndy[udfkusdurmalgyhp]frbxekqhjnlctfzdyu +hwcjiwcxcssnmnme[xlzppuxcxdpbvewby]pqdeqfmdyqmmbxqiupc +xwuvppawdzrjisb[bmpeccjqsctvwyi]gwqpfhtubqauxqhfzxk +ugyyhsvvvfczgel[cvyerwshlahgplax]oekcilkxiqatczwzhy[aipcdcarnifhyuf]rlgnwufaczioikwpqsf[fpxepwhtkqwtukh]caswtmvcnphxrazer +vmsvqoheidspuinpzqg[rpozdnxdpfwuwlrm]vyjsktiqrpenvwaavmh +sjmvrmdtbmhmphcjwb[eeqqallxlkskzbs]udgtfrihnhybypsihmh +afdmxqobrfgjfwk[vpvemtovoprafzppvpl]qxrlubsqyijakdp[wupygbbbynslvmvli]qrzyjxhogpqqtjd +tihxbrlnfmzegwy[qdijbejptemrzytqfbo]lrvnawdgjwfnvtyx[nglkdhpoevpcrpah]qwykwzxclrohynz +sryakekpkeydjxueul[oiaglqlttnpiarl]esmhduixwxcfaoehxt +jypdpivjwglmavgez[wqspyqitwljcriwndi]myarfryqmdrzqsgwfl +kfnlvqfrqzfbevhr[eczqsuhqdwgozvytuef]hwbunynrglbixofeaa[pozsocjodzutnrtc]pfeercwfapxajkkgydm[msmxhohyjfovluc]kdrxkwutbveelpl +secojqrvaqrthax[eszcgtimvyvmdsftmti]jfjikyfoabrqdmfd[ohksaqmuinkzsppw]dxklblmhezdfhmxbv +jltltxwwktjfkuv[wjnkvtgzgmvdhbktnf]gnzjwbisstyuqckkmx +czcaualhufbajyo[fqfnrhjlrfruhgdenz]pmlkiidyhzlhomh +xjgjmbjsriykobqn[pwibijybuywbibhz]nziviewoncbghhtfcf +oamkezqllrxnhhzs[befbgrgnjxtojus]qkwusccnfhdbsst[naqbibvvapqhkriss]abihzpaqtolpkvow[xnefxrlcnsyhxlhcnv]pmtpryhgsotfxcdtilm +hvtrenjknsviucseda[bclufjqrovzyhiemnoj]gvgrolegqzonfkujsd[unnphajlgnfmzehlm]zksbscjjarexejpudv[nhpboqyxtdzxqvxt]iexgbhlrmcciitj +ctmjaphrgijhgtfw[gouchexnzedcdwhem]gxvcsadlmroasxo[qfxzjndjcapxptsfm]jqfovcprndleoqq +wlhykxnpzshszjne[bfqnfsstqeoahjdx]lolxbkosqsvolonmoj +sthlhcsbauaebww[kuuxmhityeazoeqfhc]eysvldhkkkbyeozxop +sdwfqlcpqeylhfwtf[nmbkqzjwbanvtxr]qiopzigqsdswvdvdxfc[gxpudnbbhnhkcrxdc]hdsdmzihjurcpbddz[rkeuoskwvfjeefu]cdbhfvxomytiopjumrf +synqjoeasvoyswgv[kqoftptbgzckmmsks]lgajmrcctdzjjfyxqys +trtvrdtpbtyxvqsbt[fibknusbgvujcxsov]tjqcrwopxytmxebqb +sspdfvcppmtdurf[ivsjharmnrdpvcoriy]ubgfhohkvsszhabmet[djncvfojgzdpybwdz]rwldjpfzsnejcuhkbms[xjaqwrcprvqumkdqo]xirjztxykkxjwqyx +viczzsntavwxmwjown[mhpxdxrklaskfrgbq]samdpaxsnttamvrmpx[czewaevsqkbaenhm]edkmgtvpcxtuscxmcqp +vefxgudwkxtjokrfuss[rgffrfokbymuwum]cjzqxxfduznbqbt[cydcmvouabvvxuxxx]irucyonzfvxscofisbg +jpeckcersibodzh[yxprjgczoerndzm]qzzqftprfevzozuyrj[eguuaxgzgttuvzli]fwtgwhdhlejjqvc +gadnesbuiuzqiafjcc[kwctfzdkxtdliuixxom]arycduudngofnpj[rmqwuilezdfcxtofsk]segxynmaclycgpsqag[hzptpxllgogeyvszlr]nyrltuncqkfwiiskkg +ijlecxcuexxcxunh[lqoxywueqpvhkri]hqbihfwtfloctkab +ftgauixyucigpbe[iluiajlhofsvzljeprf]aqkwgegblbxawmhof +xtxoyldwnvehxonytcn[sxrvbegltpbzztuc]xagvhzvpzpnxliwvdnn +tsophvuauhabzfv[ceqxhicnzewigcdis]iabyzmhhebvptodqcm +alirhzyoxvgxxtova[vudatqllgaqymtty]nivykkvsdolxggbuds +uruwjwtifwljtsu[aybwraplpezehiju]oryubhjzxyqdwwrb[lxtqbcoumimcvewzly]basnbsekbxxaqfjbvs +kmtekihebcvsgty[pwnqwysyzlkahwyj]dsysyduxqgefmlnqc +dsunyioeihjynhnxryj[dlfwakjnireptem]btowzqrniwbcpsviq[yynburxyzuktrnhb]eqrpujiikkrxhmzbc +chebtohanjhqlfrqf[idrxikrjujqopjynn]kbdsvjfvtzlcznr +papbfwmccibasmwyr[ifrhfmbbnvcenimx]mplwskzzmfxksnjehv[wallxrhfuqevmidd]hwcoktxdlzboxrjix +eptjqtxdsztdzdvkiv[vencdxzwnxxhvcmu]gdddumdnqzoxbzacf[xollkibylumzxclui]wuwybwkxkcvbzfdrfu[jvpshkdkgqqhazptcq]fiwvrgahpcruykbmowl +osetyjfvtypylkwao[ccxfjjipcwnjyryku]olmxupovwwllxewrh +lzocwgmaoypsigv[fzpaozucgautadgrru]hcakeugllheavbhiz[lgdupssdzzqrpaioj]opbyxmvortwdyktt +vvsldrdbnolxydxoqz[uixwbpbqrdstyzc]mhoawiztewjblvq[xkwujyclunjamftlq]eldrjkncwnehqmaike[cwsnbvecidbdelw]xjvnnvpbpadhqeob +jelludsopkopxvdhckj[vooyfpbhxotclgekyt]ombahlkfktpojjrn[rlbogijavtumxfvipv]ciihylgccmvjcfa +zflbtdvqtyigiwzb[ysoyrcmpuvprtgfjltt]ftpvlqunjqdweqjx[hzvvdkudxouqatuzy]kalrxusgoqzcbiahvca[tfglytzetcfthioytfb]deexdgigqceflidj +oaykrymajqyffwqfk[hlfppkcubhcbgvz]yejxoeldvtgitful +vmcfqulheyfuvbaa[vkrpgbwdyjvrjuet]gtfmaldbjcaiaguy +bdslurdjqrpwlmyy[iovfvvvqnsjqttjqgeu]ympnvldmmihjjkymcty[pqfnjveswpdougyxlg]pakkytgqzecydexh +fsglfnqwtydvgxmq[vkcclnxeshpvejzyhzr]xvlfwbnamjzqmzrrmxr[jbuonpvqbqtiqek]eknuvcuvmnkeprjf +nhfknvbxgvyyekeq[djldkdfocjbdaofo]fvvyptzxmpliiwkdkc +vdpjbeluhukxzcc[oewefpztueezwwhb]pxxbnmsfcgoxzmqyhl[aqubfnabwmguqovi]nappxjrsgdfqlmdpiy +pjnndvlkbgnbwarutny[jmklxmqttqpaijkmf]pqnqhvnsewmcfadxdd[uzwiexbboyfcflst]jsqwngfxfdmsxdxiobj +jhkcbwhnfsgpaqqynvd[abninwnkumrjgpmoaoj]zliimvruxwmauyy +lqqnummvihrlqxplx[zjdekkaigooxbjnga]tbizdcplonpsodwuep +jjgkskszndlsflsiku[lwkwgieeyzicudn]utxrgdosycuhgqyeo[sanykskfeywnenzsm]dgnlnzwavpmubah[qyizyckdbvmfnqx]gbzgzwnlyuscspgw +xnekvtdeeyskkpswfnn[kfnzkzkhcpmhwhpqsh]pfigokjarcfxlosd[cenibdbpdrsumbtt]lipwsaactrshnyybdjc +dmojhtkuzejsgcyedbl[cymlvwmnwbbmbgo]ipsqvepupkyccqwnd[ysyhuposaefopyfk]txytximedsqwqoaitxd[vcwwpyvatzbzyakij]xxdnjorbgakbuetl +ipgxfxvgslnignagep[tmuifmchyffcplvnolx]oojmnrsgotdeklm +ugzbprvzfnfhehgfttf[tzptnsaefdshjek]tvqsmmpsphudpqd[bzglrjcbbpfpplyian]umjzaxrazbajsapqnhg[ipufrslijiqrwlbgmk]kzkpbixdegebrhieeoe +hxmlffverhgfxwwaroa[fxkztuifvrvdruf]jexsfnykyaxftdbgbpj[xvshcnxickqwcefi]hchqbvhclinuowa +vynqcfbrogqaznjlll[kcskfyibyiadaie]otkjiwdfxbdcestcatb[uiyegmmwupcjzyonei]llibnymxwmwzzxlnz +bdjiutxtmtkzncrfbxw[wzdoeugxoqrhwug]jzqfkihcxqhszuuhoeq[rtvsfnykpwwiwohmh]rrxrwrcaqbfvtrie +kmqmgmcggamtiyhlo[utsphbkqmqkyzcwyic]pjbmuokwcjdqlrhtu +xpypokpqfoqocohrw[nvgryrwayzoilmftwm]nrsbscypdtewdapxg[vqkjvvmcrsrqiuuk]qwsphmcdaooxtyn[fvpdehayvcilrlpu]gstiqzpmufzxujacy +tczqngmfcptykxkfy[qfivbtyjlyfjeqj]iffrsjemxkfenqmzn[nzaheesungxbpxszdq]bdsoysfandtdhpc[cjisndnfnfuoqiqwym]cltzpdhbtiybhxyl +hnmvpwrgegmsdomih[wrnfmvvvwiyxghulre]zfxzgodlssnsusg +colpncvdwwypholo[wnxyprbzhmywlolp]jipzcbvsklxbkat[bsiwaewerxxrneg]bcutnstrcvyuzewzqbs +otzyetewozofrkx[thtnuafiqrakyzcpbm]ekylimlvvtqhhar[ycerkqaazvdcaszh]zrevfexceptxskn[xetwzbpmhdtdzian]fukjjozvlqluxrb +gkywwkcjseoagrwk[kufpsjbvwjewvbx]kyckxktuxshyxwih[iiuoznpdootgptb]jduitjfkvxwllgicy +uqmwvyplzgytbgqjq[loqigrwbnnimqcektx]spnuxxtllykkojh[mydgfcvvaxvvgsxzhjb]lwgulsodpyaltymasd +fksodinyocwxnnkaebe[nmcqsirsfcrhkmey]xgkiwrxkvbqywwkxzts[vfizjjizxofrzltpl]memfyylffvmevcrwkh +uchxcfotfekjecgy[ytrnfdhkjzdahluuz]imgbprgwvdldeixbt[zromhgwteoyuzcl]shdtontjnejkdljleq +ulvelydmjmeicpcdo[fqlwmnhxsgjhugftais]zgrnkcmorycyslps[oxapavnxbkowooiol]pdicbxawyqmqtyzgq[oxgjkmbusdblnqbmzqi]unuvfzeeobmpqynunqo +omrmyxygfmlnlpd[mvszaozmwrfqpup]zqdogulmykihlubuv[xdmdckgkvqmnetqlab]xmpghceghczgavrrv +yoatzqilyyuivop[ykxyngmmcmotrjlkymi]yzsqqgxjtsuavagzznr[smtoxkxsmqjlxmdzmb]cmcobacpxmkwbywd +fglceilfzoyffdjlfe[kezklbpwgpmhxuiq]setlktchqpqxxrnzxpu +ntbuvzwoqchmnvafgvc[zlauayjbtjhfywop]crqfjqrgxqymacsgxnv[azuwpicqgavrqhgt]znatfrjfqxwxhgzs +elzqwwboqgfxfnyfrsi[vzhksunahhykcdfswh]qrsqjbhxkrsmeszni +sdiicfwffazszasltbt[tznbxqxeqtlryipaxz]qgbmitrvubbsmhtws +mqkteepllctzakpkbu[gqsiyydzbwfqmjigtc]bbbxhitwhdwkkugm[muxdddndjbxhywyw]eqbarakixmyxhmv +pocaqbemhftjejzvx[usknxixfuklqkan]miaichlaiabgvnfgqz +rirrbedwvrscctg[icfecwbutkswyiri]knghflubjptlmwdr +mjfwnobmyoythiyje[sssepkvlhhrvhxors]zlzpxjhhxxgjnazcfvj[ulqbynzrmjexgadwj]spleenuncdpsrqwq +eoithdxjbgnbyyc[fkjnxenvoismcfuyysb]umbsyqabwxjkvqifbv[ymrqiqjoefnppoez]honsgygxslvsizfhamp +ffjdubxyvazkwhvsby[krkpanuzuuxikpia]dptftdylturndqhy[gdqlzihoqfwdpaqc]eoicjxresawqsmftfxm +cwcgopdynopgwfvgrbp[ikkdjijguwezycqbmw]egdllmqiilawuvz[bxilxeolqwdqmmuacoy]mgdvomzddskafqk +eiiutongpvrxrkpyji[ykswsksoqhqbvgnl]yquftkxgwginbemff[mrwvbtwcnuacsfw]ykskpjofajoangpf +rahyjyeezsvfqkm[zscuytqgfwahxdvp]okryildyuyjsmmvvr +xpthozpeiuyqbalwlq[tdzyiluslgrohvirzra]cnjwxduhfoodixkpeog[xebrsoiwtjrewzh]nzrzyfybbfvpxvsr +skslvtagmulcodbdab[egdeugynmziawpgrebr]ytyuxecnlihllqbw +tdiajsypamyewbeufoz[moewrbzuqmctgvqmr]icnkdhxomhvzgedkat[afztmmsqfznglpop]hahfonuommldeqg[wohkagbtdsmxwby]eyxdtuxeyfvrfdcnbjv +xjqnucbfimkvifudj[xtshlnaobzuyebfimex]ebhbavaeefqcvvavjd +vuhaiiuaohbmegfvhhf[nguvmuqeupygtvctfkh]extrclsbdamvglnxo +ysdrhjalujfvnrgcwq[bieoqkzejcsgmhu]obmmuqhrmjnpunpgeq[oskawgrrorijvmxpqoo]nfvocegjoslsnzzvdo[xnwcxjpqdeasuxuwn]mjkcuhwgktvchsd +vykfhogyisfyumjt[eutrkfoumrjyqgzj]ptlytdgrzrtshiy +ebsxgomqvzaaaprfmcb[cueqlexewblreiuzs]lzraiyzopnxupisokfj[rpdtjkxjepzfqwpga]guhftswcatwtqqz[fheshslcsaadmplqph]bqccysnlnabptrtls +eboueezomzzsgxbvf[utawwotuztbgpxpmq]aeehegeusiwdfjlfsz[ziejqsczbebkaozpte]mwkqbfxlklbvijtl +dovncfknhbcjicefn[heqnvtpizggkgudnm]nejfcqtstvzwatzeaj[iwdagahyrthvrqnaymz]nmznolwojrtdesddma +gnkxpvhbdibupxna[lxssiiqgycrdiikw]fpbcfcgaqrnobaodbpb[svzdlwqhmlflwui]yexwgwfkgzkejwvmag[ghflfwssaoeooakxxpk]nkvnowymdpgsiguwyuz +jheoazphamrwluf[lckkorhbrbrrxqm]ptwpouvktkwceornry[mojtegrvqcqmkdd]kfbowsycbpyiehrowk +qufdawcohwrknqb[mgpcppsvpiacqbzrwh]ixvpwtbgaexthqwe[slxovbgdrlesgrtm]dhddpmqwxxplbqvxad[lryxhwvmnhoywds]qkrhdumjzxidmutx +yusdbapezozrhjsrd[mfnmoctnmhdmefkpqbs]lqdxhxaxvswynqyx[ewzhsaccykeqjtfvq]dckqgmdjsrhuvsnoau[gercfplhujwazygnf]rcjpktzjjkohghwsqmd +oimpphfxsruowxoq[ncdlctncjgujpaauw]oxafycborpayqzil[huzidruieieskxfjvyb]jfdollmeywtmtej +fbdexkvmkvbsmytfqkr[hkvsnarsgpopkfqihco]witphhpuduxpbrmgij[agalckecqyjyyrvs]frxdfnybnlawmsrcsc[pnstdicnjramcps]gleulepthdwtaix +aneanigfwrkzohkxxh[ucuiwsuzthliyodypo]waogofulqnjdpbep[zvmbrrcppbiscclczac]fwctpdnlzzrrijh[oqhyuaklrgpsiotuv]wazemeupvyrihlxzbu +ckdyyvglbalddaq[yhhnqrttyjjakqid]jlhmafpnqupxrbqo[qefhpvcinhyzwtvzf]ulhrtasbwtkugjoipzh +nwvrsbzowmjhivq[wzyhjoehewgxppg]ilurfrdhmalyobr +qmrlrhbmhyegvyobjsg[deqoctrkekususgjm]fhxydpcmqstrssd[zpzkryziyeeuagp]vfllzbrkzqysusj[fgzaapjznvxkkijhfne]xgslyehnivgjwlacf +kbtwkduqpvmbmuhgw[zdzjxyujptsnaadgns]ldnvtcvnqcrrgdmifs[svvtvwhewsdazxgsi]zyxyrocrxzeacrdqe[vbvjsjdskdsxtefnnd]wddyjjxkgmsbwfx +xdapmrzaxqkjuoz[ahldgkmozbjwmztlt]euedbnamzopbnpt[pcmucmomozgealw]mgnqarjicsyvjfprl[swyhhdquxgsyyym]cdhvjmetmtkmpzycx +pbjjgieinycscdiobs[fyqreavhvawquxnxpxu]aazgdyvkdvlsjyfqf[yrnwyrfmqgcwmlzhv]zbzntnpmfzhauaca[qgefeedmgiwkuglwtnt]koefqstfjnjvlfl +pgbthpazqbeprmkylv[futhxbgmnyhrnobwi]snygyhmmpzrojekxg +qozuzjwhthxbsevql[jbciuqxcimcokzkuzcs]kqocmrrdmekowfkcf[nfjmyfiavwewgsbnjz]xoiowsvpahmijohcqf +ntutqubuhxoxgnf[kfvmpjlfxoddjayycx]gcdnaqzocopwfagqaw[fjlxtzmovoxonva]igucqjnidmvownm +ozulmmhllvwdvwp[aoqfeopspzpxjwr]tzbmlyrtbfueqhemg[jghoksscgrempcubnio]twnzcjioicyzpdquwqv +xmvyepyjxwyswemplmh[bdcwdpksksxpcos]nruigcwtbupuwix[eirujsaryrnafokvx]cmlzpxvgrjtrzued[bqohejpipkenwvhtaze]dovbgmthgpkhqrvomqz +ysbyfzubhzlfakjf[bbpybxuuimeoikuv]qvfceoexeaggllol[itoqxzuykwetgjx]vmiiwpdaesonetk +wrjfoblpjaaisaq[pcidvtrbpyywwfo]tnmtphgtitwlafajifk[xljzrwpjxjefxhkwmfq]fjesctkzoigeylcnbat[ftchankacrqowoc]fpbstrsmzodksjy +ogllmkbpstadkigydev[fjdeezqpidvenougw]uzltqjlanxvmjbfc[djxjjgymiahdsrguqtc]uhjzbbgmhcdvolvggur[ioaatnmlfejotuw]mrhmijqjyxeioib +gkmvnwoebeoquyzddrv[qsiediridzjhoxqsgyo]hsrevlgzioovmcp +ldzfrxxxxpqqajwe[qfbwtgkbpfftykwor]qsrsfypomvqozrihw[jgvxztruoxayecoiom]wptkpgvyrrbzvrxlr[inzygbyafndrmdjhwo]atavhspuuhjakoscder +assvouxaowizazddz[mplcyrqagrfmhayalce]qumunneqmgcqjumlyyr[nbdtvazalavaphpbkdl]ifhwfyhtoluqhduhk +jvdbnhpclubnbuwd[pzrffqsvzwsdmmiox]oxncblupxgcgizxzwqk[uzzeupzxlntouaxjqd]eiujtlsizaptbprwluf +xkqjkvmbkohqbqpl[fzjikqzfckhqjqa]euhqcdvcejpxzih +ttnzbewupzwmegpg[rwmfymeikipraohixzp]cqizvjgmnfpvozqlyw[aotszpssukxnowbsq]cjqezsjomiuwozfq[uudmrnbsgwpjxhhklom]qhykiktusplvbtjznc +hoveagrldomfoze[ywmtdjjqopenmqm]qvpjicyeznlfeym +uevhmwoihdeptrrbuwu[aicgbidnmgmreid]gmggvetrrwmcokjys +yrqrmaofofelmoxpewg[wmofoarjyntpilizux]bobughtzaqqrpdd +ougekdkucjsgirpulu[qlullmdjnkzkimvvlkj]jqhjyswrljnfkswi[mcjvxpehvshbmtwnj]yackiargospshqt[wnmbjhzaediycalz]klzlghrqnxqltkbpg +mvscfnpfptogupbtfkh[vvbcypopvppclyyjs]rghxlhkkskwxjegk[txbwshyykittluy]wiwedogmzwdxrlfl[iespheudeafnxmu]sopbobqnhcpeqrka +vppjnarghjumornanod[iruvsxbssvyeokpsd]fgvxooooasjpcniyrt +docrqvrgzaskdje[rlrjjojqowjgahz]ywzbjlysunkcajriaj[smlrlubjvujffejkl]yahnzgcldvxqugxu +mxhhowgjvvhisjxieu[yaadtkrdtxuxeld]uxudxctvuuwkjzhny +akauiqiexienuidqzps[npxzqticzqaizfqbwm]jsesrfmbdzcftaxlz[rvhfqiblhebjwepojcc]vjgzyhmlrxzpisjjdo[rdxcqiqtiqibdbpb]upycfngdlyklyvngtm +iukhpogyqbukfrc[omtwrciodyertinicyu]tjahyvgwceuqiiyjoei +ajiqhepodfuziofn[nuweilbnkfmnsrib]pfiwusvwdbuogbt[djnfwsynglfgcajflaa]erghhmedobvaltvjfb +qubbxpwzwudaijxyav[kbhadxlkqwyzhxwb]cdukwdsqzxgceire +dyoipoyihskswsmsa[cqrfmlmegzngpxfwvoo]ujurjagbwkbcjco[orukolmlyutjisrltfh]wcbxwkrynjqdbhil[rjmvkwhsbbuvvac]hhrcfuszusxhnsxavnz +mfacicwuyblqlcrbma[neamcnnqrldslsm]gtyuiwxmpkxtbijvyu[xybupqxpakbqngpwh]ucalmrhghtprxxube[efbigcwynmrsodjfxv]nhzmqjvfwmiovbvt +keejntcdhfyeawuxr[xkyziglybojfbeoez]twuleomhkjboapgbmg[bcbwbcykirbykzyxepc]fqwedycmvrqyovoiqqj[kgeospmsdtxiobid]eazviyzmzkgtcywc +odzricjacwsewcjd[vjypaumdqwkgmngyj]bwfxysqxlicvqojr[gyixcgtfturmeydy]rhoreeupdydkevr[bhpmatygcagiztnwtc]apzgavbokckosesptz +ijzusubrburbuqzrxyx[niesciebzmeqptjyuo]vmwqdsmavggtmojubo[uwlrhyhxupudswamjn]swxcpgbrgfgfkbxdr[hbiirasahgzdlorpzh]gyafmcksvzplopbqpim +sxzmflhsbatcmaeorvd[wgzptiosahebcdkri]nfmlzngrnvbncvnf[qzevmspvdoesophb]xwrsfymjufcjouj +prenzyptlpatdtl[owbjqoywsxinwdx]bgdxmckkyzjwfhx +yjytemvncachepdpp[ajkdubkmjfucaij]vzcyjqjnvtuorox[audqoozyhnawqow]cnpwcdjckzqjqvxpwq +hzvseyalkoukfinolf[mxfgpgohmghwjccoz]epnawldqhzzfyqzfpp +atbabqgavyqjunxx[csqttgezpjviqso]emshshcecmudfjmdpxf[qldxfxekfxfkzpfui]ezttimakrqzpfhcwe +oqasignmlcndcvxbp[bxwbzczioiafidkle]bmcmgkvoklibhutok[lfyyhxczcgxsqvu]dlotdyqpgqhpxadcl[yezngymyoxwjvsffsj]sotoucrcwsubsboyztj +ktzqueeahqrxgao[jngvjanyqsoegvdnqeo]fmvtmptipadxmdh +rebkyxyfcdnlwbsj[xlxsghzcrgcvposspy]urwgtqawynbfzjvjjon +jguufdsodnlxuagnrik[viuyxczwtweybtbblz]hspnzxfffjslsxwbkyk +ojkowvbqnnvkegqf[hfyjtfomnelqcznfwu]rtcfwigqcfxbpapt[yuwiygjwkgzopbo]rzqhloromfhbemgxtr +zsisflucwgbzergujp[jqsyvmevlczujkgya]jfpdsrlhydgwmmznb[hzzuuwruhanrlacxjhu]ytfzjlcelnmpmisixl +cjabzidrccarvsjw[gbitdfulhoasybqhf]cebzwvqlrdbzlxbldqq[pvftfahcvgbaoubs]kyzrynaxalqvazsryvp[drjarcxgvmitnpb]yrcopiziynsmtmyljuh +pnvzdxszavvtxxqzu[mthhvsdtderjjwsxsye]jzhdepcliphabkirqj[crabarxvdvkkxoen]axcdjyxgbwxkjeuygry[wevvugzspmmgbnn]pkjlcvgpffsluejumnn +uhwirqdlrbhktcedft[lvswaaqbaakyzwit]ufghayuaxgdcwff +xhnnziwzhekpwyxxlfe[zffeuqksqcywznifqrl]gddhmdlzydwdidcn +xrfwpuhachqutrwcqy[albdixdvplyvteboa]dzhcxxpqrzfehjh +dedxzededczqrhpbbc[ctsvvgtqggfrpjeq]auijpocqkgbnjnf[ufpihbtafflvjbav]msvyrkwhmxlujtrpa +vrfonzibtnkzotwr[zpqmjwxgrswxwvahtmz]nusxjvmmdexnxekq +cytbfblpyyujruaxifw[exowaoxwzyvrtyfma]ipbuuiopdxiopznxv[jyykfklmsilaxznxh]pvkugaxufjdwuan[npuehzrqfjixjekz]fuzuqrmjkkjiokcw +bjzdldvfwxxxefgtii[rwwaxdrvsjqctemv]hjilyebcdlurqbffj +bnkigptbdgiisws[nlczvjmonksbiyk]bfymuwukbkqkvhyo[vejoxoqhxognrgc]bpzlhxupauzewxvuqvl[netcbnacylnyltcqc]beslyhhwheplirltas +pgxzyeykndmxntip[dvlngmgydirkyojcl]hevogchhvwlumduamn[njefbfyhnppjoofp]jivtguydwpcfockqurc +bskokeuunevhkbiwggj[hkwauozybrrwhfitnfq]airyuqgrnuokbzsyclk[oypotznidcpxkhwhj]tvjlkqqzxgebvam +mkzhjtzjtzcddndrx[iuksqclypaohlzbkznc]ikpzdcmcvxotkdrxfq[wnynwueczbuctbeaf]zfcbatppugrpbwyx[mivcpesqgerjjcuqe]dsrdmzugwbepgbcqqq +mnzvtidskweiychtc[wurejipylmzbwmwkl]xgdgccxgpallpbhyg +ypomeqwcacphpqm[ofscrybteawrbvqhtxs]lpsimhrenerojoghoh +nuzlbjqzbnxmomrjlpb[ztyepzctslllsmma]uwesrgzxvgepmzrbnz[lvkavpaohbgsdzvpp]dsmeiyrlkpfrahq[pzvjsgsikunmeseey]pfplecnjxgjfxvcqzln +mcsalggrfrurkxsfufp[bdufquaaorjupnjtr]kyemyqkytctsbpsasyh[fkllkidmdhqhqsfnar]mtycxvanrloifsucae[lqayzpjtgmxvtaskzq]plpvcleipsxfsfjhmmj +qewoofcsqvfeqiulfum[fsbdmgmrlbrcxqbltgp]vsavhutuqxqqyguivfc[avtvqpcbkjaxsdwcif]qrlumtxtbcirpfwxe[ergapjfseuqeueuse]jhxdqaoociqplgjxfc +atyiwanxdchkpaorygi[zyjqciasgrjecnz]xojylxzsxvjfgqjft[iinfzfudroehnmbyr]blinjcdzwsghrddzqx +sucnrmwljzsvipqfcsu[ccxjjvekhikxdgq]gvgrvgljgbbbnqfsh[zyxiohdkgvwkoxzhky]jicebgslukbzhdji +mnbaiffupkfxpemr[uyzufdzkfvngnoogpb]sssjqfesnoegngu[pxoxygfniklvhwgfcp]kydobvhxtomntdmwp +hzpelembrwbqphxi[qtatymcowjkgpiw]qipzlxwanhtwkkyut[pgcazmneiprepkrs]qsylhoplelkxxtn[ojoblpesurwcjkzmw]ybnygyagneroitehq +qdnwpyegdrbmfqo[mpyvghubxywxodn]pdkygcgvqbigkxjln +tbmxtcbosbngtpijv[efwxjziaiumatly]uvivkwastbzmmtunox[kyffxqqzpvpafqlf]cchjkiksobzfspeij +orlelitjeeleenqlp[aymprhcrqopmcqpzyu]bxrezgoauocsjkhvzme +cxdedomcafoqgxw[fdhzlcuebxoykssqp]thbzytmnhjdmlcpwtrx +cumdrbdcvlcivlruu[sokvdlqnoepnxojo]iaeigxckpehotfixc[nqoqbomvzvvitunbfn]kdufmsqqqzebnrueau[pltgnudqherpyedgrp]mkglrgvgbxbggzmmqcu +nsikjklxfeoitvqob[vmbxlzqgdqmynzp]bplnmqtnnhvpvff[nmlhjuneukjvjkjgzj]xmbqpenxqpfxvhbwb +zlddovbifjiezsqz[crhesriswhownhf]clabhuqqnketuyv[vhtixbfjfdhmial]achmqaiunmuesmkkdkc +gmsuhcgelhdspxj[sybzfmauqlgkjogzrb]mgzajsyejptvpsusds[covquenstvxpnnlbc]tadiwlnreyzgxcsgmbn[nfcpdnvcjuyldtoh]pqfmdmbmcnkdisfmys +tjxmyqictefdozfmefx[fcgobkpwbcnpzgomkw]fspophklvonvlcbtid[mkfrgrxovqpbqoqkziw]ibgxvxumwutcsugay[jiaoeloiaxgxbfh]jykbetswjtedltzjnf +fbsmekoosbvkognn[dfxqpqajgzhaimtyoo]pftspxmsqteibgjm +pbgxdmfrqnwvdhxsfg[usrfcijvtrekavr]gwscetktrkspodldf[pnhvtgrgcppmuvl]spjltqxvvmlubbkf[ajpmhfmyqjobqoow]lswnfnklfdyfuqvbk +cawugksswvlgxdstzn[ezfehjoeipttibvlx]npuswjpyatbrelllxfy[fdbjnnocpzatmflw]pexjyhnbuuqwamxhz[vigonxrdzipivgdji]dnfcyndhowhjzbyijay +pdrksarqjvlrrcwov[tduyidcjcnzstoqka]umsllhkjhrlwvyrrbx +hhkxhaghfxwpweaye[zhxivrocojhgwgd]omomgwxksxanqhomg[tmvbqezeztbytpyk]qvlolqozfbbkebwr[ytpjmiaqomipdmgmt]wbwqtuozsvnodxsgy +petkkoaleoybvha[cedybeqszffnzygzu]falsgqmlztvovgxrc[bpbzewfubwshlvfou]unjsadlvpyibplqejoh[etkoencdmenqdxjn]pnpyohnpslrouhee +tjifcboldeelxcaa[irfakfvczturdsi]ptyfvbsxqidcarakplu[fzjzyxwmkpvczwhmrp]pkfjobrepwrniaip[pywzpfjvifhgxgbzh]xagnarcjotulvac +gszqyloltjqtzfbhich[qgshjjzqmjhzycjfkps]djlbecwdccxctkaaku[imybifywfkwtdzxa]xweatffhbsilhfdkyxa +xulziztgnwdhcydxzsv[nwmualmytxsvfaef]lfnpclsvannzeyxowic[lnmesizizcaeghofyz]tldjkalslgsebiahzme[bwteirgjsnquwgpupjg]rwzvvwdgezrfprexsm +kzfdabhpzfuvqzpvia[qrmffavoapeocslqef]cibfbrcmvckywojotp[fzqatyzbgmhjlgg]qjhlfaclhllzupcb +htzlnnigoezmmmfxuvz[tayvpakyoxxtzyltn]dtdujuuutdvtrnjue[lcoegvnmayglhdgrwc]ilmabhmhbplhvatdtz[jzpbyzbxnpvdmalyk]ysuewcjqjctwobo +mvjirrnzzluxqmdk[reykaseaqevebtkrc]jkfgzowvutbuckxxhwk +vgterkzfbcmcesethyb[utqbftidqiicchbhm]kzfeujqxamtqftih[eoarrtyorhyhnpvtmga]ylcodxbpupdfrute +jzgzqqllmuvggwwyv[tzyitevulcwevyata]iypnebqihjvscadoxm[mvnrcboulcmyotqqki]tueesgkaidhjeidrzre[zhtdipjtdehbxtntdjz]ibgvnjerjoxpyrcin +qbkppwaozkpalvyvf[eslfeupnrsraqxhlh]vfvgdbmkspbwwiilhl +ggppkguhwfodnfc[oicyrgagmmafiglul]vhglsdulvvkfrtydral +kicuvlrhdillifbezq[xgyxwritxmvnmzsclzi]vwbemwvsfahknqebvw +vboegzomiuaieemt[zhhquhjuaaazkhweo]ymvmrednlydsalr[otpjbvyujrtuxxplpuq]xjowlanxaqfphfbnrid +ukkzmeacfkcpwico[tainlxdpkjmedeyh]aloiqpxevbitamsi[topflwgohkxlaetas]andrdhnpgvoifqrdrha[lchoadqizskorafwot]ouoxmcmjdaxnofddqko +pnnepgtfvzijvvxcbk[vudouvjqfhnmocalmrf]ovlwvfwxryudapicoui +rkxvyikqysdqwztrwwk[iczynwoubxdxwbwnw]oxdcxqabwbdlxxghnaw +mnyqkobolicsbibrxvk[duytuwjunbqbmwf]byrnbtbzttduovxvbau +fofdxbknsklhtxlncbp[xxkpqekrnoikzisdzd]sxtseawjlqnpcmt[vmdpbdnomdzoqtirusk]cejmchbtghptuxvlmme[sspxdpjrfotirejw]hbecxttpcplbprhgnqu +fqbkapadvoyuujytwt[shtzysumpigydmcwkss]nqceoupxklfyswp +dbhrlyowzywvydold[jvffjbezzdmlfvwkfwk]dtdhnwdejeffgaw[emsqelshiiuklgozvm]qfnocnyxwolkenaaoq[jkiwedcexufqwth]qkzulubbrauzistyn +kfvnwyoxswzgegno[dbikkhvqdsegehty]jykwesaprpfogcz[etrqyxauilhcmeoubro]pdbgsjhckpzvbpkuv +vjcrfqndpcisqrbjn[udbrvriucsdujetfntn]oztgeynclidukwo +vysvtqeithvqslpk[thrgywribedmldzul]zifxqenfdqyuhwal[zbwvycvqgjutypqx]oaxgzslvhhiitcacvkc +vmyizqxdhnhkrarb[dmdytoynjtesktjmtd]muvbmtrhwcononlv +gczqehfmimgqsqc[imqplcuenfcvklaol]pvuchxxlhtkomyc[xlnhxnvtikshzqixhyc]gvrmejmkdtdjutnauk +lodynussigujruayais[ktzzractmievvkmhjyz]zbqxkpvmnrsegwc +nvdexfytibypqtq[gmjkkwpxbkrskcolj]whfkfuugcopbyboz[ialwkdpgfyodwta]nlwbvqltnhdnxpykl[fexwnkfjfynznmcf]fekphgzbosgluwstbim +lpmgreadxvlituqykg[cjtmfajbwsjohwovk]jdijgoqjbcjnuowrq[unzekrelkbjpmzpqs]ravapumgbazyscnzzl +bcvowpbqpmkgslvzgls[rmlllcjmnknhpfkncn]ezbxhnqcjdxoxia[ifkhknkieonsicgby]hatevlmiulgappqkzdf[jvwxtvtexujxxgdxanl]wcvstocdshkuybyg +dbhllvhwblqoorvnopl[nnmamtezbloieops]brqypzbcxxlfcqvgws[jmbqogkabmtjkwiy]lhrouaarouwbspentkd +zxrxfiadhqxnwoibkb[adpiddkbttradecy]eozpenaylhjtqlwo[qtogkzpyvazzeinpxxw]mjozglsnbnskvjgbnb +zlrexphchavfoxs[xkchcuxvaopujja]bkdxsliitppkzdiilyr +egizwfqcttdeamzotj[rcecwdldxvzitssmy]dphvxfiibhjbwjce[tsknmztgewuvcmai]lrrvupcgegnyhkrwnmp[rsxdxfckwdmmnbiaupf]efpgqegecmjqonko +ikdnhbshmkoxydhi[igxtbmlowljhwzvfrz]vfjleyvxsebiiwshc[fedmlcegwiimlpenksd]xofxlghgkfdbmhqdsy[arfcqdwqjqfaysgwdmr]gyrzltwzjqjlgwoe +dodoxezhtjlmdjgjd[nwymvwzmkvwrhfq]yawxmozgawmgvseotxq +osrppxcaroupzotjnc[ihgsbwgihjxyhdt]rglspvnkdzzavyuoyyc +tesoxodlthgyjlko[kdevzcptgfsnqlbp]rucwudduatnmdyo[exicgpzxonzphks]dogbplhjnywstfjruz[qjomksffyuhhiqnzkb]ymeobdgtcsblxpoebn +wuarhtarirxliwrzcvz[unefpvwrqsnzlqiyme]serzxynljgcmkmnbbeh[ibxgiwqnqnzszec]wvbtpzaquvylychx[oynbqmhbmvdwbzwpag]kzejxwtngvayeglocqr +hyjjgytpckgliajy[dwfofthghxucnptv]biobdtckvjbmofoo[grpvjhgzqqqpkoehk]wvkwkavjrcmawnzzk +epqetfblxhozpueih[bnecsbzyoqeuyxnhuc]kxgpnameztkuffn[mjaxorphexetglamhhb]srhzqpfrdqkpuaxex +xzahgksigbgoeycd[pbbgbjtxjfkrptf]bitjutwxsausvhtfy[emvnlpxrcgnlaosu]sgblxqbkfzzdfjqlat +drqmaccamxdulrhug[cxriqysutqqetqogmn]ntlhqnkrfkduxikxae[zzzfapmviisfyytu]dekxbweansnlrrhjhpr +cohsgbtzkuorrnym[euzrixwxznkzrgs]zkrzdjwridpourjhx[nsgrhgodwjtrxihe]fyhqouxlvnkqovbv +eudnjsokyjpqopqmspo[lygdzuqvmwqvsaz]qsfdvzufzfnjxzflkdj[rkwpjvhqwhoobkrb]kyyqnkhztwpjfko +ibksqrkftyysxggx[jfkwjuzaakymykesbpv]hrqkwwyvvzpyiuoaxrc[zqxyrgulrcixmdocv]radohjbdggmlzrbr +gjeuzydlizovnfjtqc[mmqykhbhxztcmycgkgo]cyfymkpciprsryxfz[zmdewigwxrkuqeuyio]xfyfbmtbssfcscst +quytjjbfdxlywabykqw[wrytqtdyeuzpwnaydcb]gdmsgkuwqkhlbfbiubl +hcaltnxoualjwaibig[klhpumuywjmgoeklbov]najjmwgvwcaqloi[plcsefenjborwnjlw]snremuqxieoucfuaikn +nnbgetxpcfabihc[zztuumdsokfgtof]nacllhfjauhywiay +biywdxyloeifpkfitw[syqupakwarykmnpg]qajyfrfcrcqqjeq +vmqqgxgubafggkfyjv[samgegnuzwimpfibe]wedvmxriezwrzvwu[cpbfohmvckgcrtfu]lxzynmskwpdnzwa[lwqrgdcvcwytlakeb]govnzecdihclqlnm +gzvexxzzfhfhvyv[gsqyprtywhxcmqi]jwgvbqynppmhonofkor +cinylclsqpelaftk[frijsczdbzkbrahsejw]gsfqcywfnpjhhxgrgu[tpxavuhzotceuxwbin]jsdaoqdvxkgarlw[kzfndalmklujzld]libylenfcnucwdq +djnlfkxyvgcciygavgr[sbgddpmauvhoevarmt]zoadbqgmvljbnvzhf[xqrcnrarvzvdatewr]ddbkmgdmvzwqscvvld[pepjqizjdutkvwulr]mqhlspenmgnamam +akmlmngwegfvpxpfc[khelhwvodxwvxgfhujm]loohnxfrcrfhunehf[aytqodcdwbjowoobql]tmjkmxpjvxxgilkq[aamongigaintswehsyn]obgraeifzqpfavxorz +qwuiuwfuzeugzisgdiv[buhztxtutnsjqvznpco]zchcuxagskaiuigtc[bpxjwcknmopwieo]hbetzzhqbcetcktckfl[seykohqtrrugiwlxo]miqgbifchozmawrbnj +gokmvmnenjhnlfsab[pyyxwdixtewgjgij]zifzpdbscpxkqed +gvomkacoxqruraj[chbvfmlpzvwkdbxszzv]yqqblegkxznmjwny[zhakhxejpshkllocloz]zejncsowxmyjfsu +kmzmakoecdeuwphlyq[bxkmcbxxqxbjxzvgcoq]wujgjsskyulinwafw[vrdhgjirbmpiimj]kdagywkfxucdqrqiof +rkncghhmksarghy[cfgmtyveyfgjikcukdk]jmuflspuchuqxmp[dvhjanbripgblqgnr]pituzbqsqolglxrprii[pvexlzrdlvxsmab]qsldfnauwajhmea +usomxhvbqmriwtturd[oudaimrmsngypdwgtv]ttiylejjeixntwle[mtantpbhnfnbqhums]wqqimtspbpwcwgkj +msngkjkenyzsuvs[qtvlzgsmbvcnuvn]wfsuejzjpshjwek[zehjcjehpqofzkvru]cumensmiwaqjbakgdml[ptzvzzowsxwhrno]qiuhenzhdaaigllcuu +tnkmbepgvirhbvhi[hsexgrjitwrdksqwg]tmtsljflseutvri +exwijntpbtlxfix[htpkfyxechripaeuq]xvwfuyghxwxtbrvp[futepqkjvqjgcmaie]cltxnelzeixkgoazvye +wxtniufytvnvfoi[lxoffaansaxwsvv]exyiiicouqllwtesv[cqjrccuswyqqscktks]rhxsosoakppbahngu +osponabdzzpakjywk[hizagebrkdhzgvfvxwn]yfzjcsylumdlfhybo[qnajgrkojgnyejot]qkjtwjxpzvqwpqmc +rzxmmbmmctzbvehcdoi[tmcjnprzcpovugdlvse]syprasycsjmvxassbn[cwoagxqnsmvchtybuod]ukdkctwlywpofoxjv[vjdkgcebgshzqchavu]tyoertdjnsrifeqcj +djntcedqzjhhzvwbbc[gvmvlzrakynemvmg]oyadknsynzeppoifc +zrzqcasptpgzkzo[ffriajdplzmjeaunm]cdmoajgelziwxhy +hzagilfpwcxkdqenlt[pfnqxpllbzquoolcf]uzjuhczilfhsagj[ziueohgoduamdfd]ttawzghdavserflte[prieusxxbeogytknpol]ifsqydaoickejjhfcpm +rtqyvbvkuhzobmmf[ceitppxyeeofhbihwmt]igkwtqtuspoesuid +pcesitgxkjevqvivvz[hsmjxsuljwddfrua]ihnilctbdzmqsiaval +vnauzswyqqcqxfp[rhmkxukgswpymqaccui]alnfshblhwmliptv[isrbkoxgplmzubfoarf]cfsbnqbfstksmyj +jarrciiedilomtu[vqmrvshnqymuafkghj]sywvhqlonkyeicqihj[tgsipywkjfcntsui]krjeevotdoupwxggg[lacpflaydmuexswx]eyqiazqhrfidzoyjv +tbumulwhnlrvcvo[dewrkdykuewgbmyv]irqalghftktpetbabmq[jhphvjrddugyhkzhdk]qlswcjdjiagwnzmt +jykxdypogkguezgcgp[aeqqsfoolhjpjpzoztd]ftypflejbcgcrumx +mccspzcjyjoeahapjhj[psodqsplydofbvvrlej]dfbbyflojtbjsdqi +gmtoktgpbyaljwygh[eznlivsdfskxwhqyvi]qfzpnnsismbslpse +lmfidqkfidudgvyfz[epwcdvjwuaevvavr]mzekkgdhqgdrqhbply +wtbxbqefbzxbxrhazgo[wmasevszdflflcbz]cgkzpwjfxkjjiznjgz +gwamjnltiyjwsqi[etpmmdxdyskalha]ijcwjhlkfvpmytrgki[znfqhfprcsifllp]eetiigtwrcijdonaga[jabwgtqxgnhamouzrrf]mgtwhdhoohpfjdwm +ftcvaxemmkhcgisxd[lfchmpvdygikmivv]xipougvfmwaipvymhci +dvbygqliriwcakpmata[wodhnceybjxjisagg]tvefxxirirlndlfiyyh +mznolsiotpeszsn[vxuljfxlmbembsn]ypswpswzasktioilmf +gyhdxvpctmlqklm[mggbzkyztsaeeanvq]osybcvddwhfrxpo[miqkvnbrkrpvdkw]bktmkbbyhpgkeygd[yujtsessfgstxaop]odzhouvvlceuftordp +ojudzvhrgmufnjvnc[kawgqqjkegurfckbhjk]yqescbxwuytnknp[vmpspiisssjvjrjc]gajimhovnrwrtzoj[qzifmjawuzgjittfe]luzzohfgmwpgtjegno +yrlihwonhunhiiizrm[hazgovkcfkwepjj]hylctefspjioxwpq +mygugbmyasgwwtuet[sqisgkhcxqxozcgcuek]txribhuweqphrccp[rgirvganjngcgmxcrq]cyzhzifqeqmohmxs[zbhizuadkcuqvku]otcbkjlcvrbrgci +yphtqkibqbtcwskaiy[ncztpmnmazsqtrpgipt]ubywagmohqvweqnr +ltkacxcgeuzgqwndmc[fgqftqheajrmxmwkl]pzguyzrannpdkmoiiw[rumhgicakfauwdr]xxrotzzxlznkviqssoe +kdteqbiezzcogrm[uyulaxnacehgkqi]vvgjxojcvaeuwse[lrbvujwaidbhupqqp]qzprzviadblrdjytct[ihixbmyzlchvqzok]ovatwjszinstkvkcwrk +rvcpwirzvmxgipx[ngyuzdsgjvtodxa]aqjkwdlltcbxmbky +nrfbnpazhvqoxufoil[atazhehzfbphvmmfmd]xavgaapdaangfvse +fltumienffdqrogcz[colltugqcbqjhaqovny]hxsyqefqrjpfvtyo +vdwliiyhqqneegueto[wromxahmpgxkedvg]vszttwnombqsvcpc[xnbuhhageytxqvz]vkqbzxqswjeqjebdkgz[itopywuifvgcuuthau]nwxlokywcfdmrmyf +lnxfcfoxpklsxhnad[tvttrczwyrwrfsldkv]xvoyvjxkqmfstppn[kyeclggkmleveqlw]vtvsxvvrprmxvdxll +bfbrujzleisjxfxu[drnbnoglwrlyiaj]pqmefgvscemrqgttdr +abezbjfpqbrtkpugs[iskmwsrwcenfqfcq]bpghsuqvcoraihs +lpmefpenkbzmlqgmq[avphunzetxfjsmmjdxs]aionmjdvqicrkkuhqkg +oovycvpryzdfxqe[citmqfwvesbtemv]dpskdbxenzvkmdq[cxebfoqzbkridgsxa]mdvbrwsutplcwvkv +xoagoeyhlcfwjijvv[vhtyjwosozccevd]yygksnlkcsulkxwnn[xjxhtcibykdzzito]vhpzqcjyngshmxvqfpx[nxmbzwbqntpjbly]nkrlhmjwwnisoslom +bngreaenftyseubam[isooaeaaujjugyacg]prqqjctbrrvwlknev[hsudwgxcmeoeklchs]uyrmhtzwgbwqowwk[durtalssedcdpbpj]afxgbeoposqwbjj +uegnvefthogmdrk[rfegmijatgpkzwygepn]rxrgtdntpivcexrghp[otrcktlhkoiuhzzmjrq]elltyvnqdnnttmxafr +ecfvyjfcoogbbhcfcgv[amtrrevlpkabhaqbyzp]njmrtansamwlnlr[nnxrbkalmzfustv]yzfqdnnicgniytkxv[hhyhbujjwtdwgfx]oayimcktqrvayqr +shkthohfaiuffqja[kypzkqszyejltld]zlptltkzsntvjftooga[nrevhlgxlxrdhfp]ntoiugoblmiyblfgz[etmdfpjnkssxxmflzgq]uameicduzizvskxt +zkbwjiaiaapwrtl[zmdjoypqpcoohwiai]zhutipipeeoaggj[ipicjufclvyscnyhyf]vjbdthqyehomdvj +edlvyecttfrivrrxx[zbxdriofrvcdvqxhtou]veptmlsgqmnmgydziyr[kqaicxgbpdvicogbiq]icpqpaeawkuqjpawg[anpqidabaxviwwnc]qdrhnbnwtfoshew +rfivrodvhzbdcbrbdg[xepcryrugrdvdvu]oktqcihzwmkigwdif[utknwrvopeqnznelzsu]jhlayryeovpwlqqq +kzpqjwynohsmyefwbun[uqijmrinjbfzhxx]jdmvhjadchyqzjtmk[fnvvjifdteoppkvwa]gvqtikxjgoxdqlm +vrmlvtiqtmnkhzxjlk[pimbbahsqeuifhipra]exmvxfelanrjzqzq[jhqavhbsdzglohcyvd]vdmxeuuxbceyuajxyb +qlzyhenvpnqlhftocwv[fgxvjjpwadeflhq]omyqdbxvdqvqwcwj[pvqpclzgyuxqsozsoiv]rbftgqwizitdviltxdz[twhkknisnspuzizics]yshtpvvilxzynzx +scjtcmszrcywnorrt[csccijdirjkusdd]ixqwjxqgigntissnu[cfvfxijajdfxian]mpzfpsctcrzteay[cqzwbtfbqscsgoulqv]qiajsnvyhuocfbs +auipynpqbrwjzlmzl[aujvitfxniudypagrvo]pssylomazqmizwlwi[csdigjqelfgzraldhzz]euqvrminyahycqtss[jeitaccwvctalfrl]igykfetkzrysfwudo +eqyjthcldnhfkmrs[vokkahiukvtrqhh]yaeqjcljcbefdbdvga +ffnlotzrjimasdesyvq[tdjiwphyoudihpfxcht]tryyqdjlcuqrvnqich[pbqacbutcqblosh]kwjtegfgffjejcs[cfpgdaeyjttqflljug]mmqqvplbayzjgljlkv +fmedyfuhqjbpgdn[zgrnmpzjzltwzzrul]rwbaljlzamjxeyoh[ujapzqljttupqeq]srsnomadmxvnplt +sdmsvobzqyyimoqxp[dlxsrcwlcliplma]ggjcgvaptysicxrf[nzbfjguguhgdbnkavi]cdwiukrzcdafcwvau[redyhialkkakkdw]tshgrsyjyhrdrgxfazc +statywcdcubhgql[dxaddykuzlbwbncgm]xvbcrhfffhovlkjwc +xwrjsohnxwhuxxgkal[drdarprpdqlmrnyyl]lcxqhtifgvumxhyfg +dceusydtgvoidiwvr[xwxdkrpqztimdqcli]isbrbjqiotgrgpyesct +dfcoyiynyqguhlvqps[ixywuqsjvkcvdgvtir]xjvatxxvkqxswffdvg[wgdvusxfyposefy]zsyoekezyjzgogrztv +boxxwcovmrwtvpc[wvswxxwkgrfjzspxk]tcupcgnxuowpndaycqh[vykbdrgegnzsqlcxfru]aaldggnttnpoufwstkb[rrepursbaqqdznt]yupovasycjtwuysfxtv +aferniqruinktcmafzd[zwmijickemmrgtqgl]pabcgqclmnkelnd[rnylsjpdxphsetesnsb]oansnqzlrsdzsoxufj[ygbbwrrxuceezoxmjlt]cdhxylrchoniesm +zujuchvijhqnzbnncbc[sedjhgvmlhzzembtlxx]ofwmzrlmdabvkfqc[uxmleezwssylqghgo]okpqtbroeqklmxntgk[ddzdtvmgfbrdwfp]omsfvtbuqcxuhjd +pkcrwivfpomxfofcqe[xrmhrperqofodgfdlt]dphiiahoqqquedgjrio +kqdjfvkupfhlary[rvlklzcmhrhrkrlb]ttzeslijskqjeeru[nduifadlvotzxlvmfzq]rjgajfgfcmxfuhh[rmrkzsmkejolrjgjnn]xosjsaspfjqyfrsrw +dlhzwfvcekvrggzv[ofqvnzupatpgzfahy]ftacvsvkgqxrqtanhs +owtfabwcaygijoy[nosyvwsgkpyfesucm]esecvhmcjzycmsesybc +paczhwhkhytwllmc[dxtpbrtkeekvoqqkvno]zjuyuhpzbsvzodpbrnv[ozdaihegoqeuihco]pxptnsdupkfgvmhruf +fkxezddxwnlzlarhk[mswldjncrtgjijeo]ioddubxtscouxucy[qunukqpvvgzpxukwn]fsjmsbjibbbeccux[fomhpmrdrozafwvs]izzildhimulujdo +cmoxgmdxxduzdczqoim[dyjnrdkyixdcdyqqz]ywngnwwpbamtjuhj[cyfwletseqzeesmxlz]olarxthcpvophvbc +jihdvvjpiawlurkpna[rozyjywumsckmzsmv]rhppipwcrnrqnqymjm[cjozbldvixcbzgtdni]nhgtgqgnwkgvtqxcbq[ndpdpvdwyhckolnoiia]nrpriclcqejmjblaoca +mqrofejeandcwdb[euzfcxvwvjgjsrjejm]zvialbaxczkcbamow +lpjkrutazbxjrsh[aaokpurkwyqmqcj]ldlutqskisfsjehus[rwswxgrjiajnzmyva]kpxjkjranacklquuilh[qswseahkaawgoqbwoba]powmdzttqqgnwoz +mtrgomgkttblalylml[fczsdkxnnhxkjvoxyp]qhcdlqnkhlqkume +ejaxgxfqzttfjro[nbudxjzmewgejjr]yettpxcyntlbldt[ecxxeskbvsmevezs]mwwceidvokbtuji +bajbfwkcbptthrpz[oxibvttbgfxxoydzozx]qyikbmrtebdqcxew[ezfeuqfqpkghozohpr]sjtwsvtsiuvulesw +pkcglwyjkpslkzfbbkv[kzaxrqlcpdoafrhw]crsuleuevkueuhu +yzvbeybjoiiawarzk[pchearjoaubhjushnuz]fnovtxneceajvroio[jjltmacrhiepqmd]bjwpzdgdusdlpon +ntcswtooxfxewxfqs[whcrtyxxvojtbhvcwya]othglptbiumercc[zjvappnrruptaqcnhtk]vervxzljrmrfdmgepx +mxylkjghptnxmngpxt[scnxrqcdftpsmfttyt]iqccdcdjhcdculfaxv[oypotbnuowotmgnutn]sqtevrkuolowyagy +ilzgxgodlembephhrox[ficbjdyoqsontgftgjo]eoaksyzlqwolxcwxt +azuhgtygltvpqybiuhf[aabjtnyzrjmxggpflz]dfbhxzxopayawmrehf[bfxaxfuuxmaiygdpohs]hjlapbinhdphibdz +rbwahitvgoeoydvuuwi[ipgxmdggicierzxfl]kfvwfixdztoxdsju[nmmixwldeahcoszjyw]exlnyfffpmrqmapdzqh[deqslgzpznbktvn]dalcyomluamkjamhmcv +clasxatlmbbhmpbe[fxjhfcsoxdrmjlhemjl]hiihjdiuandtorus[kkktqqtmzdzvonws]diaqvpvnyfndpukqtm +oshcmchulrthjugf[hhkphbgxvavkutm]emqhtezcshpfezmun[xmizipuebzhdblrn]btiszwdiyykvovlhjs[kgbllnxkvfymsqp]kordlzgacffdjyes +syfytdnzapvppsxwvuk[hssgmdjumfwcuahbzu]tjmijmhyixegulhwjda[obvfnrbrdefnkkxmy]iqfdmokbfvubkyv +ooyhsaozcfvzbligkh[aezppzdmnnebgew]rjipwlwyzcadfrcm[ucpdhklscwpzzhmx]rcplkjidmzwgldmbxnh +usgwebqpguedtwal[ucahxntpxjzwlkyks]rtkegixncuempbik[eqoxdwxwbougjjet]waqfnsxnwgbzhjas[rdjdmnzmkcoskhwmwp]lmndepamkrbrezgo +lzexedsejjsovjhhmzq[xdzmigtseqsprybxex]ctqumfhtaatrinmk[dfqxslvuwdnqimy]ilfphdggfbvvmuuox +ejomxwuqpakxbggi[tyaxtcrupbficckkic]hixqaeblbratemmv +brcadksonvcvrovnlcv[xqxceanurghlxoop]tkjynckrlxjcwxcws[iwjtchdptjhnvfefujw]bpibnujwktpnkwal +ozpqshbippcazgbjwsf[eeiatzwmxezmsphxag]wbmhjqnracacplsd[qqqskczuqsmsaffnqvy]rwexxbhvanycinne +qjcbuqeoxvfzgzkjx[nmjdpsmgekqtgrz]psffzoymswjccwlvk[pzayorfnkpiqsiwdksr]dqjsdpxbdypbofvjd[rteibgexrljensnsfbv]ywtfitjjgcqjqdqnai +eqctvrzmizmzadiv[nfkcjhlffxwichh]owulkigprckljfa[xwiexfzduspgkmamyz]dslflydyueutucbz +gaptucbphbcauhpb[inmcacncuhnijxba]wojvrbwisnpqgom[lholtuvxkozwvqicgqc]yfqvzhaxgbtrtpt[lfwlypvzebajjcrfg]jptstikegtittkncnp +rdmqymmuuvlqlifp[tunrfdqlqcskqzfn]mznubonmfmnddggsl +bpfzfmjrnvvwock[jfgazbkopygtwbeyfb]zxilzgfaykfbfloqe +jgoiehvyjxuigojewgr[wpejfaphlaoasct]abvacgtlnghcwjhu +givjipvjxzexjhw[xhnibqkmqkccsqvdbmt]axhurinkxnjahjqrpf[kpuvbutiwegcyjcmhs]xvpeggiwqjftpkbc[elnyvjrckkoudanf]rbetfdgudyurbhjg +llwritpzvxwzjcou[kywjmlrdgbptakqh]pjpxwtjfyvshsaof[fajaogkpjxnklwjm]tubchodcesdoseiyc +jthqitsqmtsorji[xbpqxddyptkjplwkirj]yatiinytqnkxblve +wwmxeeruhuctslt[eeolefqgiexdnepz]wtaprpghficxxhuhw[qivyocneharsphhqhe]wkjbvcfoalkjwbmf +mmcrhrvyfzqlcrwhhce[tmreurytppiemvporrr]qjcivrzqwlbravpsra[zilvcfakxnllharqhi]hqztgurarfrpmtxvdwk[aybsiaabiqtxvegkfol]rdposwuhdwgdiqdnd +bxxqkcnpyjrhckwg[ndxfglcetarccwax]ekgmeuxdzsevypla[lkyczdaqbgeusesaqpo]ycagugbwbyytiqqww +zyjztilqxzyqhnsxri[eqdxnwvdejxnxhkl]jxvbrnndhkizjqpudnb +jvjvdwddugygslqxxlh[khubfdbygyumlsz]klhfsjpeedjxsxbugq[zgyevzlwzhypnsjw]uqsfyxqdhtyhhqp +cwuvzqzxwsptjpi[ydwizxalwppbndoy]doilzhmzzclxyolblo +hvyktbbtisuoixxlbp[ielefwdbakmijesfd]ygoplccrqumknyeyba +byxuiqrkocycxolu[keirspyapzwoeqsioyx]uqbfvwfyrigpovez[bexwlugermolrvyhajs]baxemomocyoxynb[xmuyqtsyflylfxuopf]rjboetafmjgrpsm +tdklkptxgstlhke[rdmlbgaqzezppltw]mmmgqwlhurtjqygissa[mrbfvjpirijwrirqsjv]cxbsbwsckpmuelsrx +zvltaytdxmaumarpia[bczfhpdfxomflhqmy]sqijqpemvyephhbi +qmxcgorfdqsuiudpa[heapfprpzjujgtbg]mngqrqyywqrispeh[pgrhcnjpcunepjj]habgqhnhgbbqdptbo +blfcfwbcvxfvhxav[hgaehlcybapzhxu]wkcghbrtkkwvjyzqlr +knxtxqrxtialzcb[wnbtaiesijtoxcpa]bwxxslcjmzlmaccropd +xsuneruvwxpqovsx[qoyrvfdonvtegja]osapkfmwfyoyfbomx[dngezvkrojaiypd]iheegrvjogprspujlk +ezcdwtmyvgaqnwvir[blmpcywkvmzsuyo]zwisjrxqeselwsnbf[bmxecxmhgvutavznsxd]afuyhzbtlovctkvmppw[etavleaprramiwi]odmsaglweilbnemynpz +pyrbvyndildippd[hfbkkwkkenhpegzd]glkplukxdjodpmndp +rbnxzhtibohbvjbtlpk[eevybrbygduikemgg]vtkdqwgrzfmkgdpoz[zjcxbexbxmncrbrvlc]ezqsyjlbwumelgih[tselcvyztrdlkugvx]vgqjdcgybgbsddtaxaa +conkuduwkjlgrfc[evbshdudauhmqhejp]vgshestjrgoxjmtedf +qayvcfewuveyogr[hyenmhabxswictfv]golqmoruooihgeelk[kfizdlmpmizsnsdvcnm]dzbneckijzdnadazot[yfxhyaecuwdkwvzr]qhkicwsrsbzjwpota +lcztngoqsiwvfqhnwmk[zvfkipklnsakhcpzgtc]vyesgzpglksagzezcfb[zgyhivlzfzatvqlk]autcwwoipxmtamazxcw[efvcjwlrypkqgap]hcvafpyqabhqrgklyll +zedcfrhfzqxfsge[scfaefxzwalnttqmkwu]qtilslwpcadwvaj[npftppifpxpnvqtvetm]jiqtmeqjghuwqpsfd[txhrtyrvwdrazlnfu]nkzjxxiplnewcjv +gjmomiqzzhsrnbo[jwhqsbyluqjjletch]crvorftrpojbbsd[znqatuxgxrclcss]rfjdcsjwsqmvuphcvxp +mzjqzmseuxltakor[rjfzudufbzhemipao]vtzsxumzviwiqog[etectpaoshwzlut]osqieltnflfqdnksdce[lbueyqxlfuwefsuue]qybniqnpkdsmirlo +flqybxwhijhdqba[hdzrbuxakxxrdbkset]qtxkjzatvekzawmt[koxwjtmbgymuqxggz]auwejfcoiofibpgtkr[lsbcavrwgygsuqlksef]tgqgzvxnthlpacbz +eqtjkpttgwtnelvbwhn[hzjyymxntkqquur]qcoxaiyffkkitjn[wbywpfremnqzvepiqu]knvvkbrdfojkanufw +ezacebuuwsjurgex[mlvnrrlipcdywriyatd]zlexrnirycvouts +gimhfftrumsmvge[fkaxvinxrtcncwycj]lrnulsujawsmjsd[wgfadsurmhiydflwk]uyzksqugvstnkkybp +wbjxgkmxhkqyypyfha[sepuyxyvgozypvacar]xbgdthsqwooasishixf +tijyosliiskkmuwpy[cjqnhwnzbekvhlw]kltiqunfyjrtocv[aqtrefpxkelrjchy]vurioaurakqrwnre +kupcmifhcvjbkuhydkh[rvanehtiejcvbiholi]qcaksnuoycdanmx[zeoogomzpdwezmugl]nlcgeroxhtitayvctx[ogvmluodhaqxnrhenx]zjjfjsgyfglhacjnrhg +mcrxrkwvqoctzkthwzs[wxgrtuvzcyprxrxyu]xlbiinpyuhhzyxrppup +rnxjtuzfichyyrkpj[rhirkzutlarvceqy]hpylofjvreuibpvr +aucrxigpotylwkz[yxfeikktjcxbvnjo]prpnuvlyybvecrvxc[xtydsqbcxsadlfijqdd]abmuipmottbbcvcrfus[hbeqwrliqlaednpcbo]hlqboxsmzxdndwsgc +rxcqvrkeazdwlrum[txghdyqabezfzxngb]uhphklwpwfwlohasmth[rxixwgamovwkutpysew]nmvnrdggfypawtro[qwikkddzvvvigqllnru]idezdxcxzczrmzscsk +bvkryndkaaypctgubsc[oeagmbkzrpajjazm]oumyivtormkblitv +uponvppnjwuqdzutdsf[cysewmcnwvxemsqnu]trfjheetuwtyugt[iqgjwbyeyxrncynfuo]iayzdndfzhuvgfn +bbmyqlzefpudqwfrw[rdmdrgxiooxyvihppgh]ounosrgyslweaogvj +emuuaxuvfmiwomd[gdovbgoyoyafbeggh]swiemcjscimazwbcqa[wsrjizehkfpeimwo]lgvmmtgzqtqhgvuru +ufroikrhavhrurk[vbxpjvirmrjsvlu]voejxnvidkqgetnksnv[dbhrcnaybfatbip]wjpafyfywyqmsugaeag +klsplmpgaxtpylszp[pasiteibxnjmtzbokc]xpadcdaechphntvdxv +ykhxmwleggpiyzbu[zslsjywxxtxviladgg]txteqpaaovqculopkrz[awtygoizdamiaglxv]dbicgkaacrvfgyv +xzriccfleusulnlvvt[vtsussorofvupuwrat]idoigjzaiabmlbwhcas +mziqkskltbhvghsfuyu[aculbnusbqlnhnwpwt]nbmpwptnavupjxs +rldmlvadnumupyxqm[gzzzjbieaiupkytkb]vibwqcvqvybamco[jnitcmgcxonojznec]qsaxoelsuixechvn[bxxubbxveflcfed]pabprztdqxmocfkqt +xmpazxprwkwbasghfb[nuhgoguvmloomlgqyj]vtnakhlizbmtiqfqudc[ijjevcorrrjzangjc]eyasctcswtctxnu +mvdiopzywfanaqy[hjvcxnznslqhcqrkec]khqxiuhqkvzbfkog +ltrzictithutitxt[ghgxcrairpbnnoemvso]ekjiysoqubdndgkw[qipmdfcfxuqmolkxe]kxpapsvkobzmmbfiw[udpdrxeozgjdjhhnkm]mrpflzzjawefwpzeb +fdyukyewblhyjyx[jopwomhiisxnuerpi]glsaylkpbyxllgwmfv[rueojdekuaimcvkniv]witrkqkmzkyxxwlspe +uvfhyswjtnyhqobzfpd[nhgpmqskcogyceairy]xowcrcyirmuruxtckh[sxddnsiedqedpfiykji]kpbzbugmaleqxyl +vqqimxfbueniooe[lzxzfjihkygecvzvv]flcrirjngewtumxzs[yandwyszuzlcubt]dvhbxvnywsqjyqhqo +lunihongrpvpalzq[tkzljqepunhqznyptpj]wkipnucjkldgsubida[tdetpgexmnviwswpt]pimhitvqrrjvoqwis +lvaekzofnqvdubfrsk[lvtmacbdzydqabjkgxb]jbxaasjiawptstqogi[yaenwdrdllrltchumxl]mbpslcugeuhqzgqz[uzducptflfkjdrgwrm]unxbcxdgnoykefjtzbe +eukrbtlorkrtqfab[lekqnqbejpjadne]aelfusrvaapcnpjxb[wqqogplrxvgemxek]pwvvamjmbsszdamm[heouyapzgvjlotyuhxw]cbpecxzwilyxwhez +pggpeuuyirrouzm[llkjbvwilxuvtyeiit]gupoanjhyesnwhpltp[ofhibtfooiebglzhday]yvjyvndeuucjrimrxr[yeylaewmxyfcyuic]csntkkssbctgwdwjvw +nlytteqqgkalpmrc[sbpxcsqbctzpuaakx]bsddanjfxabwiljmlxd[ruegjrpgrmhyfoaz]onwknfhnjitgtubtckf +csaiacfvzsbxgthemo[npnzkvvtguwizylow]htwpxuzhyqiukmldt[yhdfdlhdjhkcrlg]ipoknipafbwgxytfpoy +xwfcctwnwjeskqag[lftxxdyrypdbyeey]mmkwkojnqpaohjijh[rpsfpligfoulumlq]yrosewdrqkbgicvsrmn +vgmwxvnqhyblfpka[qnmplnesqondpvjxd]xkjprddmfvabofu +btynuvvabcnisxbqvx[xlnbrzabytflrxd]fjphbndajvoiwisptv[mxqpntetsskqjij]hzhipxqihobzzzq +xehxreqkkfjxipbdc[sxcdjlkmlhoxvdy]gahtakcbmopomka[dqxdvispmbnwwzhc]ypvvjdrhxypkpqyq[ibpufwgxwhokarghroa]gajqcodcioqeicayace +qelkhkmkmustwwbgnk[uvppfsvufazoogql]rigakcrbqudgyvrm +vclqaggfqozeeylqr[ozvvsgmagqdrieg]kwdavlebaonurwu +cospfllecgkgqtzpoda[ygnwzkxglcitxfbpojp]fmjziwhwyfmlgymin[oxzpbbrgubhmnhepmeh]dtgwodfoyponzkgkq[uyruiqiqeiosqrgpd]vzqywdxoywfzagvlvgz +wmpnhrjhmrljibaol[lkgtlecrklokuufgref]fpbroqptvihmmvlapv[kqyhpvvnziiatpmysj]ihgvfldqjawqblllm +epmrcmqegwfrwduzatk[bwvgebhmynydytly]qkuxfjmlityuqpiuz[mrcbeojpwfmogyqtx]fcuwcopogsuxrwcmpd[fdjccinxufucskung]djrvwtngllkdkzpskbt +ioysscombikdlfl[rgvssthnjkjyqbus]rxxgsfkzthnelrlqi[fmouezssntzpkpvoz]xpedmurwcxbmrogmqc[muvshqttktmhppw]bcaksnqurrkzfuvsy +yrlqwmybuzttmta[wduvgviyivhsbsfoaj]xapgyafdheaypmliw[wzkgiqrgjgybkqlqtw]klbbzruoorgsbgnoh[fcztvzhzdcvytmx]xfuwxklasmlzdpmd +hmlxxegorjkxmwub[szfpjebirhpctwhqjo]jhmflkbfjehpcmmjmc +izroszkaqdimvccaj[hxneogylklgpkhnm]gxjrzoymwdorjxfbnfd +zkcdwfzlffkzejmpz[wacjjgvdswnetpj]olypdweadesbolvc[rtyiqvmqmwlyirldxl]dshmdsgmhyvljdzucnm +ckbqoxrgztxewnlzt[xmndrwzvoououidh]natgwmoyjmlqxspdouo +swhnzjzdspsfdfe[emfqxuzpzupyqefdh]oqzqhvhkedpagibvkae[rzlobzqrpuvpkicb]bzoliytdrdroreles +iztvetvxjqpltvkvsud[zhifpxvnvfweeau]fdfztegddzegjltcfo[cjapyvcsmyppiovo]zidpbkafpcfkzxdwv[moqbrmegacmdotcm]hspyralgfmhiyvxa +jdafqreeawkefqtdyl[xoaybwduvbepfdfvz]gvqpeyxvzvulrjt +pddpgibqytztkbgsuq[ymujijikkoudcngw]beufjijpbvnumuim +ucxbhtwexygmrcg[uqurbfgrteletvvkqon]dubwuxxfagugtxsnrg +wjsyuzatnltcqwfim[kbcgsyuzgxxjjvb]lilpvgkqxyzrpaj[dewurgblijpigaz]prryhpooioetvovtskj[uoskeykuyinefrz]dyyodskolistloiwsje +vjdndymndnmoekurc[jhrgpcevpktrczlt]xwmyfsfdmppvxmrh +ncotkjbzckbxpvdynq[jeagqygsdeylrzqct]putohmklmktyecovyk +htryepnqeptnntbvy[ruetrynxkllonponrzp]uimyvygbbjskgfuuu[gossoavktylxmncyyfs]yotrlpozunzomjtc[tgoikyfrrmlvyvoe]rlnwzyigyvkhequuh +quaqpykfzgcsvjvktt[uewzjdwgvbqsjjqorhi]jqpqlbvwatrkjwuefhj[qbnjoafobpfminlswxz]motffatnypzjzimkskx[znplbzndpvqyhyiuxjn]euozgurjumhmbsksaqn +oqwcdtnqratojpa[tjzkliezitfoeej]jcmjzggnpndrbcdt[vmqdzdcmnaukaulpxrh]jvhftmpjndinconrd[jabrequmwzqgkflxe]qfbpwimzbdaedtyll +dmojpwvuihorsnuuntz[jdyqngvtlytqqbgkhii]cregynlhfgjwcnep[rtumpjtsmrbrblxlt]fwweoejcozelkas[qjirbrbultjnrwxqgnw]crarxbqyfrflijjqvcy +qjjmiujbippvbplba[rgwtrkyumzpcfeli]wzcernyldinuinn[vkckrhdnarhuete]lbxndnnigssqlvtd +nnqvkwawhoswydu[vyogzkuofpiahaccjmt]iqmnxjlbjavnuyfupx +ucnygbobqgvuyiuhxje[fuobokgfwbvpqbfiyj]jxcvhlictpfkaour +rhuckpaaqppfdoo[wioieplfptapozwb]uoiohcdkyohvsjiis +ewqoemggcqdhnrmehqg[mnekdxnxneimqudm]sjjhuhuphhusqtmt[mpbvgfwbhdiedzh]qsixlalnrwrbgjvi[ncuapspdwulmdwqva]uueriochuuievfzbt +jsuomvkrvqofxwtl[nyuglrpjfuonsdktpz]mgejjewvakggbzr +nuagdeojtvcbcoethg[dfrjdlokuqvyzoccyd]jybqgicldznxesoalgz +drmtftzvxarkzim[eqfezqeviirhllnne]qedeseblbyjtwswj[rpsjqjbxrtzfazlikux]mxwswjacngrjggmpjjz[rrhkcjlsogctsnm]eaaugmowojdgcclp +tbzffdcdmjlvzjo[xejdjrwbyqiocuxeiq]oghxfuptfdpnxcoluz[mrampxwfbmsssheliu]hfvydfhchubogir +juvhuklkygekzbznki[wiykilvlzxkfuqvo]lzcvkmzznkwauzrh[jrhmbyqljqnyijio]yrrxyxcjlyeratxp[fvpuvopxdcpjjqdlez]adqimncfauwosnuu +ukltbucihswauod[bhqaeqkxbwivywmt]qitkxnmylbyavvizdhl[tldglmhmjviujxhmqf]tpejtzahvavzgxdbuj +fqtildszglpqzzjl[dgbnuttrslrulraavu]adjaybskolsnapzmuj +goaoupqphzoejsqpqd[kmcnaedqlpiihaft]cffsimwkqvusstdj[jnkdxgldkvfyrux]ygigbtjpwzzuyzzpjm[tklflcorajolsxozxr]oguklnturjdlgnzokbc +ewgkzbnemxmcxgkqigj[dzacevlmkuiyxlgqnkz]oxvvktrcmrahcvmlnbp[otrfgbaaqmkofacmrlw]etrmldlvsnhehvjk[ldvcxxpdqmgmnmrw]lqyafdemdlqcriwh +psonarhezabpfsifv[uaqwtwobaexigqnc]fuqrrfgtwtqvbnjjx +jzegdhrxnytavmx[kdldajeatgbqscvf]bprcipjdemanmczkt[piosrwzmzmqnwkh]hvcpvmuoblvumniat[exkpmlxhaynhxvrdmgz]vmuoxjinapzklxaru +ovgbmdielzykiofb[oiujujsxewzjczsowk]ptlvujuolzevdlij +ixubgymonljdliwyflg[naxmhtywscwdgncnhkq]zikafaodhrbjpslz[ofvxmfbsoijfofozrwi]ieymceoceiohwaxs +kyindqkvkdulbxbu[twxhaiaixtafaydx]iwbaxohuhfafreuc +sirqeuilhguzjwoildl[ddldmsqqierffbvftq]xniqqnqutqzclhoj +uyjikikqsxdnvvqptpz[ymhsvvjxoijzkftht]hmcmhhdmmxkuzhfcifq[dwoqersxcrtdzdwa]rfxvekmjgrdfutfyrc[xhbfbjylhvtptculh]lbbwcmukfgskjvhyrf +ohiiukzjxgigfnurxv[tqsjmkobruzafjl]nbsznnqdcaxetyxegku[ngbuxgnqpxnweesoxuf]xlzokactshqnwjbpzw +xpixpwufmmfestlf[chjkyywtsoksgcffe]xyhkqtytuuazytydyw +mjeioloitmqjfxpxk[jrrpevldwlolkfoaur]ozkxincwxwnrtwqaoqj[bowfbswohzbtdojftd]coiebgoxmwyvcsd[utolilugilysyjfi]ivzfjbjdkrldfxv +yoydqexqgijzgbxns[klmoyhlynafcjwhgllz]lmblxlcbdxnzpdyfxuo[uqzaoedsewctgaplxay]acoovzqekxxjgrh +iinmymsvhmzyqnss[buxwtdshunlxlfjbhvx]tymymgtvwiyirdt +jslqipxcivbgifjpn[qkvesxvurjlxpxoi]uiskmkydgjuwipynyhw[ehwnfnirchutzod]hwyrmbmspvyxxcsbz[iblijoorvduvtrbtdfx]vmkmogtwknogvxheid +ygamayhzabvmjweoojx[iuihqamxpamebyihhcy]shltbfotaolqije +zfqtclfvfqqbztnch[mllzuqutsrywfxdahle]aivazuuusuunrnwoxj[zhqqwnbilfzqmow]smfhaitcdivwbhqsfc +yyfiotslsucmofojc[xejwcsxptsxvlpik]rlslgphlgfxydgu[knmtespszyxpghrw]gmbmvaozgrvqqeeqg +pqbjbexaeyakyaaxi[omgcbnluzwoklnv]ofuzblenimvaqtxjez[vcxbplpfqwpzkftml]cejegegtppicmmbu[yluyvzthmacplsvwpvf]layvotzubjmgejnz +ljuprbgycxrhdmghqqc[nlrcynvlolnnqssdg]xhonbxirrxorjuzpujg[qlvlvpqpqtwjuneh]vikbwqmgwisndlqrmcg[xhethlrfkbthdmu]dckjqdbrblnojcrzurr +mqutqmdwozuhzwqqxq[dzwzteljtplitdhar]rxghimhyqxowhlxv[mlyoqapnlnyyfocn]vivneyldkjcptbqhp +sjhqaabpeywbipcxpnq[gowomrhpsyrbprhgy]epfpwebswptfcwghpus[xtyuymkaubtsklja]ymflhwvugjqzjro +aozxxdegoqmyscxet[ssyqfwkxxcuazrt]jmzkmoouxevdffhmv +egqxowrobuloznoyf[hgzcdrutkfegvbwehj]sbqgbkajfdvhylhy[pbyjyysgfabkqqlklz]bmgtcrxghywvnlfvgx[ufqpfqavzhnvbxqjnb]axmsnnumwpxscjufqp +tgexouwlvezphimqk[akxteehqejbqofh]gqaqxpqtutrxjdwh[mgkvyppcynonofl]mvhwhpweeutuwoh[ykvtgfumeptgawckn]vbxioamtwgayepi +ehwlukysindvrores[bmlmhiwontkxtkvr]qdadhkvcrvpfwewnt[qqrjjvoffqmwzmnkeve]iylhaugqsafcgfkzuqg[qlghikpisieuexn]encddrspyqffsprdz +emhhugkpxoaimgd[gatktshudmjikpvm]hmdwdegfbdunpzqy[kqmktubpxtauvts]eixsnjdzhdqllhdo[ohpbpjtlcocmboouaq]gwkzaltcrojxdxfkr +gyiflvcgrvflnqsfua[govhyextdputygvvn]mpazvdcrlxrozfyfcsr[lktddzwjgtvycwryw]jhexlibwfeiohlfjfom +wvnbjqwykgnpujeos[bgpgcsvbguimschbxzk]fxlofwgixrlscmgdpa[rxjjosjniqheyesyyf]fbuovdpuwhognclgw[ftpcohfizteexczkrca]caihefjjiqvypct +znsokldvcjpxjog[mmkosmhdjarmlpvp]rckhnldzjkcyxhpe[hxpzqoeheamnyjb]xpwcusvvjufgmqpjd +wnfvoxftftdasxxvwzf[shljlydeedkfkwjzrjn]zoiutacwoqmzrtft +aavzczotsjkzjqd[spctqczcqcyjbch]abwtqpotbsyxnqm +psaxaferpdjkycbefq[xqgdjlcktplyirogu]ayvzfrwshchgkwk +nqezrycwcuqadjxgygz[cqgfbndiaxmcigiglf]miznonmaygbxduatm[ytssutmaudrdfnaje]vwvblylaxpzyuqokqw[jkbbsvkgmwqibzp]rphvqqzskkjjykrlrl +aastgvboysnlkxeq[amoiceiqwyyzwizpra]xvnidsjvbgmwndyvqup[fqmasljimjciejz]vsuaqkawwzcdegslhw +kroepfhjfbtngclblv[nmqbwnzlppwwogx]tcmygfjunqozmnwhv[gnykhdptiycroiq]ejwqgdblbwxhprzuwww[tnfzvhsfvbgpnjdn]dxamipqvqyycujyqlg +nmczyoxdczyqdnyzlo[iudpmifsntjgaakwxj]lbhyrfcescrxaabp[zpzkolmrfnnqgrlkj]vxrynwlcrmuqomi +ozzsbixefedyqugctr[ehzredumaoouoqmob]ajhvlcgqyqgpphtwhxv[tnvtgncjfzpsgewcd]bwolubbkpwqqeoayo[ugtsozzakczenvgjtg]cxtduivacbeypub +vjkbvjmsmwjqofeiq[qvwfansyyzzoxti]zuaejbqegivwayycbpw[eeiahaseruwjsqfbqpk]ikghnvcjvtxtgcd +vivrgfiukxnbynsqp[cyuxfqupotifxozqnc]iobeautkmsbtwovbrdb +gmswnmzxtlgkskz[ilsfgpqvhfczowcgy]jgbfasfqdxeckkl[bkknioqgtrirutu]mnwvreyzozmwsikmrq +xvcbxpcxcekdkzjg[xhaezauemdknbbihbzk]tuuyyrxavoectcoudg[jpatgaisirkdlyuzul]ddafnkyfhdaazptd +wjuuzneefhlnvmesby[zxqqpbcrljufssq]mehwiypnradpyar +gejmupwxgpbfiugsx[gssvhpgjkbgyqdgvpx]phhxtbgfniztdxs +tbcbksrhfnvybudmqsa[janytibukbknmcv]bnvnzoiztqsxnxvery +zmcrbfzmzecldlunt[nizsuoobvamfrlu]pegsxhninuqxufq +owgmknvhkuwplumklyv[tpcacgallsjgeuf]estbhqisggkmxcrxt[cecydypetuklwahrxs]okdiwhdydchkjhei[tpunnntujbzwjwrq]bcpxsvagbvvxiissg +zlcfrdllydptpnljo[ysyvwymstsmbjoy]ukwowlyltntxpnvp[hfvczmmzgyhvpfvph]yssagzxajdthcxea[uixmfqtqbguxqsk]gfuddvwyinlvxcq +ifwsawgrffgimlcwqz[gttlydqxzgwcfng]uezrozxqsrgoxnf +sdzmakebdnqjulckb[kpeetbjmqnjsxypx]fattzpkviicgbzxhtad[dnnceupusnyubcrwoa]dwicwgfuccxltygmxe +bhvftjhxhpxomsyawu[wszezzsyswrdrlqr]rhvaknuzoopejwnmq +iddffrsryqmuvyrsyd[klvpmmknqkqbnxuew]wnsuskrkejoyetzlaij[mbxwmnqnrfqexoeaml]spyxfzlrewhwzeo[hogofwwdkwvyswdcey]edmmnhtfauckalllsib +sicisnsqujdgmbdk[pjgkpjtwtzacufridds]xnoqmobgoaojxuccvi[akyizulhrpqvdzl]nuoxcrdvuxdtcwu[ejfydgnmckcjqhmbsx]lwbbrynehycwqui +mmhwekjgjfjmmimta[gctswyndsthdyhire]baajrssklpzxqmlvke[ltkglmlowvpviklmnzp]xqgdcynvulmhzani +fcwuhpcmcmusmcmzsk[daajoebedzmqrvtbpg]cmubtjbrxkumvect[swemlhyklrgynkae]msxqqcdegnmfewkn +ohnbhxtnlvqsttsis[xibvstjbtnheqqqshhj]nlmikiiylisznwcq[dizyuuiuwhkhmtrzzg]fjgbjwxwlkcoqcgogq +gkxejlwkxayppjevu[rlwqikjiqcxcvgw]zkcjcopkwedfihrqzke +gcakbrxzymhacsg[edvagfjmxhrrytuxthe]mojwznzdsgxznkl[asvccotlewjfzypkiex]gdfoemtsozpsiayo[ryiippkmjzthrvwl]popxgzxfogjvgxry +cjbixfgchamiiqvfk[gwxgfniaznjuurx]dszifvjwbmjffzn[dntqokjkwmynchvwx]lcxwmevpndfqswnin[jpwcnfxgzfdwcgsx]hxrfqzflyvumwksagie +ptyeunotosvcwam[oimxlvevjqkzxlucnx]kzfesplnuzsakqhl +zwhvoxdolwwwvxtprp[mskfzikftyxuifscxsz]poodydwynngwieq[onntfnfnhsbstcccye]fydyxjpspwpwuqx[cckukovhxxcxrkd]dpcuytdrvsgrsbfjrwi +mgvvtoestsdfrrkqdp[jsgddzbtstbtgwcz]wbewvyvzgfcitls[byvjjhihwocudzfpw]uvswjmgdmezggeklden[zomsrocssnjxwxunet]gexqvwznakldhnds +msfnmrvwrghyzjkgzfu[odljvajkagpzgmfrkyx]aggpfmghrovrwyknxw[ngqglnuypmgejixww]twcvrjddnhduugpxcvg[wiacotdtiglghlma]evtvmgrrqafpaxu +qblqternpbrtiuh[fapmkfrpbuzhwcfnybk]ardetkryijgtjmdj +agnvlcifudtpkskhz[ssksropazylummmbch]zjssxslmlnmjoxxf[wmedjpjwjtijfmucv]frmxcjyvhtnyglrkgxq[immpojsucooxlbdwz]jiqurgdnrjejroukde +oieagfvbgeblwzzzm[lngokglaibefcvenlwn]fdsqzeblukuhfzyhf[twfxwotgbbehlaxntq]qydpgasujdlhkmhlb[tygpnjusvpadbkayoba]ntdupgbgwtyasupw +nkhamuohfhcavwbv[hfugoocbsqqsdxmfc]vgkzdlkydwyqjyn +gdoccbczcjldspfueoc[duqmkqhvplsatlhz]iafuyzmppcxzrtiir[qbxmjbnnzrvararuvhr]uipvgmhashuevyl +tvrgoqgjslpixzd[dvcgrtjbyihdxvlginb]iyppczuwpewlklk +mnlitvdbejsrnywrqw[jkjhnxyadzqdamvb]xywotroqfapnbhndpf[mhzstybvhusjhspfyyw]ctbjwfigduuutxu[wokoleeyoutpzcha]gpjmqufzmyldciqtn +azzofyumdbjdfaoxzrg[qmdsebebhkhhdpt]ygyshnczkxlcruxjz[fwxrkvqhhlyuqvxhdcu]liavngiqxieczgjqa[jvptolwhlncroasmr]kancigwgphwgwxb +mkqtbfxzplgmsslvne[vjgztezntbnrrptsabt]bnvqdmfenlchukjgi[ieavsusemvkjepivnej]gbyeowflyuuvgsowctc +iddhnstlrmffvsaz[xnejqqslbnbgnmlyu]eujdrqjvxlpovzxwqmb[oqgwexhdhjujitcwy]dphgwjcaxssylcb +pipmxilwapisesgun[ktzmndpffhnsfnchc]yljnipppqujqevubxg[rorbgmlkbhjoxbryo]ondmcsehqvvexnghqpm +lktmrzrxpluntju[nljelzujtjzunkezb]ozrmieeacpmaqghf[jaexvmneyluaohiju]xtuzedgcugczrzle +izpcfmamliqncmcgaw[rfyjbmvbiopojxxb]nogrshoiyvmxyzjyn[jegqvdtkcqhidepcda]sgdnnctcbmvtqsbwt[rtmyhffobmfvwcl]krvynuqvannkyicot +dewutxcsanjdlmchu[wcicioikzjdejoulljj]bqxeefxgedpsavlw +asfkiixaolgtwtjw[hdkpghivmztxiisb]wtwrflrthfrcattgar +gvgvnlrikbfepogjf[ipgxrlfaltggvmkfiht]votekpzvkopkujkufl[iyhdgdagzhnrawet]ajhduyaxppxwgvgujmd +tiebcylayagfdqw[lkftgyduvzdzpsjkcr]mqrdayvtvywsquj[xectwtbhvpnymjcmgon]sweddpysjrwgssll[lgzhfkzexgtxamjbmgh]zvlhicbqqvmwngosysq +oewghkhhldonunufju[olrpkibylltmvokyjna]eedjithbjuymlzq[gomlxncpbgzolpm]qmxofuwfegkikwfihck[wudvrycglrxlypz]lsghgmgcidcxvws +dzisgzrxauzpmmq[ehrywgvtnvhkvin]clqsfudqvcnwwxru[vzeqaaheyudnqgdfb]lmasdsjzekcpjht[gboxhzpaguxuvyha]ipqozarhswigzeqzdom +dyyqwcghdabypdkgndn[kmnrezvgzkfmxyopiin]vbxvpeyeqncygca[biypmucmnkcqvqfjgyz]wqwfitifrfckzzhftkf +ffrywmbbpzparzz[silwmcdyckltvwu]syphmujhpatfkccz[kagdkkcnnoxwtxfe]bbxheegelkvftabcky[mbuxajqsttmhnmfeobw]smploudflhpjbxgpnev +qzqdfxgjmnrbltg[fnfbksredcpkbqtp]ncrdcfskzzqztrm +uvfviatjevwnmugvgk[jwpgxsfvfkijpdxo]wpdwqxjmxddyigesygp +qjsbieiciaeemfblfac[jjudeshcfzeiezuepgg]ktjghduwspdhkldzjyn +usxxvmwheuvgleswoo[irucqcgtsjgxeqwur]pkjsipvxxkjoqqp[osjgklsxyryzoxkfnm]xqocoktbrletccuw +jiirthsyxhzgjcrx[yfuorkbrffeseaakcr]amzdbwfoaioblppammo[pbrbaxhfftauuxvo]gpnsbsppifolsrra[kntharjptgxiztu]qatjusqejmdzaqycw +ssyfomequfwxahvfvy[kctdlusjzhgntjy]zvtmizweshgffnlh +pzfvptwkkdectmi[koencyjqifclilknecd]wctndrlxwbwkxqazsj[jklzmkhlqwwpvxv]mazihpfxewkjypfth[vannhyvviuyjhivwco]qghwmufezcwrxtuvx +dltmdrlzeauhhwsom[naqwzhfcgzictvbsswp]rtlevxtzzviqkabimc[dafvtawzxjabdtx]kfuyxbmqrkqemkeetoq[dmalddncrdzuslnpovt]ufzjluhczhxmnanov +xioeqonkswrhfwqt[hmpztzezyzpqafedtpr]wmwezeoixeriejbskie +asocnxlrbkkafwscv[ouuntljnzdspcxxub]wzqnqrvlwoccjagszr +scrsvkbwabaqpjs[xiijpmbiflmxyxwkfn]iysftpuvocbtwaggugf[yrqyvyoqxniqxcxmbqq]gixcxmltuozcxcqehl[kutzmitklfdfouflbh]xdozmussjlcttdf +apnolukxcjppvyhjenn[ktziuhqmkbjuqffimzn]essdusalxlbxvbsva[skvzdkvwpchapohlyq]mgcfirbsdbqomtxmxi +xxfucigatkfvpubv[yrpoezyzhwkpkkkmot]vapkpzcbwhacbrp +itcqefgdapiuzqtdzm[vvcaufavmazjpfirrto]hbrtkmfzxjewtaswfm[xtuzqidapfxvuzgqm]xhpufritjjxpdlx +nfeskfxpmbdjrhgusld[vkbvbootlttpfkt]nlsmsujsgjnjigxlpm +lbindwpgcwkdslufzsd[pvxblmfzbdbtwihu]zmrgvwliqftoxtsaxg[pyldqlarmljuuzaj]cgzueqqndeotcvsnv +xedaztzmryqxwnb[uhqpmhywmsnsyiq]ysaelvgeordrthhdtkw[jdnpojewrrdeotk]ynbkvsnjoxwgwxe +vkfmkgsnqpgareui[lfezzjgbdptknrxfq]aatkorgxlumdhvjay[ngkudbpkmdvdskihzh]nyhmsgfgpuzhzkbh[vuejragqqtizjmqeqdo]ascjasathqvncdnkd +cvotsugnqushbrpprhk[totbjscfphjjmur]rrxgqtuyulqpmywjz[nejrzhylbilebdtqvm]hlsppreuytghvew[bwooimafehcdzhmyp]qnowsbfdbeupqtila +nykwyqwbrhifjickcwr[bkwtqhihmczedyoubdj]jjwfyabbyjjqihit +dmpuzthecwjclvd[lxhxcrnhvdpijjuypu]wbwmabirpitypyjqk[ywytahvxbsnntgskdj]nmgcaavgvyndrcq[grkvyncdwfbmfdb]odnojfyxxgzspzuk +cxguqyufjifeyzgkw[otebhoxdrvumjpzgb]svtkxxqnblsmaodb[mnfwxqqdwqotjbg]fcvefinmmnutloh[ljkeuuuxicazbuzlfx]qhrjvfrcqxsizjhn +yuhhdmuebufhyly[llyllkurxorkwlx]tbpgsrxtmztlofcobjs[mqoepigsswhitdcnd]gxjxulsmxzqjnyx +nuiovuspjehxkpv[qsyjmiietfwvqzj]ekuzppxgppqkpve[ozfsqvrxfeumsigv]xdzyqybyucoxdoklj[crnwzfdarswufanfljs]vsbixgjpzbdddcbe +jmvfqdzgsklcrslovql[gjhklxyugbfvnqz]pzitsmcqszousne[ynlltwcmydmhewn]otvtxsxrrnmwswnje[aegqtdvcxhorjaof]hbekoaqmdlkljjuufj +qqtgcjcihigaujbt[xqlhtduvqwoxtos]vpuvpxdusalphiafnq[jmwiomadjxspohwrxi]zjymzmygsnzzulziln[vqgdgsqkzgzbzbcsxd]xitnhrochbzbthxnzkr +jrwchpzsztpxhvph[iqangpgvkiylfxnlvjn]dhnfjcukccyzjmw[gjugzeqyqfofstyg]vhkwihbkrhpnoplbksl +jxegyldqmsgxgxfbu[laousqjpancokjp]uzcekpbvslycdabm[itwqqjmxywnpmlfhfq]lmzuyvovezbnoscoeog +tlhzhxqkdcxilhio[dgocupjdlzogjwdxh]azfvreuwrvquptrlf +llvukyljihylpgiq[rbdleeyvacbovvwrqt]khplkmlyeccipwqwoz[whvvhrzdwiecqbeb]hmkgsugxhfukfzg +gqxtomykiwexvcyy[gennwfyucypiyhw]djjiwcipnaoakagmlw[mjoyxpjjsrzurtaozkn]xocuerjupzzlmbnshb[erhtdqhgsvjsczmzba]adbruotfkowmvwugbr +dpxyxexpdkdtrcxr[jnzrmfjuxhkqvaj]vbzavumhudmpvccqsej[whqvbyszqaovrgmstr]ybockttkvclvxwx[nhowunciatmmsjsc]ohqeflsduaoelvu +boajjbclanzyjge[pcviglbztbaqfvxfe]rnurgxjnrmwciev[psitzaorpbtywmor]duvoistyxrzdovakb +ixnydttxbafquyvu[vuoyofxakqeocdu]uukrnhkrwvzbpyemn[cqndyeyyplkdvgkhaf]qtchwgkqvcrmsax[crqkwmpcxgvuhcepoe]huheekppokbwogmfw +ltgsblvagefbohc[jqcolroyboslyuljw]hkdfbyjxzkkhglu +iduenjlchukmkmkcyiw[hefkxhfefqcxtfgw]zmxzdcvoiaexqfxmy[zzunhvsdkcmwrtomxx]ftpbizjapbhzzpmjo +yadqdnkbvrzyesp[qfectyenugkfoednlh]hetoqjdjygpjgpdo[coclcclcgbmjuqsolon]pvzoqiwtwwrlhrefxfq[fweutmyirwounikbbe]avwxlrppqyipxzbqsye +hvzyppakbpizzqtzylj[fglenofdnkakgscsit]dtmyozwhcamapqzhmqq[mzwsceguaunjdqgzy]oqalbiyxztbhzcj +kidpcgqijppstmrk[bvrxisbchiudttb]pxtcpbmjqnuzdnrrj +vbbwnaciqnnywtdapbd[nxsuwwtdaezftmimh]hpfbjpprqiqstff[wblblaaxwoxhiui]ookdivqptkooppc[rfykjlavjvqshrc]udqozimcxwxvexdsodg +ikoiloawdwwukhyog[wldmblycrwkogqdkmd]nonshrrxzgdyitowef +iwxcdvpwurlwoua[bplgjzqiufihbpkr]vbznjwpmurnncebwqjl[mggntaecbkaivkc]foyyhitpcozlohpye[wmnupcvcxkkjrtwob]fehfpqrzptnjdbrjqm +kqgccpaxaiawhlxwvao[jwqdyozkwlkjxaxeae]pmzegiqggikntebuqdf +dinkcecgpjkucufxmmx[kghamrhzvzkmkvzvf]fsijghkzvcnruuch +gqpmoujcqbjmbkw[wklovtupjtpakkr]bszxogslsmsuvdc[bzamfeevwtkxiaqmq]whvpwuqqpetbmxcxfei +rzprsbmijwurxdper[stcbtzdffxiikekwkdm]ecsvpslvgzqdkmcmg[dubrkljphbedinwakza]tmuaknuopyvuuvb +jejqpwjnjgswlpdw[bmlmhbehrgdhrfpn]bgcavfaqrbusgmdol[wcnqvfviopfafsh]qxbdmorlqqhziovvtsd +gfkacbhzzuupzdciobw[apugufbmkzdcuvyz]rxxvujlycyyauho[jcgviszjgfrqvqddqbe]evzoharbjafyqtvpw +lkhvmxrbbthjzsqn[vrsinufxgtdplcziyi]udnwpmlftjjyiyr +bgbpjlqndbevlrx[uuzlxehnzsmjszt]mafmvjrgaehcflm[uysuexeaoyrfqiqoe]eogngphvosbbkbcbx +biqleovznpnvlgbtgq[rflcogyjfnjnvrz]qjxffnzysxpsxxo +nghkeaqqxrczcohg[bfqguyypsfcksjhz]ijcgbkcgogmyrih +ajncuvxcuwllizxkfjl[iggocdpbmhuujlfukl]mpoulqjowqkzeebf +qqqoxjvsvbiiaytvwu[aiwjzpwlfgalktoy]vbwyiusngxwciune[lkawkiqvzrgksyyz]pjokuzxjurxligex[alhahiygubefaljtv]azmhwehqgrglebxosta +jtoauqvnncjmeigaamx[kfymrhjevoyhepqnc]ihlwiegxzchevpf[zxjjidnncpzbzaw]ebixvaawkwocytx[qlxbemucbynolblv]bzbjrtnghmcdkscxx +mbtokokyfqfdhmxwhb[qgazmvdcwebeifi]rsntzgeqyfvjftliwa +yuwtphemsequwdirfmd[icnjausljalhzphpy]cfzystpixjcmrrs[xywzdfebzgtzelgl]xswnagiklvbjxlfnpq[akxuhgxhpkdwmwigca]vinsbilqirohswgipe +bqbosglgnqwsfbxddw[emjzxcffmxkqlmn]wfgjtfdvhemhejpmxa[zfxoffptksgmnlbntx]otneelfhzpamjmzwqg +ushngvjtmvypcadpd[arcpanyyoceyyaee]udvkmybxmgahfle[jbalikfwxmcgtiurjcc]llxqjcpwoboxhaivwdm[crozklzdqjlrrhu]hojkvvqissprjoqwfo +ofwpbcnnyzbqqvkes[peogfvfpyvbnydj]xvtiykidzuxltuxxp[tojcelfsgwxvwqhg]jpmadadkgfrumezy[monrbqpsppiaaifxz]kylmdiorjlsovny +hnbxabeskhcgpoaexi[thvxentmengrzgkjuwi]mhxhszvkflnnftd[twqccachbgauoscdol]vvfcqjzsrwjvkwfsw +bkjhqcswrncpikvpm[shqohewbmungadi]hcrqtimandhfbso +amfxjvxvdmerqowdnxe[cumwepdamezeecnq]lkezawesphsybimf[lapqafmfsivtmytdoda]vmfmejuxoigyexwwyo +ezvclrwlggiosvdqxer[kwumjgmaayygippb]zqwtdswaxmydbiihi +lmandocgeressmfxga[cijznnpfcbsdystlges]fkllytsytcvvcnxl +enbwhqlzytjctefqwhr[zoqcmvgpsfndvfvy]zlwqhyoulrcveni +zwucvenctpqzlxeadn[toegrygcfpfkafgxs]axvqswugizubynzsb[luvlrbwplytdwlheaxi]nposqrfedyuugpjnik +ymdzrqgulicxzfuf[twglxtaryubspobxclc]vucpqrzzyadvoiteqle[xbsxohuegxwudsrfw]axpmobgigohcmagr +esgnejqywqqsywkg[hryixrmpqepyrovv]gqjccwoanbzljsf[maaujjtokmjpppsgk]qcvrrtrrxwevbvovo[xoymwepaurypzvpth]qmlqfhvovyowpdwz +qksxeymivlzuscgsl[vjcwfdvybvoiahv]otcgndvvjerofpx +ryxelxmxsrhtmsqvxff[wxblvfrersnfcyvvpv]rbxocxhparlhcaqexny +ehvjcabqtmabutiu[ovzwhfvgwqxefpay]nzszulqbxsksloc[rgdlusvaoksgywaexk]xcwytqehromugefg +svfhxiqruxzcjqlb[dkfccqvvehkwwfjmth]lvkfctbpueegqdfb[miffoptlmgzzses]yochzabyqkmnheasfl +icdcifhjwhiqzqyu[wgzmgznoewglpcvgow]eujehgisllhkzmmivhq[exesoswhvvsthcso]pjcmtknevqdvmmamejh[ylqwwcuycvpofgqwqf]fyxecpnvxzecnzqew +fdmskgwxwrznenwsp[qzplbuzhacotyil]plorkkwrjamagmzil[niohlobikfzfyqk]bmxmlxozzwbkrrhnce[xxcczenzizachda]hloxeszindohsfsnqx +zqsfgmjarzxabud[sqbwrxrtfgydkkwsekm]tovzszloireanluvx[zrdwqaaruhiabxfjow]djnrprliuoenkrxkt[lojfktjsdwdjycamlzd]qlgczlpoxptsjooi +gjwuximhfklvnyver[urndgjzxbrreido]eowyquwgvnxbsmb[dbigflhjsrccqacr]lhxcuzlmzdopnfluwm +dnmbsutzllsxouvh[tqykceyhjdfisrswht]ufkpseiwzfjbtpkc +madjaycornkcpolglq[vvnpkdstjgxcjsf]kvejknagbwlxtxbrbvi +fufmmdtydxyrclcrqx[nrjdoldmmxxfhncdk]hdbebtjtcvcfqmw[rhfbbtfhhsqiwbtnlrz]kihpdnvnacqqosnhpa[gndixqjiyvfmvrgjrzo]fxwjbxmicjjyvepuzpb +vyblgyhujolwblvys[zapkgjwxfsivrxdfr]wtqlezngwqoktfhiegh[ecalvtwzjxbqfrcbwvv]tvzxgabmyuvlztgux +dnqbpkwbdwbfbyoz[mjnprwkicaftsgm]qvtafasppyrbtuqvn[pdlcgrzteozofjkfo]cevpxzfqcrroinmxy +pdpjqznbmahueoc[ecsdszaxvxzuhamxqq]lyusvisydqemnslw +phxrfpqtrkqzdtgwetm[muonzqrbiyeetiqxu]rwhbzxkfwcchkpumq +ltvxqmlcrivtcytk[vcfeszakkcrjslo]tybwtklhhxsvhzxuio[tpcsmftwasalxhe]ivhbtyfxeknudns +blotcckbcsxnxkbd[ijibgeakkajijumjeiv]svfnhnnkaqfnzpqdox +zpesktqlipowpsmqubf[vjnynvphcvmazjotxm]bjdrheobrnylbebw +ftoxxvywsxkptnvz[qcotxazjsqbnflu]xgmfsauvpibkozp[yzpsqrudrnbayikuau]vgtgzdoxpsonwmse +dqamsxipelobmbtxs[slvyfkooyzbcuxo]dthowqdeedprlmyg +ltozqbvhvyqclav[noavoyiuiyamvcanqoc]dkragjcbgfqhmujqkvs[pnzefpolsmchtkula]ihwxogvjbctklkk +vtewmubtnbmusat[rpjmicrcyzajgpzo]khkjajkxflvurcsmd[gumvdiloapvorhmn]somhrdimswsyeeq +zfrvenflhmjgoesmax[pgqxadyxekpnwwnckin]kqqmdrmcgyweogyfya[wbwicwmfsbthzmrfe]wbstpswtzaitlwbcv[nhialwkwamoawjq]usgyumpojqmvdxhzlat +kztexifpjlasulbd[gplrmaltusmjvgovnq]yejlzyghxccxtnvihx +liuvjttbtfsawbpfi[wtezrsztlnzmeaxu]ciolgkqyxkxxvwtblo[dtlfmyfrmfxdcikrb]kmerspmgttnjucijg[wdzyrbvslhkzqocimee]lrrvtrxcydogapi +bbfeqegoyoyektexr[wceufdsxjpughajipa]lmnlqkrztzbtkwcbxhz +ypwocnxnpuqetxgb[faqgbonmbihohshmtdo]cpjhlgocldldshzy[uhwgnkdervikvatfpav]semfeosdiynzoomskf[yvczydmxhxcaowkwg]kkwxeutjaronwowi +rgvuclhfrvlkxiqo[qeywgwrafcswqya]xppwskysvkvseiltg[bykdhqgbgzjhgoungi]invxesxqmtohbmjllh[fuejhljykbpzxdykgj]xwnyayrfadhdwyds +fbwwaocsouhupdi[efqzvlecvhwinsjeywg]lbjmwdbdjfnmtsaka +gqvsxigtgoafmvbekhx[sjgsrwdtqwqqylakvbb]kqrtyagzfrqrvlfkumr +xfuxljcwxkiomhkepi[iaprxlbtpvrvlsig]leqnifsqjfqalkgafib[rfxqsfemmpvfhmrjn]gbqvgdcfcjlcmnxkljn +veiqbspjrjymoalmtrt[okpsiscbptuumxisiv]yrhuahhkvbigdlko +uhhwsbsmsbklwewfc[dhnisoxocvomjaay]wouhbmhzfyighaufn[durxoxeyxjhvkwyjfx]novsbfibzjulaxzuesx +kcfxkxnznogyvymzcbm[mkgpejhpbyziksgv]yvzndwangiuuzwvkv +orkzkmqdeumjzdda[nsbmhjdjxqfnkkxto]goeaunixhitoaiog[nospihuvybakztioqip]vjzyxpmmezlnaumym[nwxvmqhsprcinifl]uvwjnqwjvuyjjpugj +mfrhagodpscknas[sbrtzvfrqcxsufv]czqpqctptdlhmytumos[vnyckhoptjkjxuqa]pmooukcidyyvwqtgohu +resxynlcutzggmtczo[nmmabdsbvwktiykqonp]gmelhvutrvcrgdna[obdmwoxrrlntfejymf]hdxasucdibwwxgot +mnrhbocsgkfthhvnuke[egdgbouacqxndelu]ajtnqlomsyixsehntrn[mpprufbezhacatf]qeuwsfcjtkpzfbz +logpvbfpghznuvcgwj[poykcbzvdrpbrlqzlxp]jctrzpridwbvgpvv[nihdkrnanrgbdqaaf]wrzphhqbpznufcxa[gjhuobpheguxqwut]xlxxdfunzjoknpa +xckjcbxewjcqegrm[bksphbygnxtbklur]bnawweidbrdpfsw[uoyymiftyibdhjc]lpyeqreaxmmjquc +hnhempuuiakcvgkv[ykdxjfqspjlwdamqd]nlyuylqcjgacgbtaq[swmlxfpggzcagkysuj]syrldafxedcddhhwddz[zgighmpfjmwajrcwihv]atdkrfhvjyqojist +fkrrirhpatymfnakjpo[sxyemqclncjkjmmfncx]gvewmatlydgleqm[sgdeklgyvflcufvtplq]dundmukthwoddhaxw +ibhwnndalipgwboov[oetxmvnstllojrpjggr]raawxffqpbwaoafsvfa[voaodafksfxrkimxfac]mrklxyjcdcfbsmpp[ojavtfuwkeogikk]exijoqwqduzdnvpf +fvjerjfawdvkbzkke[ekoozekkfayzwzjgix]ysjkrywjcqpwoguoh[ykjvlzirmpjxbzpxtz]njyukqukczggofql[jkliiyuolnqdhdbvqae]kpsfxwfkweeexjxlsn +hocvxscrqarpnhiyizi[edzlzfxffzfmxmssq]gqlnxmmhcmsabueqxaz[mpxvrwpnncxgddguygj]fwhbjqrziztgrkmx +mdhjmsdwdhyhrqzucp[zuswgksuugzizfo]ekgygmdfansrlvzyt[efhwmzbpzwywckakd]xvwmsbwppzjvwuuqakl[igcjlcbgovpdyssmqc]lcumchflakunifgeg +mplyixtwewxpmgxnmgi[ngrpejtnvrgwtupvr]kesjeqyleotfmggcea[zzokvnfeweaduwzfhrw]obyjyyqjkucokbu[snbyhfbchhqxknu]fivmakraikkuetpria +xqgkoczxlgmlffarh[pqiqruxadypdionbepo]fxskihkjyfzlcoomvl +afohxmbrfvqlacrf[imutjpvzzgvzgcjerck]lerhcxzrzkqlwumny +yqjwgatgqryemqsp[bwzbdayfxdumyfojft]dfbuzmuzgxmnzqgshfi[pakwsmfbtitkiqvanoq]xuawmajdiicregkpm[kqpfntzvovcmfsxqmnq]ghppydhrurfeiuac +kfhvgwfuqjsfepj[sncjjxefsdbvjumyo]remoooxfyjmsskyds[jtjwfchkozxniiy]jgfaixubqjcrtvh[npxegekihcqiurb]dvtfybcjyaoushdagr +fkfbhopbvmmqxthr[kfkibyedkqhtkdu]fntaxfihxuwwpnxe +sfpdwtxasoodsvwclzn[lroruhvvtivzyzydac]tmwhjsyqjqlpwzv[esrzuwvtzwvnitsuf]efviugvdcoegmashh[gvpwpimfmjnfuncw]fbfppbsyymzfazivsz +amthppeoesqlfwc[kkasghvolqvbcbdeczz]onknhfpsjzvpvkegny[gxwbzdipdgehnryyj]jodjkpmhcwwszfbggsv[qfutgdlyxkdpbpcc]oadwfqaipddbwssib +fqibujqjzfiraeobjzl[mtvzbskboukcyjenxrv]qjqwxujlhqrxyzmytd +cwvxqqouchaqwkhpcfz[elwmjtglbrbyxnyoyyd]nccylfdoyorjbdi +jcbygfuxandbdexnhc[jyhbtswhegyhooolh]aniljkdxybbdbsm[afokcqicbhltcge]omjynmdbdgknpxhjm[wkgmjtmhnrpamkfncx]skpgvvjpnmhwkcgomcg +sacklxtvscuxwmhvtw[bahodhuctayhpnt]qicatycoooyspis +mhexuvtezfzxnevd[drllkjffzfmmukleut]soquupmvgilyzsr +hmhdovlwwfwcuikdx[qbkapgzxphauqrmjat]jqadlkhlgqfiacaepvm[ahqwowftcseuqezn]yltcacnflbfskajvakx +dhnspqvpwgsexlwwrsz[xpowmglcpasxvuk]vbahprxinxmsxglxvgd[ukvfffwqirhekvl]pvbdddgneqxoqjp[rmkfpyqmzjpdderhme]svtqppchbmdqvldgyih +agqlrgzefrrkrmdw[pqxuhlyvhdbcuvd]zyaedppqqpcyonyme +rsvoaesmgxsttbl[gzleqcjyweilywpb]wuzskljcawklfng[ojzyojtotmukhfnjanu]aosalbogciawswglkw +yochyqaasxdyfmegyac[okjzywgsmktayhmujpj]xgjqazwjvzhdleuhz +psmnnwiolxpqymly[fcrevcjztuteryp]nnacfwnqwxbrfqhyuke[kudikhthknlfvqbm]kridanxqomwtelxk +ppjowileomfhohmpcoa[euqrvizdyhubfilt]rbnwiaxaqveirvoeb[vbsvlpraulqyevyje]azqidrepohooimob[xlcvqhwzwdxluywoqks]mvgewzixvecqcqlmkzg +ncepobognelfiytdx[ekvxtlhjnamkonm]pizszllzfgumulkys[xgpudqjkjzpilks]xirarekiuvcivtjju[wjflckjkfvvbkgxmp]rpvriqsyglljrskx +odrrepfcxtyriobvz[kxiwrsavktuyjke]wnwydovrxmmuzehfm +mfdxppslkzpwvwr[mavnyeavcuoywuv]vspiiafyboscewkcsmq[pyevwvptadphrskuivp]tekdmxlgmnwjgcs[aewugqwpbpvyrmqmyyi]cuedkzylgatqgpdc +piufuojcfshdstw[udvhfbgmvpxffwr]doagyxjdtibmgoobq[fikftfravgtrtwni]wpuqessshgkrupqe +elfwnlaowbgexiajkyt[eswlunregcncpmeqoca]kqquvoocucglemrhjc +uzkfrwhffmydgqqzkl[trvjzqqorsdiimpk]znflqdahqdhvhlaa +rjcogeolejfldwmoqhz[cloemdcanqiplavw]vpsyimqbgtwcxgyd[kakuadbjenwdiicq]exfcsokofcjmwseo +qazslzzayvzvtbixrd[nofwkmnhotfyfptto]irajxlrmeszmibhk +wirtatnszvxmlnkvjvv[btvgpyqdeiidexdeapn]unlvcnygttuetqfg +bhdesglwqnjvgpovm[joeuqfahjhgmrth]jtzjppcucapkyzcpei[idqjrcxyjlupzjhx]kqljgcmnpjnswef[cszkdkqnmbsrxykt]ykkbwmiclaqwbpon +zkptfvsmlnzuoryqz[uhbusiqtctqdtfma]ubdrujhmnyvflnvs[yovgsoipmkxmrtw]suwzspemdtfiojr[vsrttosqlvmzwoqmlyq]nnsnkiyhxjecfvkhxf +gqrxyvtuvcyqvarsuv[dlulhvxsijobenjo]pqglecsfwgnuhelsh[rqouyrnjtlxfowp]nowkcfckezryxxg +aqmbikwcxxevjbw[zwxktjxquhloozfgizr]ffpzrapawfkrsny[qqekkqexjyoghfnaxrm]uylkkxyxqlrjgbowycw +ghesvpyxqricmgcmj[hvfcvovijglkxubrfqf]lbknfpyahabpypl[gashwurszsmlhfui]rsyxunohtmwvqfqslr +ylpuzunivhaylsrfz[kieununfecpxgzhk]pbnqrgyrgymuimsgfa[duxocpauqtfctrpreji]gdtcugdjxbzmffq[hviaibmwbutaiatf]tutsegblquetvfomynh +mgwtwourfjwmtws[ooawaihqxwinzat]fjallnmkhzbzfsx[rloquuqpzsnagpt]spehwxbmjexygksvt[xljdtevbvhddzwnoaar]auqtaqupgumspzpb +yfdfpclchklypaljq[bmkgewuljfpwpgrrg]ovkpfmumrmlybqyumux +wrftrzlpyrptwmj[penvkoodhzmwwzbya]itmeejhjetfomdla[aeilgulmlisvzluc]zkqdzajjhxkhows +zmgmnslhogyzitpirm[mknytoayplqwltdh]gmgpnzmipdkegoxao +uebarfghvpmgzhx[iuabicjfokgnybpb]swhnalbokpyqdrmaxd[tjsaihsqayjaywac]ywzuozbyvtsofvkiqj[afjkdhpemqsoivr]grtkptncyinxlfgdjgm +riqkipsgbptayuab[bcwdvfvzxiaidpiok]xdssawxxjavachfzpf +ypponvgfxgwquzkyu[vfbaoxpirtcgklminil]bbdxfwwptedctcm +zwmwdfwutuaoqyq[orzmkmmagojdfhkry]oegdfradzppwqwjm +fihqtfiaszddkwtozc[ggzvtiwjpuehpfvzev]sksgdqwtghgmavktpu[vovmwdwckbdggsuy]catvlusjdruqlgowf[bawanswujqcoxfzxbpl]sjmisqghvzvlpmvwuf +bthfaqnohcrtyvcevz[shahnffqoqjxmsaskyl]hjtecdroaharoqqlwme[xoknhnevqdeypythrj]pcsqbcykpskqvofn +qwrarlbyivqfsodi[ngpyxyllcdqmduhgx]hrqdfjoxtiuyqrcu[evlkctrqtadjostj]mthgbwnsfdkemvjlyb[bobjvmuycmotqja]wugdihgnugrqtcvv +ylhkvimzlxrkvqinx[umqrxhhwphpigynkl]bzdbjvsmxzsrvotag[sucrmnnwziscfbuldhc]xwqxczdtomfyutk[wxytdduimznbnnelpt]tgsdbftehkvmdetx +psavwiadlsloigorknn[yqsrbqsbzhogkdynyz]urgruwqpmycyslsj[ofdbbtooimzgubl]lbbisonaxmyudybcwm +arehddcepyoemixmskt[wopnathzlqxnnoiu]mymgjthqiaunymyes +pxfwbzbltiadcmh[lrdbtyxqdvcesyntzjf]jranlgsxskjjgfvhea[ytbmxhfejbdgcdtnul]zibykmovsdmyouxpj[fmfkhcfzstqapgjz]wnpjnohtpadnnlu +nckwcvncimsthnlu[rfyyazzgngkygfm]hlpxvutwpmaggblg[qrexhoxbnoyaszjk]ahenipwwckpoqhpe[hknngnrucfiftgo]yssifrkfyaldeaa +lrrhukctkbgoukeptxr[bzxzooiqwnebllazdhz]xjlbolmtakxdgnnjdeb[botuufiokrpddif]hbnqkqlyqamdugef +vlhwjvmrmqjdhrzlrb[sifgbytoqrokxfbvzev]dhdnsqteiomronz[wboyewofjqjmwzq]tqdhhaysrgexceeofe[dnvowqfgopopoqstvhk]npxeihgajbtqnhqg +cremegzznkdkyxj[mfuzjsratdlqxbgedy]zqrblvedvkrfgazq +ckqzaquqgfbmjan[qjpbtrzoerbtibp]wcpozsyvrchscndex[mvknznmotgjrfgv]canwkxntkzmszwlov +iqvyswlmcvrlgrh[cuexdiquljbdyzencz]omngyigmhnwisrohd[uejvjjgmlndhmtxzp]ucrwarxsiqtjmaddb +ivzrwlxpxgzuuuqmtru[czyxcfcxribjycj]pntvptdzblfosriqk[lojzoiluavlebquqtex]sxfcfejktdlltmx +tjppxfesnuonvyj[kmevdokeodpvknr]fesmrhpgdyxguvuvyiu +leftawcmocfkpdmzdt[xmlgielmatgwhdnqzsv]jiwfzhxvzxqhhpizv +xesonxwclvyetdcr[dvjijcenufeabkxnqyw]ogsuoydbnqoekzznh[dvsecdihbpfgacac]srwcmhiiwxtualx[bpemagylqzyxqoaa]kcuegvlpfzcwaker +tffukwerhhsbvwnhhk[dgymmmsmogyrmpd]fihstccnovmeipbf +njvhmuumwzwfzigojn[znpdqbjmfyuziavjv]hdnemtbdvbuxkkpkf[pbcvqwnquhbmugept]wseocpmukxsonkomrsk[nicixvgreikvvrat]fmvqxgrjzuspfyuqou +hcysmytbwutfeit[lyimkduppuazwyarp]scmqvuzhptpjenj +pbwoaecjkbbhcuiiv[znfkivdlaohkhmujeay]khezajqvgquousnjab +ujzussbupuiluxxsluu[afziojarfxhlounm]rkeysyrwsheuxaj +bobowsdmpdtlzzyjk[vhcmcwztdinxrzzqim]ooazeqoxyqipupm[kzbaizssrlwawrh]rwzglobtwokunia[aijrdsjpseqcsxds]otpxblmqfrdojgwndi +ejxvdwerghueasxes[dfbujbubdntkmli]fruzltpmrrlxjtlnvt[humnridbnputqpu]dsembdskqhnrtzesh[bzeltfmllnaegsmi]pgldmpkdpimgxjcge +cfommkiravpmqflvfg[mxrtecpvyrjkazvxuse]uqhkabaiqrafotd[tbyvblbmumrwdwovg]nfgbczychazchst[wfuotesxrieykalsd]uohrkgematczlrityxj +qztosgsqradmgybxrga[hlejicgvaqzhkfbhbb]cgsgwzckhygbszdvi[njpxihtzdyryavflj]icnxdwnruwwyzsk +uxyvrlyggnaviay[qwthehqgvglktqhqu]ksgnoxqxgkjmwuethng[sbbsvqnisduagslb]cuaobhmvuaqvvvnqfe +erymnlrruxlqjcmkn[mevvbnpbexblndj]gfgvnksluyipaykfde +dxscmhdmjkdhtudsqvi[gvrtwolegaemtia]opywqbkjbfndypc[oekozzbeqwfiflasv]yfgsbitixwbjtoi +ysxudmuqzgoloqnykt[fcgtxmhrrcecqmddrj]qtrozsbcpficfquvkpj[cgqpatemexjkefdbe]ohnpfhftbocgsxzpumr[eiqhsgwotemjlnnqefk]gfaoeohysayszml +cevcyseikybcbnmn[jpmyfkdmnmrhyakru]dxlrbhtjtuihtsdde[wvcrjtitpvlnyppnc]lcnpitcbcmfxhkrrjew +qdaeiqosdnatmbdxwj[atfzmwbrygimubjbi]eqmwenccfvvdyyhd[yaumggrlwxuimpbjhj]opojnvgqlddssgz +fiilqdyckyxglumal[mcmerdidyzyvolqlsu]tybpakjvysehukdzfs[hkquimszsyiivblq]ifkovlrqhlnvdcmctpw[bbfmqiuidwwtvxcyxsh]rxbulmjkszwcujvoxx +ejnjgazbggstrokfiqn[hwchebnufwvztstxxk]knrowqqjlpkeaogreh[ispqgesjsangcoygvpi]limwwxptqsggumpkav[affknwmlnzrbabg]tupfguyoxwpoiatebzu +qiapnmpiekmqwaxk[vfasdzfzabwydicao]togthxpkeucrpjuzq +bqzmyqagrliazan[exfepmvuswdztkgzk]oitrytelbuvpmfix[fzcpqdblgkioqnm]xtzynyytsasaiajhtpt +opicwmmyrisxmoj[owhsmoigdsolqmjd]pmgsqqwwjqvqobueh[zfcjdlleobetagnzt]mwckfcohdalqzeodptb +ejzvbutzumjnzzfgnoe[ixayktiqmcngbks]jrfufjnbcocgaufucy[ryglzpvuwtgohxtw]fszrmyqiiikxktye[vnvfudzvmseqhzlfq]syipqltfrymgbgmqxyi +fguhalhxpswuhwjmn[anqihfnbgmkkttimvl]hvkgwincfxssrnnzn[dmpiagbxeztyycsr]ufwamkmhsqvabiddztf +urstysgnriccvbkiwp[yffbbcipbgnlhnx]voloohtrdgtmuosuj[sjkbdbvpbcnleib]nucopgkgenowcccvgqx[rjopvaiewdvgmumr]yxzxryntexnuhgrvdes +yjkmxwouqlmohkv[mjogakueojtohoo]qobrjdolakkvxjbxb[qnerargpebiqxhkqawg]vhklgbktomjutbtm[islelkygphlpagjqij]xbtwafadjphpzhz +pczqpuroxpifexe[uqcqtneiektkmrb]nyoakxnlgrxobwlduux[dhhfoxkqvnvcchsct]cqcouyerjxmkbkjccg[idyikrwqdreiyhsxdcj]xlzoyafazrrbdwljnd +mpmjnhjgnmnqwowd[lfanwgamnmdxwiqe]npfvhehcxtlgcrzid[chzvtakthbbfgaamref]oaxeaktsxndsanlhxze +pvfcksodcgsmjiqwszc[lpixtwnyrpkjsmui]bvjpqhqzesvyyjlogw +ifzbfcvdoxkdzhrq[bxzpnkgzmjoocojqi]sihxbegqwropinnqu[uuemfqzpcjaegexhz]arbzkkywynrjjis[fhjxmtljhjhcexhjh]lectilzbsefciuxmj +epgzlimhfeamgbakeje[movhrjjqpkxnjzmn]ujjejiojoiqyiyuvb +kgyplkvxedlrivba[rrvhbjuukauesywzgi]sefglvbqrbfpwjpbndf[lxpmdnklhlnpooeq]cseosnrqjchpeicy +hzxrpcnfcuvytvptmlr[xkqdzxmqajoisgy]itvqxuzohywmwuvlrm[unurstpskieknsp]xfxutqlwgxbkszbp +nzyehlmbirflrigh[xkcxkxpmbzzlwnzbj]vtiuialppefxqhcuc +ihggeghdsdhixvlbmr[csjfaddciewuprmr]kkfiuczfhmrmgolb +ztiyoyrgufqxkfk[hsftvmvfjwplrbxum]xdeuxodxrcfwsvr[ifkfgxpuoehydemf]rqcnabfgqyrbtoxkp +ygpwvcpcshyjslrm[ccytynfblnccxbstzuh]gjpwxmciaenmcizexf[bldgazexvgyaovzywi]wtynmfiznxylzzhsgwz[qaxcfaazazxsaozyks]odryojvivbgnachz +xhlfqbqoatmvrfpe[wrfmrapwuzhqmqmzmy]wkmqmtbyshkyfwzo[zcifoyozwurqexe]pysjwmlknukydpnrzan +elexrwwnwmearzxuzi[ajkpdbxrtpnwngx]raybcmpouawjfqlujp +bdjnunqhhwlpeumihz[ytxkjsuighhjzfu]qeqjvpmmzpsfnus +vupxgfyaxnciedexmom[fvqffpkeurmvxvopmx]dzlsrwjfphehbkyum +ckzmymusejzabvuyb[wxbswbalirmbjumhxnb]hovexlwnzdbytmp[ulxyngaxvhwhcjlt]xfgofykhgqxxqbogmn +xlgtwmtszopnrfpg[zcjobnutrnmuslxya]ouxjiahawxovbbhahcp +bbezpvhanriufkcof[lspgjssrxkwcdyx]snwkrsinhjurvhicn[wyimmtkjbnxudgxx]fvhiaurorkxhogbown +owjicopdgvoloyswyiv[wqqpvlolkvkeyljrxd]dtnqlobojrurxvhmoig[cwiehwzvrmhtqyfmlvo]ztvfpgydalzyzky +akkrhttulhpzlyulceg[sosggqltgzfydzpco]tgefhbejbxfsxejsbgb +rhaynhcvrkoikpbamh[tbgjdaikneziopop]czthnlotpopwgdvcl +wscoyqvflhwskcjdf[mwpcrduwevtcjduw]uybsbwdhtlnwhvw[nukfdjraoqoaxyeuix]darwzmggglgaesyg[ryapeobwugpoohzy]ozudeagtfhlksnnrw +nrkiszjbkgclvxgwfs[bclhxtwvelakriyxwv]daaunctownhuodswuc +rqsftpfsggukeqa[czvrpfljtsdpbgzoqit]omksopmvqgdyhfvfiuc[ineryoovupytgix]ywfytjoppwkszftm +sjtoqcuwwnmnklb[pmzwkeqnsgnhthww]zkootlimihbctpalhcc +boewgrjfdxkepnlxo[jgcxotrswrdequngh]iwikkhflekspxykgiv[nelzixyahwsrtusfi]ictmunxrofoeccjtd[qeqijxvqhglwamdjcvc]mldxwzgrycapaexur +gwswqgnbmgrekfoqgq[gvdnmnkwqfutvfaa]ivqlohrmbqsoineq[jjgcegcdnjzuigbjze]gyhjcoqoqxqwxouc[xgseyypojrsnohnrica]umzfkjzjdsvsodl +zxamezowxmpjvvwz[cbdeavssccpvrznloem]ibjdhheoubjrhqu[nxvnyftysyuggqwr]mjbtcxyosolkeaahft +rfwgmpzvpchijrhqfj[xjdrxfgheiyijhc]rbcfdtctoouponvr +nqrslruljwsphkvf[dvlnrokayixcmgf]rsfivpietxptzwl +yeqmixesucwapviz[mppclaadstzosfpay]ycztjinsvvywrevju[pigptwaieiahxpzcas]odlsffjpdacydqapjgm[zetjlzxbchwdopgd]lndltscdjxyfgxihbrc +flsctoizaxydslw[grxlmkgckzdfxag]xarpwhhahlpvccry[vienektyecnyvagq]aavbdkiqjofyekil[rkaxahbatmfpimqj]qgkpebxjhwkpodufo +ucckvtbprcmdjvmf[eeqvgsvkvyzhjluexx]gplguxddsudjqlmrdr[xlnqtzhxcbpbdqp]uuqkodbvgxekmeoa +ophlkphyoqamwbu[nbsurlakpxxgyrf]xerxknhcyewzddcle[ydzhegufxmghoneeq]fwybaueovkjhkphx +geawkbpklybiwrncbky[hftcemyhbxsjjdfur]vqnbxghowdbsesops +vcdhlrxvycnvsizqop[fprxccobdsrfwhy]wdbvkhaosqznbtt[dmzbzdelxmitmje]whoekteomhigpjkwruu +iqzznislctfbjfwqsy[tynnrwpeemglajphxg]gfzmrhextughasosati[qsejecgbbetmnzzydyq]ddiskcrtxfguwkly[xpkmunwhccmwkjapp]cdnlcbhhxuplehasn +bmfhrhdtmvimxlmesez[lqmxqpdlqghxlevd]neolsesusvaxzdvx[irnrgqbigwlnzsuk]hrhxoxubvzkipgqfc[cjcvorvhyrvmfll]npkmtfxysboydkden +nbmqatjicimprrcici[tbblcdhcvcupgvxibxz]ccslwipzsuyihkng[sbgzshzorysqctaaacq]dyssqkfywggiaaqu +pcvyyabqmeryplh[jbqynrzyjkhwwgj]etwzjlszjzdbkkewtv +bubxbqqbnbouodcgxzw[dowpsrdjpuuouuh]rhnrizcztkilhuuwhbh +sbqkzpwosgujeovz[japgfjauipufpmlvn]ivnwbyatyuesvvrov +joeqayhdcwcrvbnf[vqfpuvxduqotkdy]kuavekugumzajaxfw[scyzqisremjpsdcmuo]bjpynpdzyzrbmmg +gwdqyqclwdfzpquzc[ozbvuwsgkcexhgsy]kdwdrqopthygiwdwm +tvlczfnrbnpmoyp[wcnstymqrvfoqqosw]sjmunjohxbrybmnm[bnzbnogdxaffnvpjowf]waiaapexfkufpazqn[hodebokzgpbbtdewpb]qzbomhrouunriuxanta +xcvjzwaytzttyobv[bzpagodqlpmmsgy]xpdfkpgsmkgpvkxumlu[chfejuaglsrkruoa]nagzgkrkpyxvjvlr +bnrxwwtsvorohyu[pupbgwrkyqhkbgho]tffqsororwpcdlaphc +riryuebgtvdzxdla[jtcopgrqurtfigfnrq]ovetktdsbrjpvgfg[xtsbnkxsdznzlwx]ftmymefonptpdbzsge[xjqgxcqpkqtvbmul]ztizzeufautgupcqelt +bmlmvylfslqqicwviq[nvxmszbqlexbcef]rqkawnbpuelvwki[bwapsyibuhuopujwmm]yoojkyaudzhoddrmvg +pjdpdxvrbbxxfwpeust[wztobueipqiaaicduq]onogsdcpainijdpz[basykjybxwuwjvxytb]mfxuzylepdplppj +noixgkmkngsjnwwhm[lgcpbkrpmkxxeidim]augzuhmkhdatdrhnr +xncybroqvekbvocdhm[ahxhavcyzvvnwwnfsf]eegitlwvzoqznxuktn[zjwkrbrjofgvedjuf]ujupljhpjfhtoddgqp[jwqpvwwjoaxbwkfj]strlqdkexjcnxwahdxz +ucyrdkrbgaamnaoez[cnumtrblnknjveyjgwv]vrlouyjivhweembem[izybbytphodmvvonvz]iqnendwvqwwpbwpstuq[jilkvguqvtgjpetbkma]kgttxqsamveamxb +ighlrtyekigrpbcx[uospnwlmvlhuujiro]jyrbqcrxoklegsmpeub[ferotpqcwlrfylet]vocevqkkydwdxzqavfq +vreeihsrnbdaduky[uidmukwdoghwycpxzl]hvapmkokuoljwyxi +zywvzrdkcvqbmwsbkuo[hipsuufkkjiunlqu]uhisdpbjcvkpunlayhr[iethrnmpmidjjrnnv]qnwoxpmbpmpnilkbq +ussacrkglqvwqawhxvo[uqdvxdgtawrfdjc]cduwaedcvfpeolqr[nlyblneokgmpfelr]yerzpiiwkwuiwilt[hgekbtoncoseaug]kmdjmalprlowtbrav +owhtgwpvffgjcletp[adgnkwibobvkgfkxale]jgqziknoasxylvw[mocmthhqcjfwjuuiuu]qlgqtnaljwdiejweksm +vxmbqzeafbwvozvsm[jtyqkvagfwyfvuvay]ailxefllrxesazxlv[odmoxgdiadiaetdyvdt]tiavxclhxfqtbvbu +jnfimlvvjtvtzajw[acyjznnyspczqvjf]ozltqkyrqtfrgpva +lrqapqafjqfroqz[zenrntyrnrjtuij]kaewwkrjpcmeylerv[camcigwjgpyeaqg]wpkzihyjlcquzrg[ttfagxotubvfeiqkg]amqnhawihumfajhvd +lvxcwtjjgsxodivad[gfigqaiqkxfcpmj]yaqjmrkuidrdwvviohz +qbceftsjjcumflk[uucxifoxdpecfndprsf]gqthbmmgbbakgrlsm +fsxulvnzmjywovnhat[bthhpzjyawpycgsuxbt]qbqbpjefdcfsfsqbe[uizjjjshwqgccitr]kiehvhvpwhfsasftyu +bkojzixxqjfcftla[glqknzmobetfwsnafev]ratttzyklaxfmfufyv[muwgybxllocskzecx]wyfwhiljpcfcwbhjlt +fcuieutbdlmwmpprjk[nkpbsvtngzrdxgwf]qmnuuepgdlzkolbcm[rjezaqbmfjycxai]paejktmptuiftsl[cbgxlqzqpflvskdmvy]aygzfhlhsqdcquut +rxmngytsppvfcpcscx[phvvbrmqmyequosdztu]vchpgerlpizjwcwkumf[lbjjftbncxuvwdaud]rxfbttgxfwxudhkk[jjzqmfcswwkxsmsluwg]nnjbbkpqankgskjrad +hlbdbzhwzlnpzurrg[rymtuuyqupqdpexefk]tukjhqaedzhzxsqz +fpryuguzmsoizmyp[xtootqplumygzizsqye]abwsvuvxyxwwasvuc +mtabpldrsqsirtega[hgbyvgmmoxihgzulnl]txvozvllasypksvhwhz[poeqvukgvlnbbbbk]lamyuvjvubyqvijesgr[ascxlaksbqqnrrqejx]guetmwzxqjlxjvdm +duxjzazmbyqzxmntnn[mjguwpucpwblyypmkj]csgnjihsjwrwjjj +pushontjgkevnlrkvn[dcibcdsbuftswnqifr]nneewpdmoaahwpt +okcmoevreebuujjdl[nzonouoydhqlmxbyb]kzleqfmoglkipweur[rrtypikbmtkzegy]cmehcxntlavmojfw[tvvcithufoahlxby]odnzrzscwjvxtcpdh +cxszxofnlpxzzurgqxd[islclvtnwrvxiqvybzp]agikgpscjwfvjrp[xfyvjgtigxamybfcxb]juslmurkvwlapendag +zeoxbnfdtlgkqzsig[cyrzkztphbnutuie]otzkrrqohznqwhx +yrsqyknrqcdvbdfcvie[uoikxvuzzihiihn]tdrrmpyisukewgxtz[pcdyynkvijsjpzelypx]axztekjsveddcukyu +bvublvqfqtrxxxtj[vyyxbnmmsmwhmvwywz]zqnifammxhjjcdczxt +iuhhzaiwcucvrrpcqi[cmqxwhpbiozhcjiew]thvzbxjvisbolbddky[tomeprddcnfanklkqq]fralaioewzbgbxxyad[zjgnnnznwqccfjyichm]rptkbqzdwmvjwarnuwr +tfeyzjqxrymktfvj[rmtbxgyrpznwmdvxbdf]mlxqqrocxuzklptmiwc[qdjbddpsonpejdxmpoi]pusiuffhdzpemzd +yclhxrtfzcdhrtm[hcoqrqbulbeziclq]xdlugofehqtqjonj[wcssoobwocoyxvdwq]lypemphdykevdonct[fuaunzhmdchbahgq]qfkfdkmmaxkewddwpmj +lnlskpioicgxmxel[umysskqmyzaxfjeh]cpqruxvbujqkmdhnuev[rqwsypedhnfkfqebtr]cyvrdyivrmvznpcc +shbqidoghlpjpxj[vmwwenaxupuvvptfp]yvjsbdunidbbkjnwpm[gwfgkpizyrvwzhaualv]tevcvdkhzjvniuut[sgmjeiemomrljvnlxu]cypgquavpduminrxlzb +uropacyqybozvyr[eqrnjuuhlopqyqh]rvznyebhzjhjxkuels[iepxmgnogtcfiwcfx]gxszowxzwkrdjvohtk[uegnjpnkrqqmnnmxjjm]lvxhojwlawuzsszq +cpeabckktwlhmnhj[tprdlautoabcpkronhu]jvmhenjwvhauljuid +pthfhbxzjbvghynkmm[vpzaeaijtgtixhitqim]fsaypthcfkzrxtnwr[xzkggwpgnxnfgnvawq]uvjmfmxdcdrkanecd +rxjlrkaudbmetnyrrin[jrjjzactumkuwruckg]vwzkipklzcprfquld[dfjpumtbhydndawlbp]cxwuyyzmhkhmyoaziwv +bumtfjdmmowvduukwaw[ukzkunqpgzgahea]kgmtyvromleqoow[jcszbzaxnyacfyc]fcrzscgevcehniswrxt[mpuxkyphidwhukm]vwskwkgmcrmijtujpba +qkupefsfxnqknoxrk[lvnnuhetjviiioxtp]pjtucqwmybjxnqoviyq[ylzusbponqrkwxll]kovqwsqvwscflkrcwn[zgefedeguzltsmlopj]navdwikahjyvimsnukl +grckowghnjntaxdp[dnelxhpxwzyeggptoa]coenxbdzrpydaqwa +lksmpxtjhpanwbuufn[snfzvkkfhiyibfgmtox]rpbqpzxkiwpxnsrie[datbzytabaylvvhek]uqvxzkzegrrxfcxinw[tmpqywtelhqohkmzuvi]fkwbbzvyzzkohjgz +zyzsrrzsfdlvntmed[utfrddkienuaqcvz]amncxndkvsufgxsu[vpyegmaxvugmdehma]kmeyojxpoluetkqeky[fezcwvaxbuyqttz]mwaklylrcpgnxuw +lkdzsmlnhsfwkmgftm[bpesperctavrfcn]wgzsbkjyyrbcjzghvlo[gixpfkuukvaoecc]zrvymealuxycdlse[cnmjogkfmapiwvkbk]vcgzczxskqenrst +mpeadvyrbgymqhl[razwybnbnxlpdqdtp]imkqmksortpqdqmka[ykbtopscgbsursrwj]evdetgtlaoimeqemyq +qoxokykipszydrgci[mykmfccqtwdxixqiig]iadoxhgcoxnhhliqvr[ttvqbebxyxnwndtz]aasvecaltuqijjmxx[lzovzwzsnwkglorhe]urcmgffjdzouaac +gywgdpzjikpouyzhhx[fznqxhtzozbzijwjvk]ivvlsbwjwxhymwpmdsw[fehugmercmvunun]tltuczprzfvplhqcpi +tgljlexexeebootoyce[pnrvcajzvoefxboyncd]snsnpsjxiyrdmgt +buinlwzbaqgpuoot[pjdralopgcrobfpyl]tttsbhburbjfbtegc[zwdoqaxyubvarmisox]emdozhtvjfcmranqm[kcygeikmvgptspj]pezznfpmodndwvm +xidbntshgqdckieib[urwkpgpqlzuroemjp]srfwixbhqgbnfpsgkpl[uygjtjaixctjtnanuf]qdloyaplyovscng +qundlfpfexfkrmpcd[vukdaxqgqvrcqerbf]dehpfpgaymhudzz[vkqfgcllumlbuszz]eizntkyxsysnlfy[sdvnheddugqdagh]yicuzmoifivylgwmipz +zzgzmnbevlvdlpv[bhoezbdqoelbzmft]bnfeqbplxfvydhluug[kjwpseyayhovkds]aqirzcbxtxginpmjn +xwkvxxptyfibxunjdv[eigrywezdgwtwfzli]fbfurspemrezjyuhsqf +yvnhkuzvtnirdxmxmd[vijtjbffcfxtnmxdh]untbfzmjmhmlfeyixu[edlyghinlksfxoikq]ixrupxdicymsuvkhvk[srnptcdcaczhrvqjq]wrqrzomktabfuupccbc +ipwwgkvjagdlqkoxlat[widqrotdnywnnbdn]rtviotwkbdqpggscdt[jzbcukafvquuxiu]ctmziuyofwucvdvjom +advbztpxdzdhyncuzz[ivjohzdjgqefgcr]nlqmqaenjzacgyaf +knotcnkidizcpveacjg[vajecumyblgcfpy]biedjbtbahcygvsdax[odhgbqawgonxvlu]emxplzktdwcitdioi[wcmtnnqctaowoxwgjn]dgcgmhvajmoouri +uumyvgqczjaadkspfu[cmacsgwkvcivtsn]cpefaqmflxkfmlkp[mfsvltdmnyzxqcrlxk]ykmjlnxxmsvfuqf[bciddbscmtyduhrwvy]cxwohnzlgzbtflqerlr +klioqytpqhkxqiriz[rjgrssxpxozhzbc]fysfmaiblgqhkeue[bycqedeolknahiy]pdusnyfxfcgodvj +sgjjqocmmcccpem[odeofpebaahroicm]pluzqzwkdzcovxic[zmyulzpuuiabvykn]ylxzlyooxnlibiy +btrucplpxrokmcts[gytdxlzkfakenliallw]qhxznozsjsvhvnzhf +nefefqadkmytguyp[ucqagcoyxinbrvbw]neksoxgtnnfojobtx[bxhdwvwfhybtbzkijj]poayieifsaocrboesfe[tnggfefcucifowqp]olmjwaqlaiwkkbtruw +tivudfusgnewzshs[mausfjbgxmyibin]yponuityptavbhekrlg[qeyafuevtlqemtfa]owtdxadrwwbxbrkl[obfcyxbifipwhduubu]mjocivgvrcbrllso diff --git a/pytudes/data/advent2016/input8.txt b/pytudes/data/advent2016/input8.txt new file mode 100644 index 0000000..d827762 --- /dev/null +++ b/pytudes/data/advent2016/input8.txt @@ -0,0 +1,194 @@ +rect 1x1 +rotate row y=0 by 7 +rect 1x1 +rotate row y=0 by 5 +rect 1x1 +rotate row y=0 by 5 +rect 1x1 +rotate row y=0 by 2 +rect 1x1 +rotate row y=0 by 3 +rect 1x1 +rotate row y=0 by 5 +rect 1x1 +rotate row y=0 by 3 +rect 1x1 +rotate row y=0 by 2 +rect 1x1 +rotate row y=0 by 3 +rect 2x1 +rotate row y=0 by 7 +rect 6x1 +rotate row y=0 by 3 +rect 2x1 +rotate row y=0 by 2 +rect 1x2 +rotate row y=1 by 10 +rotate row y=0 by 3 +rotate column x=0 by 1 +rect 2x1 +rotate column x=20 by 1 +rotate column x=15 by 1 +rotate column x=5 by 1 +rotate row y=1 by 5 +rotate row y=0 by 2 +rect 1x2 +rotate row y=0 by 5 +rotate column x=0 by 1 +rect 4x1 +rotate row y=2 by 15 +rotate row y=0 by 5 +rotate column x=0 by 1 +rect 4x1 +rotate row y=2 by 5 +rotate row y=0 by 5 +rotate column x=0 by 1 +rect 4x1 +rotate row y=2 by 10 +rotate row y=0 by 10 +rotate column x=8 by 1 +rotate column x=5 by 1 +rotate column x=0 by 1 +rect 9x1 +rotate column x=27 by 1 +rotate row y=0 by 5 +rotate column x=0 by 1 +rect 4x1 +rotate column x=42 by 1 +rotate column x=40 by 1 +rotate column x=22 by 1 +rotate column x=17 by 1 +rotate column x=12 by 1 +rotate column x=7 by 1 +rotate column x=2 by 1 +rotate row y=3 by 10 +rotate row y=2 by 5 +rotate row y=1 by 3 +rotate row y=0 by 10 +rect 1x4 +rotate column x=37 by 2 +rotate row y=3 by 18 +rotate row y=2 by 30 +rotate row y=1 by 7 +rotate row y=0 by 2 +rotate column x=13 by 3 +rotate column x=12 by 1 +rotate column x=10 by 1 +rotate column x=7 by 1 +rotate column x=6 by 3 +rotate column x=5 by 1 +rotate column x=3 by 3 +rotate column x=2 by 1 +rotate column x=0 by 1 +rect 14x1 +rotate column x=38 by 3 +rotate row y=3 by 12 +rotate row y=2 by 10 +rotate row y=0 by 10 +rotate column x=7 by 1 +rotate column x=5 by 1 +rotate column x=2 by 1 +rotate column x=0 by 1 +rect 9x1 +rotate row y=4 by 20 +rotate row y=3 by 25 +rotate row y=2 by 10 +rotate row y=0 by 15 +rotate column x=12 by 1 +rotate column x=10 by 1 +rotate column x=8 by 3 +rotate column x=7 by 1 +rotate column x=5 by 1 +rotate column x=3 by 3 +rotate column x=2 by 1 +rotate column x=0 by 1 +rect 14x1 +rotate column x=34 by 1 +rotate row y=1 by 45 +rotate column x=47 by 1 +rotate column x=42 by 1 +rotate column x=19 by 1 +rotate column x=9 by 2 +rotate row y=4 by 7 +rotate row y=3 by 20 +rotate row y=0 by 7 +rotate column x=5 by 1 +rotate column x=3 by 1 +rotate column x=2 by 1 +rotate column x=0 by 1 +rect 6x1 +rotate row y=4 by 8 +rotate row y=3 by 5 +rotate row y=1 by 5 +rotate column x=5 by 1 +rotate column x=4 by 1 +rotate column x=3 by 2 +rotate column x=2 by 1 +rotate column x=1 by 3 +rotate column x=0 by 1 +rect 6x1 +rotate column x=36 by 3 +rotate column x=25 by 3 +rotate column x=18 by 3 +rotate column x=11 by 3 +rotate column x=3 by 4 +rotate row y=4 by 5 +rotate row y=3 by 5 +rotate row y=2 by 8 +rotate row y=1 by 8 +rotate row y=0 by 3 +rotate column x=3 by 4 +rotate column x=0 by 4 +rect 4x4 +rotate row y=4 by 10 +rotate row y=3 by 20 +rotate row y=1 by 10 +rotate row y=0 by 10 +rotate column x=8 by 1 +rotate column x=7 by 1 +rotate column x=6 by 1 +rotate column x=5 by 1 +rotate column x=3 by 1 +rotate column x=2 by 1 +rotate column x=1 by 1 +rotate column x=0 by 1 +rect 9x1 +rotate row y=0 by 40 +rotate column x=44 by 1 +rotate column x=35 by 5 +rotate column x=18 by 5 +rotate column x=15 by 3 +rotate column x=10 by 5 +rotate row y=5 by 15 +rotate row y=4 by 10 +rotate row y=3 by 40 +rotate row y=2 by 20 +rotate row y=1 by 45 +rotate row y=0 by 35 +rotate column x=48 by 1 +rotate column x=47 by 5 +rotate column x=46 by 5 +rotate column x=45 by 1 +rotate column x=43 by 1 +rotate column x=40 by 1 +rotate column x=38 by 2 +rotate column x=37 by 3 +rotate column x=36 by 2 +rotate column x=32 by 2 +rotate column x=31 by 2 +rotate column x=28 by 1 +rotate column x=23 by 3 +rotate column x=22 by 3 +rotate column x=21 by 5 +rotate column x=20 by 1 +rotate column x=18 by 1 +rotate column x=17 by 3 +rotate column x=13 by 1 +rotate column x=10 by 1 +rotate column x=8 by 1 +rotate column x=7 by 5 +rotate column x=6 by 5 +rotate column x=5 by 1 +rotate column x=3 by 5 +rotate column x=2 by 5 +rotate column x=1 by 5 diff --git a/pytudes/data/advent2016/input9.txt b/pytudes/data/advent2016/input9.txt new file mode 100644 index 0000000..800446b --- /dev/null +++ b/pytudes/data/advent2016/input9.txt @@ -0,0 +1 @@ +(6x9)JUORKH(10x13)LNWIKDMACM(126x14)(21x8)QLKUJNVVZIQGGFCJZMPHK(2x1)ZH(59x3)(38x14)KELEPIDYLCGJUBCXACRSOCEZYXLOFJSADZAYXN(8x11)HORSWAQU(21x2)YEZNNYDLDSTGWMQFSMTEZ(111x14)(14x14)IMLQOUGGZSUMFQ(73x10)(5x8)KWHRS(6x1)OQMANE(6x4)FALFZJ(3x3)OAQ(26x15)LALOJKTKJWTMRDDQQVCSDHJYGF(4x12)OXMQ(63x6)(6x10)OSJMJX(9x13)(4x2)FAUQ(29x13)UDCLMPVICKKUFMPQUENGCRIUGHOKM(7x7)JNKRSAT(79x7)(11x1)(5x13)RUQIL(47x12)HDIEMWYDIMTVXSIRZSRMIMZVMCEIUOMJDGHQXPWDFLOYIWL(3x5)IHX(1x6)M(33x3)ORLXEMAAICHAIJUIPKKWPWZMVXJSCZZYG(9x11)TIMKMEBMC(9930x13)(1513x15)(779x2)(333x4)(197x8)(27x4)IVLXTLXGDDQPWQOAXDEISEOTSAW(68x4)(4x13)OOZQ(3x5)NIN(10x12)UDGXNSJXLP(17x6)FZETGJDTLNUQRLHWU(4x13)AIZY(9x10)HESLLDOPY(69x1)(5x13)LULVA(10x1)CBTQWNWMRT(3x11)UYT(4x13)APGU(17x2)ADKQUAPCVNCXGBUGI(8x7)EGCQRTUU(108x11)(30x14)(2x13)LW(16x7)OTSCBRYUGBHSLRHU(2x1)KT(58x4)(3x12)SBW(7x15)IJTOSYM(30x8)MGFBFVKJDCFQHTLVSLZSSRVALHIYUN(25x4)(19x6)(5x2)ULAFN(4x1)LZBJ(60x10)(33x1)(26x14)FXVHHVMIQZBNSJRJWVQQBTLCJT(14x15)MCNCQPHNNPDVLT(326x1)(90x6)(8x9)(2x10)QQ(7x9)(2x9)QA(15x5)(3x12)YYF(1x9)E(2x5)PN(30x10)(16x1)DNOMTDTPGQECFDZR(2x11)PO(83x9)(18x6)(6x6)WCIAVF(2x4)PG(4x10)LMEG(2x9)TM(7x8)CYTGIPV(23x13)(1x9)V(1x15)E(4x14)EFSQ(102x15)(19x4)(6x5)GOXZGT(3x2)VQM(5x12)ZPRXJ(17x1)(10x15)RJNMNYZGHQ(37x2)(11x8)BZHBHSYQFZR(7x3)ISJOGDR(3x8)HEC(25x2)(19x6)(7x7)WKDHBGA(2x1)HH(2x11)TS(297x11)(289x14)(6x13)QERECU(4x3)IKNT(13x7)(7x11)(1x13)C(242x1)(28x4)(22x3)PHZYSAKYKBEGOCKKMRKOOO(12x1)RJDMLFYCFSIP(90x1)(17x2)YMAFXOHNVIPPURYIK(7x15)UYDUWQX(33x9)AIRWLTEJXUBYKOIBBDABIUKOYZXOPEGIW(9x11)RMBVBJFRV(88x9)(8x10)UQXEIUOO(24x2)OJEVOVTOFTKJSBPOOUPDZHGM(5x14)OWMBL(8x13)DKXEFKWI(12x12)WDCXEDVGOCPY(299x2)(239x3)(172x5)(67x7)(5x8)SYGVZ(5x8)DREXA(6x1)FNDUMM(30x2)PMYQAWIEQSOAWKGTANFXJVIPIXAVXK(5x5)ANQRI(83x3)(15x12)TGXTICPXLKWBCIP(13x5)DVMOKEUOBYENI(10x14)MIBPUUQJWN(12x3)GRHQZIDWWGLK(2x7)WR(11x7)(5x15)EIKHL(36x12)(21x4)AJDVITQLAQQOJJOFFKNLS(3x11)EZR(5x2)YHNYY(6x7)YCSGKC(18x13)ZEIUSEMQHQWMZVPLNZ(2x9)NN(79x7)(73x7)(67x3)(60x10)(9x5)TGBRMOCPG(32x2)FDWNZGDQFMFCQUHYSAOQAOTEIUBCDNIW(2x12)JM(24x15)IRWDGUFXLEKCWDNZRVBNRYSS(1280x14)(193x2)(12x4)(6x10)ZHTRGA(155x7)(34x8)(27x12)(5x10)VXVVJ(4x5)PLYR(2x4)YO(10x2)XXATONMJPD(7x5)(1x15)L(72x8)(21x7)(4x13)QGHA(5x15)BYFQB(18x5)(12x9)GHLYVOFFOHII(15x4)XQRPRDSSBORQHKA(3x11)LVM(8x8)IYHEOOSI(575x5)(289x5)(15x3)WUJJUHESVBKMKWI(144x1)(27x8)(21x2)ZWKIBQKYDICTDWZJSMFMB(85x4)(2x11)YJ(9x9)NEIHAQFQS(3x13)FMR(18x7)HTTQTCRJQAOGPSGCEP(24x3)FGXUVDQTTFSBUWGYWIWIVLNH(13x12)(1x3)A(1x13)H(14x9)(9x5)(4x3)SJAA(74x13)(18x6)FKPLHFUKSNVZXJTTYB(21x3)(15x8)LDLRHRRFVCEAEZW(17x8)BUQDCTSPWOMNYXSXQ(10x5)GYOKDVURIQ(10x1)ZSXQJVASBA(244x5)(237x3)(56x1)(2x3)IH(8x5)JPNMZEJU(15x10)SOIGFVVDBCHWLUX(8x11)IMNGAHMV(36x11)(6x6)AVOERJ(1x15)I(11x15)TGRCPFFXZWN(80x2)(2x11)UD(3x4)AJO(19x12)FQOHLQVIFPAEBOCLBOD(7x13)ZLCBKLN(18x12)BOEPSWVDLNKVUFDHKV(39x15)(10x4)AYYJAXAJXB(10x10)EWKJCLSLBE(1x6)C(6x12)EMSRFU(2x8)PX(483x14)(186x8)(178x12)(6x9)VJVAVY(65x1)(1x5)F(2x6)GE(4x13)BUJP(9x14)IMEJXLWER(20x12)HUUEGUTSDWPZHFZKXVFV(59x8)(5x13)VYEFV(25x6)DWBRYFPBHUNYZJUMZXCKFIHIE(1x11)F(5x8)DLUUQ(1x2)K(19x6)PPXCSNESTBPIWHDFLGG(4x10)NHOY(273x3)(18x9)SEWPNVRXHLBCKGESND(31x1)(1x6)J(19x5)SIQBBERDYWEKHMAJEWB(58x1)(43x13)(15x13)BKGAXDZLFQHWDIS(7x7)JWIGQYE(4x9)DHHW(3x6)OHR(140x13)(28x15)(10x12)JOMQKBRMDS(5x13)PUVLJ(44x7)(4x13)DKZR(16x15)NQDHKHTUOJOXBWWY(5x13)BAOCL(34x10)(28x1)JCJWLCJRLTIFXVJQBKHWOTLJFIVI(9x4)YFQNAGIPW(2478x7)(1083x5)(417x15)(117x10)(92x11)(31x1)XHEFNUFJDMXCTUQFXSZMYHFEHXUVGYQ(7x2)ZITTPBY(9x14)SSCNHQYKS(22x5)UVJATRGWLHAIVMQAGJMHEK(4x4)IUEZ(4x5)YKGS(96x14)(12x1)ZELBJAPFUHLZ(72x4)(2x14)NP(6x8)SMHEEP(14x11)HKYNMOLKTUVIXZ(15x1)NSAGJXXSAYRTIUK(5x15)NPRBV(182x9)(76x12)(4x9)LLZF(35x11)DLKHAYYAZXRSZKTEHJNIZQERZANTBHDVFQM(13x6)XPSSVVUTYEUKX(1x2)X(33x14)(2x11)IG(11x8)FPEMVSXFOHQ(3x6)BRW(46x11)(1x3)Q(3x10)ZHT(3x7)VNL(1x7)R(10x12)GZWTUNGVDQ(1x1)Y(120x10)(14x9)PBYCGWOFRQUZWJ(83x6)(17x12)(3x4)EAM(4x6)CJOU(53x6)(13x5)INHCJBTGHXSDE(19x8)CWOKMSSFKYMDMSLRSPA(4x6)XDUP(6x4)LYNJVO(2x7)AD(509x1)(188x4)(74x10)(41x9)FUNFGSCSMVNLSJIJIBJZMBXKRACPLVGYEVJVRXTLF(1x7)O(15x5)ZIFCLBIMIFPOFVA(8x5)(2x10)SA(3x15)SYB(29x12)(2x4)LR(15x13)SUPSUGVKOEIHPAZ(43x9)(18x6)IONNEOWXXVFDIQOMQM(1x14)N(7x7)VICZLXN(253x1)(26x11)(2x15)OF(4x4)EINM(4x7)VPFW(90x2)(2x12)OS(18x15)IHDJBISYOELRBFBMRT(16x5)ZWDVZWPFHTFZRHGM(6x15)RMASVP(17x8)HHEQZPDKXKRYHABWF(64x9)(24x4)XXMFXKEZKTMCOQDOYEXVQWGY(12x14)IXJHAYHVQVBG(9x11)OEOVLDHWO(47x10)(14x6)OQYNLIFVBHCLDV(21x7)GNVWPMWHRPNVRYWBOKXXH(2x1)GE(25x9)(3x3)YHT(10x10)WGUTPDXLCO(10x4)PTGWGFREXV(2x8)CP(569x3)(119x13)(56x1)(50x5)(1x5)T(25x8)QVDBRPILAVKKPNKCWACDVQKAM(8x1)UDZHAVIS(44x10)(32x5)(8x9)WVPZVSEF(12x10)EBBNJTJBZPSH(1x5)I(1x2)M(1x10)K(27x1)(2x4)IV(14x1)(9x8)(4x4)JVUB(112x15)(99x2)(49x3)(1x14)C(1x5)D(2x14)WK(5x15)XXYUI(11x9)KLPOYCKHWFV(14x6)GVHBCOJYAOCJAH(10x3)BATKUDEPLN(3x2)SPJ(2x1)TA(275x3)(41x4)(18x5)(2x12)PT(4x15)MAUM(11x6)(5x15)RFIRF(220x15)(29x11)XWFPDWBZOCIASNAPTYSYUUVQCLCYG(5x7)LJJUN(34x4)(1x1)I(4x3)DPAN(12x12)LFHZRFTTUZLE(46x13)(6x5)FMHJMK(2x7)PZ(9x13)SATIDLMYD(7x10)RXCEUNC(75x9)(5x15)WCKRG(15x3)MYYAJYGJIBOWXOX(29x1)AABPHEDEUZZCJICBHSJZFVGLJCQMX(3x1)UNW(803x15)(441x13)(65x6)(59x2)(8x4)VCYBDQQS(15x9)MHGZPTDZETHSKLL(7x2)NMOFOIS(7x14)KUAWWUP(15x8)GNNUKIVQVUVZULA(161x1)(87x6)(4x4)BHUM(1x14)W(40x2)HZRMQLYLMDMWKBSXEAOHCJVANHFGTEAPXAALYUNE(18x14)MIGSNNUDEKHXIVPAOP(62x6)(1x13)B(12x8)SJKLEEFTVPLM(4x3)WONT(5x9)TAESF(12x5)AQTLVIYDFKZV(53x9)SWGZYFRQBSYVZRKBUETKECZABCQOBKWTLUXIIRCYXIYYCIZPWXYLJ(114x13)(65x12)(33x12)FYYFQQIQMKTPWLRATCIXJWQWZHDZEMDSX(19x9)RDXSFWGCVHIAEFRATQB(8x4)SMHSAZUP(22x14)(1x4)O(2x9)TL(3x10)JWD(325x11)(107x6)(80x10)(1x9)I(7x14)VRZNXOX(17x5)SXTYFBITZSWXLUUFJ(11x3)LOCMMDXNMXN(15x6)ESLRVLYBOQKPEZA(2x3)ES(7x11)EDZPYNR(69x15)(8x15)HATTKOTD(1x15)C(1x14)O(35x1)(2x1)CW(21x13)MQITCFLIILUSRLVQGSKXW(121x6)(12x15)(6x13)HZQFNF(9x9)UIDOFTGVI(57x8)(15x14)DJHSOBMGQLFKFTQ(11x6)QWKTRHFEAGK(2x4)IH(6x5)ZHDHJX(10x15)ACPQGUGWIL(3x2)QMK(2x3)OT(15x6)NZGYKDPCNTWTZCH(3552x13)(852x7)(284x12)(277x1)(8x11)TGYIXQNL(40x13)(17x9)LWDCCCCWVOGYOWYZP(3x8)ZVN(3x10)SDQ(3x3)DWU(123x2)(10x14)NSZEKFDZRL(26x2)ENELBBZQLDXFNGFSVGYFTSJPBP(19x5)STCNNNFTTGNFSHLQIMV(7x14)BMGHAMA(30x9)LWDBIXXPHDSHEHLGUWINWVVCSQLNYK(72x1)(5x3)SMBBE(1x15)U(4x3)XLJH(12x6)LYEVOLDUQOII(22x3)UYBOYDZYRBWIHVBZJZJIBD(10x15)ORGFBMUTUK(535x12)(100x8)(6x15)PJFDCS(29x7)(4x2)RERM(4x1)BFHS(6x7)GNJACX(13x6)THUMFYQLTLTCJ(28x8)RTDQHJQHMBOOPZUEWWKMSANXGGQL(56x7)(50x4)(4x2)EUXN(3x12)LWU(2x13)YV(12x8)PXZISAYRVHIE(1x4)L(77x13)(70x12)(24x14)XLKAJZMEOBGJQOZFGDAARDDF(4x13)HMEZ(22x13)TRAZZTZVHZFJQBCVPUERWP(116x7)(8x13)FQQDJSSI(21x4)(3x3)GUX(1x12)J(1x7)F(26x14)(12x6)JVDQPKZGKVQJ(2x13)DV(36x7)(10x4)HVKCDIWLKC(8x5)LGTFQODZ(1x12)L(152x5)(4x6)CURR(80x1)(17x15)GUVFWMLWUJEGNLRVL(6x7)NJXRSS(7x14)AKRRJPI(8x5)DQVRMWFL(12x15)UMLQPEZXZYIZ(10x10)FTKQEWMORC(25x8)(4x1)NPOF(2x4)ZB(4x5)MNGN(4x1)SVFL(819x3)(422x1)(161x5)(63x11)(10x9)LMWKXPVXUD(12x11)NVMYGSXJQBVT(2x12)XS(14x1)LCJFACSGQHOPUG(44x6)(31x9)IYNFDKSDSHMXTGMRIOPAQJRHQBFEKDH(2x4)SX(14x3)HIZENUSZORNUXE(7x2)(1x12)C(3x10)LQD(246x14)(79x13)(32x14)FBUFQJMOZAUHZPGKGNZOTHLBIYETINMF(13x1)GKCLXCMWWPDZV(15x7)MNXJKTCLCEEKJCJ(39x4)(14x14)QYBWZMQBFIWBYQ(12x6)VHQHHLDLMOBZ(93x2)(40x1)TYXOJHUCXHXFBLOHLFUUDAHEWHQJFIUZMAGFRGWP(2x7)MS(9x13)VVJYBKHTL(19x4)IEBQYXDIHQGRMTODBIF(5x6)GWEDR(1x3)M(345x13)(185x7)(8x14)ZXFOFWFV(9x8)EZMSOIYCO(61x13)(33x11)OFPSLJWRGPSLTALOWBSVBFAAYMKCPMYTY(9x6)IUDMWEHGP(1x10)H(6x9)QPVXCO(71x11)(1x11)Y(5x14)PSMCR(7x2)ZAZQZSB(24x14)DCIFQYMEDXSNYMDBSIPOWQUL(5x5)OWYAX(4x5)ISZB(7x3)HWLAEOE(125x9)(45x13)(21x11)YRXZKZQVBPNYBKZIFSYMH(2x13)EL(3x14)HXM(6x15)YQWWDS(5x10)VWCRE(44x7)(8x6)ONMUMKWM(24x15)OBREAALATPCTXPSADMXUXKDK(31x8)(25x8)(18x15)(1x6)K(6x15)WFSHOE(1064x8)(180x12)(91x7)(2x9)UQ(77x10)(14x9)KQHDSHPDIDEWFX(7x13)DBZDGLP(17x1)PEQPQFLLLGAZMPJLK(5x8)DTSJE(5x10)JGHKO(16x10)(2x7)LP(3x11)PDI(40x10)(1x7)Y(27x13)IXDUDNKRJKLBBKIVORLOGMGJWCQ(8x6)(3x2)RTB(323x5)(79x9)(44x13)(19x1)VGWKUHADQZUENXNLNGP(12x10)HCFBPZQRWQEQ(3x10)PLL(12x13)(7x2)GVCTUOT(118x1)(57x15)(13x12)XQESMYXNDFYYW(1x8)G(3x6)XFU(17x8)BHBGTSSJBGGFRPPRT(48x7)(10x1)BLQHPNBCVO(8x13)QAYCKEPP(11x14)FBTYJKKUQCA(4x4)JNWW(97x11)(33x3)WYMAFQHRKESJTBRMNMOARAUYBABCIIZHH(11x8)DTIJCCBXCHK(4x2)ZLMO(25x11)(1x3)L(2x6)EN(7x1)FBJYMYH(11x4)GRWQQFIQDAL(89x9)(83x7)(23x14)QSLZVMSWOGEMUVQUMMBBXZS(33x5)(7x11)ZCEHLWD(14x2)BSRRFIINKZJUTM(9x3)XBPUGZIBI(426x11)(144x11)(10x2)ZVQMPUEXDS(7x14)(2x3)NP(8x8)(2x10)WY(31x4)(8x14)MQXSEJDJ(2x7)FW(4x13)XEQJ(59x3)(17x11)MTJKGUKCQPWDUSFMV(3x6)VDL(8x6)OHZZPPZE(8x12)JMJZCIBE(267x9)(6x7)QQULTD(109x3)(32x9)KHIFGECKKBYSJQUPZYCSWRGOISZBQZMP(5x11)WWVRO(53x13)RNKMDBXJEJEYGREGYLVFXJAGXKPLZGSBEGCLRHUBWMMIMMSEJLKVS(20x10)(1x12)Q(1x4)J(1x10)T(44x7)(3x1)HQS(2x14)OY(4x3)NYOT(3x11)HRB(5x3)AWNPF(57x4)(51x4)NRDWDRLNIEMNTPTKPXWYVRZVJXCEPIWDOZHHSPWTINYYPNKRIJM(788x7)(373x2)(13x13)OMNINNXSMZGVU(110x10)(9x4)MUCJLTXXY(23x8)(16x10)QPEZTMHGTAZMDZFT(4x12)QARM(50x15)(3x11)XOH(16x6)YBLZLQWJABJGQWOU(4x1)PMXY(4x15)OHDQ(118x4)(5x11)EPKSP(24x4)AWIBAENYEFRILVCXFWNDTDKD(1x4)B(65x2)(12x2)YLEUJZAKLKME(24x13)TTXHIHEKQRZMJJYYKWQLCBJP(10x2)FCVCPOTJEU(102x12)(76x14)(7x12)UZQCZAB(3x1)XMW(9x1)UJSGSEURM(11x13)BOKCOFUHRNM(17x1)AEMFGQNASPGQHPXUB(1x13)P(6x11)CVFTDM(166x1)(74x3)(3x12)ONA(36x9)(29x12)AGQWRIAFZDTLKFAWUBZVULOQIYWPP(17x9)AKFFQIWNYGWXFBZZN(71x7)(31x2)XOIACTRUJMFXAVRZUMXKBXZFREZNVJJ(27x15)(20x12)EWQHGQNTXRUIOVHORPOV(3x12)TVU(117x1)(109x14)(10x12)BEIZCDNSAS(86x7)(27x9)FURZRGYPYLGCCCEKYZJPGYYDBQQ(5x2)SBYXR(25x4)ZXXGJHSMUOPRERLXZXQJLECBO(6x15)JUOYIW(91x3)(23x14)MGGWDYYRPCJTIYELCDIZVHS(2x12)KD(6x3)BCDBJV(19x3)(13x4)RXIRDQSOWIPGW(11x1)QGAYMDNYTSL(8x11)FJQAMNNG(1063x13)(250x5)(60x10)(24x11)(8x12)BJYJZMJY(5x8)BJXMU(7x14)NZTAXLS(4x8)VBAT(2x3)HO(176x5)(169x4)(13x15)TWSLJCGYWHLHA(73x6)(36x12)AOUGLFXLSSEWZXFMZUNGDGZVCYYJZUPNKRIH(3x3)UFP(3x1)QIQ(8x15)NPNWNAWS(50x15)(3x6)YIW(1x10)D(10x14)FCLZEIFJWG(1x12)N(6x8)AZDFPX(7x13)DICRGNA(799x2)(533x11)(276x6)(100x9)(17x5)LPMZDSXVBZCMEDFQB(24x8)TCDTFHHXXVEQIVVZCESDANQS(10x15)EPDXGVSSBQ(7x13)WQSTXRF(10x11)RIBWTNVIOX(3x15)VSF(61x6)(8x15)TWCPLZZZ(8x9)AVRPJLHR(21x9)QDODHNZHZERQGXTVKLHYW(1x13)U(53x11)(2x15)RC(32x12)CWBFTTDPKPGPZVZFIJHVLZRCOPJRNFOJ(1x1)I(26x11)CDUFFOGUBYLOBYJNLCWGPDRSMS(201x12)(8x5)(3x1)YIC(8x10)BDXPEMTD(64x4)(10x1)RBHVYIUNFH(5x14)KYIHZ(14x2)TGSOMUZWRGPUNE(11x3)QJHVUCUELOW(8x14)VKMCUJKE(83x11)(1x11)L(5x12)WLWRL(4x12)NQVE(36x3)FJDUVTWHNITJXXVVUMFUDALUXKSIPQFJOEDT(8x1)GDWDODFR(35x2)(22x13)(4x14)OSLD(7x4)VWJVMIF(1x6)H(10x6)VDQYBSDXHG(149x10)(16x14)DROZRQNSVIJWCMPZ(67x6)(54x6)NDDMSLQZBUOSOSAFMDFQGMQBMSGREAKGVTMWIRQPTESMEACCZIOGQH(1x15)J(8x10)CFHPKNID(24x1)(18x2)EMDBIEKPGRSNYXDATP(4x4)HSHR(79x9)(51x1)(2x12)BB(6x15)LNUMRD(25x8)(10x6)FBWLKYGCNJ(3x13)XRN(16x7)(3x9)ONH(2x10)HS(47x1)(2x2)MS(34x9)VLUZLSWIOQZSOBREZDZXEQYKYWTNHHWRNZ(9x6)(4x4)WMMX(78x9)(17x7)(1x10)J(4x14)WZCZ(49x9)(3x5)IPZ(35x7)ROJEZWTCDQCBOWTBEEJCVWBPNMBNXJDJZMG(183x15)(3x6)KRR(54x13)(3x11)JXV(4x7)WRTT(1x6)Q(16x15)LLQNPHNXKWRMAGKX(2x1)ID(21x15)UGXWFMKPKPUMLJCQDBWGS(4x1)NZTP(71x2)(21x7)PKYTHOAENWACXNCPHTTTU(14x12)ZFQGENBKFBMONH(1x7)G(10x10)VSHYAMJWEV(33x7)(4x6)LAZL(12x9)KIDULBTPZHYR(1x4)U(143x8)(29x3)(22x13)LQNQIWKSHNSMJZKWJQWDQA(79x10)(1x8)V(35x12)BTLWYXERIMYWZOFPFAVAAZOFQAHKQXAPOWO(24x13)RLAORQSPJCCOLZLXDAAOXYHY(16x1)MZLJXILHCLGHOAPW(12x3)(7x1)ELWCOIZ diff --git a/pytudes/data/advent2017/input1.txt b/pytudes/data/advent2017/input1.txt new file mode 100644 index 0000000..b7e8ce6 --- /dev/null +++ b/pytudes/data/advent2017/input1.txt @@ -0,0 +1 @@ +3294199471327195994824832197564859876682638188889768298894243832665654681412886862234525991553276578641265589959178414218389329361496673991614673626344552179413995562266818138372393213966143124914469397692587251112663217862879233226763533911128893354536353213847122251463857894159819828724827969576432191847787772732881266875469721189331882228146576832921314638221317393256471998598117289632684663355273845983933845721713497811766995367795857965222183668765517454263354111134841334631345111596131682726196574763165187889337599583345634413436165539744188866156771585647718555182529936669683581662398618765391487164715724849894563314426959348119286955144439452731762666568741612153254469131724137699832984728937865956711925592628456617133695259554548719328229938621332325125972547181236812263887375866231118312954369432937359357266467383318326239572877314765121844831126178173988799765218913178825966268816476559792947359956859989228917136267178571776316345292573489873792149646548747995389669692188457724414468727192819919448275922166321158141365237545222633688372891451842434458527698774342111482498999383831492577615154591278719656798277377363284379468757998373193231795767644654155432692988651312845433511879457921638934877557575241394363721667237778962455961493559848522582413748218971212486373232795878362964873855994697149692824917183375545192119453587398199912564474614219929345185468661129966379693813498542474732198176496694746111576925715493967296487258237854152382365579876894391815759815373319159213475555251488754279888245492373595471189191353244684697662848376529881512529221627313527441221459672786923145165989611223372241149929436247374818467481641931872972582295425936998535194423916544367799522276914445231582272368388831834437562752119325286474352863554693373718848649568451797751926315617575295381964426843625282819524747119726872193569785611959896776143539915299968276374712996485367853494734376257511273443736433464496287219615697341973131715166768916149828396454638596713572963686159214116763 diff --git a/pytudes/data/advent2017/input11.txt b/pytudes/data/advent2017/input11.txt new file mode 100644 index 0000000..1614b28 --- /dev/null +++ b/pytudes/data/advent2017/input11.txt @@ -0,0 +1 @@ +n,nw,nw,nw,sw,sw,sw,ne,s,s,nw,s,s,ne,se,s,s,nw,s,se,se,se,se,ne,se,ne,ne,ne,ne,ne,ne,ne,ne,sw,se,ne,sw,n,s,ne,ne,sw,n,ne,sw,nw,n,n,ne,ne,ne,ne,n,se,n,n,n,n,n,n,n,n,n,n,nw,n,n,sw,nw,n,nw,s,nw,n,n,s,nw,ne,n,se,nw,nw,nw,nw,se,s,s,s,s,s,sw,nw,n,nw,nw,se,nw,nw,nw,nw,nw,nw,sw,nw,nw,nw,se,nw,nw,nw,nw,nw,s,nw,sw,nw,nw,sw,sw,sw,n,s,nw,sw,sw,nw,nw,nw,s,n,n,sw,sw,nw,nw,sw,sw,sw,n,nw,sw,sw,sw,sw,sw,sw,sw,sw,n,sw,sw,sw,sw,sw,sw,nw,ne,sw,s,sw,sw,sw,sw,sw,sw,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,s,s,sw,sw,s,s,s,se,nw,sw,s,s,se,sw,nw,s,se,s,sw,sw,sw,s,sw,s,s,s,s,s,s,s,s,s,sw,s,s,ne,s,s,ne,s,nw,sw,s,s,s,nw,s,se,s,ne,s,s,s,s,s,s,s,s,s,s,s,s,n,s,s,ne,nw,s,s,s,se,se,s,s,nw,se,s,se,s,s,s,s,sw,sw,s,s,s,se,n,se,s,ne,se,s,se,nw,s,ne,se,se,se,se,se,s,s,se,ne,s,nw,se,s,se,sw,se,se,se,se,se,s,s,n,ne,se,s,se,n,nw,s,se,se,s,s,s,se,se,se,s,sw,se,se,se,sw,se,se,s,se,se,se,se,se,se,ne,se,se,ne,s,se,n,se,se,se,se,se,ne,se,n,se,ne,se,ne,se,ne,ne,nw,se,ne,s,ne,n,se,sw,se,se,nw,se,ne,se,se,s,ne,n,se,se,se,s,ne,se,se,ne,se,se,se,ne,ne,sw,ne,se,s,ne,nw,nw,ne,n,ne,se,nw,s,ne,se,ne,ne,se,ne,n,ne,ne,ne,ne,ne,se,ne,sw,ne,sw,ne,ne,ne,ne,se,ne,ne,n,ne,ne,ne,se,n,se,ne,se,nw,se,ne,ne,ne,ne,ne,se,s,nw,ne,ne,ne,ne,ne,ne,ne,se,ne,n,ne,ne,ne,se,ne,s,ne,ne,ne,sw,ne,ne,ne,ne,ne,ne,ne,ne,se,ne,ne,n,sw,nw,se,ne,ne,sw,ne,nw,ne,ne,ne,n,s,ne,ne,ne,n,ne,ne,ne,se,n,ne,se,se,s,ne,ne,nw,ne,ne,sw,ne,se,n,ne,ne,s,n,ne,ne,ne,n,ne,ne,n,nw,ne,ne,ne,n,ne,n,s,ne,se,s,ne,ne,ne,ne,ne,nw,s,ne,sw,n,ne,n,ne,ne,nw,se,n,ne,ne,ne,n,n,ne,n,ne,ne,ne,n,nw,ne,n,ne,n,ne,n,ne,ne,ne,nw,n,s,ne,ne,sw,n,ne,n,ne,s,sw,ne,ne,ne,ne,ne,ne,n,n,ne,ne,n,s,n,ne,nw,ne,n,ne,n,s,ne,ne,ne,n,n,s,se,nw,n,ne,n,ne,n,n,n,s,n,s,n,n,ne,n,n,n,n,ne,n,n,n,n,sw,n,n,n,n,n,n,sw,nw,sw,n,n,n,n,n,n,ne,n,s,nw,n,nw,n,ne,n,n,n,n,s,n,n,n,n,n,n,n,n,n,sw,s,n,ne,n,n,n,n,s,sw,n,ne,n,n,n,n,n,n,n,se,s,n,n,sw,n,se,n,n,n,n,n,n,n,s,s,sw,n,n,n,n,n,n,sw,nw,n,n,sw,s,nw,sw,se,n,n,n,n,s,n,nw,nw,nw,n,sw,nw,n,sw,s,sw,nw,n,n,n,ne,n,nw,nw,n,n,n,n,s,nw,se,n,n,se,n,nw,nw,n,n,n,s,n,s,nw,n,nw,nw,nw,nw,nw,sw,nw,ne,n,nw,n,n,n,nw,se,sw,n,n,s,ne,n,nw,nw,nw,nw,n,n,nw,se,n,n,n,se,n,nw,n,sw,se,nw,n,n,nw,nw,n,nw,n,nw,nw,n,n,nw,n,n,nw,n,n,n,n,n,n,n,n,nw,nw,nw,nw,sw,n,n,nw,nw,n,se,s,n,nw,n,nw,nw,n,n,nw,n,n,n,nw,nw,nw,n,nw,se,nw,n,n,nw,n,n,n,n,n,nw,n,se,s,ne,n,nw,ne,nw,nw,nw,n,nw,nw,n,se,n,nw,se,s,n,ne,n,nw,se,s,n,n,ne,n,nw,se,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,n,n,nw,nw,n,nw,n,nw,nw,nw,n,ne,nw,nw,nw,n,nw,nw,sw,n,nw,sw,nw,nw,n,nw,nw,nw,n,n,nw,nw,s,nw,sw,nw,se,nw,nw,nw,nw,s,nw,n,nw,nw,n,nw,nw,nw,nw,n,ne,nw,nw,nw,nw,nw,nw,sw,nw,s,sw,nw,nw,nw,nw,nw,nw,nw,nw,ne,nw,nw,sw,nw,nw,nw,nw,nw,nw,s,nw,s,nw,nw,nw,nw,ne,nw,s,nw,nw,nw,nw,nw,sw,nw,nw,s,nw,sw,se,sw,nw,nw,s,n,nw,nw,nw,s,nw,nw,nw,nw,se,nw,ne,nw,nw,n,nw,nw,nw,sw,sw,n,nw,nw,sw,nw,sw,nw,nw,nw,n,nw,nw,sw,nw,s,sw,se,nw,nw,nw,nw,nw,nw,nw,sw,nw,nw,ne,sw,nw,nw,n,nw,sw,sw,se,nw,nw,nw,n,nw,nw,nw,nw,s,se,ne,sw,nw,nw,nw,nw,nw,nw,nw,nw,nw,sw,sw,n,se,s,s,nw,n,sw,s,s,sw,sw,s,nw,nw,sw,sw,nw,sw,nw,nw,nw,n,sw,sw,s,nw,ne,ne,sw,n,se,nw,sw,sw,nw,sw,nw,ne,nw,nw,sw,nw,nw,n,nw,se,sw,nw,nw,se,sw,sw,se,sw,nw,se,nw,nw,nw,nw,nw,nw,sw,nw,sw,sw,sw,n,sw,sw,nw,nw,sw,sw,nw,sw,nw,nw,nw,nw,ne,se,nw,nw,sw,nw,sw,nw,sw,nw,nw,nw,sw,nw,sw,se,sw,nw,sw,n,ne,sw,sw,sw,sw,se,nw,se,sw,sw,nw,sw,sw,nw,sw,nw,sw,sw,sw,sw,sw,sw,nw,sw,sw,sw,sw,nw,sw,sw,nw,nw,sw,se,sw,nw,sw,sw,sw,nw,s,ne,n,s,n,sw,sw,sw,sw,se,sw,nw,nw,se,nw,sw,nw,se,sw,sw,nw,sw,ne,sw,s,n,se,se,sw,s,s,sw,sw,nw,s,se,sw,sw,sw,sw,s,nw,n,nw,sw,sw,sw,nw,sw,sw,s,n,sw,nw,nw,nw,se,sw,sw,nw,se,sw,sw,sw,sw,sw,nw,n,sw,nw,ne,sw,se,sw,nw,n,sw,se,sw,sw,se,nw,s,sw,sw,nw,nw,sw,ne,n,se,sw,se,sw,nw,sw,sw,sw,sw,sw,nw,se,sw,sw,ne,sw,sw,se,ne,sw,sw,n,sw,nw,sw,n,sw,sw,ne,sw,sw,nw,sw,sw,sw,sw,sw,sw,nw,s,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,nw,sw,sw,sw,se,sw,sw,n,sw,s,sw,sw,n,se,sw,sw,ne,n,se,sw,sw,sw,sw,sw,sw,nw,sw,s,sw,se,nw,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,se,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,n,sw,sw,sw,sw,sw,n,sw,s,s,sw,se,sw,ne,sw,s,sw,sw,sw,sw,ne,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,s,se,se,s,sw,sw,nw,sw,s,sw,sw,nw,s,se,nw,sw,sw,sw,s,sw,sw,sw,s,sw,ne,sw,sw,se,sw,sw,sw,sw,s,sw,n,sw,sw,nw,s,s,s,sw,se,sw,sw,sw,sw,sw,s,sw,nw,se,se,nw,sw,sw,n,ne,sw,s,sw,se,s,sw,sw,sw,sw,sw,sw,se,se,s,sw,sw,sw,sw,s,sw,s,nw,sw,sw,s,sw,s,sw,sw,s,s,sw,sw,s,ne,sw,sw,sw,s,s,s,sw,nw,nw,s,sw,sw,ne,s,sw,sw,sw,s,se,s,s,sw,sw,sw,se,sw,sw,nw,sw,s,sw,sw,n,sw,sw,sw,sw,s,s,s,s,s,ne,se,sw,s,n,sw,se,se,s,sw,sw,s,s,s,s,sw,s,s,s,s,sw,sw,s,s,s,sw,s,sw,n,s,nw,nw,sw,sw,sw,sw,s,se,sw,sw,s,sw,s,s,sw,s,sw,sw,sw,sw,s,se,se,n,ne,ne,s,sw,sw,sw,s,sw,nw,nw,n,nw,s,sw,sw,ne,s,sw,sw,n,s,s,s,s,se,s,sw,se,sw,s,sw,s,nw,se,sw,s,sw,sw,sw,s,n,sw,ne,se,s,s,n,s,s,s,sw,s,sw,sw,sw,s,nw,ne,n,s,s,sw,ne,s,sw,s,s,sw,sw,sw,s,s,nw,s,nw,s,s,sw,ne,s,s,s,ne,s,sw,s,se,s,s,s,s,s,s,s,s,s,ne,sw,n,s,s,s,s,s,ne,s,sw,s,s,n,s,s,s,s,s,s,s,s,s,s,s,s,sw,n,s,se,ne,s,s,s,s,sw,s,nw,s,s,s,s,s,s,s,se,s,sw,s,sw,n,s,sw,s,sw,sw,s,sw,s,ne,sw,s,se,s,sw,s,s,sw,ne,nw,s,s,sw,sw,s,s,s,se,s,s,s,n,sw,sw,ne,ne,sw,nw,s,s,sw,s,s,sw,s,s,s,s,nw,sw,s,s,s,s,sw,s,s,s,sw,s,s,s,sw,s,s,s,s,s,s,s,s,s,s,s,s,sw,s,s,se,s,s,n,s,ne,s,s,se,s,s,s,s,s,s,s,ne,s,s,s,s,n,s,s,s,n,s,n,s,sw,s,n,sw,nw,s,s,ne,s,s,s,s,s,s,n,s,nw,s,sw,s,s,s,s,s,s,s,n,s,s,s,s,s,se,s,s,s,s,s,n,s,s,ne,s,s,s,s,n,s,ne,s,s,s,nw,se,ne,se,se,s,ne,nw,s,s,n,s,s,s,s,n,s,s,s,s,se,s,sw,se,ne,s,s,s,n,n,s,se,se,ne,s,s,s,s,s,se,s,s,s,s,nw,s,se,s,s,s,s,s,s,se,s,s,s,sw,n,s,sw,s,s,s,se,s,s,s,s,s,s,s,s,s,s,nw,s,s,ne,s,s,sw,s,ne,s,s,ne,s,sw,n,s,nw,s,se,se,s,s,s,sw,nw,s,s,s,s,s,ne,s,se,s,s,s,s,s,s,s,s,se,n,s,sw,s,s,ne,se,s,s,se,se,se,s,se,nw,s,s,s,se,nw,sw,s,s,s,ne,s,s,se,s,ne,s,s,s,nw,n,se,s,s,se,s,s,se,se,s,s,s,s,nw,s,s,s,nw,s,s,n,se,nw,s,s,sw,se,s,n,n,s,sw,s,s,nw,s,n,nw,nw,s,se,s,s,se,s,s,ne,s,s,s,sw,sw,s,se,s,s,se,se,s,nw,s,se,s,s,nw,s,n,se,ne,sw,se,s,s,s,s,ne,se,n,se,s,se,s,s,nw,s,se,s,ne,s,s,se,s,se,n,sw,sw,s,nw,s,se,s,se,nw,se,s,se,s,sw,n,s,se,se,s,s,ne,s,n,s,se,se,ne,s,s,s,s,se,se,se,se,sw,s,se,sw,s,s,s,s,se,se,s,nw,s,se,se,s,ne,s,se,s,s,s,s,s,s,se,se,s,se,se,se,se,se,ne,nw,s,n,ne,s,se,s,s,s,nw,se,se,nw,s,se,nw,s,se,se,s,s,se,se,se,sw,se,s,se,ne,sw,s,se,s,s,s,s,s,s,s,nw,n,ne,se,sw,s,se,s,se,s,se,n,se,s,se,se,se,se,se,s,se,ne,se,s,se,n,s,s,ne,s,s,se,s,s,s,s,sw,se,s,se,sw,sw,s,sw,nw,se,nw,se,s,s,ne,se,s,s,s,s,s,se,s,se,se,nw,se,nw,s,sw,s,n,sw,se,se,s,se,nw,se,sw,s,se,se,nw,s,s,s,s,sw,nw,n,se,s,sw,se,se,s,se,ne,s,s,se,s,se,s,ne,se,s,se,se,se,se,se,s,se,se,se,s,se,s,se,s,s,s,s,s,se,nw,se,nw,se,se,s,se,se,se,s,sw,se,se,se,se,sw,se,se,se,s,n,s,sw,se,n,se,s,se,se,se,s,nw,s,se,se,nw,se,se,se,s,se,se,se,se,se,nw,sw,se,s,s,sw,se,se,nw,s,se,s,s,se,ne,se,nw,se,s,se,se,s,se,se,se,se,sw,n,se,ne,se,se,s,se,se,s,se,s,se,se,s,se,s,se,n,s,se,s,s,s,se,se,se,se,se,n,se,se,se,se,ne,s,sw,se,se,se,n,se,se,se,s,se,se,se,se,n,ne,se,se,se,se,se,se,se,se,se,se,s,sw,se,se,se,se,se,se,se,se,s,se,se,se,se,se,s,se,se,se,se,se,se,se,se,se,nw,s,se,s,se,se,se,se,se,s,s,ne,se,se,se,ne,se,se,se,se,se,se,s,se,se,se,se,se,se,se,se,se,s,se,se,se,s,s,s,s,se,ne,sw,se,se,se,se,se,s,ne,se,se,se,se,s,sw,se,se,sw,se,s,sw,se,nw,se,se,s,se,se,nw,s,s,se,s,se,se,se,nw,se,ne,se,se,n,se,se,se,se,n,ne,se,se,sw,se,sw,se,se,se,se,se,se,se,n,nw,se,s,sw,n,ne,se,se,se,se,n,sw,se,se,se,se,se,n,se,nw,se,nw,sw,se,n,se,ne,se,se,se,se,se,se,sw,n,se,se,nw,se,se,s,se,se,se,se,ne,se,se,s,se,se,se,se,se,nw,n,se,se,se,s,se,se,nw,ne,nw,se,se,se,se,se,se,se,se,se,se,se,se,s,ne,ne,se,se,nw,se,se,se,se,se,se,nw,se,sw,se,sw,se,se,nw,se,se,se,se,ne,se,se,se,se,se,nw,nw,se,se,se,se,se,se,se,se,se,se,nw,se,se,se,se,se,se,nw,se,se,se,se,se,se,nw,se,se,se,se,se,se,se,se,se,se,s,se,se,se,ne,s,sw,s,se,ne,se,ne,se,se,se,se,ne,se,se,nw,se,se,se,se,se,se,se,se,n,s,se,nw,se,se,n,nw,sw,s,se,se,se,sw,se,se,ne,se,s,nw,se,se,n,se,se,sw,ne,se,se,se,ne,se,se,se,se,se,nw,se,se,s,se,ne,se,se,se,nw,sw,se,n,se,ne,s,ne,nw,n,ne,se,ne,se,ne,se,se,ne,se,sw,se,se,n,s,se,nw,ne,se,se,ne,se,ne,se,se,nw,se,se,s,ne,ne,se,se,se,se,se,se,se,se,se,ne,se,se,ne,se,se,se,nw,nw,se,se,se,n,se,se,s,ne,se,se,se,s,se,ne,se,ne,se,se,se,se,ne,se,n,se,se,se,ne,n,se,se,s,se,se,nw,se,se,sw,se,se,ne,se,se,se,se,se,se,s,ne,sw,ne,se,se,se,se,nw,se,se,ne,se,s,se,se,se,ne,ne,nw,se,se,se,s,sw,se,ne,sw,se,n,ne,se,sw,se,ne,se,se,ne,se,s,se,ne,se,se,se,ne,sw,ne,se,se,se,ne,ne,ne,ne,se,se,se,se,se,se,sw,se,ne,se,sw,ne,se,se,se,se,se,se,ne,se,sw,se,ne,n,ne,se,se,se,ne,se,se,se,ne,se,n,ne,nw,se,se,ne,ne,ne,ne,nw,se,ne,se,nw,se,se,se,ne,se,se,se,se,ne,ne,ne,nw,se,se,sw,se,ne,se,nw,n,s,s,se,ne,ne,sw,ne,se,ne,ne,ne,sw,se,se,se,nw,nw,ne,se,se,s,se,ne,sw,se,se,se,se,ne,se,ne,se,ne,se,se,se,se,ne,se,ne,se,se,ne,ne,se,n,sw,se,sw,se,sw,ne,ne,se,nw,se,sw,ne,se,nw,ne,se,ne,se,se,se,se,se,ne,ne,ne,ne,se,ne,nw,se,sw,se,nw,ne,se,se,ne,se,se,ne,se,se,se,nw,ne,ne,se,ne,se,sw,se,se,nw,ne,ne,ne,n,n,nw,nw,se,ne,ne,se,n,ne,se,ne,se,n,se,se,se,ne,ne,se,se,nw,se,se,se,se,se,ne,ne,se,n,se,ne,se,ne,nw,se,se,se,n,ne,ne,se,se,se,se,se,ne,n,ne,ne,ne,n,se,se,se,se,se,ne,ne,se,ne,se,ne,nw,se,se,ne,ne,ne,ne,ne,se,se,ne,se,ne,ne,ne,ne,sw,ne,se,ne,se,nw,ne,ne,se,ne,ne,se,se,ne,se,sw,ne,ne,se,ne,se,s,ne,ne,se,ne,ne,sw,se,se,s,nw,se,n,s,s,ne,se,se,ne,se,se,ne,s,se,se,se,nw,ne,se,ne,se,ne,ne,se,se,se,se,ne,sw,ne,se,s,ne,ne,ne,ne,n,se,sw,s,se,ne,se,se,ne,ne,se,se,nw,ne,ne,ne,sw,se,ne,ne,ne,ne,se,se,se,se,ne,se,se,se,se,sw,s,se,ne,ne,ne,ne,ne,se,ne,ne,ne,se,ne,ne,sw,nw,nw,n,ne,se,se,s,se,s,n,ne,se,se,se,ne,se,ne,sw,nw,nw,ne,ne,se,ne,ne,ne,ne,ne,se,ne,n,ne,se,se,se,se,se,ne,ne,se,se,ne,n,n,ne,se,ne,se,nw,se,ne,se,ne,ne,se,ne,se,ne,se,se,nw,se,nw,ne,ne,ne,ne,s,s,ne,ne,se,ne,se,ne,ne,n,sw,ne,ne,s,nw,ne,ne,se,ne,nw,ne,se,s,se,ne,sw,ne,sw,se,ne,n,nw,ne,nw,ne,se,n,se,ne,se,ne,ne,se,ne,se,ne,n,se,se,ne,ne,sw,se,ne,ne,ne,ne,ne,ne,nw,ne,se,se,se,ne,se,ne,s,se,se,ne,sw,se,s,ne,n,ne,se,ne,se,se,ne,ne,ne,nw,sw,se,ne,se,ne,ne,se,n,s,ne,n,ne,ne,se,ne,ne,se,ne,ne,ne,ne,ne,ne,ne,ne,ne,s,nw,ne,ne,ne,ne,n,ne,ne,ne,se,ne,ne,sw,ne,ne,se,se,se,ne,ne,nw,ne,ne,ne,se,n,se,sw,ne,se,se,ne,nw,n,se,ne,s,ne,n,ne,ne,se,ne,ne,se,ne,ne,ne,n,ne,n,sw,sw,ne,n,se,ne,se,n,s,ne,ne,ne,sw,ne,ne,ne,ne,ne,ne,nw,ne,nw,se,ne,sw,ne,ne,ne,ne,n,ne,n,ne,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,n,se,ne,ne,ne,sw,ne,ne,se,ne,ne,se,n,ne,ne,s,se,nw,ne,ne,ne,s,se,sw,ne,ne,ne,ne,n,s,se,se,ne,ne,ne,ne,ne,ne,s,sw,sw,ne,ne,ne,ne,ne,sw,ne,n,ne,ne,sw,ne,n,ne,ne,ne,ne,s,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,sw,se,ne,ne,ne,ne,ne,sw,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,sw,ne,se,sw,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,ne,nw,ne,ne,ne,n,ne,nw,ne,ne,ne,ne,ne,ne,sw,ne,ne,ne,n,sw,s,nw,nw,sw,s,nw,ne,ne,sw,ne,ne,se,ne,ne,ne,s,ne,sw,nw,ne,ne,s,ne,ne,ne,ne,se,ne,ne,sw,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,se,ne,sw,se,ne,ne,nw,ne,ne,s,ne,ne,ne,nw,ne,nw,ne,ne,n,ne,ne,ne,ne,s,ne,ne,ne,se,n,ne,ne,ne,ne,s,se,ne,nw,ne,se,n,nw,ne,ne,ne,ne,ne,ne,n,ne,se,ne,ne,n,ne,ne,ne,ne,s,ne,ne,ne,n,n,ne,n,ne,ne,ne,ne,ne,n,nw,ne,ne,ne,se,ne,ne,ne,s,se,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,sw,ne,ne,ne,nw,nw,ne,ne,nw,ne,ne,ne,n,ne,ne,ne,n,ne,ne,ne,ne,se,se,n,ne,ne,ne,n,ne,ne,ne,s,se,ne,ne,ne,n,ne,ne,ne,nw,ne,ne,ne,nw,ne,ne,ne,ne,ne,se,ne,ne,ne,n,ne,ne,nw,ne,ne,ne,n,ne,nw,ne,ne,ne,se,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,nw,ne,ne,ne,ne,se,ne,se,ne,ne,ne,ne,ne,ne,sw,ne,ne,ne,ne,n,n,se,ne,n,ne,ne,n,ne,ne,ne,nw,ne,ne,ne,n,ne,s,ne,n,n,ne,ne,ne,ne,n,ne,sw,ne,ne,ne,nw,ne,ne,ne,se,s,nw,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,n,nw,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,n,ne,ne,ne,ne,nw,n,ne,ne,ne,n,n,n,se,ne,sw,ne,nw,ne,ne,ne,n,ne,ne,ne,ne,sw,n,ne,ne,se,ne,nw,s,ne,ne,ne,s,n,ne,ne,ne,ne,se,ne,ne,sw,ne,ne,n,ne,ne,ne,ne,ne,n,n,nw,n,ne,ne,n,s,sw,n,ne,ne,ne,n,n,ne,ne,ne,sw,ne,ne,ne,nw,ne,ne,n,ne,ne,n,se,ne,ne,n,se,n,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,se,n,ne,ne,nw,s,n,n,n,ne,n,n,ne,n,ne,n,ne,ne,ne,nw,s,ne,ne,ne,ne,ne,se,nw,ne,ne,s,se,n,n,ne,ne,ne,ne,n,ne,ne,ne,n,n,ne,ne,ne,nw,ne,ne,ne,n,ne,n,ne,sw,ne,ne,n,ne,ne,ne,n,n,n,n,n,sw,ne,nw,n,se,s,ne,ne,ne,s,ne,sw,n,ne,se,ne,ne,ne,ne,ne,se,n,n,ne,ne,n,n,n,ne,ne,n,n,ne,s,ne,ne,se,ne,se,n,sw,ne,ne,ne,s,ne,ne,sw,nw,ne,se,n,ne,n,ne,n,n,ne,n,s,ne,n,s,ne,ne,ne,n,n,ne,n,sw,sw,ne,n,ne,ne,sw,n,n,n,ne,ne,se,ne,ne,n,ne,ne,ne,sw,ne,nw,sw,ne,s,ne,ne,ne,s,ne,sw,ne,n,ne,n,n,ne,nw,ne,s,n,n,ne,nw,ne,n,ne,ne,ne,ne,ne,se,nw,ne,sw,ne,ne,ne,sw,n,n,ne,ne,ne,ne,ne,nw,ne,ne,nw,ne,sw,ne,ne,sw,ne,ne,ne,n,ne,se,ne,n,n,se,n,s,n,n,ne,ne,ne,ne,ne,ne,ne,n,n,ne,ne,se,ne,ne,n,ne,nw,ne,n,se,nw,ne,ne,n,ne,n,nw,ne,ne,n,ne,n,n,ne,n,n,n,ne,ne,ne,ne,ne,n,n,nw,ne,ne,ne,nw,ne,ne,ne,ne,n,sw,ne,ne,n,n,ne,n,se,n,ne,n,n,nw,ne,ne,n,sw,ne,ne,ne,sw,ne,ne,n,s,n,nw,ne,s,ne,n,n,n,ne,s,ne,s,ne,sw,ne,se,ne,n,ne,n,n,n,ne,n,ne,n,ne,ne,ne,se,ne,ne,n,n,n,ne,n,n,ne,ne,ne,ne,sw,ne,ne,n,n,ne,n,n,n,ne,ne,ne,nw,sw,sw,n,ne,ne,n,ne,n,ne,sw,ne,n,n,se,n,n,ne,ne,sw,n,n,n,s,ne,n,ne,sw,ne,n,ne,ne,ne,ne,ne,ne,ne,n,n,n,se,ne,nw,n,ne,n,ne,sw,nw,n,se,ne,ne,n,n,s,n,n,n,ne,sw,ne,ne,se,n,n,ne,n,ne,n,ne,ne,ne,n,nw,n,n,n,nw,n,n,n,n,nw,ne,n,s,sw,ne,n,n,ne,n,nw,n,ne,s,sw,n,n,se,n,n,n,se,n,se,ne,se,n,n,n,n,s,ne,n,n,n,ne,ne,nw,n,n,sw,ne,n,n,n,n,ne,n,n,n,ne,ne,ne,n,ne,sw,ne,n,n,ne,n,n,n,ne,s,nw,n,ne,nw,n,n,ne,s,n,ne,ne,ne,ne,ne,n,ne,n,n,nw,ne,n,n,ne,n,n,n,se,sw,n,ne,s,n,n,ne,s,ne,n,n,sw,n,n,n,n,se,n,n,n,ne,n,n,se,ne,ne,sw,n,ne,n,n,ne,n,ne,n,s,s,n,s,n,n,n,n,ne,n,n,sw,nw,n,n,sw,ne,n,s,n,n,n,n,nw,n,n,ne,ne,ne,sw,ne,nw,n,ne,n,ne,n,n,n,nw,ne,nw,n,ne,sw,n,sw,s,ne,n,n,n,ne,n,s,n,n,n,n,ne,n,n,ne,se,se,n,ne,n,n,ne,n,ne,ne,ne,s,n,n,ne,ne,n,n,sw,ne,n,n,n,n,n,ne,ne,n,n,ne,n,n,n,n,ne,n,ne,n,n,ne,nw,n,sw,sw,nw,n,se,sw,ne,n,ne,n,ne,ne,s,n,ne,s,ne,s,ne,n,n,n,n,ne,n,ne,nw,n,n,n,n,n,ne,n,ne,ne,nw,sw,s,se,n,n,s,n,n,n,n,ne,n,ne,n,n,sw,ne,ne,n,n,n,ne,ne,n,n,n,n,nw,n,ne,s,n,ne,ne,n,sw,se,n,ne,ne,ne,s,ne,n,n,ne,n,nw,nw,ne,n,n,nw,n,n,ne,s,n,nw,n,n,n,nw,n,n,sw,n,n,n,s,n,n,n,n,ne,se,n,n,n,ne,nw,n,n,n,ne,n,ne,n,n,n,n,n,n,n,n,n,n,ne,n,n,ne,ne,n,n,s,n,s,n,n,n,nw,ne,n,n,ne,n,n,ne,n,n,n,ne,n,n,n,n,n,n,n,ne,n,nw,n,ne,n,ne,n,n,n,n,sw,ne,ne,ne,n,s,ne,ne,n,ne,n,n,n,n,n,n,n,n,s,n,ne,s,n,n,ne,ne,ne,ne,nw,s,n,n,n,ne,sw,n,n,s,n,n,n,n,ne,n,n,s,ne,n,n,n,se,nw,ne,ne,ne,n,ne,n,ne,n,n,n,se,n,s,n,ne,se,n,ne,n,ne,n,n,ne,n,nw,ne,n,ne,nw,n,n,s,sw,se,n,n,n,ne,nw,n,n,n,n,se,n,ne,ne,n,nw,n,n,nw,n,ne,n,n,n,ne,sw,n,n,se,n,n,sw,ne,nw,n,n,n,n,n,n,ne,n,n,n,n,ne,ne,ne,s,n,n,ne,sw,n,n,n,se,n,ne,sw,sw,sw,n,n,n,sw,n,ne,n,sw,n,ne,n,se,ne,n,n,n,n,n,n,n,n,s,n,n,sw,ne,n,n,n,se,se,n,n,n,s,n,n,n,sw,n,n,n,nw,sw,n,n,n,nw,n,ne,ne,n,se,n,n,n,n,se,ne,sw,n,n,sw,n,sw,n,s,ne,n,n,s,se,n,n,se,n,n,n,ne,sw,n,nw,n,ne,n,n,n,n,se,n,s,n,n,n,se,n,n,n,nw,n,n,n,n,n,n,nw,n,n,n,n,sw,s,s,n,n,n,se,ne,n,n,ne,ne,ne,n,n,n,n,n,sw,n,ne,n,n,n,n,n,se,n,n,n,nw,se,n,nw,n,ne,n,n,n,s,n,n,n,n,n,n,n,n,n,n,ne,n,ne,n,n,n,ne,n,n,n,s,n,n,n,n,n,n,n,n,n,n,n,n,n,ne,s,n,n,n,ne,n,n,n,sw,n,ne,s,n,n,n,n,sw,n,n,n,n,n,se,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,se,sw,n,n,ne,se,s,se,s,s,s,s,s,sw,sw,sw,nw,nw,sw,nw,se,ne,nw,nw,sw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,se,n,ne,n,n,sw,ne,n,n,n,sw,n,ne,s,n,ne,ne,ne,ne,n,ne,n,n,se,ne,ne,ne,se,ne,ne,ne,ne,ne,ne,sw,ne,ne,se,ne,ne,ne,ne,ne,se,ne,se,se,se,ne,ne,ne,se,ne,se,ne,se,ne,se,se,n,se,se,n,se,se,nw,se,se,se,se,se,s,se,se,se,s,se,se,se,se,s,s,nw,s,se,s,se,se,s,s,se,sw,s,se,nw,s,s,ne,n,sw,se,s,se,s,se,s,s,s,s,s,ne,s,s,sw,s,s,s,s,s,s,n,s,s,s,sw,s,s,s,sw,sw,nw,sw,s,sw,n,s,s,s,s,sw,sw,s,n,s,sw,ne,sw,sw,s,s,sw,s,s,s,s,s,ne,nw,sw,sw,s,s,sw,sw,sw,sw,sw,sw,n,sw,s,sw,sw,sw,s,se,n,sw,s,s,n,sw,sw,sw,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,nw,nw,sw,sw,sw,sw,se,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,ne,s,sw,nw,nw,sw,sw,sw,nw,n,sw,sw,nw,nw,se,sw,sw,sw,nw,sw,sw,sw,sw,n,sw,nw,nw,sw,ne,sw,nw,sw,nw,sw,sw,nw,s,nw,n,nw,nw,nw,nw,nw,nw,sw,s,n,se,nw,nw,nw,nw,ne,nw,n,nw,nw,sw,n,ne,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,s,nw,nw,sw,n,se,sw,sw,ne,nw,nw,nw,nw,ne,nw,nw,nw,sw,nw,ne,nw,nw,nw,ne,nw,ne,n,n,nw,ne,nw,nw,nw,nw,nw,n,nw,nw,nw,nw,n,nw,s,se,nw,nw,nw,nw,n,n,sw,n,nw,nw,nw,nw,n,nw,n,sw,nw,nw,n,nw,se,nw,nw,n,n,n,n,nw,n,sw,n,n,nw,sw,sw,nw,nw,s,nw,nw,nw,sw,n,n,nw,nw,n,n,n,s,nw,se,n,n,n,nw,nw,nw,n,n,n,n,nw,n,ne,n,n,sw,se,n,nw,s,s,n,se,n,s,n,ne,nw,n,n,n,ne,n,n,nw,nw,ne,n,nw,nw,se,n,n,nw,n,n,n,n,n,ne,n,n,n,n,se,n,n,n,n,ne,n,sw,n,n,n,n,n,ne,n,se,n,n,n,nw,n,ne,n,n,ne,n,nw,n,s,n,n,ne,n,n,n,n,ne,s,n,n,se,n,n,se,n,n,sw,ne,s,n,nw,s,n,ne,nw,n,n,ne,n,n,n,se,n,n,n,n,s,se,n,n,ne,s,se,ne,n,ne,ne,n,ne,ne,ne,ne,ne,se,ne,n,n,ne,ne,ne,ne,n,sw,n,n,sw,ne,ne,ne,nw,nw,ne,ne,se,sw,n,n,ne,n,n,ne,n,n,ne,n,n,ne,n,ne,n,nw,ne,se,ne,sw,se,s,n,n,ne,ne,n,ne,nw,n,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,se,sw,ne,se,ne,ne,n,ne,ne,ne,s,ne,ne,ne,ne,ne,n,se,ne,n,ne,ne,sw,se,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,ne,s,ne,ne,sw,nw,n,ne,ne,ne,n,s,n,se,ne,ne,sw,se,ne,ne,ne,s,ne,se,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,sw,ne,ne,ne,sw,ne,se,ne,ne,ne,nw,ne,ne,se,ne,ne,ne,ne,ne,s,ne,ne,ne,ne,ne,se,se,ne,ne,ne,sw,ne,n,ne,ne,ne,ne,s,nw,ne,ne,ne,ne,ne,ne,ne,se,ne,se,ne,ne,ne,se,se,ne,ne,sw,ne,ne,s,se,ne,n,ne,s,s,ne,s,nw,se,ne,ne,sw,ne,ne,se,ne,ne,ne,ne,se,ne,ne,sw,se,ne,ne,ne,n,sw,ne,ne,se,se,se,se,s,nw,se,ne,se,nw,se,ne,ne,se,ne,ne,ne,ne,sw,ne,ne,n,ne,se,sw,ne,ne,se,se,se,nw,ne,ne,ne,ne,se,se,sw,ne,se,se,se,ne,se,nw,ne,ne,ne,ne,nw,ne,se,se,ne,se,se,se,n,ne,ne,se,n,se,ne,se,se,se,se,se,se,ne,s,se,ne,se,se,ne,sw,ne,se,n,ne,se,ne,se,se,ne,se,ne,ne,se,nw,se,se,se,ne,se,ne,se,se,se,ne,se,se,ne,se,se,sw,se,se,ne,se,se,se,se,se,se,se,nw,s,ne,ne,ne,se,sw,se,se,ne,se,n,se,se,se,se,se,se,s,se,se,se,se,ne,s,se,se,ne,se,se,se,sw,se,se,n,ne,ne,se,ne,n,se,se,ne,s,se,se,nw,se,n,se,ne,se,se,ne,sw,se,se,se,nw,se,se,ne,ne,se,nw,se,se,se,se,se,se,se,se,se,se,se,se,se,n,sw,se,se,se,n,se,se,se,sw,se,sw,se,s,nw,se,se,se,se,sw,se,se,se,se,se,se,se,ne,se,se,se,se,nw,n,sw,se,ne,se,se,se,sw,se,se,se,sw,n,se,se,sw,se,se,s,se,se,se,s,se,se,ne,s,se,se,se,se,s,se,s,se,se,s,se,ne,se,se,se,se,se,ne,se,se,se,ne,s,se,s,ne,n,nw,se,sw,se,se,s,se,se,s,se,s,nw,s,s,s,ne,s,se,se,se,n,s,s,se,se,se,ne,sw,se,se,se,se,se,s,s,s,se,se,ne,se,ne,se,nw,se,se,se,ne,s,se,se,se,nw,se,se,s,se,s,s,s,nw,ne,se,s,se,s,sw,nw,se,s,ne,se,n,se,s,se,ne,se,s,s,se,s,se,s,s,ne,se,se,se,se,s,ne,se,s,se,s,s,s,s,se,se,se,s,s,s,se,se,sw,s,se,se,s,se,se,s,sw,sw,s,s,nw,s,s,ne,s,ne,s,s,n,se,s,s,sw,s,n,n,s,s,ne,se,s,s,s,ne,s,s,se,s,sw,se,n,se,s,ne,n,s,s,se,s,sw,s,nw,se,n,n,s,s,s,s,n,s,s,sw,s,se,s,se,s,se,se,s,s,sw,s,se,s,ne,s,s,s,s,s,sw,nw,s,s,nw,s,s,s,se,s,se,s,n,se,s,s,se,s,ne,s,n,s,s,s,s,se,s,n,s,s,s,s,s,s,s,s,s,nw,s,se,nw,se,sw,se,se,s,se,s,s,s,s,s,ne,nw,n,s,s,s,n,s,s,nw,s,s,s,s,s,s,s,n,se,ne,s,se,s,s,se,s,s,ne,s,s,s,s,s,s,sw,nw,se,se,s,s,s,s,sw,s,s,s,nw,se,s,se,sw,s,s,s,nw,sw,s,ne,s,s,s,nw,s,s,s,s,s,s,s,s,s,s,s,s,s,ne,s,s,s,s,ne,s,n,se,s,s,s,s,s,n,s,nw,s,s,s,sw,s,s,s,s,s,sw,s,s,s,sw,s,s,s,ne,sw,s,s,ne,s,ne,s,s,s,s,s,s,s,s,nw,ne,nw,s,se,s,s,sw,s,n,s,sw,s,sw,s,se,sw,sw,sw,s,s,s,nw,sw,s,s,s,ne,s,se,s,sw,sw,s,sw,s,sw,s,s,s,s,s,s,sw,se,s,s,sw,sw,s,s,s,s,sw,s,s,se,nw,sw,s,nw,s,s,s,sw,se,s,s,sw,sw,n,sw,s,sw,s,s,sw,s,s,s,sw,se,s,s,s,s,se,s,s,s,s,s,s,s,s,s,s,ne,s,s,s,s,s,nw,sw,s,s,sw,sw,s,nw,s,s,s,sw,se,nw,ne,s,n,s,se,s,s,s,s,nw,s,s,s,ne,s,sw,s,s,ne,sw,s,ne,sw,nw,sw,s,s,s,s,s,sw,s,sw,sw,nw,s,n,s,sw,s,s,sw,s,n,sw,sw,s,s,s,s,s,nw,nw,s,sw,s,nw,sw,nw,s,s,sw,sw,sw,nw,s,nw,n,sw,sw,sw,sw,n,sw,s,sw,sw,sw,s,sw,sw,sw,s,s,ne,ne,sw,sw,s,se,s,s,nw,s,n,s,s,s,n,s,s,s,s,se,ne,se,nw,ne,sw,sw,s,n,n,s,s,s,ne,s,sw,sw,sw,sw,s,sw,s,sw,sw,s,sw,sw,nw,s,sw,sw,s,nw,sw,s,n,s,s,s,se,sw,s,s,s,s,s,s,sw,sw,sw,sw,nw,sw,sw,ne,nw,nw,n,s,sw,sw,sw,ne,s,s,sw,s,s,sw,sw,se,sw,sw,sw,n,n,s,sw,se,s,sw,ne,sw,se,s,sw,sw,s,s,s,sw,s,sw,s,sw,s,s,s,s,sw,sw,s,sw,s,sw,sw,sw,s,s,sw,s,s,sw,s,sw,ne,s,sw,s,sw,sw,s,s,sw,sw,n,n,s,sw,s,sw,s,s,sw,sw,s,s,sw,sw,sw,sw,sw,n,s,sw,sw,sw,sw,s,sw,se,sw,s,s,n,s,s,sw,sw,ne,sw,se,sw,sw,s,s,sw,sw,s,sw,s,sw,sw,nw,sw,s,nw,n,sw,n,se,sw,sw,sw,se,ne,sw,sw,sw,sw,n,sw,sw,sw,sw,n,sw,sw,sw,s,sw,se,sw,nw,sw,sw,se,sw,sw,sw,s,sw,sw,sw,sw,ne,se,sw,s,sw,s,s,nw,sw,n,se,s,s,sw,sw,s,s,sw,sw,sw,nw,sw,sw,sw,s,n,se,sw,sw,sw,sw,n,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,sw,s,sw,sw,sw,sw,sw,sw,ne,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,sw,sw,sw,sw,sw,n,sw,n,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,sw,n,sw,sw,sw,sw,sw,sw,sw,sw,se,s,sw,ne,sw,ne,sw,sw,sw,sw,sw,sw,sw,sw,nw,sw,sw,sw,n,nw,s,sw,sw,sw,sw,sw,n,n,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,nw,sw,sw,sw,nw,sw,sw,sw,sw,sw,sw,sw,sw,n,sw,sw,sw,s,sw,sw,ne,sw,nw,sw,sw,sw,sw,sw,s,s,sw,nw,sw,sw,sw,se,sw,s,sw,s,se,sw,sw,s,sw,ne,sw,sw,sw,sw,nw,sw,n,sw,sw,s,nw,nw,nw,sw,se,nw,ne,sw,sw,sw,n,sw,se,sw,sw,sw,sw,sw,sw,se,nw,sw,nw,nw,sw,sw,n,sw,sw,s,nw,sw,sw,sw,nw,sw,s,sw,s,sw,sw,sw,se,sw,sw,se,se,sw,sw,nw,sw,nw,sw,sw,sw,nw,n,ne,sw,nw,ne,sw,ne,sw,nw,ne,sw,sw,ne,nw,sw,nw,ne,sw,sw,sw,sw,s,sw,n,nw,nw,nw,nw,nw,nw,s,s,sw,nw,sw,sw,sw,nw,sw,nw,sw,nw,sw,nw,sw,sw,nw,nw,nw,sw,nw,sw,sw,nw,sw,sw,sw,sw,sw,sw,sw,sw,se,sw,sw,sw,n,s,ne,sw,nw,nw,sw,sw,ne,sw,sw,nw,nw,sw,nw,nw,sw,se,sw,s,sw,n,sw,sw,nw,ne,sw,sw,se,nw,sw,sw,nw,nw,sw,sw,nw,nw,sw,sw,nw,ne,sw,sw,ne,sw,sw,nw,ne,nw,sw,sw,nw,sw,s,ne,nw,nw,n,sw,nw,nw,sw,nw,sw,sw,ne,sw,sw,sw,sw,se,sw,nw,sw,sw,nw,nw,sw,sw,nw,n,sw,n,nw,nw,nw,nw,s,se,nw,sw,nw,sw,sw,nw,sw,nw,sw,n,nw,sw,nw,sw,sw,sw,sw,nw,n,sw,sw,sw,nw,sw,sw,s,nw,nw,nw,nw,sw,nw,sw,sw,nw,sw,nw,sw,nw,nw,nw,sw,sw,s,ne,sw,nw,sw,nw,n,nw,sw,nw,nw,nw,nw,nw,ne,n,sw,nw,se,sw,sw,nw,sw,nw,sw,sw,sw,sw,sw,nw,n,s,ne,ne,sw,sw,sw,nw,nw,sw,se,sw,nw,ne,nw,sw,s,nw,nw,sw,ne,nw,se,ne,sw,s,sw,nw,nw,s,nw,sw,sw,sw,sw,nw,nw,nw,nw,sw,sw,s,sw,nw,sw,ne,nw,sw,se,sw,nw,ne,nw,nw,nw,nw,nw,sw,nw,nw,nw,nw,sw,se,nw,ne,nw,nw,n,sw,sw,sw,se,sw,nw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,ne,ne,nw,ne,sw,sw,nw,n,se,sw,nw,nw,sw,sw,nw,nw,nw,sw,nw,nw,se,n,sw,sw,sw,sw,s,nw,sw,nw,n,sw,sw,sw,sw,n,sw,nw,se,nw,s,sw,nw,nw,nw,nw,s,nw,sw,sw,nw,sw,n,s,nw,s,nw,sw,s,nw,sw,s,n,nw,sw,nw,nw,nw,nw,s,sw,nw,nw,nw,sw,sw,ne,se,sw,sw,nw,nw,nw,nw,sw,sw,sw,nw,sw,n,nw,nw,nw,nw,sw,nw,nw,s,nw,nw,sw,sw,nw,nw,sw,nw,nw,nw,nw,nw,nw,se,nw,nw,s,nw,nw,s,nw,n,nw,nw,nw,n,n,nw,nw,nw,nw,nw,nw,nw,n,ne,nw,nw,nw,sw,nw,se,sw,nw,sw,nw,sw,n,nw,nw,sw,nw,nw,s,nw,nw,sw,sw,nw,nw,nw,nw,nw,s,sw,nw,se,nw,nw,nw,ne,se,nw,s,nw,sw,nw,sw,ne,nw,nw,sw,nw,sw,n,nw,nw,nw,s,s,nw,nw,nw,nw,nw,nw,nw,nw,nw,se,nw,s,nw,nw,nw,nw,nw,nw,nw,se,nw,nw,nw,nw,nw,nw,nw,se,sw,se,nw,nw,se,se,nw,n,nw,nw,se,nw,nw,n,nw,s,nw,nw,nw,sw,nw,nw,nw,nw,sw,nw,nw,nw,ne,nw,nw,nw,nw,nw,nw,nw,nw,se,nw,s,s,nw,nw,nw,nw,nw,nw,nw,nw,s,nw,ne,nw,nw,nw,se,nw,nw,ne,nw,nw,se,nw,se,nw,n,n,nw,ne,sw,nw,nw,nw,nw,nw,nw,nw,s,nw,nw,nw,nw,nw,nw,nw,se,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,ne,nw,nw,nw diff --git a/pytudes/data/advent2017/input12.txt b/pytudes/data/advent2017/input12.txt new file mode 100644 index 0000000..990a764 --- /dev/null +++ b/pytudes/data/advent2017/input12.txt @@ -0,0 +1,2000 @@ +0 <-> 659, 737 +1 <-> 1, 1433 +2 <-> 982, 1869 +3 <-> 306, 380, 1462, 1827 +4 <-> 1076 +5 <-> 794, 1451 +6 <-> 146, 1055 +7 <-> 834, 1557 +8 <-> 1333 +9 <-> 849, 906, 1863 +10 <-> 362, 505 +11 <-> 33, 938, 1896 +12 <-> 490, 913 +13 <-> 189, 690 +14 <-> 796 +15 <-> 56, 280, 1288, 1721 +16 <-> 16 +17 <-> 904 +18 <-> 150, 1394, 1458 +19 <-> 1773 +20 <-> 70 +21 <-> 993 +22 <-> 22 +23 <-> 285, 1004 +24 <-> 209, 727 +25 <-> 614, 1590 +26 <-> 113 +27 <-> 1321, 1341 +28 <-> 351, 730, 1037 +29 <-> 29, 1828 +30 <-> 1378, 1983 +31 <-> 705, 1035 +32 <-> 1042, 1519 +33 <-> 11, 886 +34 <-> 360, 1101, 1531, 1877 +35 <-> 971, 1652 +36 <-> 188 +37 <-> 1935 +38 <-> 38 +39 <-> 39, 1472 +40 <-> 84, 1110 +41 <-> 483, 895, 1035, 1864, 1919 +42 <-> 624, 813, 1484, 1517 +43 <-> 492 +44 <-> 947, 1572 +45 <-> 45, 1589, 1748, 1836 +46 <-> 1821 +47 <-> 123, 206, 239 +48 <-> 146 +49 <-> 235, 871 +50 <-> 172, 1672 +51 <-> 504 +52 <-> 585, 678, 878 +53 <-> 484, 543, 1282 +54 <-> 374, 723 +55 <-> 1956 +56 <-> 15 +57 <-> 583, 1159, 1596 +58 <-> 313, 580, 1101 +59 <-> 1529, 1788 +60 <-> 60 +61 <-> 1033, 1857 +62 <-> 874 +63 <-> 63, 1007, 1316, 1673 +64 <-> 1140 +65 <-> 1136 +66 <-> 1337, 1546 +67 <-> 67, 1468 +68 <-> 298, 951 +69 <-> 906 +70 <-> 20, 1977 +71 <-> 1956 +72 <-> 146, 1465 +73 <-> 911 +74 <-> 1345 +75 <-> 711 +76 <-> 732, 789, 1499, 1637 +77 <-> 1897 +78 <-> 78, 379 +79 <-> 96, 462, 847 +80 <-> 886, 907 +81 <-> 1564 +82 <-> 1362, 1680 +83 <-> 225, 916 +84 <-> 40, 1460 +85 <-> 330 +86 <-> 1370 +87 <-> 87, 640 +88 <-> 806, 1411 +89 <-> 1732 +90 <-> 603 +91 <-> 547, 904 +92 <-> 1106 +93 <-> 782 +94 <-> 401, 1039, 1148, 1356 +95 <-> 95, 344, 1092 +96 <-> 79 +97 <-> 1555, 1649 +98 <-> 133 +99 <-> 866 +100 <-> 116, 1183, 1450 +101 <-> 964 +102 <-> 521, 843 +103 <-> 1002 +104 <-> 675, 1752, 1760 +105 <-> 447 +106 <-> 625 +107 <-> 200, 923, 1573 +108 <-> 108, 1535 +109 <-> 1938, 1984 +110 <-> 992 +111 <-> 410, 436, 1789, 1985 +112 <-> 730, 1742 +113 <-> 26, 774, 1620 +114 <-> 891 +115 <-> 556, 980, 1502 +116 <-> 100, 405, 438 +117 <-> 1220, 1747 +118 <-> 417 +119 <-> 1671 +120 <-> 225 +121 <-> 215, 1414 +122 <-> 1421 +123 <-> 47, 488, 1390 +124 <-> 1750 +125 <-> 1020, 1456, 1645, 1811 +126 <-> 945, 988, 1558 +127 <-> 1562 +128 <-> 246, 419, 878, 1057 +129 <-> 198, 214, 526 +130 <-> 1572 +131 <-> 624 +132 <-> 1086 +133 <-> 98, 430, 1950 +134 <-> 1179 +135 <-> 1603 +136 <-> 136 +137 <-> 137, 248 +138 <-> 604 +139 <-> 1080, 1744, 1829 +140 <-> 786, 890, 1336 +141 <-> 819, 835 +142 <-> 142, 1657 +143 <-> 590, 670 +144 <-> 622 +145 <-> 182, 930, 1164, 1741 +146 <-> 6, 48, 72, 152 +147 <-> 1880 +148 <-> 1486 +149 <-> 1595 +150 <-> 18, 653 +151 <-> 1834 +152 <-> 146, 289, 1949 +153 <-> 1379 +154 <-> 694, 1025 +155 <-> 1143, 1469 +156 <-> 437, 1492, 1616 +157 <-> 1044 +158 <-> 410, 1391 +159 <-> 1327 +160 <-> 387, 892, 963, 1287 +161 <-> 964, 1017 +162 <-> 786, 1098, 1351, 1445, 1508 +163 <-> 415 +164 <-> 255, 790, 1410 +165 <-> 252, 425, 1186, 1662, 1838 +166 <-> 791, 1012 +167 <-> 167, 836, 1922 +168 <-> 1586, 1998 +169 <-> 679, 914 +170 <-> 1975 +171 <-> 672 +172 <-> 50 +173 <-> 614 +174 <-> 723 +175 <-> 246, 747 +176 <-> 400, 1338 +177 <-> 573, 1617, 1724 +178 <-> 473, 1572 +179 <-> 183 +180 <-> 200, 1380 +181 <-> 1394, 1657 +182 <-> 145, 1825 +183 <-> 179, 399, 955, 1236, 1295, 1840 +184 <-> 712 +185 <-> 185 +186 <-> 551, 1627 +187 <-> 1195 +188 <-> 36, 440, 1277, 1362 +189 <-> 13 +190 <-> 1111 +191 <-> 985, 1372 +192 <-> 496, 1137, 1283 +193 <-> 827, 1053 +194 <-> 610 +195 <-> 1231, 1497 +196 <-> 1960 +197 <-> 584, 1359 +198 <-> 129, 651, 714, 1663 +199 <-> 1047, 1805 +200 <-> 107, 180, 658, 1397 +201 <-> 1590 +202 <-> 1268, 1768 +203 <-> 1683 +204 <-> 567, 1848 +205 <-> 276 +206 <-> 47, 461, 1794 +207 <-> 207 +208 <-> 1248 +209 <-> 24, 1589 +210 <-> 1063, 1504 +211 <-> 907, 1815 +212 <-> 1948 +213 <-> 388 +214 <-> 129, 561, 793, 1569 +215 <-> 121, 252 +216 <-> 216, 1728 +217 <-> 761 +218 <-> 631, 816 +219 <-> 459, 807, 1008 +220 <-> 1231, 1447 +221 <-> 713, 1541 +222 <-> 856, 924, 1924 +223 <-> 1103 +224 <-> 1426, 1761 +225 <-> 83, 120, 242, 784 +226 <-> 311, 560 +227 <-> 587, 667, 984, 1091 +228 <-> 1852 +229 <-> 229, 1198, 1204 +230 <-> 1505, 1944 +231 <-> 1158, 1594, 1925 +232 <-> 232, 345, 1417 +233 <-> 828, 1677 +234 <-> 982 +235 <-> 49, 1012, 1254, 1956 +236 <-> 489, 893, 1545 +237 <-> 988, 1450 +238 <-> 1719, 1791 +239 <-> 47, 736, 1027 +240 <-> 1167, 1457 +241 <-> 270 +242 <-> 225, 814, 1873 +243 <-> 243, 282, 914 +244 <-> 302, 328, 559 +245 <-> 1753 +246 <-> 128, 175 +247 <-> 1230, 1660, 1824 +248 <-> 137, 537, 1423 +249 <-> 1209, 1391, 1749 +250 <-> 298 +251 <-> 799 +252 <-> 165, 215 +253 <-> 1437, 1741 +254 <-> 1356 +255 <-> 164 +256 <-> 310 +257 <-> 1267, 1821 +258 <-> 1177, 1876 +259 <-> 1257, 1432 +260 <-> 311, 1115 +261 <-> 1504 +262 <-> 1268 +263 <-> 565, 1023 +264 <-> 408, 1806 +265 <-> 1009, 1144 +266 <-> 599, 616 +267 <-> 1182 +268 <-> 1026, 1456, 1470, 1854 +269 <-> 269, 686 +270 <-> 241, 1445 +271 <-> 1232 +272 <-> 487, 863, 1286 +273 <-> 1614, 1748 +274 <-> 1332 +275 <-> 1010, 1334 +276 <-> 205, 478, 888, 1049 +277 <-> 277, 1330 +278 <-> 734, 1561 +279 <-> 535, 1190, 1913 +280 <-> 15 +281 <-> 1206 +282 <-> 243, 475, 1571 +283 <-> 283, 1936 +284 <-> 324, 702, 844, 1601 +285 <-> 23 +286 <-> 286, 1080, 1127 +287 <-> 295 +288 <-> 805 +289 <-> 152, 656, 691, 993 +290 <-> 595, 616, 1199 +291 <-> 1028, 1218, 1844 +292 <-> 1447 +293 <-> 378, 1771 +294 <-> 811, 1790 +295 <-> 287, 367, 693 +296 <-> 861, 1948, 1950 +297 <-> 1631 +298 <-> 68, 250, 641, 745 +299 <-> 299, 898, 1152, 1574 +300 <-> 353 +301 <-> 990, 1340, 1960 +302 <-> 244 +303 <-> 1645 +304 <-> 445, 448, 557, 1611 +305 <-> 1350, 1442 +306 <-> 3, 445 +307 <-> 567 +308 <-> 1799 +309 <-> 864 +310 <-> 256, 853, 1911 +311 <-> 226, 260, 970 +312 <-> 1308 +313 <-> 58 +314 <-> 1795 +315 <-> 1225, 1627, 1903 +316 <-> 1065, 1991 +317 <-> 317 +318 <-> 546, 1415 +319 <-> 1883 +320 <-> 417, 1040 +321 <-> 1927 +322 <-> 686 +323 <-> 1018, 1619 +324 <-> 284 +325 <-> 1114 +326 <-> 474, 872 +327 <-> 439 +328 <-> 244 +329 <-> 329 +330 <-> 85, 1868 +331 <-> 331, 680, 1224, 1243, 1291 +332 <-> 1748 +333 <-> 1673 +334 <-> 676, 1306 +335 <-> 809 +336 <-> 797, 1559, 1858 +337 <-> 978, 1874 +338 <-> 538, 1077 +339 <-> 432, 1033 +340 <-> 340 +341 <-> 1267, 1683 +342 <-> 587, 726 +343 <-> 1560, 1705 +344 <-> 95 +345 <-> 232, 1032 +346 <-> 581, 1992 +347 <-> 530 +348 <-> 667, 1479 +349 <-> 1620 +350 <-> 861, 998, 1069 +351 <-> 28 +352 <-> 352 +353 <-> 300, 1513 +354 <-> 1109, 1747 +355 <-> 950, 965, 1394, 1616 +356 <-> 1136 +357 <-> 1443, 1698 +358 <-> 973, 1814 +359 <-> 1662 +360 <-> 34, 921 +361 <-> 1418 +362 <-> 10, 668, 1656 +363 <-> 450, 766 +364 <-> 615, 1941 +365 <-> 1071 +366 <-> 749, 1375 +367 <-> 295, 1708, 1925 +368 <-> 383, 928 +369 <-> 369 +370 <-> 651, 1048 +371 <-> 665, 1460, 1686 +372 <-> 390, 958, 1682 +373 <-> 1559 +374 <-> 54, 1395, 1847 +375 <-> 799, 1061, 1383, 1773 +376 <-> 376 +377 <-> 1463 +378 <-> 293, 872, 917 +379 <-> 78, 449 +380 <-> 3, 1117 +381 <-> 1995 +382 <-> 846, 896, 1506, 1918 +383 <-> 368, 477 +384 <-> 1009, 1788 +385 <-> 1926 +386 <-> 1602 +387 <-> 160, 667 +388 <-> 213, 713 +389 <-> 586 +390 <-> 372, 1140 +391 <-> 863 +392 <-> 590, 1259, 1384 +393 <-> 645 +394 <-> 423, 1537 +395 <-> 782, 1496, 1893 +396 <-> 1497 +397 <-> 397 +398 <-> 847, 1265 +399 <-> 183, 743, 1564 +400 <-> 176 +401 <-> 94 +402 <-> 402 +403 <-> 558 +404 <-> 572 +405 <-> 116 +406 <-> 769, 1563 +407 <-> 1790 +408 <-> 264 +409 <-> 847 +410 <-> 111, 158, 1467, 1880, 1902 +411 <-> 1221 +412 <-> 858, 1088, 1848 +413 <-> 1589 +414 <-> 468, 637 +415 <-> 163, 415 +416 <-> 416, 817 +417 <-> 118, 320, 1671 +418 <-> 1029, 1987 +419 <-> 128, 765 +420 <-> 420, 1180 +421 <-> 1170, 1766 +422 <-> 563, 1400, 1904, 1926 +423 <-> 394 +424 <-> 730 +425 <-> 165, 478, 957 +426 <-> 1505 +427 <-> 1478, 1780 +428 <-> 1658 +429 <-> 650 +430 <-> 133 +431 <-> 469, 1491 +432 <-> 339 +433 <-> 667, 1549 +434 <-> 852 +435 <-> 435 +436 <-> 111 +437 <-> 156 +438 <-> 116, 874 +439 <-> 327, 1387 +440 <-> 188, 540 +441 <-> 441 +442 <-> 692 +443 <-> 1037, 1153 +444 <-> 758, 1064 +445 <-> 304, 306 +446 <-> 1072, 1495, 1890 +447 <-> 105, 1665 +448 <-> 304, 591 +449 <-> 379 +450 <-> 363, 450, 466 +451 <-> 1135 +452 <-> 990, 1344, 1604 +453 <-> 1390, 1755 +454 <-> 1853 +455 <-> 1199, 1735, 1852 +456 <-> 484 +457 <-> 457, 1973 +458 <-> 786 +459 <-> 219 +460 <-> 1655, 1777 +461 <-> 206, 753 +462 <-> 79, 668 +463 <-> 699 +464 <-> 1843 +465 <-> 829, 978, 1820 +466 <-> 450 +467 <-> 770, 1475 +468 <-> 414, 613, 1230 +469 <-> 431, 1470 +470 <-> 1292, 1659 +471 <-> 603 +472 <-> 719, 1398 +473 <-> 178, 1419 +474 <-> 326, 866 +475 <-> 282 +476 <-> 1512, 1669 +477 <-> 383 +478 <-> 276, 425 +479 <-> 1029 +480 <-> 603 +481 <-> 991, 1878 +482 <-> 1726, 1783 +483 <-> 41, 855 +484 <-> 53, 456 +485 <-> 1814 +486 <-> 1470 +487 <-> 272, 1693 +488 <-> 123 +489 <-> 236, 1155, 1793 +490 <-> 12, 1349, 1498 +491 <-> 913 +492 <-> 43, 1121, 1822 +493 <-> 1148 +494 <-> 619, 1528 +495 <-> 1960 +496 <-> 192 +497 <-> 497 +498 <-> 1185 +499 <-> 1933 +500 <-> 1948 +501 <-> 1364, 1433, 1826 +502 <-> 893, 933 +503 <-> 514 +504 <-> 51, 821, 1116 +505 <-> 10, 905 +506 <-> 506 +507 <-> 892 +508 <-> 508 +509 <-> 1078 +510 <-> 1716 +511 <-> 1197, 1900 +512 <-> 568, 1284, 1422 +513 <-> 1604, 1817, 1927 +514 <-> 503, 773, 1725, 1883 +515 <-> 1396 +516 <-> 542 +517 <-> 1299 +518 <-> 1562 +519 <-> 1622 +520 <-> 1254, 1868, 1881 +521 <-> 102, 1765 +522 <-> 1438, 1980 +523 <-> 1779 +524 <-> 1235, 1968 +525 <-> 1267, 1484 +526 <-> 129 +527 <-> 1211 +528 <-> 597, 1017 +529 <-> 529, 609 +530 <-> 347, 1737, 1890 +531 <-> 851, 1320 +532 <-> 709 +533 <-> 819, 1091 +534 <-> 856 +535 <-> 279, 535 +536 <-> 536 +537 <-> 248, 1317, 1763 +538 <-> 338, 1793 +539 <-> 539, 1485 +540 <-> 440, 1216 +541 <-> 541 +542 <-> 516, 1232, 1831 +543 <-> 53, 1234 +544 <-> 639, 1090 +545 <-> 1898 +546 <-> 318, 1208 +547 <-> 91 +548 <-> 569, 750, 1090 +549 <-> 1720 +550 <-> 660 +551 <-> 186 +552 <-> 642, 672, 723 +553 <-> 1927 +554 <-> 717, 1841, 1997 +555 <-> 1938 +556 <-> 115, 1453 +557 <-> 304, 904 +558 <-> 403, 1438 +559 <-> 244, 1046 +560 <-> 226 +561 <-> 214, 793, 1570 +562 <-> 1992 +563 <-> 422 +564 <-> 860 +565 <-> 263, 804 +566 <-> 566 +567 <-> 204, 307 +568 <-> 512, 1084 +569 <-> 548, 985, 1910 +570 <-> 665, 1844 +571 <-> 735 +572 <-> 404, 1026, 1111 +573 <-> 177, 1994 +574 <-> 846 +575 <-> 723, 738, 795, 802, 926, 1215 +576 <-> 1650, 1962, 1996 +577 <-> 1501, 1670 +578 <-> 1504 +579 <-> 1016, 1729 +580 <-> 58 +581 <-> 346, 581 +582 <-> 749 +583 <-> 57, 613, 1219, 1941 +584 <-> 197, 1366 +585 <-> 52, 1518 +586 <-> 389, 1597 +587 <-> 227, 342 +588 <-> 1408 +589 <-> 1229 +590 <-> 143, 392, 1044, 1078 +591 <-> 448, 1289 +592 <-> 592 +593 <-> 711 +594 <-> 770 +595 <-> 290, 1169 +596 <-> 1854 +597 <-> 528, 755, 1241, 1982 +598 <-> 663, 806 +599 <-> 266 +600 <-> 1065, 1694 +601 <-> 746 +602 <-> 827 +603 <-> 90, 471, 480, 1083 +604 <-> 138, 1003 +605 <-> 1703 +606 <-> 1289 +607 <-> 1309 +608 <-> 808, 1100 +609 <-> 529, 1621, 1943 +610 <-> 194, 610 +611 <-> 1337, 1609 +612 <-> 980, 1350 +613 <-> 468, 583 +614 <-> 25, 173, 1623, 1914 +615 <-> 364, 775 +616 <-> 266, 290 +617 <-> 1514 +618 <-> 1031 +619 <-> 494, 1761 +620 <-> 1126, 1150, 1221, 1513, 1712 +621 <-> 1770 +622 <-> 144, 1761 +623 <-> 1367 +624 <-> 42, 131 +625 <-> 106, 914 +626 <-> 1849 +627 <-> 1477 +628 <-> 1379 +629 <-> 969 +630 <-> 1114 +631 <-> 218, 1935, 1979 +632 <-> 1015, 1665, 1816, 1819 +633 <-> 1326, 1628 +634 <-> 1347, 1720 +635 <-> 816 +636 <-> 636 +637 <-> 414, 1566 +638 <-> 1668 +639 <-> 544, 824, 1542 +640 <-> 87 +641 <-> 298, 1196 +642 <-> 552, 1619 +643 <-> 972 +644 <-> 814 +645 <-> 393, 1148, 1205, 1302 +646 <-> 969 +647 <-> 935, 1575 +648 <-> 648, 1424 +649 <-> 1794 +650 <-> 429, 854, 1586, 1711 +651 <-> 198, 370 +652 <-> 996, 1996 +653 <-> 150, 1919 +654 <-> 654 +655 <-> 658 +656 <-> 289 +657 <-> 978, 1954 +658 <-> 200, 655 +659 <-> 0, 825, 1258, 1792 +660 <-> 550, 1232 +661 <-> 661, 1405 +662 <-> 662 +663 <-> 598 +664 <-> 1014 +665 <-> 371, 570, 1247 +666 <-> 989, 1778 +667 <-> 227, 348, 387, 433 +668 <-> 362, 462, 703, 1091 +669 <-> 1184 +670 <-> 143 +671 <-> 671, 901 +672 <-> 171, 552 +673 <-> 1865 +674 <-> 972, 1961 +675 <-> 104, 1581, 1800 +676 <-> 334, 1995 +677 <-> 1836 +678 <-> 52 +679 <-> 169 +680 <-> 331 +681 <-> 823 +682 <-> 921 +683 <-> 1800 +684 <-> 750, 1505 +685 <-> 722, 1338, 1993 +686 <-> 269, 322 +687 <-> 989, 1178 +688 <-> 1338 +689 <-> 1535 +690 <-> 13, 690 +691 <-> 289, 721 +692 <-> 442, 1014 +693 <-> 295 +694 <-> 154, 862 +695 <-> 1552, 1735 +696 <-> 1044 +697 <-> 993, 1793, 1801 +698 <-> 698 +699 <-> 463, 1022, 1399 +700 <-> 897, 1085 +701 <-> 1782, 1987 +702 <-> 284 +703 <-> 668, 1031 +704 <-> 704, 849 +705 <-> 31 +706 <-> 1909 +707 <-> 1276 +708 <-> 1301 +709 <-> 532, 1607 +710 <-> 1094 +711 <-> 75, 593, 1251, 1297 +712 <-> 184, 712 +713 <-> 221, 388, 713 +714 <-> 198 +715 <-> 1607 +716 <-> 1110 +717 <-> 554, 1819 +718 <-> 1755 +719 <-> 472, 1942 +720 <-> 1043, 1984 +721 <-> 691, 1641 +722 <-> 685, 1360, 1679 +723 <-> 54, 174, 552, 575 +724 <-> 1466 +725 <-> 1231 +726 <-> 342, 1023 +727 <-> 24 +728 <-> 1928 +729 <-> 975, 1759 +730 <-> 28, 112, 424, 1324 +731 <-> 731 +732 <-> 76, 1698 +733 <-> 1895 +734 <-> 278 +735 <-> 571, 1440 +736 <-> 239 +737 <-> 0, 1214, 1949 +738 <-> 575, 985 +739 <-> 1467 +740 <-> 740, 1449, 1885 +741 <-> 1243 +742 <-> 845, 1588, 1676, 1956, 1980 +743 <-> 399 +744 <-> 744, 1990 +745 <-> 298, 1966 +746 <-> 601, 1294, 1601 +747 <-> 175, 1106 +748 <-> 1433, 1565, 1795 +749 <-> 366, 582 +750 <-> 548, 684, 1210 +751 <-> 751, 1967 +752 <-> 765, 1297 +753 <-> 461 +754 <-> 754 +755 <-> 597, 1089 +756 <-> 756 +757 <-> 1350, 1936 +758 <-> 444, 1044, 1279 +759 <-> 996, 1310 +760 <-> 1943 +761 <-> 217, 1333 +762 <-> 1671 +763 <-> 1761 +764 <-> 1881 +765 <-> 419, 752 +766 <-> 363, 928, 1100 +767 <-> 1220, 1986 +768 <-> 1337 +769 <-> 406, 1307 +770 <-> 467, 594, 1707 +771 <-> 1624, 1782 +772 <-> 1230 +773 <-> 514, 1266, 1305 +774 <-> 113, 1198 +775 <-> 615, 1753 +776 <-> 1307 +777 <-> 1785 +778 <-> 778, 1776 +779 <-> 992 +780 <-> 1406 +781 <-> 781, 1272 +782 <-> 93, 395, 1207 +783 <-> 1544, 1729 +784 <-> 225, 1168, 1587 +785 <-> 1050 +786 <-> 140, 162, 458, 786, 1060 +787 <-> 1210 +788 <-> 1431 +789 <-> 76 +790 <-> 164, 882 +791 <-> 166, 1688 +792 <-> 792, 946 +793 <-> 214, 561 +794 <-> 5, 1561 +795 <-> 575, 1208, 1875 +796 <-> 14, 1205, 1427 +797 <-> 336, 1006, 1352 +798 <-> 1176, 1754 +799 <-> 251, 375 +800 <-> 840, 1471 +801 <-> 801, 1246, 1897 +802 <-> 575 +803 <-> 1692 +804 <-> 565, 859, 1978 +805 <-> 288, 1447 +806 <-> 88, 598 +807 <-> 219, 1579 +808 <-> 608 +809 <-> 335, 867, 1734, 1843 +810 <-> 1279 +811 <-> 294, 1043, 1560, 1583, 1600 +812 <-> 1487, 1527 +813 <-> 42, 1405 +814 <-> 242, 644, 1175, 1638 +815 <-> 1050, 1177 +816 <-> 218, 635, 1427 +817 <-> 416 +818 <-> 1765, 1999 +819 <-> 141, 533 +820 <-> 1238, 1393 +821 <-> 504, 1755 +822 <-> 1320, 1397 +823 <-> 681, 1120, 1798 +824 <-> 639 +825 <-> 659 +826 <-> 1722, 1834 +827 <-> 193, 602, 968 +828 <-> 233, 1835 +829 <-> 465 +830 <-> 951 +831 <-> 1606 +832 <-> 1619, 1964 +833 <-> 1109 +834 <-> 7, 962, 1869 +835 <-> 141 +836 <-> 167, 875, 1145 +837 <-> 1752 +838 <-> 838, 1146 +839 <-> 1247 +840 <-> 800 +841 <-> 1337 +842 <-> 1438, 1466 +843 <-> 102 +844 <-> 284 +845 <-> 742 +846 <-> 382, 574 +847 <-> 79, 398, 409 +848 <-> 959 +849 <-> 9, 704 +850 <-> 915, 1455, 1911, 1987 +851 <-> 531, 1001 +852 <-> 434, 1172 +853 <-> 310, 1533 +854 <-> 650 +855 <-> 483, 868, 1598 +856 <-> 222, 534, 1133 +857 <-> 857, 1249, 1923 +858 <-> 412, 1540, 1575, 1607 +859 <-> 804, 1655 +860 <-> 564, 1243 +861 <-> 296, 350, 1130, 1521 +862 <-> 694 +863 <-> 272, 391, 1558 +864 <-> 309, 1071, 1227 +865 <-> 1537, 1669, 1825 +866 <-> 99, 474 +867 <-> 809, 867, 1004 +868 <-> 855, 1539 +869 <-> 1550 +870 <-> 1885 +871 <-> 49 +872 <-> 326, 378, 1552 +873 <-> 1307 +874 <-> 62, 438 +875 <-> 836, 1056, 1326 +876 <-> 876 +877 <-> 1933 +878 <-> 52, 128, 1527 +879 <-> 879 +880 <-> 1292, 1561, 1770 +881 <-> 881, 981 +882 <-> 790, 882, 932 +883 <-> 1322, 1963 +884 <-> 1842 +885 <-> 885 +886 <-> 33, 80, 1765, 1959 +887 <-> 1012 +888 <-> 276 +889 <-> 1391 +890 <-> 140 +891 <-> 114, 891 +892 <-> 160, 507 +893 <-> 236, 502, 1602 +894 <-> 1525 +895 <-> 41 +896 <-> 382 +897 <-> 700 +898 <-> 299 +899 <-> 1797 +900 <-> 1736 +901 <-> 671, 944, 1147 +902 <-> 1597, 1940 +903 <-> 1283 +904 <-> 17, 91, 557, 1169, 1764 +905 <-> 505 +906 <-> 9, 69, 942 +907 <-> 80, 211, 1348 +908 <-> 1398 +909 <-> 909 +910 <-> 1683 +911 <-> 73, 911 +912 <-> 1929 +913 <-> 12, 491, 1591 +914 <-> 169, 243, 625, 1867 +915 <-> 850, 1538 +916 <-> 83 +917 <-> 378 +918 <-> 1438 +919 <-> 1951 +920 <-> 1814 +921 <-> 360, 682, 1952 +922 <-> 922 +923 <-> 107, 1161, 1254 +924 <-> 222 +925 <-> 1691 +926 <-> 575 +927 <-> 1165, 1270 +928 <-> 368, 766 +929 <-> 1707, 1914 +930 <-> 145, 1096, 1434, 1791 +931 <-> 931, 1983 +932 <-> 882 +933 <-> 502, 1921 +934 <-> 1297 +935 <-> 647, 1319 +936 <-> 1255 +937 <-> 1210 +938 <-> 11 +939 <-> 1348, 1666 +940 <-> 1408 +941 <-> 1440 +942 <-> 906 +943 <-> 1977 +944 <-> 901 +945 <-> 126 +946 <-> 792 +947 <-> 44, 1400 +948 <-> 948, 1045 +949 <-> 967 +950 <-> 355 +951 <-> 68, 830, 969 +952 <-> 1225, 1757, 1929 +953 <-> 1534, 1726 +954 <-> 1511, 1888 +955 <-> 183, 1418 +956 <-> 1702 +957 <-> 425 +958 <-> 372 +959 <-> 848, 1512 +960 <-> 1868 +961 <-> 1509 +962 <-> 834, 1678 +963 <-> 160 +964 <-> 101, 161 +965 <-> 355 +966 <-> 1740, 1866 +967 <-> 949, 1802 +968 <-> 827, 1534 +969 <-> 629, 646, 951 +970 <-> 311 +971 <-> 35, 1670 +972 <-> 643, 674, 1449 +973 <-> 358 +974 <-> 974 +975 <-> 729, 1955 +976 <-> 1495 +977 <-> 1603, 1889 +978 <-> 337, 465, 657, 1615, 1953 +979 <-> 1801 +980 <-> 115, 612, 1239 +981 <-> 881 +982 <-> 2, 234, 1411, 1511 +983 <-> 1970 +984 <-> 227, 984 +985 <-> 191, 569, 738 +986 <-> 1926 +987 <-> 987 +988 <-> 126, 237, 1894 +989 <-> 666, 687, 1079 +990 <-> 301, 452, 1903 +991 <-> 481, 1435 +992 <-> 110, 779, 1637 +993 <-> 21, 289, 697, 1675 +994 <-> 1151, 1639 +995 <-> 1090, 1798 +996 <-> 652, 759, 1229 +997 <-> 1253, 1380, 1553 +998 <-> 350, 1812 +999 <-> 1128 +1000 <-> 1566 +1001 <-> 851 +1002 <-> 103, 1229 +1003 <-> 604, 1156, 1232, 1420 +1004 <-> 23, 867 +1005 <-> 1085, 1174, 1899 +1006 <-> 797 +1007 <-> 63, 1282 +1008 <-> 219, 1008, 1977 +1009 <-> 265, 384, 1731 +1010 <-> 275, 1438, 1474 +1011 <-> 1289 +1012 <-> 166, 235, 887, 1342, 1471 +1013 <-> 1013, 1886 +1014 <-> 664, 692, 1229 +1015 <-> 632, 1015 +1016 <-> 579 +1017 <-> 161, 528 +1018 <-> 323 +1019 <-> 1684 +1020 <-> 125 +1021 <-> 1036, 1450 +1022 <-> 699, 1600, 1962 +1023 <-> 263, 726 +1024 <-> 1295 +1025 <-> 154, 1025 +1026 <-> 268, 572, 1610 +1027 <-> 239, 1269 +1028 <-> 291, 1275 +1029 <-> 418, 479, 1957 +1030 <-> 1184 +1031 <-> 618, 703 +1032 <-> 345 +1033 <-> 61, 339, 1033 +1034 <-> 1166, 1291 +1035 <-> 31, 41 +1036 <-> 1021, 1228 +1037 <-> 28, 443, 1227 +1038 <-> 1178 +1039 <-> 94, 1578 +1040 <-> 320, 1992 +1041 <-> 1041 +1042 <-> 32, 1486 +1043 <-> 720, 811 +1044 <-> 157, 590, 696, 758, 1433, 1739 +1045 <-> 948 +1046 <-> 559, 1241 +1047 <-> 199, 1962 +1048 <-> 370 +1049 <-> 276, 1885 +1050 <-> 785, 815 +1051 <-> 1051, 1290 +1052 <-> 1165 +1053 <-> 193, 1446, 1488 +1054 <-> 1081 +1055 <-> 6 +1056 <-> 875 +1057 <-> 128, 1137 +1058 <-> 1112, 1173 +1059 <-> 1226, 1538 +1060 <-> 786 +1061 <-> 375, 1639, 1988 +1062 <-> 1748 +1063 <-> 210, 1692 +1064 <-> 444 +1065 <-> 316, 600, 1689 +1066 <-> 1709 +1067 <-> 1067 +1068 <-> 1068 +1069 <-> 350 +1070 <-> 1196 +1071 <-> 365, 864, 1827 +1072 <-> 446, 1142 +1073 <-> 1931 +1074 <-> 1529 +1075 <-> 1075 +1076 <-> 4, 1717, 1879, 1969 +1077 <-> 338 +1078 <-> 509, 590 +1079 <-> 989, 1282 +1080 <-> 139, 286 +1081 <-> 1054, 1992 +1082 <-> 1115, 1451, 1704 +1083 <-> 603, 1271 +1084 <-> 568, 1233 +1085 <-> 700, 1005, 1939 +1086 <-> 132, 1745, 1901 +1087 <-> 1519 +1088 <-> 412 +1089 <-> 755 +1090 <-> 544, 548, 995, 1768 +1091 <-> 227, 533, 668, 1141 +1092 <-> 95 +1093 <-> 1271, 1946 +1094 <-> 710, 1102 +1095 <-> 1546 +1096 <-> 930 +1097 <-> 1288 +1098 <-> 162, 1933 +1099 <-> 1456 +1100 <-> 608, 766 +1101 <-> 34, 58, 1108 +1102 <-> 1094, 1938 +1103 <-> 223, 1117 +1104 <-> 1457, 1605, 1654 +1105 <-> 1105 +1106 <-> 92, 747 +1107 <-> 1699 +1108 <-> 1101, 1201 +1109 <-> 354, 833, 1285, 1874 +1110 <-> 40, 716 +1111 <-> 190, 572, 1440 +1112 <-> 1058, 1193 +1113 <-> 1113 +1114 <-> 325, 630, 1853 +1115 <-> 260, 1082 +1116 <-> 504 +1117 <-> 380, 1103 +1118 <-> 1118 +1119 <-> 1353, 1871 +1120 <-> 823 +1121 <-> 492, 1196 +1122 <-> 1122 +1123 <-> 1725 +1124 <-> 1892 +1125 <-> 1344 +1126 <-> 620 +1127 <-> 286, 1138 +1128 <-> 999, 1268 +1129 <-> 1129 +1130 <-> 861 +1131 <-> 1874 +1132 <-> 1913 +1133 <-> 856 +1134 <-> 1185, 1767 +1135 <-> 451, 1975 +1136 <-> 65, 356, 1487 +1137 <-> 192, 1057 +1138 <-> 1127, 1782 +1139 <-> 1240 +1140 <-> 64, 390, 1385 +1141 <-> 1091 +1142 <-> 1072, 1587 +1143 <-> 155, 1143 +1144 <-> 265 +1145 <-> 836, 1401 +1146 <-> 838 +1147 <-> 901, 1483 +1148 <-> 94, 493, 645, 1167 +1149 <-> 1818 +1150 <-> 620, 1237, 1264 +1151 <-> 994, 1844 +1152 <-> 299, 1167 +1153 <-> 443, 1947 +1154 <-> 1803 +1155 <-> 489, 1163 +1156 <-> 1003, 1635, 1668 +1157 <-> 1340, 1809 +1158 <-> 231 +1159 <-> 57 +1160 <-> 1558 +1161 <-> 923 +1162 <-> 1590 +1163 <-> 1155 +1164 <-> 145, 1164, 1283 +1165 <-> 927, 1052, 1678, 1934 +1166 <-> 1034 +1167 <-> 240, 1148, 1152, 1462 +1168 <-> 784 +1169 <-> 595, 904 +1170 <-> 421 +1171 <-> 1667 +1172 <-> 852, 1195, 1323, 1444 +1173 <-> 1058, 1389 +1174 <-> 1005 +1175 <-> 814 +1176 <-> 798 +1177 <-> 258, 815, 1401 +1178 <-> 687, 1038, 1331 +1179 <-> 134, 1179 +1180 <-> 420 +1181 <-> 1181 +1182 <-> 267, 1677 +1183 <-> 100 +1184 <-> 669, 1030, 1969 +1185 <-> 498, 1134, 1673, 1750 +1186 <-> 165 +1187 <-> 1893 +1188 <-> 1236, 1365 +1189 <-> 1334, 1732 +1190 <-> 279 +1191 <-> 1620 +1192 <-> 1257 +1193 <-> 1112 +1194 <-> 1770 +1195 <-> 187, 1172, 1964 +1196 <-> 641, 1070, 1121, 1729 +1197 <-> 511, 1273, 1607 +1198 <-> 229, 774 +1199 <-> 290, 455, 1860 +1200 <-> 1901 +1201 <-> 1108 +1202 <-> 1378 +1203 <-> 1591 +1204 <-> 229 +1205 <-> 645, 796, 1250 +1206 <-> 281, 1824 +1207 <-> 782 +1208 <-> 546, 795, 1700 +1209 <-> 249 +1210 <-> 750, 787, 937 +1211 <-> 527, 1981 +1212 <-> 1212, 1369 +1213 <-> 1512 +1214 <-> 737 +1215 <-> 575 +1216 <-> 540, 1216 +1217 <-> 1312, 1340 +1218 <-> 291, 1586 +1219 <-> 583, 1554 +1220 <-> 117, 767 +1221 <-> 411, 620, 1221 +1222 <-> 1612, 1710 +1223 <-> 1223, 1374 +1224 <-> 331 +1225 <-> 315, 952, 1263 +1226 <-> 1059, 1928 +1227 <-> 864, 1037, 1823 +1228 <-> 1036, 1613 +1229 <-> 589, 996, 1002, 1014, 1906 +1230 <-> 247, 468, 772, 1821, 1837 +1231 <-> 195, 220, 725 +1232 <-> 271, 542, 660, 1003, 1232, 1606 +1233 <-> 1084, 1366, 1738 +1234 <-> 543, 1408 +1235 <-> 524 +1236 <-> 183, 1188 +1237 <-> 1150 +1238 <-> 820, 1521 +1239 <-> 980 +1240 <-> 1139, 1240 +1241 <-> 597, 1046 +1242 <-> 1646 +1243 <-> 331, 741, 860 +1244 <-> 1522, 1870 +1245 <-> 1245 +1246 <-> 801 +1247 <-> 665, 839 +1248 <-> 208, 1932 +1249 <-> 857 +1250 <-> 1205 +1251 <-> 711 +1252 <-> 1888 +1253 <-> 997, 1593 +1254 <-> 235, 520, 923, 1382 +1255 <-> 936 +1256 <-> 1718 +1257 <-> 259, 1192 +1258 <-> 659, 1917 +1259 <-> 392 +1260 <-> 1260 +1261 <-> 1261, 1376 +1262 <-> 1936 +1263 <-> 1225 +1264 <-> 1150, 1567 +1265 <-> 398 +1266 <-> 773, 1373 +1267 <-> 257, 341, 525 +1268 <-> 202, 262, 1128 +1269 <-> 1027 +1270 <-> 927 +1271 <-> 1083, 1093 +1272 <-> 781 +1273 <-> 1197 +1274 <-> 1760 +1275 <-> 1028, 1827 +1276 <-> 707, 1900 +1277 <-> 188 +1278 <-> 1463 +1279 <-> 758, 810 +1280 <-> 1920 +1281 <-> 1942 +1282 <-> 53, 1007, 1079 +1283 <-> 192, 903, 1164, 1690 +1284 <-> 512, 1584 +1285 <-> 1109, 1285 +1286 <-> 272 +1287 <-> 160 +1288 <-> 15, 1097, 1905 +1289 <-> 591, 606, 1011 +1290 <-> 1051 +1291 <-> 331, 1034 +1292 <-> 470, 880 +1293 <-> 1501, 1899 +1294 <-> 746, 1294 +1295 <-> 183, 1024 +1296 <-> 1580 +1297 <-> 711, 752, 934 +1298 <-> 1298 +1299 <-> 517, 1299 +1300 <-> 1300 +1301 <-> 708, 1301 +1302 <-> 645 +1303 <-> 1355, 1492 +1304 <-> 1361, 1746 +1305 <-> 773 +1306 <-> 334, 1325 +1307 <-> 769, 776, 873, 1333 +1308 <-> 312, 1851, 1966 +1309 <-> 607, 1459, 1496 +1310 <-> 759 +1311 <-> 1381, 1520 +1312 <-> 1217 +1313 <-> 1983 +1314 <-> 1314 +1315 <-> 1315, 1647 +1316 <-> 63 +1317 <-> 537 +1318 <-> 1973 +1319 <-> 935, 1517 +1320 <-> 531, 822 +1321 <-> 27, 1837 +1322 <-> 883, 1664 +1323 <-> 1172 +1324 <-> 730 +1325 <-> 1306 +1326 <-> 633, 875 +1327 <-> 159, 1553 +1328 <-> 1974 +1329 <-> 1939 +1330 <-> 277, 1515 +1331 <-> 1178, 1590 +1332 <-> 274, 1332 +1333 <-> 8, 761, 1307, 1333 +1334 <-> 275, 1189, 1482 +1335 <-> 1478 +1336 <-> 140 +1337 <-> 66, 611, 768, 841 +1338 <-> 176, 685, 688, 1449 +1339 <-> 1339 +1340 <-> 301, 1157, 1217, 1630 +1341 <-> 27 +1342 <-> 1012 +1343 <-> 1408 +1344 <-> 452, 1125, 1622 +1345 <-> 74, 1835 +1346 <-> 1860 +1347 <-> 634, 1428 +1348 <-> 907, 939 +1349 <-> 490, 1349 +1350 <-> 305, 612, 757 +1351 <-> 162 +1352 <-> 797, 1818 +1353 <-> 1119, 1353 +1354 <-> 1436 +1355 <-> 1303 +1356 <-> 94, 254 +1357 <-> 1419, 1664, 1680 +1358 <-> 1358 +1359 <-> 197 +1360 <-> 722, 1909 +1361 <-> 1304 +1362 <-> 82, 188, 1448 +1363 <-> 1752 +1364 <-> 501 +1365 <-> 1188, 1661 +1366 <-> 584, 1233 +1367 <-> 623, 1394, 1781 +1368 <-> 1886 +1369 <-> 1212 +1370 <-> 86, 1370 +1371 <-> 1772 +1372 <-> 191, 1473 +1373 <-> 1266 +1374 <-> 1223, 1981 +1375 <-> 366, 1375 +1376 <-> 1261, 1599 +1377 <-> 1675 +1378 <-> 30, 1202, 1406, 1845 +1379 <-> 153, 628, 1557 +1380 <-> 180, 997 +1381 <-> 1311, 1407, 1666 +1382 <-> 1254 +1383 <-> 375, 1714 +1384 <-> 392 +1385 <-> 1140, 1933 +1386 <-> 1949 +1387 <-> 439, 1387 +1388 <-> 1770 +1389 <-> 1173, 1679 +1390 <-> 123, 453, 1733 +1391 <-> 158, 249, 889, 1945 +1392 <-> 1881 +1393 <-> 820 +1394 <-> 18, 181, 355, 1367 +1395 <-> 374, 1404 +1396 <-> 515, 1860 +1397 <-> 200, 822 +1398 <-> 472, 908, 1622, 1701 +1399 <-> 699 +1400 <-> 422, 947, 1551 +1401 <-> 1145, 1177 +1402 <-> 1764 +1403 <-> 1875 +1404 <-> 1395 +1405 <-> 661, 813 +1406 <-> 780, 1378 +1407 <-> 1381 +1408 <-> 588, 940, 1234, 1343, 1603, 1865 +1409 <-> 1427 +1410 <-> 164 +1411 <-> 88, 982 +1412 <-> 1452 +1413 <-> 1707, 1766 +1414 <-> 121 +1415 <-> 318, 1415, 1612 +1416 <-> 1416 +1417 <-> 232 +1418 <-> 361, 955, 1418, 1737 +1419 <-> 473, 1357 +1420 <-> 1003 +1421 <-> 122, 1973 +1422 <-> 512, 1870 +1423 <-> 248 +1424 <-> 648 +1425 <-> 1425 +1426 <-> 224, 1946 +1427 <-> 796, 816, 1409 +1428 <-> 1347 +1429 <-> 1810, 1862 +1430 <-> 1430 +1431 <-> 788, 1488 +1432 <-> 259, 1432 +1433 <-> 1, 501, 748, 1044 +1434 <-> 930 +1435 <-> 991 +1436 <-> 1354, 1436 +1437 <-> 253 +1438 <-> 522, 558, 842, 918, 1010 +1439 <-> 1649 +1440 <-> 735, 941, 1111 +1441 <-> 1707 +1442 <-> 305, 1930 +1443 <-> 357 +1444 <-> 1172 +1445 <-> 162, 270, 1636 +1446 <-> 1053 +1447 <-> 220, 292, 805 +1448 <-> 1362 +1449 <-> 740, 972, 1338 +1450 <-> 100, 237, 1021 +1451 <-> 5, 1082 +1452 <-> 1412, 1572 +1453 <-> 556 +1454 <-> 1454 +1455 <-> 850 +1456 <-> 125, 268, 1099 +1457 <-> 240, 1104 +1458 <-> 18, 1576 +1459 <-> 1309, 1503 +1460 <-> 84, 371 +1461 <-> 1747, 1879 +1462 <-> 3, 1167, 1807 +1463 <-> 377, 1278, 1499, 1971 +1464 <-> 1908 +1465 <-> 72 +1466 <-> 724, 842 +1467 <-> 410, 739 +1468 <-> 67 +1469 <-> 155, 1652 +1470 <-> 268, 469, 486 +1471 <-> 800, 1012, 1471, 1510 +1472 <-> 39 +1473 <-> 1372 +1474 <-> 1010, 1915 +1475 <-> 467, 1658 +1476 <-> 1476 +1477 <-> 627, 1477 +1478 <-> 427, 1335, 1907 +1479 <-> 348 +1480 <-> 1480 +1481 <-> 1802 +1482 <-> 1334 +1483 <-> 1147, 1524 +1484 <-> 42, 525 +1485 <-> 539 +1486 <-> 148, 1042, 1549 +1487 <-> 812, 1136 +1488 <-> 1053, 1431 +1489 <-> 1708, 1931 +1490 <-> 1807 +1491 <-> 431 +1492 <-> 156, 1303 +1493 <-> 1493 +1494 <-> 1853 +1495 <-> 446, 976 +1496 <-> 395, 1309 +1497 <-> 195, 396, 1974 +1498 <-> 490, 1626 +1499 <-> 76, 1463 +1500 <-> 1722 +1501 <-> 577, 1293 +1502 <-> 115 +1503 <-> 1459, 1507 +1504 <-> 210, 261, 578, 1521, 1718 +1505 <-> 230, 426, 684, 1634 +1506 <-> 382, 1921 +1507 <-> 1503 +1508 <-> 162, 1667 +1509 <-> 961, 1509 +1510 <-> 1471 +1511 <-> 954, 982, 1582 +1512 <-> 476, 959, 1213, 1703 +1513 <-> 353, 620 +1514 <-> 617, 1546 +1515 <-> 1330, 1595 +1516 <-> 1946 +1517 <-> 42, 1319 +1518 <-> 585 +1519 <-> 32, 1087 +1520 <-> 1311 +1521 <-> 861, 1238, 1504 +1522 <-> 1244, 1653 +1523 <-> 1523 +1524 <-> 1483 +1525 <-> 894, 1525 +1526 <-> 1924 +1527 <-> 812, 878 +1528 <-> 494 +1529 <-> 59, 1074 +1530 <-> 1530 +1531 <-> 34, 1531 +1532 <-> 1638 +1533 <-> 853 +1534 <-> 953, 968 +1535 <-> 108, 689 +1536 <-> 1589 +1537 <-> 394, 865 +1538 <-> 915, 1059 +1539 <-> 868 +1540 <-> 858, 1745 +1541 <-> 221 +1542 <-> 639 +1543 <-> 1746 +1544 <-> 783, 1544 +1545 <-> 236 +1546 <-> 66, 1095, 1514 +1547 <-> 1628 +1548 <-> 1548 +1549 <-> 433, 1486 +1550 <-> 869, 1550 +1551 <-> 1400, 1787 +1552 <-> 695, 872 +1553 <-> 997, 1327 +1554 <-> 1219 +1555 <-> 97 +1556 <-> 1840 +1557 <-> 7, 1379 +1558 <-> 126, 863, 1160 +1559 <-> 336, 373 +1560 <-> 343, 811 +1561 <-> 278, 794, 880, 1561 +1562 <-> 127, 518, 1562 +1563 <-> 406 +1564 <-> 81, 399 +1565 <-> 748 +1566 <-> 637, 1000 +1567 <-> 1264 +1568 <-> 1568 +1569 <-> 214 +1570 <-> 561, 1849 +1571 <-> 282 +1572 <-> 44, 130, 178, 1452 +1573 <-> 107 +1574 <-> 299 +1575 <-> 647, 858 +1576 <-> 1458, 1633 +1577 <-> 1833, 1939 +1578 <-> 1039, 1802 +1579 <-> 807, 1853 +1580 <-> 1296, 1580, 1907 +1581 <-> 675 +1582 <-> 1511, 1605, 1756 +1583 <-> 811 +1584 <-> 1284 +1585 <-> 1817 +1586 <-> 168, 650, 1218 +1587 <-> 784, 1142 +1588 <-> 742 +1589 <-> 45, 209, 413, 1536 +1590 <-> 25, 201, 1162, 1331 +1591 <-> 913, 1203 +1592 <-> 1820 +1593 <-> 1253 +1594 <-> 231 +1595 <-> 149, 1515 +1596 <-> 57, 1976 +1597 <-> 586, 902 +1598 <-> 855 +1599 <-> 1376 +1600 <-> 811, 1022 +1601 <-> 284, 746 +1602 <-> 386, 893 +1603 <-> 135, 977, 1408 +1604 <-> 452, 513 +1605 <-> 1104, 1582 +1606 <-> 831, 1232 +1607 <-> 709, 715, 858, 1197 +1608 <-> 1793 +1609 <-> 611, 1808 +1610 <-> 1026, 1964 +1611 <-> 304 +1612 <-> 1222, 1415, 1769 +1613 <-> 1228, 1847 +1614 <-> 273 +1615 <-> 978 +1616 <-> 156, 355 +1617 <-> 177 +1618 <-> 1618 +1619 <-> 323, 642, 832 +1620 <-> 113, 349, 1191, 1746 +1621 <-> 609 +1622 <-> 519, 1344, 1398 +1623 <-> 614 +1624 <-> 771, 1989 +1625 <-> 1625 +1626 <-> 1498 +1627 <-> 186, 315 +1628 <-> 633, 1547 +1629 <-> 1706 +1630 <-> 1340 +1631 <-> 297, 1800 +1632 <-> 1806 +1633 <-> 1576 +1634 <-> 1505 +1635 <-> 1156 +1636 <-> 1445 +1637 <-> 76, 992, 1920, 1995 +1638 <-> 814, 1532 +1639 <-> 994, 1061 +1640 <-> 1640 +1641 <-> 721 +1642 <-> 1739, 1945 +1643 <-> 1643 +1644 <-> 1644, 1908 +1645 <-> 125, 303 +1646 <-> 1242, 1646 +1647 <-> 1315 +1648 <-> 1957 +1649 <-> 97, 1439, 1783 +1650 <-> 576 +1651 <-> 1651 +1652 <-> 35, 1469 +1653 <-> 1522 +1654 <-> 1104 +1655 <-> 460, 859 +1656 <-> 362 +1657 <-> 142, 181 +1658 <-> 428, 1475 +1659 <-> 470 +1660 <-> 247 +1661 <-> 1365 +1662 <-> 165, 359 +1663 <-> 198 +1664 <-> 1322, 1357 +1665 <-> 447, 632 +1666 <-> 939, 1381 +1667 <-> 1171, 1508 +1668 <-> 638, 1156 +1669 <-> 476, 865, 1699 +1670 <-> 577, 971 +1671 <-> 119, 417, 762, 1804 +1672 <-> 50, 1672, 1687 +1673 <-> 63, 333, 1185 +1674 <-> 1674 +1675 <-> 993, 1377 +1676 <-> 742, 1813 +1677 <-> 233, 1182, 1846 +1678 <-> 962, 1165 +1679 <-> 722, 1389 +1680 <-> 82, 1357 +1681 <-> 1681, 1702, 1895 +1682 <-> 372 +1683 <-> 203, 341, 910 +1684 <-> 1019, 1948 +1685 <-> 1982 +1686 <-> 371 +1687 <-> 1672 +1688 <-> 791 +1689 <-> 1065, 1689 +1690 <-> 1283 +1691 <-> 925, 1878 +1692 <-> 803, 1063, 1732 +1693 <-> 487 +1694 <-> 600 +1695 <-> 1695, 1794 +1696 <-> 1696 +1697 <-> 1802 +1698 <-> 357, 732 +1699 <-> 1107, 1669 +1700 <-> 1208 +1701 <-> 1398 +1702 <-> 956, 1681 +1703 <-> 605, 1512 +1704 <-> 1082 +1705 <-> 343 +1706 <-> 1629, 1775 +1707 <-> 770, 929, 1413, 1441 +1708 <-> 367, 1489 +1709 <-> 1066, 1862 +1710 <-> 1222 +1711 <-> 650 +1712 <-> 620 +1713 <-> 1713 +1714 <-> 1383 +1715 <-> 1911 +1716 <-> 510, 1716 +1717 <-> 1076 +1718 <-> 1256, 1504 +1719 <-> 238 +1720 <-> 549, 634, 1720 +1721 <-> 15 +1722 <-> 826, 1500 +1723 <-> 1880 +1724 <-> 177, 1724 +1725 <-> 514, 1123, 1797 +1726 <-> 482, 953 +1727 <-> 1914 +1728 <-> 216, 1982 +1729 <-> 579, 783, 1196, 1800 +1730 <-> 1730, 1972 +1731 <-> 1009 +1732 <-> 89, 1189, 1692 +1733 <-> 1390 +1734 <-> 809 +1735 <-> 455, 695 +1736 <-> 900, 1736 +1737 <-> 530, 1418 +1738 <-> 1233, 1888 +1739 <-> 1044, 1642, 1834 +1740 <-> 966 +1741 <-> 145, 253 +1742 <-> 112 +1743 <-> 1980 +1744 <-> 139 +1745 <-> 1086, 1540 +1746 <-> 1304, 1543, 1620 +1747 <-> 117, 354, 1461 +1748 <-> 45, 273, 332, 1062 +1749 <-> 249 +1750 <-> 124, 1185 +1751 <-> 1835 +1752 <-> 104, 837, 1363 +1753 <-> 245, 775 +1754 <-> 798, 1876 +1755 <-> 453, 718, 821 +1756 <-> 1582 +1757 <-> 952, 1772, 1841 +1758 <-> 1758, 1830, 1878 +1759 <-> 729 +1760 <-> 104, 1274 +1761 <-> 224, 619, 622, 763, 1868 +1762 <-> 1762 +1763 <-> 537 +1764 <-> 904, 1402 +1765 <-> 521, 818, 886, 1782 +1766 <-> 421, 1413 +1767 <-> 1134 +1768 <-> 202, 1090 +1769 <-> 1612 +1770 <-> 621, 880, 1194, 1388 +1771 <-> 293 +1772 <-> 1371, 1757 +1773 <-> 19, 375 +1774 <-> 1774 +1775 <-> 1706, 1915 +1776 <-> 778 +1777 <-> 460, 1918 +1778 <-> 666 +1779 <-> 523, 1846 +1780 <-> 427 +1781 <-> 1367 +1782 <-> 701, 771, 1138, 1765 +1783 <-> 482, 1649, 1783 +1784 <-> 1784, 1872 +1785 <-> 777, 1785 +1786 <-> 1858 +1787 <-> 1551 +1788 <-> 59, 384, 1865 +1789 <-> 111 +1790 <-> 294, 407, 1969 +1791 <-> 238, 930 +1792 <-> 659 +1793 <-> 489, 538, 697, 1608 +1794 <-> 206, 649, 1695 +1795 <-> 314, 748 +1796 <-> 1796 +1797 <-> 899, 1725, 1797 +1798 <-> 823, 995 +1799 <-> 308, 1799 +1800 <-> 675, 683, 1631, 1729 +1801 <-> 697, 979, 1858 +1802 <-> 967, 1481, 1578, 1697 +1803 <-> 1154, 1803 +1804 <-> 1671 +1805 <-> 199 +1806 <-> 264, 1632, 1806 +1807 <-> 1462, 1490 +1808 <-> 1609, 1808 +1809 <-> 1157 +1810 <-> 1429 +1811 <-> 125 +1812 <-> 998 +1813 <-> 1676 +1814 <-> 358, 485, 920, 1814 +1815 <-> 211 +1816 <-> 632 +1817 <-> 513, 1585 +1818 <-> 1149, 1352 +1819 <-> 632, 717 +1820 <-> 465, 1592 +1821 <-> 46, 257, 1230 +1822 <-> 492 +1823 <-> 1227, 1891 +1824 <-> 247, 1206 +1825 <-> 182, 865 +1826 <-> 501 +1827 <-> 3, 1071, 1275 +1828 <-> 29 +1829 <-> 139 +1830 <-> 1758 +1831 <-> 542 +1832 <-> 1862 +1833 <-> 1577 +1834 <-> 151, 826, 1739, 1882 +1835 <-> 828, 1345, 1751, 1835 +1836 <-> 45, 677 +1837 <-> 1230, 1321 +1838 <-> 165, 1856 +1839 <-> 1842, 1953 +1840 <-> 183, 1556 +1841 <-> 554, 1757 +1842 <-> 884, 1839 +1843 <-> 464, 809 +1844 <-> 291, 570, 1151 +1845 <-> 1378 +1846 <-> 1677, 1779 +1847 <-> 374, 1613 +1848 <-> 204, 412 +1849 <-> 626, 1570 +1850 <-> 1850 +1851 <-> 1308 +1852 <-> 228, 455 +1853 <-> 454, 1114, 1494, 1579 +1854 <-> 268, 596 +1855 <-> 1855 +1856 <-> 1838 +1857 <-> 61 +1858 <-> 336, 1786, 1801, 1937 +1859 <-> 1908 +1860 <-> 1199, 1346, 1396 +1861 <-> 1861 +1862 <-> 1429, 1709, 1832, 1900 +1863 <-> 9 +1864 <-> 41, 1975 +1865 <-> 673, 1408, 1788 +1866 <-> 966, 1873 +1867 <-> 914 +1868 <-> 330, 520, 960, 1761 +1869 <-> 2, 834 +1870 <-> 1244, 1422 +1871 <-> 1119 +1872 <-> 1784 +1873 <-> 242, 1866 +1874 <-> 337, 1109, 1131 +1875 <-> 795, 1403 +1876 <-> 258, 1754 +1877 <-> 34 +1878 <-> 481, 1691, 1758 +1879 <-> 1076, 1461 +1880 <-> 147, 410, 1723 +1881 <-> 520, 764, 1392, 1955 +1882 <-> 1834 +1883 <-> 319, 514 +1884 <-> 1969 +1885 <-> 740, 870, 1049 +1886 <-> 1013, 1368 +1887 <-> 1887 +1888 <-> 954, 1252, 1738 +1889 <-> 977 +1890 <-> 446, 530 +1891 <-> 1823 +1892 <-> 1124, 1892 +1893 <-> 395, 1187, 1893 +1894 <-> 988 +1895 <-> 733, 1681 +1896 <-> 11 +1897 <-> 77, 801 +1898 <-> 545, 1898 +1899 <-> 1005, 1293 +1900 <-> 511, 1276, 1862 +1901 <-> 1086, 1200 +1902 <-> 410 +1903 <-> 315, 990 +1904 <-> 422 +1905 <-> 1288, 1905 +1906 <-> 1229 +1907 <-> 1478, 1580 +1908 <-> 1464, 1644, 1859 +1909 <-> 706, 1360 +1910 <-> 569 +1911 <-> 310, 850, 1715 +1912 <-> 1912 +1913 <-> 279, 1132 +1914 <-> 614, 929, 1727 +1915 <-> 1474, 1775 +1916 <-> 1916 +1917 <-> 1258 +1918 <-> 382, 1777 +1919 <-> 41, 653 +1920 <-> 1280, 1637 +1921 <-> 933, 1506 +1922 <-> 167 +1923 <-> 857 +1924 <-> 222, 1526, 1924 +1925 <-> 231, 367, 1925 +1926 <-> 385, 422, 986 +1927 <-> 321, 513, 553 +1928 <-> 728, 1226 +1929 <-> 912, 952, 1965 +1930 <-> 1442 +1931 <-> 1073, 1489 +1932 <-> 1248, 1932 +1933 <-> 499, 877, 1098, 1385 +1934 <-> 1165 +1935 <-> 37, 631 +1936 <-> 283, 757, 1262 +1937 <-> 1858 +1938 <-> 109, 555, 1102 +1939 <-> 1085, 1329, 1577 +1940 <-> 902, 1940 +1941 <-> 364, 583 +1942 <-> 719, 1281 +1943 <-> 609, 760 +1944 <-> 230 +1945 <-> 1391, 1642 +1946 <-> 1093, 1426, 1516 +1947 <-> 1153 +1948 <-> 212, 296, 500, 1684 +1949 <-> 152, 737, 1386 +1950 <-> 133, 296 +1951 <-> 919, 1951 +1952 <-> 921 +1953 <-> 978, 1839 +1954 <-> 657 +1955 <-> 975, 1881 +1956 <-> 55, 71, 235, 742 +1957 <-> 1029, 1648 +1958 <-> 1958 +1959 <-> 886 +1960 <-> 196, 301, 495 +1961 <-> 674 +1962 <-> 576, 1022, 1047 +1963 <-> 883 +1964 <-> 832, 1195, 1610 +1965 <-> 1929 +1966 <-> 745, 1308 +1967 <-> 751 +1968 <-> 524, 1968 +1969 <-> 1076, 1184, 1790, 1884 +1970 <-> 983, 1970 +1971 <-> 1463 +1972 <-> 1730 +1973 <-> 457, 1318, 1421 +1974 <-> 1328, 1497, 1974 +1975 <-> 170, 1135, 1864 +1976 <-> 1596 +1977 <-> 70, 943, 1008 +1978 <-> 804 +1979 <-> 631 +1980 <-> 522, 742, 1743 +1981 <-> 1211, 1374 +1982 <-> 597, 1685, 1728 +1983 <-> 30, 931, 1313 +1984 <-> 109, 720 +1985 <-> 111 +1986 <-> 767 +1987 <-> 418, 701, 850 +1988 <-> 1061 +1989 <-> 1624 +1990 <-> 744 +1991 <-> 316 +1992 <-> 346, 562, 1040, 1081 +1993 <-> 685 +1994 <-> 573 +1995 <-> 381, 676, 1637, 1995 +1996 <-> 576, 652 +1997 <-> 554 +1998 <-> 168 +1999 <-> 818 diff --git a/pytudes/data/advent2017/input13.txt b/pytudes/data/advent2017/input13.txt new file mode 100644 index 0000000..e911a64 --- /dev/null +++ b/pytudes/data/advent2017/input13.txt @@ -0,0 +1,43 @@ +0: 3 +1: 2 +2: 4 +4: 6 +6: 4 +8: 6 +10: 5 +12: 6 +14: 9 +16: 6 +18: 8 +20: 8 +22: 8 +24: 8 +26: 8 +28: 8 +30: 12 +32: 14 +34: 10 +36: 12 +38: 12 +40: 10 +42: 12 +44: 12 +46: 12 +48: 12 +50: 12 +52: 14 +54: 14 +56: 12 +62: 12 +64: 14 +66: 14 +68: 14 +70: 17 +72: 14 +74: 14 +76: 14 +82: 14 +86: 18 +88: 14 +96: 14 +98: 44 diff --git a/pytudes/data/advent2017/input16.txt b/pytudes/data/advent2017/input16.txt new file mode 100644 index 0000000..5311dbb --- /dev/null +++ b/pytudes/data/advent2017/input16.txt @@ -0,0 +1 @@ +x5/15,s15,x1/3,pn/f,x11/2,s13,x6/3,pe/a,x14/12,s15,x1/0,pd/l,x8/15,pa/n,x14/1,s15,x15/2,pi/k,x6/3,pp/c,s9,x8/9,pb/i,x11/2,pc/a,s8,x13/6,pj/g,x5/11,s14,x9/2,s6,x10/1,pc/f,s14,x6/4,s5,x8/2,po/m,s14,x9/1,s14,x11/10,pk/g,s11,x2/13,pp/i,x12/11,pd/b,x5/7,pa/i,x12/2,pn/h,x7/4,s6,x8/1,s8,pl/c,x4/10,pg/f,x6/3,s12,x10/4,s15,x8/6,s10,x4/5,s5,x6/9,pc/m,x13/15,s12,x4/11,pp/o,x1/15,s8,x5/4,s2,x7/3,pi/b,x13/12,s12,x0/2,pe/l,x9/3,s11,x8/13,pm/i,x9/4,s13,x13/0,s6,x2/10,pd/l,s4,x12/15,pi/o,x3/0,pb/k,x8/4,s1,x10/6,s6,x3/15,s7,x4/13,pf/h,x14/10,s9,x6/12,pi/k,x9/7,pg/n,x8/5,pp/k,x7/3,s8,x0/2,pm/e,x11/3,ph/n,x4/0,pc/i,x7/15,pf/a,x6/12,s13,x13/7,pj/b,x11/14,pg/d,s15,x15/9,pe/b,x10/11,pp/h,x7/4,pc/o,x5/11,pe/m,x15/12,pi/n,x1/0,s2,x2/6,s14,x10/15,s6,x13/1,s6,x7/10,s2,ph/j,x12/14,s13,x2/6,s12,x14/0,s7,x5/15,s11,x6/4,s7,x10/9,s3,x7/5,s13,x8/2,pd/f,x10/13,s10,x5/12,pe/j,x1/15,po/c,x7/6,s4,pg/m,x14/13,s9,x4/5,s4,x9/11,s13,x10/2,pp/b,x4/0,pm/n,x7/3,s9,x9/1,s11,x3/5,s7,x14/8,pd/b,x10/7,s12,x12/9,s12,x11/2,s3,x12/6,pm/f,x11/2,s13,x6/1,s7,x9/12,pn/h,x1/3,s2,x15/10,s4,x3/4,s10,x13/2,s8,x1/7,pi/p,x2/8,s12,x11/14,s1,x13/2,pf/n,s1,x10/6,pm/k,x3/9,s8,x5/10,s2,x1/15,pg/p,x6/10,s13,x1/7,s13,x14/8,s5,x10/15,s15,x3/12,s1,x10/14,s1,x2/1,po/h,x14/5,pa/k,x1/8,s15,x4/11,s5,x3/15,s11,x2/12,pb/i,x10/14,s12,x13/12,pm/p,s10,x8/14,pa/n,s2,x4/12,s11,pp/d,x11/7,pl/e,x8/6,ph/k,s4,x10/7,s5,x14/0,pn/m,x5/10,s14,x3/7,s15,x6/0,s1,x1/14,s8,po/g,x8/13,pj/h,s3,x12/2,s3,pg/m,x7/6,pk/n,x0/4,s13,pf/l,x11/5,s11,x2/4,s5,x0/5,s7,x8/1,pc/i,x5/9,s15,x2/4,pj/f,x7/12,pe/p,x3/10,ph/i,s5,x0/12,pf/d,x6/13,pi/p,x1/5,s14,x14/13,s7,x8/6,pj/o,x15/2,pn/l,x4/3,pi/m,x10/0,s1,x5/6,s6,x1/9,pe/l,x7/0,s9,x4/8,s5,x9/1,pa/n,x14/13,s4,x3/5,pl/d,x8/1,s11,x10/2,pe/a,x9/5,pb/h,x13/15,pi/d,x5/11,s15,x8/0,pc/f,x1/11,s5,x12/8,s6,x1/14,s12,x2/10,s10,x14/1,s12,x3/7,pk/o,x5/6,s10,x1/0,pm/l,x9/4,pc/p,x6/8,s12,x15/7,pm/o,x13/12,s9,x1/2,pi/p,x14/0,s13,x15/7,pf/e,x10/6,s3,x1/13,s6,x4/14,pp/d,x15/9,s3,x13/3,s11,pj/g,x11/6,s6,x8/2,pn/f,x7/11,pa/k,s5,x9/12,s5,pm/n,x7/6,s12,x14/1,s5,x2/6,pl/e,x1/8,pa/m,x11/2,pp/h,x1/14,pm/n,x3/8,pg/h,s1,x0/13,s9,pe/l,x14/8,s10,x13/4,s6,x0/7,s9,x15/4,pp/f,x12/6,s6,pl/a,x8/0,pk/j,x14/5,s4,pc/e,x0/11,s10,x15/7,s10,x8/1,s7,x3/11,s7,x5/10,po/n,s15,x4/8,s15,x7/0,pl/i,x9/5,s3,x2/1,pa/b,x10/11,pk/m,x3/1,po/d,x2/9,pf/n,x15/14,po/i,x8/11,s15,x14/4,s6,x7/5,pj/g,x0/3,s15,x13/6,s3,x14/4,s1,x5/13,pb/i,x6/9,pl/m,x5/8,pb/h,s4,x9/2,s14,x1/12,pi/p,x9/7,pd/k,x2/3,pf/g,s9,x5/1,s10,x10/8,s4,ph/c,x5/4,s11,x11/15,s9,x5/6,s3,x11/12,pd/i,x5/9,s6,x13/7,pp/j,x1/12,pc/i,s15,x8/2,s7,x11/0,s2,x15/14,s13,x1/12,s15,x10/13,pg/p,x11/14,s4,x3/2,pm/b,x15/1,s3,x3/9,s9,x5/12,s15,x3/13,pc/e,x15/9,s10,x2/12,s13,x10/7,pa/f,s13,x8/4,s8,x14/1,s2,x13/10,s14,x14/5,s3,x13/11,pj/m,x1/8,s1,x4/10,s14,x8/7,s5,x11/14,pa/b,x6/13,s7,x14/12,s15,x0/5,pj/l,x1/7,s12,x13/6,s6,x10/12,s13,x11/3,s4,x5/9,s4,x6/7,po/k,x0/15,s13,x3/5,s5,x15/1,s2,x0/11,s6,x7/2,pc/a,x5/4,pl/b,s12,x1/14,s2,x6/7,pa/j,x13/11,s4,x10/9,s12,x13/14,s11,x9/12,pg/e,x7/6,s6,x3/5,s4,x1/2,s11,x7/0,pp/i,x1/6,s3,x3/4,pl/e,x7/5,s3,x11/13,s15,x6/8,pg/b,x4/15,pl/j,x10/3,s14,x4/1,s6,x12/3,s11,x0/1,s6,x6/11,s11,x2/5,pi/h,x8/14,pa/n,x2/13,s15,x1/14,s15,x8/15,s11,x5/0,s12,x13/10,pg/h,x7/0,pk/o,s4,x6/11,s7,x10/12,s14,x13/1,s2,x14/9,s3,x2/1,pj/d,x8/14,pc/k,s9,x1/7,s13,x0/5,pm/f,x15/10,pi/b,x12/1,pg/e,x15/0,ph/b,x12/5,s15,x11/0,pg/i,x15/12,s11,x3/11,s5,x12/13,s11,x8/10,s9,x15/13,s5,x3/2,s12,x14/7,pn/c,x11/2,s3,x5/14,s13,x8/3,s6,x11/0,s2,x4/13,s7,x5/2,s7,x8/0,s6,x12/15,s4,x6/9,s5,x5/8,s7,x3/11,s14,x14/13,s9,x9/10,pl/b,x12/4,pf/m,x5/14,s14,x0/1,pn/c,x2/13,s3,x1/4,s15,x8/2,pd/l,x0/13,pc/o,x7/15,s3,x6/4,pe/k,x13/11,po/p,x4/8,pb/j,x5/6,pg/k,x10/12,pj/c,x6/5,s2,x9/3,s4,pk/o,x12/13,s3,pf/c,x8/7,s9,x3/6,s12,x7/1,pa/h,x12/4,s1,x3/0,s12,x2/6,pk/l,x1/15,ph/d,x6/13,pb/n,x4/15,s1,x14/0,pm/d,x3/6,s4,ph/j,x4/5,pg/f,x7/8,pm/b,x2/4,s2,x9/7,s11,x10/2,pp/c,x7/13,s14,x5/4,s4,x7/1,pg/b,s13,x4/0,s7,pc/e,x3/11,s15,x6/13,s6,x0/5,s15,x8/15,pb/m,x5/1,s4,x13/10,s4,x7/0,pn/c,x8/4,s6,x1/6,s13,x4/7,s3,x5/11,s15,x14/0,s8,x4/9,s12,x14/10,s15,x9/6,s1,x7/1,s7,x13/11,s4,x4/6,pk/m,x7/9,s4,x15/2,pp/g,x6/3,s1,x7/15,ph/m,x0/5,pp/g,x4/3,pe/i,x13/15,s3,x12/14,s9,x8/15,s2,x0/4,s6,x13/7,s13,x3/14,s13,pm/c,x1/8,pn/g,x14/7,s9,x2/3,s10,pd/j,x4/14,s14,x3/11,s12,x0/15,s9,x8/12,pb/p,x3/13,s6,x12/14,s10,x11/10,pi/o,s10,x3/6,s2,x13/2,s13,x9/8,s14,x3/11,s2,x7/4,s3,x15/9,pp/h,x8/10,s6,x5/0,s9,x2/1,s9,x9/0,s10,pa/f,x11/1,pm/p,s4,x9/4,po/j,x2/12,pp/d,x10/6,pi/a,s7,x14/7,s14,x1/15,s1,x3/0,s15,x4/12,s15,x8/1,pc/d,x11/14,s10,x15/6,s3,x0/3,s9,x14/8,s1,x6/0,s15,x11/5,pa/n,x2/4,s5,x12/10,s4,x8/0,ph/i,x5/14,s8,pg/j,x11/12,pc/k,x0/7,s14,pp/g,x5/15,s15,x11/10,s14,x7/12,s8,x2/13,pn/k,x3/14,pc/l,x13/2,s7,x10/9,s15,x2/13,po/p,x3/8,s5,ph/l,x6/10,pd/c,x13/8,s6,x5/7,pg/b,x11/10,s7,x8/1,pp/i,s8,x2/12,s6,ph/m,x3/6,pl/k,x11/7,pb/e,x14/0,pi/c,s11,x10/4,s9,x8/9,s9,x7/2,pd/p,s3,x6/0,s15,pe/l,s10,x5/13,s5,x4/3,pk/c,x1/6,s3,ph/d,x2/9,pp/i,x7/3,s14,x15/14,s2,x8/9,s11,x0/4,pe/f,x13/12,s13,x5/7,pm/b,s2,x9/15,pf/j,x3/2,pc/d,x10/6,s12,x12/0,s11,x7/15,pe/i,x6/13,s11,x8/12,s12,x3/5,pf/m,x2/6,pl/j,x11/4,s3,x5/9,s11,x1/11,pf/i,x10/0,s10,x14/12,s14,pe/a,x11/9,pn/h,x8/6,s13,x10/1,pf/j,x15/9,pa/n,x4/1,po/l,x15/6,pp/h,x13/1,s14,x14/12,s14,x0/2,pa/d,x15/4,s9,x11/5,s6,x13/7,s12,x15/10,s12,x7/8,pb/h,x3/10,s2,x12/14,s13,pf/m,x7/6,s3,x9/12,s1,x5/15,s4,x4/11,pg/p,x2/10,pk/d,x12/9,pp/a,x8/5,pf/d,x7/0,s4,x10/1,pe/p,x6/2,s6,x9/15,pk/d,x11/13,s5,x0/5,pc/o,x3/6,s13,x11/0,pd/l,s12,x13/8,pc/m,x15/11,s15,x13/2,pi/j,x4/6,pf/m,x0/8,s5,x5/2,pn/o,x7/14,pi/d,x8/6,pk/m,x13/14,pb/o,x15/2,s2,x14/6,pm/a,x15/11,s13,x5/8,pd/b,x11/4,pl/c,x12/6,s10,x5/4,pd/p,x0/1,s1,x12/2,s10,x7/11,pb/k,x8/3,pi/j,x9/12,s15,x4/3,s12,x13/11,pd/e,x2/10,s6,x12/8,pf/o,x15/4,ph/p,x5/14,s2,x9/6,s12,x5/1,s14,x12/8,pl/g,x4/1,pa/m,s2,x0/5,s10,x12/4,s8,x6/1,s5,x15/5,ph/o,x14/7,s8,x8/12,pd/g,x11/13,s1,x9/1,pc/p,x10/15,s11,x3/7,s9,x0/9,pj/k,x2/6,pc/e,x0/1,s3,x2/7,pd/g,s8,x4/1,pp/l,s10,x10/6,s6,x15/9,s15,x12/13,pd/o,x9/7,s1,x2/6,s14,x5/12,pb/k,x1/15,s2,x10/11,pg/i,x12/13,s14,x11/2,s11,x10/3,s3,x0/11,s3,x1/2,po/a,x3/5,s7,x8/1,s11,x7/9,s1,x6/13,s11,x4/2,s12,x13/10,pb/e,x2/7,pk/g,x12/5,po/h,x10/11,pf/j,x0/14,s5,x7/12,pa/l,x0/5,s4,x9/2,s14,pg/p,x10/8,s15,x12/6,pn/h,x2/10,s6,x13/1,s6,x8/9,pj/e,x5/15,pf/o,x8/0,pl/n,x10/11,s1,x4/3,s9,x5/8,pc/p,x3/15,pl/m,x4/13,pf/j,s9,x6/15,pb/g,x10/7,s5,x14/1,pm/o,x7/11,s14,x1/5,s13,x9/4,pp/d,x15/14,s7,x8/10,s6,x0/7,pe/g,s14,pn/a,x4/3,s14,x0/5,s6,x6/12,pf/i,x10/5,s5,x6/14,pn/j,x11/9,s6,x14/7,pa/b,x5/2,pd/o,x9/3,s9,pa/e,x8/12,pd/c,x4/3,pl/p,x15/6,s4,x5/7,s15,x3/2,s5,pe/d,s10,x12/14,s5,x7/0,pb/o,x12/1,s6,x14/10,s13,x4/0,s13,x9/15,pn/g,x3/1,s7,x0/7,pi/c,x6/15,s11,x5/7,pl/b,x1/14,s10,x4/0,pf/m,x15/13,s8,x5/2,s10,x9/0,s7,x7/15,pl/o,x6/0,pe/d,x1/12,s4,x11/0,s10,x10/5,s2,x7/2,s4,x8/12,pi/l,s9,x15/2,s10,x9/10,s7,x7/14,pg/h,x4/1,s13,pj/e,x8/12,ph/n,x6/15,s11,x5/10,pa/e,x6/12,pd/c,x11/8,s1,x15/12,pa/g,s14,pf/h,s14,x8/2,s4,pm/g,x11/0,s15,x5/4,pc/e,x1/3,pj/f,x4/10,s8,x2/5,pe/a,x10/9,pf/d,x8/1,pc/h,s14,x7/3,s12,x8/4,s4,x2/1,s14,x12/6,s14,x11/14,s8,x4/13,s14,x12/15,s14,x7/13,pe/n,x4/12,s8,x6/5,pc/m,s12,x0/8,s2,pj/f,x11/1,s5,pc/a,x6/2,s12,x8/11,s9,x10/3,pd/n,x2/5,pa/f,x1/11,s6,x3/6,s10,x9/12,s10,x11/1,s3,x5/7,s8,x1/13,pp/j,x5/0,po/e,x15/9,pk/p,x7/5,s14,x6/1,pb/c,s3,x5/9,s11,x2/4,s14,x5/8,pg/e,x7/6,pm/b,x13/9,s2,x10/5,s6,x12/13,s9,x3/14,s15,x13/12,s11,x4/15,s11,x13/0,s2,x5/8,pn/a,x0/9,s2,pc/h,x11/6,s6,x13/9,s11,x0/7,s9,x3/2,s11,x4/0,s10,x11/3,s3,x9/4,s11,x2/10,s4,x3/0,pj/e,x12/11,pi/k,x10/15,s8,x5/14,s7,x9/7,s11,x15/11,s8,x12/4,pb/e,s2,po/n,x14/3,pg/i,x4/15,pf/l,x6/9,s12,x11/10,s8,x1/2,pg/n,x5/0,s7,x13/4,pd/e,s9,x0/8,pm/n,s12,x3/4,s15,x1/8,pd/p,x5/4,s5,x14/3,s8,x9/10,s1,x3/11,pc/b,s7,x9/1,pa/p,s14,pd/j,s10,x8/7,pc/h,x5/12,pl/f,x8/13,s10,x11/7,s8,x6/10,s12,x15/13,s13,x2/10,s4,x9/0,s6,x2/8,pa/d,x12/14,s4,pb/j,x8/4,pg/l,x9/12,s5,x3/11,pj/h,x13/7,pi/a,s1,x0/8,pc/f,x4/13,pb/l,x2/9,s3,x12/4,pe/a,x2/14,s13,x6/1,pm/b,s10,x9/11,s8,x4/15,pf/h,x5/10,s14,x12/0,s6,x4/15,s14,x6/10,s6,x0/4,pp/m,x13/7,pg/i,x0/8,s11,x6/13,pb/p,x5/7,s1,x3/2,po/k,x0/9,pc/f,x14/2,pi/o,s3,x3/5,pe/c,x2/6,s5,x1/10,s14,x6/14,pp/j,s10,x0/15,ph/g,x4/1,s4,x7/5,s10,x4/6,pp/e,x12/7,pn/l,x8/3,s12,x10/1,s3,x11/9,pc/a,x2/13,pl/n,s2,x3/7,s13,x5/2,s15,x12/10,s1,x2/8,s6,x1/13,ph/j,x8/9,s13,x14/10,po/k,x7/13,s2,x12/14,pa/p,x1/10,s15,x8/2,pd/c,x13/15,s7,x2/1,s4,x12/13,pe/n,x11/5,pg/j,x10/1,s1,x4/0,s13,x14/6,pk/i,x3/15,pp/g,x12/11,po/e,x10/1,s14,pl/h,x8/6,pb/i,x11/5,pj/k,x2/4,s12,x11/0,s1,x9/7,pg/m,x5/2,s4,x3/12,pj/a,s6,x10/8,s3,x0/7,pm/g,x14/3,s4,x15/8,pi/f,x11/2,pl/b,s9,x15/4,pa/g,x9/0,s9,x8/10,pn/f,x5/4,s5,x6/15,pe/o,x4/2,s13,x11/8,s14,x10/1,s7,x2/0,s5,x3/6,pn/b,x13/7,pa/e,x12/11,s3,x5/10,pk/b,x9/8,pa/d,x6/12,s3,pg/e,x4/15,s7,x10/2,pj/l,s5,x15/13,pd/i,x6/1,pg/h,x8/13,s5,x3/9,s14,x10/15,pn/j,x3/12,pi/m,x0/11,s12,x14/15,s10,x9/13,pl/p,x12/5,pm/b,x8/6,s12,x11/10,pn/l,s3,x7/13,s1,x15/0,s2,x7/12,pi/p,x1/10,pj/m,x3/15,s14,pc/b,x12/6,s7,x11/14,pd/m,s9,x0/15,pp/l,x4/6,s14,x2/14,s15,x0/15,s8,x13/5,s2,x2/11,s4,x9/0,s9,x1/14,s13,x0/11,s2,x10/1,pa/j,x9/5,s7,x13/11,s14,x14/6,s8,x8/10,s3,x13/0,pc/k,x8/7,s15,x15/10,s3,x7/12,s1,po/f,x10/11,s6,x13/9,pe/n,x3/5,s11,pj/h,x10/8,pc/d,s4,x14/1,po/p,x3/4,s8,x6/12,s13,x8/4,pj/g,x10/0,pm/f,x4/13,pd/o,x9/15,s4,x2/5,ph/c,x12/8,s15,x10/5,s6,x9/12,s6,x6/7,pb/n,x0/10,s13,x8/3,ph/g,x6/10,s3,x2/3,s8,x15/6,pl/p,x13/9,s8,x15/6,pn/c,s9,x7/13,pi/p,x11/14,s3,x2/3,pd/a,x9/6,s11,x8/12,po/k,x3/5,s6,x12/8,s3,x10/6,pg/b,x0/4,s15,x2/6,s8,x4/9,s14,x12/15,s1,x0/9,pa/o,x8/6,s3,x5/10,s4,x12/4,s10,x0/6,pm/e,x4/12,pf/c,x8/6,s12,x3/7,pn/l,x5/12,s10,x13/2,s15,x3/0,pg/f,s5,pe/a,x14/10,po/h,x8/1,s13,x4/14,s3,x12/10,s13,x9/2,s11,x5/15,pd/e,x10/7,s2,x3/6,pi/j,x7/1,s5,x2/9,s7,x1/4,pm/b,s2,x15/8,s8,x14/4,s9,x12/10,s6,x7/11,pe/g,x9/15,s3,x4/13,s2,x10/0,pj/k,x7/3,s3,x12/5,pe/c,x1/3,pp/j,x6/0,pb/d,x4/1,s3,x15/0,s12,x9/4,pf/h,x0/14,pg/a,x10/6,s10,x4/13,s13,x6/14,pb/f,x8/9,s9,x12/10,pi/a,x7/13,pp/b,x15/12,pi/l,x0/11,s14,x3/7,s10,pc/n,x6/12,s10,x0/5,s1,x13/6,pi/o,x0/11,s12,x15/1,s12,x2/13,ph/a,x7/3,s14,x0/1,s15,x10/13,s15,x6/7,s12,x2/14,s1,x0/15,pk/i,x3/6,s9,x1/2,s2,x7/15,pg/b,x14/11,s9,x5/3,po/p,x0/14,s13,x15/5,s14,x6/4,s7,x1/13,ph/m,x3/7,s4,x10/9,pe/c,x15/14,s12,x9/0,pb/n,x6/15,s14,x0/5,pm/e,x6/15,s3,x4/7,s7,x5/8,s5,x2/15,s7,x4/11,pk/a,x9/0,s2,x13/5,s3,x8/15,s7,x4/10,pd/g,x7/15,pc/i,s11,x10/9,pp/f,x2/14,ph/j,x9/0,s9,x13/10,s4,x0/6,s6,x7/9,s2,x13/2,po/p,x15/7,pn/j,x0/1,s5,x6/8,pc/f,x13/7,pn/d,x11/1,s6,x3/7,pe/k,x14/0,pn/c,x12/15,s4,x8/7,pm/a,x0/5,ph/k,x7/9,s6,x3/15,s7,x11/5,s4,x13/0,pi/a,x2/11,s6,x4/6,s12,x13/10,s5,pd/j,x6/4,s3,x11/15,pg/f,x3/14,s12,x6/8,s3,x0/3,s14,x14/13,pj/h,x12/6,pa/l,x14/0,s15,x12/10,pj/b,x2/15,ph/e,x12/1,s8,x8/6,pp/n,x14/15,pb/j,x5/8,s3,x6/10,s2,x9/1,pg/f,x10/11,s12,x13/8,s8,ph/n,x9/0,pp/k,x4/3,pc/n,x13/6,s3,x9/15,pj/f,x14/13,s11,x10/2,s1,x13/4,pi/g,x12/3,s6,x9/7,s8,x2/0,s2,x11/5,pn/m,x3/12,pl/e,x9/6,ph/a,x13/1,s15,x6/12,s6,x2/10,s4,x14/0,pc/p,s7,x8/10,pl/d,s3,x11/4,pj/i,x7/6,s14,x1/10,pm/g,x12/3,pe/d,x9/11,pa/c,x13/6,pd/i,s10,x11/7,s10,x14/9,s14,x4/7,s15,x10/3,s11,x6/14,s7,x12/15,pc/j,x0/8,pd/o,x13/1,s2,x7/0,pa/j,x15/5,pl/b,x7/6,pn/m,x10/8,s14,x9/14,pa/p,x7/6,pc/o,x13/8,s1,x10/12,s7,x8/5,s8,x15/12,pb/g,x13/3,s13,x7/11,s10,x15/12,s14,x7/9,s2,x14/11,s2,x7/8,pf/n,x15/4,s3,pk/c,x14/13,s10,x7/2,s3,pn/j,x3/11,s10,pe/l,x9/6,s3,pj/f,x14/0,s4,x10/4,s4,x3/12,ph/n,x4/2,s6,x3/14,s13,x12/4,s14,x13/8,pl/e,x7/12,ph/d,x8/0,pc/m,x14/4,s5,x10/3,ph/f,x13/6,s5,x8/5,pe/g,x15/9,s11,x0/4,s14,x7/2,s2,x0/14,s11,x10/9,ph/n,x8/2,s2,x1/7,s13,x13/2,s3,x1/15,s10,x4/9,s15,pp/b,x8/2,s10,x1/7,po/f,x0/12,pa/j,x4/7,po/b,x6/10,s3,x14/1,s2,x2/3,s2,x10/13,pd/j,x4/5,s12,x6/14,s6,x10/11,pn/i,x6/15,pg/a,x3/8,s2,x6/5,s7,x11/3,s8,x9/10,s5,pm/e,x6/3,s12,x5/2,s7,x9/6,s14,x1/2,s6,x13/4,pg/b,x7/0,pe/m,x12/13,s11,x4/2,pn/c,s1,x5/10,s3,x0/1,s4,x2/8,s10,x14/7,s10,x6/10,s4,x13/0,s2,x10/4,s7,pj/o,x7/2,pb/g,x8/9,s14,x15/6,ph/c,x13/4,s15,x14/11,s13,x9/3,s13,x13/12,pp/a,x8/7,s10,x13/10,pm/o,x5/1,s12,x8/10,s1,pg/l,x11/0,s15,x10/12,pe/a,x1/0,s11,x10/15,s4,po/h,x11/6,s14,pd/b,x10/4,s4,ph/a,x12/1,pm/b,x14/4,pp/g,x13/1,s1,x8/3,s2,x12/11,s1,x8/10,s6,x9/6,pn/h,x14/11,s11,x9/8,s9,x4/11,pe/f,x5/15,s10,x0/1,s10,x5/6,pg/h,x9/8,po/f,x11/10,s11,x5/6,s10,x7/8,pd/l,x0/12,s10,x7/14,s7,x9/10,s9,x1/5,ph/a,x0/9,pc/j,s3,x8/6,pi/f,x3/15,s6,x0/9,pm/b,s3,x8/6,s4,x0/12,pg/d,x8/5,s6,x10/13,s14,x8/4,s4,pm/j,x11/0,s7,x5/3,s4,pl/p,s11,x7/9,po/g,x8/12,s14,x5/15,s11,x6/14,s14,x0/7,pm/l,x15/1,s12,x13/0,pp/b,s11,x8/3,s3,x14/7,s10,x10/6,pa/c,x5/3,s9,x4/9,pf/b,x1/14,pa/p,x12/7,s7,x3/2,pl/j,x7/1,s11,x0/4,s11,x1/10,pp/a,s4,x14/5,s10,pe/j,x12/7,s7,x15/5,s11,x0/8,s12,x9/6,pk/c,x14/10,s7,x7/5,po/i,x0/4,s6,x3/9,pm/k,x13/14,pe/n,x4/10,pa/p,x8/11,pb/k,x5/13,pd/o,x14/15,s10,x7/13,s15,x8/11,pk/b,x13/15,s12,x6/12,pj/h,x5/1,pf/o,s8,x4/13,s12,x8/0,pj/b,x13/4,s15,x0/15,s13,x13/11,s1,x3/4,s9,x10/12,s6,x4/11,pp/a,x15/10,s6,x1/0,pi/e,x9/8,pk/a,x4/14,s2,x8/12,s11,x6/1,s14,x3/11,s8,x5/10,pn/i,x13/0,pd/a,s10,x8/1,ph/e,s11,x14/4,pb/p,x12/7,pm/o,s6,x13/14,s11,x0/12,pa/d,x10/15,s5,x12/1,pl/j,x15/8,s4,x0/13,s10,x6/12,s10,x4/9,s5,x0/15,ph/e,x5/8,s1,x14/3,s11,x2/9,s13,x10/4,s9,x13/0,s10,x3/7,s7,x14/13,s7,x6/0,s9,x1/12,s13,pl/m,x5/10,pa/f,x0/15,s9,x2/1,s13,x3/9,s2,x6/10,pm/g,s12,x12/8,s8,x0/9,s11,x10/14,pa/b,x2/3,pk/g,x8/7,pf/d,x10/12,s13,x3/6,pe/i,x9/8,s14,x1/5,s1,x11/7,s11,x5/8,s4,x2/7,pn/k,x6/1,pa/i,x15/3,s3,x11/9,pe/p,s3,x8/7,s2,x14/13,s15,x6/15,s12,x7/9,pn/g,x1/14,pa/i,x10/7,s9,x4/1,s2,pl/j,x6/13,pp/e,x2/7,s5,x4/14,s12,x7/9,s6,x4/5,s8,x14/10,s4,x1/5,s7,pd/l,x3/11,s3,x7/9,s3,x10/3,pp/k,x14/4,s15,x5/12,s11,pe/j,s6,x14/15,s3,x9/5,pc/f,x10/13,s1,pn/e,s4,x8/1,s14,x2/11,s15,x7/8,pb/g,s15,x2/14,pn/j,x11/1,pa/p,x5/4,s6,x13/3,pn/e,x6/9,ph/o,x2/10,pc/e,x15/12,s14,x13/8,s13,x0/2,s2,x1/13,pi/o,x9/3,s8,x5/12,s2,x9/7,pe/g,s12,x10/14,s11,x2/12,pp/i,s5,x14/8,pg/b,x13/12,pc/n,x11/0,s4,x7/3,s10,x1/12,s14,x8/3,pa/g,x2/1,s5,x0/3,pi/l,x13/12,s4,x9/6,s7,x11/4,s4,x10/7,s5,x9/2,s2,x12/4,s2,x9/8,s4,x1/4,pm/h,x10/15,s4,x3/7,s13,x10/13,s6,x14/9,s15,pk/b,x3/13,s12,x7/12,s10,x11/14,pg/d,x15/4,pi/l,x11/7,s9,x12/2,s13,x14/5,s1,x4/13,s5,x2/11,s2,x3/14,s5,x6/1,s8,x8/9,s2,x1/11,s11,x15/6,s14,pk/d,s15,x8/1,s12,pm/p,x4/15,pf/d,x0/1,s5,x14/15,s7,x7/8,s1,x12/10,pe/g,s6,x9/0,s5,x2/10,s8,x9/11,pp/d,s4,x12/8,s13,pa/g,x4/5,pi/d,x14/13,s2,po/l,x12/15,s3,x7/3,s13,x12/1,s6,x11/9,s14,x3/0,pd/i,x2/5,pn/b,x10/11,s4,x13/2,pi/a,x5/3,s14,pf/e,x6/15,s5,x10/0,s7,x9/3,pb/p,x4/5,ph/e,x2/8,pl/g,x9/4,s4,x15/12,s14,x9/14,pk/j,x8/11,pe/i,x2/4,s2,x13/7,s13,x12/11,s1,x7/14,pj/g,s9,x3/15,s2,x14/10,s8,x9/15,s2,x7/2,s11,pm/a,x3/14,s9,x12/6,pl/b,x3/13,s8,x10/8,pk/a,x1/15,s15,pl/f,x7/3,pk/i,x8/9,pg/e,x15/4,s15,x6/0,s11,x14/5,pk/h,x4/12,pn/e,x2/13,pb/a,x7/6,s1,x0/12,s5,x11/3,s3,x0/2,pl/o,x9/11,s9,x1/0,s10,x14/2,s1,x4/0,pn/g,s11,x7/1,s12,pk/f,x2/11,s7,x3/1,ph/p,x14/5,pe/f,x3/10,s14,x8/2,s2,x4/15,s5,x10/11,pg/c,x15/4,s14,x11/2,s11,x9/0,s9,x14/10,pp/f,x6/1,po/j,x15/8,pl/k,x1/6,pb/g,x8/9,pc/m,x4/12,pg/k,x2/8,s11,pb/m,x10/9,s12,x0/1,s5,x15/3,s3,x14/4,s6,x1/12,pd/o,x5/15,s5,x2/6,s3,x7/1,s4,x0/13,s7,x1/14,s9,x2/8,s2,x9/7,s15,x8/13,s1,x0/6,pb/j,x14/9,s8,x5/1,s13,x9/12,s8,x6/10,s6,pi/h,x13/4,s13,x11/0,pa/m,x10/2,s7,x7/4,s6,x5/14,s12,x6/9,s15,x13/0,po/h,s14,x7/1,s3,x0/14,s1,pf/b,x1/4,s15,x11/7,s10,x1/9,pi/n,x14/10,pl/k,x8/7,pf/h,x11/0,s3,x5/2,s11,pl/k,x6/0,pi/a,x15/8,s13,x1/6,s2,x12/2,s10,x0/4,s3,x3/5,s5,x4/9,s13,pp/l,s14,pf/k,x0/2,s11,x10/6,pm/d,x14/0,s4,x10/5,s3,x1/7,s9,x3/12,s5,x7/2,pb/h,s1,x11/4,pl/i,x9/3,s4,x10/2,po/k,x7/1,pc/m,x6/10,pg/f,x5/2,pj/p,x0/8,pa/l,x9/6,pp/g,s7,x12/3,s3,x9/0,pm/c,x12/11,s12,x8/6,pa/g,x3/7,po/e,x2/15,s11,x12/3,s6,x8/0,s3,pg/n,x14/15,s10,x2/11,pc/k,s3,x15/7,s8,x12/13,pm/i,x7/0,s11,x15/13,s12,pn/l,x9/1,pj/g,x10/0,s2,x9/12,pe/b,x1/5,pp/j,x3/11,pb/c,x1/5,s3,x2/14,s4,x8/12,s6,pf/e,x3/0,s6,x12/13,pl/i,s9,pp/n,s9,x4/14,pk/m,x5/11,s5,x10/9,s7,x3/15,pa/d,s15,x4/10,ph/c,x1/8,s6,pm/o,x5/3,s11,x14/15,s7,x11/12,s11,x10/15,s7,x14/4,s1,x5/12,pk/f,x7/10,s3,x1/2,s14,x7/0,s11,x15/1,pc/m,x13/14,pl/f,x3/12,pj/m,s14,x10/15,s9,x2/7,pc/b,x15/5,s5,x10/3,pm/n,x4/15,pe/p,x7/13,pn/b,x0/11,s9,x12/5,s5,x14/4,s13,x12/2,pm/c,s8,x9/11,s5,x10/1,pp/e,x12/5,pg/a,x10/0,pd/f,x7/11,s3,x14/2,s13,ph/i,x1/3,pc/g,x10/8,pa/i,x11/15,s12,x7/8,pp/f,x1/2,pl/j,x11/4,s15,x9/10,pm/h,x0/6,pg/n,x13/7,pi/b,s1,x9/11,s5,x3/10,s1,x2/12,pj/k,x9/5,s3,x13/10,s8,x15/5,s2,pf/i,s4,x10/4,pb/e,x0/11,s8,x15/9,pj/l,x0/5,s11,x4/14,s13,x2/3,s4,ph/k,x15/4,pe/p,x11/13,pd/l,x2/8,pb/h,x7/13,s4,x9/11,s4,x14/2,s3,x11/3,s14,x4/6,pc/a,x2/8,s13,x15/6,pl/f,s7,x13/2,s5,x6/9,pk/a,x2/11,pb/m,x8/13,s8,x14/6,pn/f,x10/15,pi/b,x12/14,s5,x7/1,s5,x13/12,s7,x6/15,po/l,x8/2,s15,pb/i,x3/6,s9,x7/1,s11,x10/6,s14,x4/2,pc/p,x15/0,s12,x11/4,pf/b,x3/10,s5,x15/13,pc/d,x4/11,s11,x8/9,pm/e,x15/6,pn/j,x8/9,s3,pp/i,x14/7,s2,x10/6,pe/f,x3/8,ph/l,x1/15,s3,x13/7,pn/o,x5/1,s7,x10/0,s1,x9/5,s12,x2/0,pd/l,x12/6,pp/c,x5/13,s5,pd/l,x2/6,s3,x14/4,s11,x15/8,s13,x10/12,pb/h,x7/13,pd/p,x1/3,s15,x12/9,pc/e,x5/8,pi/n,s5,x11/7,s3,x12/2,pc/a,x14/13,pf/i,x8/4,s11,x13/2,s8,x0/4,s15,x5/1,s6,x10/2,s11,x14/0,s10,x1/11,pk/n,x0/4,s10,x2/6,s4,x9/7,pi/o,x14/0,s11,x15/9,pb/d,x3/1,s9,x10/6,pf/e,s8,x15/1,s1,x2/12,s10,x1/8,ph/a,x9/13,s6,x15/0,po/j,x2/11,s10,pk/a,x7/0,s3,x10/6,pl/n,x5/4,s11,x15/1,s1,x9/7,s5,x15/14,s5,x4/10,s5,x14/15,s2,x9/13,s14,x5/0,s7,x1/15,s12,x10/2,pj/a,x0/15,pb/o,x8/14,pe/h,x2/7,pa/b,x13/8,s14,x2/6,pp/j,x15/7,s8,x14/10,s13,x4/2,pk/f,s8,x8/12,ph/j,s10,x6/13,pl/k,x15/5,s14,x3/8,s8,x14/0,pg/i,s13,x3/9,s10,x15/6,po/j,x12/0,pb/p,x3/9,pe/o,x13/5,pa/d,x3/9,s15,x14/15,s8,x6/5,pb/f,x7/2,s4,x12/8,s7,x11/1,s6,x10/6,ph/k,x14/13,s9,x4/5,pn/p,x1/9,s1,x0/10,s8,x6/11,pb/o,x7/1,pi/f,x13/3,pl/k,x8/11,pd/p,s10,x13/0,pm/n,s7,x10/4,s13,x5/11,pi/g,x14/4,s1,x2/12,s14,x15/10,s4,x8/9,s2,x11/7,pa/m,x15/3,s5,x6/2,s6,x10/14,pg/k,x15/1,s13,x12/4,s3,pn/m,x3/13,s11,x6/7,s8,x13/14,pf/i,x1/9,pa/m,x6/11,pj/l,x7/9,pe/c,x13/14,s4,x0/6,pj/f,x3/10,s3,x7/15,s9,x8/2,s2,x10/9,s5,x12/4,s2,x3/9,s13,x8/15,s9,x13/11,s2,x4/3,s8,x0/12,ph/p,x10/6,s12,x3/13,s13,x11/14,pa/c,x3/15,s10,x13/5,s4,x2/4,ph/d,x7/12,pe/g,x5/11,pa/j,x2/6,pp/n,x7/5,s11,x4/0,s14,x7/5,pk/d,x15/2,pm/b,x0/11,s9,x10/9,s10,x11/2,pi/c,x1/4,s5,x6/13,s6,pj/n,s10,x3/4,s4,x12/5,s9,x8/4,s10,x13/15,pe/h,x14/1,s7,x0/6,pc/d,x8/9,s10,x5/12,s13,x9/3,pl/e,x2/10,s2,x13/11,s1,pm/h,x0/6,pg/a,x8/12,s4,x3/9,s1,x8/0,pj/f,x3/1,s8,x13/15,pc/k,s12,x6/8,s8,x5/0,s4,x13/7,s6,x8/4,s4,x1/14,s9,x4/6,s6,x12/0,ph/j,x5/10,s3,x13/1,pl/d,x15/4,pj/o,x10/12,s9,x7/11,s8,x12/14,pk/c,x4/9,s8,x6/2,s5,x10/14,s9,x4/12,s12,x5/15,s1,x2/6,s1,x5/7,s5,x10/4,s9,x12/8,s10,x7/0,pm/b,x6/10,s11,x15/14,pg/e,x1/4,s9,x5/9,s14,x8/10,pn/m,x12/9,s10,x14/7,s2,x6/2,pa/e,x8/14,pc/d,x13/1,s9,x9/7,ph/p,x6/1,pk/l,x0/4,s13,x5/9,s6,x2/14,s11,x1/0,pe/m,x7/9,s6,x3/4,pb/p,x6/1,pl/k,x15/0,s4,x10/6,pg/j,x14/9,s5,x8/13,s2,x1/11,pk/d,x3/15,pc/m,s3,x7/11,pd/p,x13/4,po/m,x2/14,pc/i,x1/12,s3,x5/15,s4,x11/9,pf/o,x5/2,s6,x10/1,s4,x12/2,pp/b,x11/0,s15,x14/3,s5,x13/11,s1,x5/7,s10,x10/14,pe/h,x8/5,s8,pc/m,s14,x13/15,pf/g,x12/11,s6,x4/3,s1,x15/11,pb/j,x10/13,s14,x11/15,s11,x10/4,s1,x12/7,s11,x3/0,pd/o,x7/11,s13,x2/0,s4,x11/5,pl/b,x2/8,pi/m,x1/13,s1,x3/5,s6,x12/14,s10,x13/3,s4,x10/5,s12,x1/12,ph/g,x15/8,pn/c,s4,x13/12,pm/b,x2/10,pd/l,x1/5,s12,pb/k,x7/3,s7,x2/10,pg/c,x11/5,s14,x8/3,pf/o,s11,x7/12,pa/m,x2/5,s7,x6/4,s11,x8/3,s4,x5/6,s14,x12/3,pj/p,x2/5,s12,x1/14,s2,pd/l,x11/7,pj/h,x0/1,s8,x14/10,s1,x2/13,pe/f,x8/3,s5,x15/5,s1,x9/8,s14,x7/3,s11,pp/h,x10/13,s5,x5/9,pn/m,x8/15,s12,x5/4,pb/e,x13/3,pi/c,x14/2,ph/l,x10/11,s6,x15/9,pm/f,x4/2,pc/k,x6/8,s11,x14/15,s1,x4/6,pb/f,x0/7,s14,x8/11,s9,x5/0,s3,x2/15,pm/g,x4/1,pp/f,x8/12,s2,x15/14,pl/h,x7/8,s15,x5/11,s8,x4/1,s5,x12/6,pk/j,s7,x0/4,pg/p,x15/5,pl/k,x0/3,pj/o,x9/8,s12,x13/6,pd/h,x8/10,s2,x2/1,s7,x8/5,pj/k,x2/4,ph/d,x15/7,s6,x9/10,pa/p,x13/12,s13,x5/10,ph/k,x6/4,pe/d,x8/10,s2,x11/5,pb/f,x7/9,s8,x14/0,s4,x10/13,s6,x3/7,pd/g,x8/14,pm/i,x10/12,s8,x8/11,s7,x15/14,s13,x8/11,s1,x13/6,s15,x14/0,pk/e,x12/6,s4,x14/5,s3,x6/13,ph/d,x1/9,pn/o,s7,x3/8,pb/i,x5/9,s12,x8/6,s9,x5/13,pp/n,s10,x12/3,pa/g,x13/4,s6,x11/0,pl/e,x3/7,s11,x8/4,s10,pd/k,x11/1,pl/p,x4/14,pa/i,x2/7,s12,x13/4,pc/g,x3/10,s3,x13/9,pi/f,x6/3,po/j,x1/12,pg/p,x14/3,ph/l,x9/1,s2,x15/12,s4,x3/0,s11,pk/g,x12/7,s11,x14/11,s5,x6/13,s6,x11/9,pl/b,x10/0,s8,x14/6,s11,x4/15,po/n,x6/13,s10,x2/1,pe/k,x13/4,pd/a,x14/10,s3,x6/2,s14,x8/14,s5,x4/2,s15,x11/12,pb/p,s7,x1/4,s5,x6/13,s9,x4/11,s3,x7/5,pd/l,s6,x15/1,s1,x3/8,s14,x9/12,s1,pn/f,x2/4,s3,x0/9,s15,x1/12,pg/j,x13/8,s6,x12/5,s7,x11/8,s5,x7/5,s2,x13/6,pi/p,x15/0,s6,x3/8,pl/k,x12/4,s14,x7/2,s6,x0/6,pm/c,x5/11,pj/g,s3,x8/13,s14,x12/14,s6,x11/7,s15,x9/3,s4,x15/10,s3,x11/8,s10,x1/10,s4,x15/9,pk/l,s2,x7/8,s3,x9/10,pi/d,x7/12,pl/j,x11/5,s4,x4/14,pm/n,x3/7,s10,x1/6,pf/p,x5/14,s14,x12/2,s7,x3/7,s6,x12/9,pk/e,x0/10,s4,x6/5,pc/i,x1/3,s8,x14/11,s1,x3/12,s4,pg/d,x4/9,s8,x5/0,pb/i,x10/7,s7,x15/8,s9,x12/11,s14,x4/2,s11,x1/13,s9,x12/9,pg/c,x15/8,s10,x0/4,s10,x5/10,s13,x3/9,pp/f,x14/13,pa/n,x15/5,s10,pp/i,x13/10,po/m,x2/7,pe/g,x10/11,pk/m,x0/1,pl/h,x6/2,pa/e,x9/8,s5,x2/6,pc/i,x10/12,s3,x14/3,ph/a,x13/11,pj/p,s14,x14/8,pi/d,x13/5,pf/j,x1/10,pg/i,x15/11,s3,x10/14,s10,x0/9,s5,x5/11,s8,x2/12,ph/f,x1/5,s10,x13/10,pl/j,x8/3,s12,x6/0,s13,x5/7,s15,x9/12,s9,x14/1,s5,x7/6,s6,x13/11,pc/g,x6/5,pd/n,x11/0,pk/p,s1,x2/3,s3,x11/10,s14,x14/0,s2,x15/11,s3,x6/14,pc/g,x4/3,s14,x10/7,s1,x13/11,s1,x7/2,pb/m,x14/10,s5,x13/8,s1,pk/p,x12/0,s3,x11/4,s8,x10/1,s2,x11/9,s12,x1/2,pb/j,x7/10,pp/d,s2,x0/11,s4,x1/10,pa/l,x7/13,s3,x12/1,s9,x7/10,s13,x5/9,po/e,x11/1,s13,x7/9,s1,x4/14,s1,x10/6,pf/l,s7,x8/1,pb/c,x6/3,s6,x4/13,s1,x5/0,s1,pi/f,x4/7,s15,x9/15,s5,x10/6,s14,x12/15,pm/n,x14/10,pp/o,x6/3,pd/j,x12/9,pe/c,x15/6,s2,x7/8,s3,x1/4,pl/a,x9/2,ph/f,x12/4,pj/g,x7/5,pf/h,x1/8,s7,x0/7,s12,x6/14,s4,x15/11,pc/g,x12/0,ph/i,x7/8,po/e,x4/10,pf/p,s6,x5/2,s11,pg/i,x9/7,po/p,x0/10,s14,x7/11,s3,x12/5,ph/j,x9/15,s3,x3/13,pb/o,x15/10,pd/c,s4,x0/2,s2,x6/12,s12,x7/8,pf/l,x13/12,s1,x11/15,s10,x4/0,s2,pc/i,x7/1,pd/g,x5/4,pe/b,x9/7,s7,x8/3,s5,x0/13,s12,x10/2,pa/l,x14/7,pb/g,s10,x11/2,s8,x5/9,s6,x12/0,s9,x13/4,s3,x3/14,s11,x11/9,pp/o,x15/0,s13,x10/3,pb/i,x0/9,s9,x11/6,s12,x10/3,s10,x6/14,s13,x2/9,s11,x7/15,pl/m,x2/6,pp/d,x14/7,s4,pl/k,s1,x12/9,s10,x3/7,pd/p,x8/5,s14,x12/1,pn/o,x11/3,s11,x2/4,pj/b,x6/10,pd/a,x11/8,s7,x10/3,s2,x12/4,pl/e,x10/13,pn/p,x14/0,s8,pm/g,x3/6,s11,x12/15,s10,x1/9,s10,x12/14,s4,x5/2,pn/e,x10/8,s10,x12/0,s10,x7/1,s5,pb/a,x2/14,s6,x10/12,pd/j,x0/8,po/i,x13/9,pm/j,x4/8,s6,x6/3,pe/a,s5,x11/0,s13,x8/12,pd/k,x13/4,po/p,x10/7,s11,x1/9,s4,x14/4,s14,x10/3,s5,x7/0,pd/f,s1,x1/5,pb/l,x11/3,pg/j,x13/10,s1,x8/7,s14,pp/m,x4/5,s12,x2/13,pj/n,x12/0,pl/e,x1/14,pg/n,x4/8,pl/d,x1/14,pf/c,x8/15,pi/n,x11/1,pm/j,x3/4,s5,x15/13,pg/a,x2/12,pl/b,x14/0,s6,x4/1,pp/m,x0/6,s6,x13/4,s8,x0/8,s7,x3/13,s13,x4/6,pg/c,x13/7,pp/l,x9/14,pc/i,x7/10,s7,x6/3,s8,x5/15,s10,x3/4,s12,ph/n,s7,x2/6,pc/f,s7,x4/9,pd/b,x15/13,pi/h,x3/6,s11,x10/14,pe/p,x13/1,pg/f,x5/11,s7,x14/2,s11,x11/7,s8,x13/9,s12,x8/12,s8,x15/1,pe/c,x4/5,s8,x8/6,ph/n,s9,x0/13,pd/i,x10/9,ph/k,s2,x2/4,s7,x11/7,s1,x10/3,pa/o,x2/13,s12,x9/5,s2,x2/12,s9,x7/8,pi/m,x14/10,s8,x8/11,s7,x9/0,pl/n,x14/1,s5,x7/5,s11,x11/3,s14,x14/0,pf/b,x11/6,s10,pj/l,x10/5,s1,x13/2,s13,x14/7,pc/n,x8/15,s11,x12/4,pk/a,x7/3,pj/i,x13/1,s11,x10/14,pd/b,x15/13,pc/e,x1/5,pi/o,s11,x12/3,pa/k,x1/15,pf/g,x11/5,s10,pn/l,x4/6,pg/i,x13/9,s8,x0/14,pf/h,x9/2,po/j,s11,x10/3,s8,x4/15,s10,pl/b,x5/9,s5,x4/1,pi/g,x14/8,s11,x12/7,pc/o,x0/13,pn/m,s10,x6/9,s5,x14/12,s11,x7/0,pi/a,x8/14,s15,x7/5,pm/o,x2/10,pb/n,x15/14,s13,x5/8,s7,x0/11,pl/p,x7/13,pb/i,x1/11,s7,x10/12,s15,x14/9,pl/f,x4/5,s2,x3/7,s15,x5/13,ph/d,x8/0,s8,x12/4,s11,pn/f,s6,x11/1,s1,x3/8,s4,x6/9,s15,x12/0,pi/d,s3,x15/5,pa/o,x0/14,pn/p,x2/8,s2,x15/12,s2,x6/13,pa/e,x14/11,pg/l,s13,x9/2,pn/m,x6/10,s12,x3/8,s11,pc/k,x14/10,s15,x2/11,s12,x1/5,s14,x4/13,s5,x14/15,pl/d,x13/12,pn/h,x4/9,pg/l,x6/7,s4,x0/1,s3,x4/2,s1,x1/0,pe/i,x12/15,ph/d,x6/0,pg/k,x5/9,po/p,x14/13,pn/i,x12/15,s6,x13/3,pb/p,x8/6,s8,x14/2,pf/n,x6/10,s5,x11/1,pj/a,x7/15,s7,x4/3,pg/h,x9/6,s1,x13/0,s1,x10/11,s14,x6/5,s7,x1/15,pb/d,x8/11,pc/h,x15/14,s10,x2/8,pl/o,x3/9,pf/p,x13/0,pg/j,x4/12,pf/l,x14/7,s12,x0/3,ph/p,x8/14,pl/m,x10/7,s13,x3/9,pb/p,x8/10,s5,x9/2,s9,x10/13,pj/a,x6/3,pe/b,x7/9,s12,x14/6,s11,x15/13,pk/m,x7/4,s4,x12/9,s15,po/n,x2/15,s6,x11/5,pm/g,x10/2,s3,x13/15,pb/c,x11/7,s14,x2/5,pk/g,s6,x0/15,pl/f,x3/13,pa/i,x7/0,s13,x9/11,pf/o,s2,pg/a,s3,x5/14,s8,x10/4,pm/o,x7/15,s10,x12/10,s6,x3/1,s7,x6/7,pk/i,s1,x2/11,s4,x7/0,po/c,x14/9,s9,x10/6,s14,x14/1,pf/m,x8/11,po/l,x7/15,s11,x11/5,pf/g,x10/13,s5,x0/1,s2,x4/8,pp/i,x7/0,s7,x1/14,s6,x8/5,s13,x1/11,s7,x5/8,s7,x14/2,s5,x12/0,s1,pk/e,x11/14,s6,x12/2,pm/d,x8/3,s4,x6/4,pn/e,s15,x1/9,pa/d,x2/12,po/c,x8/6,s2,x2/4,pg/a,x12/10,s15,x0/6,pb/d,x10/13,pk/i,x8/4,s6,x10/12,s2,x11/7,pl/e,x0/12,pd/b,x13/9,pj/k,x0/1,s13,x7/8,s7,x0/5,ph/n,x2/14,pc/l,x13/3,s8,x2/11,pb/p,x12/1,pf/g,x15/5,pc/n,x10/7,pf/i,x4/1,s6,x12/3,s3,x9/11,pk/p,s12,x5/10,s4,x11/0,pi/c,x9/4,s9,x7/12,pm/a,x13/9,s2,x1/14,s7,pp/c,x12/7,s15,x8/15,s8,x3/14,ph/i,s1,x6/10,s14,x9/8,s12,x14/2,s11,x6/8,s11,x1/7,s5,x5/13,s10,x11/3,pj/g,x15/2,s15,x11/3,s2,x8/12,s13,x0/3,s2,x12/9,pm/p,x2/11,pl/j,x1/15,pe/o,s9,x7/5,pn/c,x2/0,s10,x8/3,s14,x2/1,s7,x11/15,pk/p,x14/12,po/f,s6,pl/a,x11/9,s11,x10/0,s8,ph/m,x12/9,pn/d,x6/2,s6,x14/13,s1,x11/10,s9,x4/0,pa/m,x11/12,pc/j,x10/3,pp/b,x4/14,s13,po/g,x10/9,s15,x1/12,s8,x3/8,s15,x9/0,s8,x1/4,pa/k,s3,x3/8,s5,x7/10,s7,x13/12,s14,x5/8,s1,x11/13,pb/i,x6/5,pd/a,x2/7,s3,x13/4,pc/j,x15/2,s13,pi/n,x13/3,pf/g,x6/15,s2,ph/l,x13/4,pn/g,x2/8,s12,x4/10,s13,pk/j,x1/9,pl/o,s8,x12/11,s5,x2/5,s9,x13/8,s9,x14/5,pg/d,x13/9,s8,x7/14,s11,x3/2,pa/e,x0/10,pc/n,x15/1,s5,x7/9,pi/o,s4,pj/c,x15/2,s1,x11/13,pe/h,s1,x0/10,s14,x2/8,s4,pa/f,x0/3,pg/k,x5/11,pa/i,x9/8,pb/c,x15/10,s6,x0/12,pf/o,s1,x7/3,pc/a,x5/8,s12,x12/10,s13,x14/6,s5,x10/3,s5,x9/13,s10,x0/8,s14,x4/7,ph/k,x5/1,pf/a,x13/8,pi/d,x3/10,s9,x15/7,s3,x8/4,pl/p,x14/3,s6,x15/5,pm/e,x0/1,pk/f,x15/5,s3,x6/12,ph/d,x3/10,s13,x15/14,pa/c,x9/8,pf/d,x0/4,s14,pa/p,x5/3,ph/f,x1/15,s5,x14/10,s4,x6/8,s3,x15/10,s11,x11/8,s5,x0/5,s8,x15/1,s15,x3/13,s11,x9/4,s15,pe/i,x12/15,s5,pn/d,x7/2,pp/m,x11/15,pa/k,x7/1,s14,x12/0,s12,x11/1,s2,x9/7,s5,x10/13,s6,x7/8,pb/d,x3/9,pf/m,x4/11,pc/p,x8/2,s7,x12/14,s12,x10/15,pm/k,x11/6,pc/h,x9/4,pk/m,x3/1,pi/g,x7/12,pk/p,x10/8,s12,pe/j,x13/2,s15,x6/5,s3,x1/3,pl/a,x11/8,s15,x4/7,pg/f,x3/1,s15,x2/11,s12,x10/0,s9,x3/11,s8,x8/14,s5,x3/9,s3,x0/4,s8,x15/14,pa/i,x12/7,s8,x3/8,pp/m,x6/5,pj/c,x13/14,s10,x6/4,s3,pe/o,x14/15,s9,x8/4,pk/l,x3/10,s2,x0/6,pe/a,s12,x14/5,s10,x0/7,pl/c,x8/6,s2,x11/12,pk/e,x4/13,s7,x3/10,s12,x9/1,s9,x8/0,pj/a,x14/2,pg/h,x9/0,s13,x10/11,pc/f,x8/4,s5,x11/14,s14,x6/15,s10,po/d,x12/2,s5,x13/0,pi/l,x2/5,pj/n,x4/10,s1,x15/12,pp/a,x9/7,s15,x12/3,pe/h,x2/10,s15,x14/15,s15,x12/11,s2,pg/o,x3/5,pm/n,x7/6,s11,pj/b,x0/15,pn/d,x5/14,pf/a,x0/15,pe/k,x11/10,pn/c,s2,x6/15,pf/j,x11/7,s14,x6/14,s2,x5/15,s13,x6/0,s9,pg/n,x11/10,s10,x5/4,s15,x9/6,s6,x4/1,s5,x13/2,s4,pm/f,x8/12,s13,pp/j,x9/6,s9,x0/14,pa/e,x11/12,s6,x14/2,pd/k,s6,x15/7,s8,x9/3,s4,x6/5,s15,x7/13,s6,x6/2,s15,x4/11,s13,x3/8,s9,x2/7,pn/a,x4/1,s7,x11/10,s7,x15/0,s13,x7/10,s3,pg/e,s8,x9/2,s3,x5/8,s6,x14/7,s3,x9/2,s2,x4/7,s6,x15/10,s7,pn/l,x2/14,s11,x3/1,s9,x6/12,ph/m,x4/8,pg/i,x5/12,s4,x4/0,pn/o,x13/10,pc/f,x8/2,s8,x11/14,po/p,x13/6,s5,x12/0,s7,pb/h,x11/4,pd/p,x8/15,s6,x14/10,s9,x5/1,s6,x12/6,pc/g,x1/10,po/h,x4/7,pj/e,x5/12,pn/p,x0/14,s1,x10/11,s5,x12/0,s14,x5/3,s9,pg/h,x7/12,s9,x6/15,s13,x10/13,s13,x8/9,s15,x14/6,s12,x1/11,po/f,x15/5,s6,x7/1,s10,x11/12,pb/d,x5/3,s3,x11/12,pk/l,x4/10,s9,x3/14,pn/d,s1,x6/12,pa/e,x14/0,s15,x2/5,s1,x4/12,s4,x10/15,pb/k,x12/7,po/h,x11/6,pd/l,x4/5,ph/k,x14/3,pj/f,x5/10,pc/b,x3/0,pj/g,s15,x6/2,s15,x9/0,s9,x8/4,s5,pi/m,x15/11,s1,x9/1,s8,x15/5,s12,x9/0,s9,x13/8,s8,x2/9,pl/e,x14/0,pi/b,x6/5,s7,x8/11,pf/g,x7/2,s10,x10/9,s5,x8/5,pi/j,x4/2,s2,x9/15,s2,x4/12,pb/o,x8/14,pc/i,x7/15,s4,x10/2,s5,x8/14,s11,x7/1,pl/a,x4/12,pm/n,x14/3,s8,x11/13,pb/f,x1/8,s14,x9/15,pd/n,x6/11,pa/j,x13/8,s12,x1/6,s6,pe/c,x4/5,pb/d,s2,x9/6,pm/h,x1/2,s9,x0/10,s12,x9/13,s1,po/j,x5/3,s1,x2/4,s4,x10/0,ph/n,x14/5,s9,x11/0,s1,x14/6,s11,x15/10,pg/b,x1/13,s8,pd/h,x11/9,po/g,x12/13,s7,x1/7,s3,x14/10,pb/d,x0/11,s11,x14/1,s6,pn/k,x12/15,s9,x4/7,pg/h,x10/14,s10,pi/c,x15/9,s3,x14/1,pk/h,s9,x3/10,pi/l,x13/14,pe/n,x7/9,s4,pp/d,x12/1,s3,x15/10,pl/n,x9/1,pm/k,x14/3,s15,x0/1,s15,x15/11,pf/g,x13/2,s15,x3/14,s1,x6/10,pj/e,x5/15,pg/c,x10/4,pp/l,x11/1,pj/o,x14/15,pm/a,s5,x6/5,pp/f,x10/11,s10,x1/12,po/k,s11,x5/11,s4,x14/12,s8,x8/11,s15,pl/a,x10/14,pk/o,x15/7,s2,x11/5,s5,x2/7,s5,x6/8,s10,x11/1,pp/j,s13,x5/0,po/a,x9/6,s8,x7/5,s2,x2/13,pj/b,x1/0,pa/d,x4/7,pp/k,x12/14,pi/l,x15/7,po/d,x5/11,pa/h,x0/2,s2,x6/5,pe/k,x11/9,s1,x8/1,s2,x5/6,s14,x7/3,s7,x6/14,po/b,x12/4,pm/h,x9/0,s9,x15/2,s10,x0/8,s1,x1/14,s11,x3/11,s14,x10/1,s1,x4/15,pi/d,s15,x9/11,s10,x0/2,pb/k,x4/3,s11,x0/10,pa/p,x9/4,s9,x10/7,s9,x0/13,s11,x9/14,s10,x6/11,pd/j,x8/13,s12,x14/12,s5,x6/0,s5,x10/11,s3,pn/a,s9,x5/8,s12,x11/7,s8,x9/6,s8,x7/8,s7,x4/1,s2,x9/15,s7,x4/12,s6,x8/3,s3,x9/1,s3,x12/3,s2,x8/4,s5,pc/f,x3/12,pn/m,s6,x13/2,s7,pf/b,x3/7,s9,x4/11,s13,x7/5,pl/n,x13/0,pb/g,x2/7,s12,x9/6,s11,x8/13,pm/h,s2,x1/12,s15,x11/4,pe/j,x6/7,pi/g,x12/15,pk/a,x1/2,pf/e,x4/6,s11,x15/13,pj/a,x6/2,s11,x9/12,s7,pi/m,x3/2,s4,x15/10,s14,pj/e,x13/7,pb/m,x6/3,ph/i,x11/15,s14,x12/7,pg/b,x4/5,s2,x1/13,s5,x9/0,s1,x7/5,s11,x15/1,s6,pp/d,x3/9,s4,x6/5,pi/m,x11/7,s1,x10/15,pc/h,x14/0,s5,x12/15,s5,x9/2,s13,x13/10,s4,x1/12,s8,x13/0,s15,x1/3,s2,x7/13,s9,x2/9,pd/b,x6/10,ph/e,x5/9,s11,pp/d,s15,x2/11,pl/a,x15/4,s10,x2/0,s12,x7/15,pe/k,x9/4,s3,pc/o,x0/12,pn/i,x5/3,s9,x0/8,pd/e,x10/11,s4,x9/14,s3,x13/4,pj/f,s10,x8/1,po/h,x4/0,pb/a,x3/5,s10,x4/13,pd/i,x1/14,pl/o,x7/11,pa/m,x0/15,po/l,x14/7,pj/c,x15/9,pn/k,x7/8,s12,x0/10,pl/c,s15,pi/e,x4/2,s1,pl/n,x8/5,s4,pm/p,x6/9,pb/o,x0/11,pa/e,x3/13,pb/d,x1/15,s2,x11/6,s6,x3/9,s9,x8/1,s11,x7/0,pf/i,x2/15,s9,pm/l,s7,x4/6,pc/n,s6,x0/12,pm/i,x11/13,pj/e,s15,x8/7,pd/n,x11/3,s15,x1/4,pi/b,x11/15,s9,x14/0,s7,x2/8,pa/n,x3/0,s14,x9/6,pd/p,x5/15,pf/g,x7/9,pb/d,x2/11,s7,ph/j,x1/15,pa/n,s14,x4/6,s13,x5/3,s1,x6/15,pf/d,x13/9,s8,pk/j,x6/2,s1,x7/14,pl/o,x1/4,s3,pn/d,x3/7,pa/m,x14/6,po/e,x3/10,s1,pp/b,x0/9,pi/o,x5/13,s13,x4/1,s15,x8/7,s10,x15/4,s14,x0/14,pp/c,x9/11,pg/o,x6/2,s1,x1/7,pn/a,x0/12,pe/c,x4/7,pn/h,x13/9,s9,x2/6,pl/g,x10/7,s12,x0/8,pp/f,x15/3,s15,x6/14,s10,x9/1,pc/n,s2,x3/2,s9,x0/10,s14,x8/6,s11,x3/15,pp/j,s7,x8/6,s2,x7/0,s11,pd/a,x13/5,s14,x7/9,s6,x5/13,pk/b,x8/4,s5,x0/12,pn/e,x9/15,pb/d,x2/7,s5,x3/5,s15,x13/12,s3,x5/2,s4,x9/10,s12,x14/4,pf/j,x9/15,s6,x7/2,s10,x14/0,s10,x15/1,pd/p,s12,x10/12,pj/a,x7/8,pn/f,x1/0,pg/p,x14/6,pd/i,s7,pg/b,x0/9,s13,x11/2,s5,x9/15,pi/f,x13/4,s3,x8/2,s4,x13/0,pn/h,x5/9,s7,pm/f,s15,x4/3,pn/c,x1/8,pl/a,x3/0,pg/k,x13/11,s12,x2/7,s9,x12/11,s11,x5/6,pi/p,s12,x1/9,s5,x0/10,pf/k,s15,x13/14,s13,x1/10,s3,x6/0,s13,pg/d,x10/11,ph/n,s5,x8/3,pc/b,x12/10,s14,x5/3,pm/p,s4,x13/14,pk/b,x2/3,s10,x4/15,pp/e,x7/11,pj/c,x3/1,s4,x10/2,pb/g,x1/14,po/j,s14,x12/8,s15,x6/14,s10,x15/3,pk/f,x1/12,s3,x4/0,s11,x1/11,s7,x7/10,s9,x1/2,pl/h,s3,pd/e,x6/0,s14,x1/11,pi/p,x2/15,s2,x3/4,s13,x1/5,s4,x14/15,s2,x7/3,s11,x10/8,s2,x0/2,s15,x3/11,s6,x14/7,pj/a,s3,x3/4,pe/p,x15/2,pa/i,x10/0,s1,x2/1,s9,x4/6,s9,pf/e,x13/3,s14,x5/8,pc/h,x1/7,s6,x10/3,pg/f,x6/9,pj/e,x4/12,s2,pp/n,x14/5,pc/a,x6/2,pf/e,x3/7,pj/a,x12/5,pp/h,s10,x9/4,s2,x15/3,pd/c,x14/6,pp/j,x5/1,s8,x14/9,s12,x0/4,pb/e,x10/13,s12,x1/3,s13,pj/m,x5/11,s11,x6/8,s1,x9/15,s13,x1/13,s13,pe/c,x10/2,pm/n,s8,x4/1,s3,x11/5,pd/h,s3,x6/15,s7,x2/5,pj/k,s10,x15/12,s15,x2/0,s10,x7/6,ph/i,x14/0,s7,x8/3,pj/k,x1/9,pp/i,x14/15,s11,x10/1,s12,x14/0,s2,x10/7,s10,x11/8,pk/b,x14/4,po/e,x15/13,s11,x8/1,pi/m,x5/0,s7,x9/2,s13,x8/0,pn/d,x7/1,s10,x13/8,pm/l,x11/15,pe/d,x7/10,s4,x12/11,s14,x1/0,s12,x14/13,pk/f,x11/15,s4,x9/5,ph/m,x10/0,pg/o,x3/8,pj/p,x6/13,s14,x3/2,s2,x0/11,s7,x4/13,pa/l,s6,x3/12,s4,x7/5,s12,x10/14,s13,x4/0,pc/d,x2/6,pj/g,x5/8,s4,x3/2,pm/h,x0/6,s4,x15/13,s6,x12/11,s9,x7/1,s8,x9/15,s12,x10/12,pa/c,x14/4,s11,x8/5,s11,x13/9,pb/n,x5/12,pd/c,s1,x8/3,s3,x11/9,s3,x3/2,s8,x11/1,s4,x10/0,s2,x7/4,pm/p,x12/2,s15,x8/10,po/f,x15/1,pe/h,x0/4,pm/c,x1/11,pj/k,x8/13,s1,x15/10,s9,x4/3,s9,x11/6,ph/p,x0/15,pb/g,x10/2,s3,x14/0,s3,pc/e,x1/11,pl/p,x5/13,s8,x0/3,s7,x4/15,pb/n,x7/8,pa/j,s12,pl/k,x15/13,s6,pd/i,x10/7,s5,x14/13,s4,x1/11,s4,x6/10,s1,x4/13,pn/f,x0/12,s6,x10/14,pd/e,x15/2,s6,x14/0,s2,x8/2,pf/i,x7/4,pp/e,x5/13,pa/l,s10,x6/10,s4,x0/14,s8,x2/13,pk/i,x1/0,pd/l,x9/3,s10,x10/7,s12,x15/8,s4,x1/0,s15,x12/6,s12,x1/11,ph/j,x10/2,s5,pc/f,s3,pe/h,x3/0,s14,x4/13,s9,x7/3,pk/c,x5/1,pm/n,x12/4,s3,pe/f,x10/15,pd/g,x6/12,pb/o,x13/11,pk/n,x6/8,pj/d,x3/0,s9,x8/15,s7,x14/11,pa/c,x5/9,s2,x4/12,pk/l,x11/3,s11,x12/15,s3,x8/5,s11,x11/6,s13,x7/2,s15,x13/6,s5,x1/15,s5,x5/11,s1,x1/15,pp/i,x9/13,s7,x4/8,s13,x15/6,s4,x13/7,s7,x6/5,pd/c,x4/1,s5,x0/9,s5,x4/13,pa/g,x15/8,pi/b,x0/7,s15,x2/5,pj/a,x13/9,s3,po/h,x7/5,pm/a,x12/1,pc/p,x15/9,pf/l,x10/8,pk/e,x6/2,s12,x7/12,s4,x15/10,s2,x9/8,s6,x3/7,s1,pd/n,x13/2,pj/o,x1/4,pa/n,x12/14,s6,x11/0,s4,x8/2,s7,x14/3,s8,x7/13,pb/k,x0/11,pl/o,x9/15,pa/b,x14/12,s4,x0/9,s3,x6/13,s9,x15/5,s3,x13/2,pj/i,x4/3,s1,x8/12,s12,x6/14,s15,pb/p,s2,x1/12,s11,x11/13,pn/h,s2,x0/9,s12,x12/5,pi/j,x6/14,s7,x12/8,s2,x14/11,s9,x9/10,s4,x3/1,s2,x8/14,s7,x2/11,s14,x6/8,pl/k,s12,x7/1,s4,x15/11,s1,x4/9,s9,x2/6,pd/o,x10/12,s9,x3/13,pc/a,x0/10,s15,x12/9,s3,x1/5,po/e,s13,x4/12,s5,x1/11,s1,x10/9,s11,x7/14,s2,x15/13,pp/j,x2/10,s15,x6/15,pg/m,x13/1,s7,x10/12,s4,pl/n,s15,x4/2,s15,x11/12,s14,x8/3,s14,x7/12,s6,x9/15,pa/d,x3/0,s8,x14/6,pp/c,s13,x1/15,s6,x5/2,s3,x10/13,pd/m,x11/9,ph/n,x12/6,pg/m,x4/1,s9,x8/13,s9,x9/11,s9,x10/13,po/a,x12/6,s12,x14/3,s7,x4/15,s11,x7/8,s1,x12/10,s5,x6/14,s11,x4/7,pp/n,x9/8,s4,x15/2,s10,pm/f,x6/9,s11,x15/12,s6,x5/7,s10,x0/1,pb/i,x2/12,s13,pk/l,x5/6,s11,x7/1,pe/d,x12/14,s10,x10/3,pc/p,s2,x0/12,pn/h,x5/4,s10,x10/7,s4,x9/6,s7,x15/13,s2,x14/0,s15,x13/9,s3,x8/3,s7,x12/4,s3,x15/11,pd/o,x6/0,s11,x3/13,s12,x2/7,pn/g,x14/15,s2,pd/b,s12,x6/11,s7,x13/4,s2,x15/10,s7,x14/6,s2,pi/o,s13,pj/c,x3/2,s2,x12/9,s10,x14/5,pa/l,x1/15,pj/m,x14/9,pf/o,x2/0,s3,x3/10,s3,x14/13,s3,x8/11,pg/h,x1/10,pn/a,x4/13,po/m,x6/15,pg/a,x10/2,s3,x4/13,s7,x1/14,s1,x6/4,ph/i,x13/8,pf/j,x6/4,pd/m,x1/3,s7,x8/13,s13,pk/o,x2/3,s11,x13/14,pe/d,x6/0,pa/o,s9,x12/14,pb/d,s4,x9/11,pl/h,x10/13,s15,pn/m,x12/9,s13,x11/2,pg/a,x0/5,pk/p,x15/11,pa/i,s10,x6/0,s14,x11/7,s6,x0/9,s9,x15/6,pg/l,x5/13,s10,x6/7,s4,x12/10,s13,x0/8,s13,pf/o,x10/5,pa/b,x3/0,pc/p,x8/2,pd/h,x14/0,pn/j,x9/12,pd/o,x2/4,pk/b,x5/11,s2,x14/7,ph/j,x10/5,s8,x8/14,s10,x7/9,s8,x3/1,s9,pp/m,x9/2,pa/e,s4,x4/13,ph/d,x2/12,s10,x5/3,s14,pl/o,x15/4,s1,x7/14,s14,x10/3,s9,x13/5,pi/e,x1/4,s9,x15/11,s5,x0/13,s10,x2/6,s15,x15/14,s5,x3/1,s6,pl/k,x9/11,s6,x12/7,po/b,x2/0,pf/c,x6/8,s13,x0/13,s14,x8/7,s2,x3/12,s9,x4/7,s3,x10/11,s1,x1/3,s13,pl/b,x9/2,pg/p,x8/11,s1,pl/j,x13/12,pa/o,x8/3,pp/f,x9/5,s4,pg/j,x7/4,pi/p,x11/5,s2,x2/3,s12,x0/8,pk/g,x1/12,s12,x11/14,pl/e,x1/2,s13,x11/7,pd/g,x4/12,s8,x2/1,s1,pc/a,x15/11,s12,x8/2,s1,x4/1,s15,x5/15,s5,x4/8,pk/h,x7/2,pf/n,x1/9,pj/m,x11/13,s15,pi/f,x5/0,po/k,x11/14,s12,x3/13,pb/c,x8/2,ph/d,s9,x7/11,s14,x15/4,pm/b,x11/10,s4,x0/13,po/d,x10/6,pg/i,x7/15,pl/c,x6/13,pb/i,x0/15,pm/n,s15,x1/12,s6,x8/9,s9,x4/5,pa/g,s6,x12/10,s13,x8/3,s7,x10/15,s13,x7/8,s3,x10/12,s8,x0/9,pf/p,x12/3,po/a,x6/15,s14,x14/11,s10,x9/13,pd/p,x11/3,s9,pa/c,x15/10,pb/f,x13/4,po/i,x3/10,s9,x13/4,pm/a,x10/0,pd/i,x6/7,pe/h,s15,x5/12,s8,x2/4,pb/g,x11/6,pi/h,x12/5,s4,x8/4,pp/n,x9/10,s1,x12/2,pj/c,x13/8,s10,x4/5,s14,x0/13,pi/e,s7,x6/7,s6,x3/10,s4,x11/13,s14,pa/p,x8/1,po/c,x13/6,s5,x9/11,s7,x13/8,s1,x11/4,pg/d,x3/0,s15,x1/11,s10,x12/9,pf/n,x8/1,s4,x2/5,s8,x11/7,pl/m,x9/4,pe/b,x0/7,s15,x13/6,s1,x1/14,pm/p,s10,x10/2,s8,x15/0,pd/e,x8/14,s2,x12/1,s14,x9/8,s2,x14/6,pn/k,x13/11,pg/c,x7/15,s14,x0/6,s4,x4/2,s9,x13/10,pd/h,x2/6,pg/n,x1/9,s14,x13/0,pi/m,s8,x10/7,s7,x3/5,pl/b,x12/2,pg/e,x8/6,po/d,x0/3,s3,x11/9,s1,x0/1,pb/a,x7/14,s12,x6/1,ph/k,x5/10,pm/b,x13/4,s13,x0/9,pd/k,x1/11,s4,x5/13,s13,x0/8,s4,x11/4,s4,x1/13,ph/g,x4/10,pa/e,x11/3,s1,x5/4,ph/c,s7,x13/14,s2,x8/7,s8,x0/4,s8,x3/10,s1,x14/1,s14,x9/0,s5,x5/10,pg/k,x6/13,s14,x8/1,pa/j,x0/4,pf/n,x12/9,pb/j,x0/5,s2,x15/8,s3,x4/12,s3,x2/11,pg/i,x6/12,s12,x7/15,s11,x5/13,s9,x2/9,s13,x10/12,s2,x6/5,pf/k,x9/15,pe/a,x4/7,s3,x0/11,pd/i,x4/12,s5,x6/7,s8,x14/9,s1,x13/4,s1,x8/2,s6,x11/6,s15,x14/8,pj/o,x6/3,pc/m,x10/7,s14,x13/6,s11,pd/p,x12/10,s3,x0/5,s2,x11/14,pg/c,x15/6,s9,x1/10,po/i,x7/0,pm/g,x5/11,s1,x3/13,s12,x9/2,pl/f,x14/4,s3,x2/3,po/h,x0/14,s4,x11/3,s2,x12/2,s5,x5/6,pk/g,x10/1,s5,x5/6,s9,x15/0,pd/a,s11,x2/12,s14,x7/15,pg/b,x3/0,po/n,x2/8,s4,x4/5,pj/d,s3,x1/2,s7,x5/13,s8,x10/9,s1,x15/7,s4,x10/3,po/g,x5/12,s3,x6/11,s7,pa/f,x8/12,pp/l,x3/6,s6,x4/0,po/i,x6/2,s12,x4/3,s9,x11/0,pa/f,x9/7,s12,pc/o,x11/0,pa/k,x3/8,s13,x14/13,pc/n,x1/8,s15,x14/6,s7,x5/2,pi/o,s1,x0/9,s11,x1/13,s9,x5/9,s8,x7/3,pp/f,x1/13,pc/d,x2/3,s11,x0/1,s12,pl/g,x5/11,s3,x9/10,s15,x3/5,s15,x10/1,pm/e,x5/13,pf/b,x4/9,s14,x6/3,s6,x12/15,s4,x8/7,s15,x1/15,pd/l,x6/11,po/b,x4/10,s9,x15/6,s15,x12/5,pk/g,x13/6,pe/a,x2/15,pb/i,x14/13,s4,x9/1,s8,x14/10,pj/m,x12/4,s6,x2/13,s8,x11/8,s12,x7/15,s7,x5/11,s13,x0/1,s1,x5/9,pa/p,x1/12,s14,x9/2,s10,x10/7,s9,x2/5,s11,x14/9,s6,x5/7,pn/j,x9/8,s12,x2/0,ph/b,x12/7,s1,x14/15,pe/l,x11/9,s13,x2/14,s3,x6/1,pj/o,x12/15,s15,x6/9,pf/c,x10/1,s11,x11/12,s6,x10/3,pa/l,x7/12,s7,x8/2,pc/o,s10,x4/9,pj/d,x1/11,s15,x0/8,s7,x2/4,s11,x0/8,s4,pe/h,x9/1,s13,x11/4,s15,x1/9,pn/l,x6/8,s2,x11/10,pp/c,s12,x8/1,s9,x5/4,pa/d,x10/7,pm/e,x11/2,s8,x15/0,s5,x2/11,s5,x13/8,po/p,x0/10,s14,x2/14,pk/j,s8,x6/3,s12,x7/11,pi/a,x9/5,pl/k,x12/7,s2,x6/11,pd/c,x4/0,s1,x7/10,pl/g,x12/9,pp/c,x1/2,pg/l,s3,x7/3,s8,x14/0,pk/m,x15/13,s13,x12/4,pg/o,s12,x11/15,s7,x8/7,s2,x5/13,pm/f,x12/6,s12,x0/5,s14,x13/4,ph/j,x10/2,s1,x8/6,s9,x11/9,pn/i,s4,x15/10,pm/l,x7/3,s14,x4/2,s4,pe/h,x7/1,s6,x9/13,s7,x14/1,pi/l,s15,x15/7,pp/h,x5/14,pi/g,x2/3,s10,pb/a,x5/15,po/g,x11/9,pp/f,x2/10,pc/n,x9/6,s2,x1/11,pj/i,x9/0,s3,x10/12,s5,x3/4,pg/k,x1/0,pj/i,x3/7,pl/c,x1/11,s12,x3/14,s13,x6/10,s6,x11/14,pd/n,x5/13,s6,x12/4,s15,x2/6,s8,pj/l,x4/1,s8,x7/13,s3,x1/3,pb/h,x5/9,pd/f,x0/15,s14,x1/7,pg/n,x4/11,po/d,x14/13,pk/j,s6,x5/8,s3,x13/14,pe/m,x2/12,s1,x14/11,pb/a,x13/8,pe/d,x11/1,pl/k,x15/13,s1,x5/14,s5,x4/0,s2,x3/2,s15,x14/12,pc/b,x1/11,s15,x6/8,s5,x10/1,s2,x9/7,s1,pf/k,x4/6,ph/c,x2/11,pd/o,x9/10,s10,x7/1,s1,x0/8,s8,x4/9,pp/f,x1/12,s14,x9/6,s11,x14/7,s12,x8/5,s14,x2/14,pa/d,s10,x15/8,s5,x3/4,pc/e,x6/2,pb/g,x3/13,pa/d,x4/5,pp/e,x2/10,s2,x7/9,pb/a,x0/3,s13,x6/13,s2,x15/7,pc/l,x6/3,pk/g,x2/11,pf/i,x6/12,pj/p,x2/4,s2,pn/i,x14/8,s3,x0/4,s9,x8/10,pp/c,s4,x3/9,s2,x1/0,s12,x8/5,s2,pn/j,x7/9,s14,x11/14,s2,x15/8,s6,x1/13,s15,x5/2,s9,x1/7,s10,x3/11,pl/i,x10/5,s8,pd/p,s10,x2/6,s12,x0/8,s5,x11/4,s8,x7/13,s15,x3/5,s14,x15/10,pf/m,x2/11,pe/d,x14/12,s15,x1/10,s5,x9/11,pc/a,x0/2,ph/m,x14/7,s10,pd/k,x11/8,pm/l,s11,x1/9,pc/h,x4/3,s12,x15/0,pl/i,x11/2,pc/n,x5/14,s10,x3/9,s5,x14/10,pa/p,x12/0,po/b,x15/10,s9,x9/12,pm/p,x0/1,pj/i,x2/4,s9,x6/10,s14,x13/0,pd/c,x9/14,pm/e,x15/5,s3,x8/14,s6,x4/7,s8,x9/11,s9,x0/14,po/g,x6/15,pj/d,x1/5,pe/h,x15/13,s4,x9/12,s13,x6/13,pk/p,x5/14,pl/i,x6/11,s11,x10/15,s5,x13/12,s12,x6/4,s9,x11/10,s10,x1/15,s7,pp/m,x12/7,pj/e,s4,x1/0,pb/k,x13/6,s6,x1/7,s1,x15/11,pg/m,x6/3,s13,x13/7,s7,x10/5,s12,x1/0,s14,x6/5,po/j,x10/13,s5,x14/12,s8,x5/2,s12,x10/12,pc/l,x1/9,s13,x5/4,s6,x8/11,s13,x12/10,po/j,s11,x15/14,s11,pa/k,x3/5,pm/p,x4/14,pn/a,x7/5,ph/d,x2/0,pm/c,x15/7,s11,pn/j,x0/10,s9,x8/15,pe/l,x1/13,pb/n,x12/10,ph/o,x8/9,s11,x10/1,s6,x8/7,pj/b,x10/0,s2,x5/3,s13,x4/13,s4,x9/1,s4,x10/13,ph/e,x0/6,s6,x15/5,s10,x8/3,s8,x14/13,s6,pg/b,x0/11,s2,x10/5,s7,x12/9,s12,x10/3,pa/d,x15/14,s15,x9/10,s1,x13/12,pe/o,s12,x8/1,s1,pk/m,x11/4,s5,x10/6,pp/a,x0/3,s13,x13/1,po/n,x3/5,s12,x7/2,s13,x15/6,s10,x11/7,s6,x1/15,pl/e,x6/2,s6,x8/7,s5,po/c,x6/12,pl/f,x8/7,s2,x0/1,pd/j,x11/4,s14,x15/13,pe/g,x1/5,pa/h,x10/11,s13,x8/14,s3,po/p,x15/3,pc/a,x14/1,pi/m,x10/13,s5,x12/11,s8,x10/5,s15,x12/7,s15,x3/6,pa/g,x4/0,pn/c,x14/12,s3,x3/4,pa/p,x9/11,s10,x8/0,po/e,x10/3,pm/b,x11/4,pd/e,s5,x5/13,s6,x10/8,pa/k,s11,pg/d,x4/7,s10,x15/12,pl/a,x3/1,pk/b,x8/9,ph/e,x1/7,s12,x14/10,s9,x8/6,pk/p,x0/4,s4,x13/3,po/i,x7/4,s3,x10/3,s14,x0/7,s2,x9/15,s1,x0/7,s11,x3/13,s12,x0/8,pc/g,x11/12,pb/d,x8/3,pp/j,x5/10,s1,x7/2,s10,x5/6,s9,x9/12,s11,x3/8,s9,x15/10,s7,x8/4,pc/h,x14/2,s15,x15/3,s15,x14/5,s5,x6/15,s7,x9/11,s3,x1/13,s6,x3/7,s12,x11/6,pa/g,x0/9,s4,x8/11,s4,x2/7,s2,x10/14,s14,x8/9,s15,x1/4,s15,x8/14,s6,x13/4,s12,x15/1,ph/j,x13/2,s7,x14/10,s5,x1/2,s15,x11/13,s10,x9/12,pg/f,x0/10,pi/c,x13/8,pe/p,x0/9,pa/m,x13/5,pp/k,x0/10,pa/c,x7/13,s4,x1/4,ph/f,x0/8,po/k,x2/7,s2,x9/1,s6,x5/8,s10,pi/g,x7/11,s7,x0/4,s11,x7/3,pe/j,x0/2,po/k,x14/3,s14,x15/8,s5,x14/12,s12,x10/2,pp/h,x0/15,s12,x6/13,s8,x3/1,pe/c,x0/2,s15,x14/12,s9,x10/4,pj/p,x1/7,s2,x3/2,pn/k,s5,x6/15,s12,pp/e,x7/5,s14,pj/m,s15,x14/11,s9,x4/5,s4,x13/2,s1,x7/5,pp/i,s11,x14/12,s7,x8/9,pa/j,x10/6,pg/o,x13/8,pb/n,x7/0,pj/i,x6/12,s1,x2/15,pm/g,x10/9,po/c,x2/1,s15,x8/4,pk/i,x12/3,pg/a,x0/6,pp/f,x14/5,pl/c,x3/1,po/h,x6/13,s14,x14/4,s13,x9/15,s3,x14/11,pa/n,s7,x3/10,pm/h,x9/11,pp/a,x2/7,s12,x3/11,pb/e,x14/1,pp/g,x11/9,s14,pe/k,s9,x3/12,ph/d,x7/10,s2,x11/13,s9,x6/3,po/m,x11/13,pe/g,x8/0,pa/o,x1/14,pg/m,x5/2,pc/j,x14/0,pn/k,x13/3,s3,x8/5,s14,x1/3,s5,x5/9,s10,x8/15,s5,x6/3,s14,x2/0,pb/e,x12/7,pm/c,x4/2,s1,x5/3,pk/b,x1/7,s13,x8/0,s2,x12/3,pp/f,x6/9,s5,x15/12,pi/l,x3/6,s2,x10/14,s15,x0/4,s5,x11/14,s15,x15/8,s9,x12/0,pe/n,x7/2,pb/p,x3/6,s2,x8/7,s13,x11/6,pl/d,x4/1,pj/b,x13/9,pi/e,x0/11,s5,x2/15,pl/b,x10/13,pm/h,x4/7,s8,pf/k,x14/12,s11,x3/8,s11,pj/n,x1/0,s13,x14/11,s2,x7/1,s11,x8/2,s13,x9/11,s8,x10/3,s13,x13/14,s1,x4/12,pm/p,x6/5,s6,x13/10,pe/i,x12/11,s13,x1/15,s2,x5/3,pc/a,x6/9,s12,pd/h,x5/8,s11,x7/12,pn/i,s6,x8/4,s15,x7/9,s3,x12/4,s6,pf/e,s12,x15/0,s10,x2/3,s13,po/a,x6/9,s10,x7/11,s12,x9/10,pg/m,s9,x12/5,s9,x2/15,s10,x3/14,s8,x4/12,s6,x0/13,s10,x3/2,ph/a,x12/14,s2,x8/6,s10,x3/5,pi/n,x15/9,pc/h,s9,x0/4,s2,x1/13,s14,x15/11,s1,x5/2,s1,x10/3,pd/j,x9/0,s1,x10/14,s9,x12/2,pb/m,x3/8,s3,x7/6,pl/n,s9,x3/14,s14,x4/1,s4,x8/12,pk/g,x3/13,pn/d,x10/11,s2,x13/14,pb/i,x10/15,pp/n,x4/11,s4,x0/9,po/f,x13/3,s7,pd/b,x9/8,s14,pa/n,x0/1,s3,x5/4,s7,x13/8,s9,x11/7,pp/d,x4/9,s7,x14/3,pf/j,x11/9,s4,x2/4,s1,x1/5,pd/l,x15/2,pe/n,x14/1,s12,x0/13,pc/p,x5/12,pb/k,x11/13,s8,x5/1,s10,pn/c,x6/14,po/d,x7/3,s7,x0/8,pa/k,x3/7,s6,x14/15,ph/f,x1/5,s6,x9/6,pk/l,x15/11,pf/d,x2/5,pl/i,x7/13,pj/g,x15/4,pf/b,s5,x2/11,s4,x15/10,s4,x1/3,pk/o,x14/6,s13,x13/5,pa/f,x11/12,s6,x1/13,s2,x6/11,pk/j,x9/13,s1,x4/3,s2,x2/9,pi/d,x10/15,s8,x12/11,s11,x9/8,s6,x14/7,pc/b,x4/0,s9,x1/8,s12,x14/2,s11,x1/8,s13,x3/12,ph/p,x0/13,pf/n,s11,x9/4,pg/e,x3/11,s2,x4/9,pa/p,x2/13,s1,x12/4,s11,po/e,x10/1,pn/p,x9/5,s11,x1/4,pg/k,x8/2,s5,x9/10,s10,x11/8,pi/n,x4/2,s2,po/l,x14/3,pm/j,x8/11,po/a,x14/4,pk/l,x2/9,ph/e,x3/1,s15,x0/5,s14,x8/10,s8,x5/1,pk/j,x4/9,s4,pi/h,x1/10,pc/j,x5/4,s5,x12/8,s11,x3/10,s12,x5/15,s4,x11/9,s8,x13/2,s10,x3/8,s9,x12/1,s2,x13/5,s8,x15/10,s2,x12/11,s8,x2/3,s2,x11/15,pe/k,x12/9,s9,x0/8,s10,x14/9,s7,x2/12,pl/b,x6/14,s7,x15/8,s10,x13/9,pd/p,x1/0,ph/k,x2/8,s7,x14/0,s7,x11/13,s7,x4/10,pj/e,s14,x6/8,s11,x1/5,s2,x11/6,pk/o,x12/0,s2,x10/14,s9,x0/4,s2,x7/8,s8,pa/p,x15/9,s5,x4/7,s4,x3/13,ph/e,x1/5,s1,x8/9,pa/i,s1,x12/14,s14,x2/8,s10,x10/0,s11,x3/13,s15,x4/8,pd/n,x14/7,pi/h,x10/0,s7,pk/j,s5,x7/8,pl/n,x14/2,s8,x6/11,s10,x1/13,pb/e,x4/14,pl/k,x13/8,pp/m,x1/11,pn/i,x12/8,s13,x5/14,pc/m,x6/9,s9,x4/7,s10,x0/10,s8,x8/4,pg/b,x13/2,pe/f,x11/5,s8,x7/3,pc/j,s12,x0/10,s12,x6/11,s6,pa/p,x5/3,s1,x10/0,pg/k,x2/11,s8,x13/14,s5,x3/4,s8,pm/l,x14/8,s5,x13/12,pf/d,x1/3,ph/b,x15/14,po/k,s4,pa/j,x10/6,ph/c,x9/0,pn/a,x2/6,s4,x0/3,pk/g,x14/10,s8,x7/13,s7,x11/14,pm/e,x12/13,pj/h,x0/7,s10,x11/3,pg/b,s14,x8/12,s6,x9/0,s6,x15/14,ph/l,x6/2,pi/m,x12/10,s13,x14/5,s12,x7/1,s10,x2/3,s1,x10/11,s4,ph/b,s10,x3/7,pg/m,x2/8,po/k,x3/5,pb/n,x6/11,s3,x12/4,s4,x13/8,pf/e,x2/11,s9,pg/o,x13/15,s14,x5/6,s15,x4/8,pb/h,s5,x15/3,pf/o,x2/8,s10,x4/9,s9,x12/15,s15,ph/b,x2/8,pp/i,s2,x7/1,s6,pk/l,x4/11,pg/i,x7/2,s8,x3/12,pp/n,x13/14,s2,x2/1,s5,x11/9,s3,x6/0,po/l,x9/3,pc/f,x0/12,s1,x2/4,pl/d,x12/5,s8,x4/3,pe/o,x2/12,pc/b,x13/5,pj/l,x12/4,s6,x3/15,s5,x0/4,pk/o,x10/2,s3,x15/14,pf/b,x6/0,pl/i,x7/3,pg/n,x1/2,s9,x3/12,s1,x9/15,s9,x11/7,pb/o,x6/9,s2,x0/7,ph/k,x4/3,s10,x8/2,s13,pi/c,s9,x9/13,s7,x4/2,s13,x0/10,ph/k,x15/13,s12,x2/9,pc/e,x5/14,pk/h,x11/3,po/e,s1,x10/1,s15,x12/3,pb/k,x5/0,s3,x6/7,s15,x14/4,s7,x6/9,s14,x1/10,pa/f,x14/13,s6,x6/9,pi/p,x10/5,pg/f,x3/7,pd/m,x8/5,pi/b,s8,x11/13,s7,x1/14,s8,x15/10,s10,po/l,x2/0,ph/d,x12/5,pl/a,x11/10,s10,x13/4,s4,x0/15,s7,x9/13,s7,ph/g,x6/2,pa/o,x12/14,s9,x2/11,pe/n,x9/3,s15,x13/1,s2,x9/15,s12,x5/12,s11,x7/9,pc/f,x10/12,s5,pl/p,x1/15,pi/b,s11,x4/3,s5,x13/11,pe/c,x10/12,s1,ph/k,x6/13,pp/g,x14/8,s7,x2/5,pa/i,x13/9,s4,x4/3,pj/o,s12,x15/11,ph/l,s7,x3/10,s14,x12/13,pe/c,x10/11,pm/h,x4/9,s15,x5/14,s10,x6/7,pc/a,x0/2,ph/k,x13/9,pd/n,x0/12,pg/j,x3/8,pb/f,x0/1,s3,x14/9,pi/n,x5/11,pe/j,x3/8,s8,pc/g,x9/11,s1,x7/1,pa/j,x13/15,s9,x4/5,s9,x7/2,pg/d,x12/3,s7,x10/1,s1,x14/8,pb/e,x1/5,s10,x6/7,pc/j,s7,x15/8,pm/k,x14/9,pn/h,x8/6,po/m,x10/11,pa/p,x14/9,pj/n,x6/13,s15,x7/15,s5,x2/0,s13,x1/9,pk/b,s2,x0/2,s12,x8/1,s5,x10/5,s11,x11/6,pn/m,x9/12,s4,x3/1,s11,x8/15,pb/e,x6/5,s10,x4/11,pc/l,x8/6,s2,x10/7,pe/j,x4/6,s4,x14/9,s3,x1/13,s10,x10/5,s1,x3/2,s4,x5/8,s3,x7/11,s4,x3/6,s13,x10/12,s2,pb/k,x6/13,pc/e,x9/1,pp/o,x0/5,ph/j,x11/2,pm/n,x7/15,s3,x14/1,s2,x5/12,pg/c,x11/0,pb/a,x12/7,pf/d,x15/6,s7,x3/11,pi/g,x8/2,pm/l,x12/0,s8,x10/13,pf/h,s15,x11/2,s10,x8/14,pc/n,x3/0,pa/p,x1/4,s8,x7/10,s15,x15/4,s13,x13/8,pm/k,x0/3,s12,x12/7,pl/a,s10,x15/11,pg/f,x0/1,s1,pm/j,x9/4,s12,pk/c,x10/7,s9,x14/15,pn/o,x0/10,s9,x15/4,s6,x12/6,pk/j,x9/14,s13,x10/2,s15,x14/12,s3,x8/5,pg/a,x11/10,s12,x4/14,s15,x11/7,s9,x2/9,s14,x14/5,po/n,x1/8,pl/g,x10/2,s9,x13/4,s1,x11/9,s13,x8/2,s5,x3/13,pp/h,x5/2,s1,x9/3,pd/k,x1/4,po/g,x2/7,s4,x9/10,s3,x12/8,pp/j,x2/10,s4,x4/7,s4,x0/13,s4,x5/3,s6,x1/10,pg/b,x15/5,s3,x4/14,pd/h,x6/5,pa/e,s2,x2/0,s9,x1/8,s6,x5/12,s14,x8/6,s4,x7/14,po/g,x8/0,s8,x12/5,pa/n,s2,x15/9,s7,pf/h,x2/7,s7,x4/10,pp/l,s3,x6/8,pj/a,x12/10,s12,pf/l,x14/2,s12,x12/8,pp/d,x7/2,s12,x10/14,s13,x3/1,pn/i,x13/15,s10,x10/7,s3,x13/1,pb/d,s4,x0/12,po/n,x3/13,pf/b,x12/6,pd/o,x10/13,s4,x4/12,s12,x10/0,s8,x8/6,pj/i,x12/7,s12,x13/3,s4,x7/10,s9,x11/0,pf/h,x2/5,pk/j,x6/8,s11,x11/14,s11,x0/4,pm/e,x3/11,s7,x4/13,s15,pn/o,x8/15,s5,x7/10,pd/h,x5/2,pe/i,x11/13,pl/m,x3/12,pn/g,s12,x11/2,s7,x5/13,s11,x14/7,s2,x3/12,pl/p,x10/9,s15,x4/14,pa/b,x15/0,s10,x6/7,s1,x0/5,s7,pe/l,x6/13,s1,x7/1,s15,x3/4,pc/k,x6/11,s2,x13/12,pi/a,x0/11,s6,x12/1,pn/h,x7/11,s7,x15/5,pc/i,x13/9,pf/a,x8/5,pi/l,x14/3,pd/g,x10/15,s7,x1/3,s14,x15/14,s1,x2/4,pp/e,x0/10,s12,x15/4,s14,x7/11,s14,x6/2,s13,x15/4,s9,x1/10,ph/j,x14/3,s1,x4/2,s14,x13/7,s10,x2/6,s4,x12/5,pm/l,x2/1,s10,x5/13,pf/d,x14/3,s9,x5/10,s8,pb/g,x7/0,s12,x9/13,pk/h,x3/0,s8,x5/8,s6,x6/15,pf/c,x4/12,pi/b,x1/0,po/p,x15/10,s11,x5/13,s15,pl/d,x2/11,s7,x6/9,pg/k,x8/1,s4,x0/3,s13,pf/a,x15/14,s5,x2/8,s8,x13/15,s6,x2/12,s9,x11/10,s15,x3/8,s11,x6/9,pi/n,x5/15,s15,pk/a,x12/9,s3,x4/7,s7,x1/9,s9,x5/15,s4,x12/2,s12,x4/7,s14,pd/b,x15/13,ph/p,x5/2,s13,x10/3,s13,x9/0,s6,x7/11,pa/i,x1/10,s3,x12/7,s14,x1/5,s9,x7/9,pg/e,x1/13,s6,x4/12,pl/o,x14/9,s6,x8/15,pj/d,s12,x11/1,s4,pc/h,x4/13,pi/l,x12/8,po/h,x2/15,s1,x14/6,pc/a,x4/5,pd/p,x7/1,pa/l,x9/6,pn/f,x15/2,s13,x12/1,s1,x14/5,pm/d,x3/7,s5,x2/9,pb/a,x6/3,s15,x8/12,s10,x10/7,s14,x1/5,s6,x11/3,pd/g,x9/7,s9,x11/0,pk/f,x4/12,s6,x2/6,pd/l,x4/9,pg/i,x15/3,s2,x14/8,s11,x13/0,pe/o,x1/5,s15,x3/10,s1,x2/7,s11,x10/13,s2,x4/9,pc/p,x0/12,s8,x1/8,pf/g,x11/6,s15,x5/15,pn/k,x0/13,pi/f,x3/5,pd/h,x15/2,s1,x9/5,s4,x0/15,s6,x9/13,s4,x10/2,s13,x15/7,s6,x1/9,pi/f,x7/14,s1,x0/6,s12,x7/3,s15,x10/2,pg/m,x1/6,s13,pf/b,x14/9,s5,x15/0,pm/o,x5/8,pg/c,x4/15,s8,x10/9,pd/j,x15/7,s2,pp/l,x9/13,s3,x2/7,s3,x6/9,s10,x0/14,pe/f,x5/2,s6,x4/1,pl/c,s2,x7/5,s3,x8/0,po/h,x13/15,pk/a,x4/6,s9,x2/15,s2,x7/5,s13,pb/n,s1,x3/4,pi/d,x11/0,s14,x1/4,s14,x8/5,s4,x12/10,s10,x5/1,ph/b,x10/13,s6,x3/5,s11,x15/4,s4,x11/12,s11,x14/8,pm/l,x13/11,s9,x2/10,pk/b,x4/12,s2,x8/0,s15,pj/g,x14/4,pl/n,x7/11,s2,x6/4,pm/i,s15,x5/2,s5,pl/b,s9,x3/6,pk/e,x11/9,s11,x1/7,s13,x14/15,pj/d,x9/11,s12,x7/1,s2,x8/13,s14,x5/7,pc/k,x12/8,pj/h,x2/4,pl/o,x7/15,s9,x14/9,pg/f,x10/5,s9,x15/8,s15,pi/c,x9/1,pe/h,x12/2,pj/p,x15/14,s2,pa/b,s12,x0/9,s1,x10/11,pk/p,x13/14,s15,pf/n,x6/10,s8,x3/2,s11,pe/c,x13/6,s8,x11/10,pf/a,x12/0,s5,x1/11,s1,pd/g,x8/2,s7,x12/0,s4,x4/5,s15,x13/14,pc/o,x0/5,s4,x15/13,s7,x8/10,s11,x13/15,s7,x12/6,s7,pj/i,x15/8,s7,x11/4,s3,x9/0,s7,x7/15,s3,x14/5,s7,x4/13,s14,x1/2,s2,x11/0,pn/o,s10,x12/10,s15,x1/3,pa/p,x15/0,s1,x9/2,pe/f,x11/13,pn/g,x2/3,s12,x6/4,s1,x11/1,s11,x8/14,s5,x15/0,pm/o,x2/9,s7,x15/6,s12,x13/7,pl/k,x4/1,s14,x7/6,s13,x4/9,po/i,x14/2,pn/p,x1/8,pe/a,x5/12,s7,x15/6,s2,x9/12,pm/j,x5/13,s6,x6/10,pb/g,x0/12,s3,x10/13,pa/f,x11/7,pg/j,x5/15,s3,pd/k,x8/0,pm/a,x2/5,pf/o,s3,x15/6,pi/g,x9/7,s13,ph/a,x4/14,s3,x2/11,s1,pd/p,x14/1,pc/a,x7/10,s5,pl/h,x12/14,pc/k,x4/13,s4,x11/6,ph/o,x5/2,s15,x13/7,s2,x8/14,s1,x11/12,s7,x9/7,s11,x12/1,s9,x3/10,pb/k,x1/13,pn/l,x6/12,s8,x7/14,pp/g,x3/5,s15,x0/7,ph/e,x1/10,s6,x7/2,s7,x14/6,pk/c,x12/9,s4,x6/5,pj/g,x0/8,s14,x9/11,pe/h,x5/3,s15,x4/15,pk/m,x5/11,s15,x8/15,s7,x7/5,s11,x9/8,pg/n,x0/11,pa/o,s2,x1/4,pp/h,x9/7,pe/i,s14,x12/10,pp/f,x7/5,s15,x9/6,s6,x5/1,pm/d,s6 diff --git a/pytudes/data/advent2017/input18.txt b/pytudes/data/advent2017/input18.txt new file mode 100644 index 0000000..ea1762c --- /dev/null +++ b/pytudes/data/advent2017/input18.txt @@ -0,0 +1,41 @@ +set i 31 +set a 1 +mul p 17 +jgz p p +mul a 2 +add i -1 +jgz i -2 +add a -1 +set i 127 +set p 826 +mul p 8505 +mod p a +mul p 129749 +add p 12345 +mod p a +set b p +mod b 10000 +snd b +add i -1 +jgz i -9 +jgz a 3 +rcv b +jgz b -1 +set f 0 +set i 126 +rcv a +rcv b +set p a +mul p -1 +add p b +jgz p 4 +snd a +set a b +jgz 1 3 +snd b +set f 1 +add i -1 +jgz i -11 +snd a +jgz f -16 +jgz a -19 diff --git a/pytudes/data/advent2017/input19.txt b/pytudes/data/advent2017/input19.txt new file mode 100644 index 0000000..f18900e --- /dev/null +++ b/pytudes/data/advent2017/input19.txt @@ -0,0 +1,201 @@ + | + +-+ +-----------------------------+ +---+ +-------+ +-+ +-+ +-+ +-------+ +-+ + | | | | | | | | | | | | | | | | | + +-------------+ | +-+ +-------------------------------|---|---|---------------------------------------------------------+ | | | | | | | | +-+ | | + | | | | | | | | | | | | | | | | | | | | | + | | | | | | +-+ +---+ | | | +-------------------------------------------------|-------------+ | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | + +-------|-------------------|-|-+ | | +---+ I +-|---|-|---+ | | +-------------------------------------------------------------------|-|-----|---+ +-------+ + | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | +---------|-------------|---------+ +-|---------|---------|-----------+ | | | +---------|-|-------------------------------|-----+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | +---|-------------|-------|---|-|-------------+ | | | +-------|-+ | | | +---------------------|-----|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | +---|---------|-----------|-------|---------------------|-------|-----------|-------------------------|-------|-------+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | +-----|---|-------|-------|-----|-----------------------------------------|---------|-------+ | +---------------------|-|-------------|---+ + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | +-|-|---------------|-|-----|-----|-|---+ | | | | | | | | | | | | +-------------+ +-------|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +---------------------+ +-------|-----|---------------|-|-----|-----|-|-----------+ | | | +-----------------|-----|-----|---------------------------|-----|-----+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | +-|---|-------|---------------------|-------------------|---------|-----|-------|---|-|-------|-----------------------+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | +-----|---+ +-------|-----------------|-----------|-------+ | | +---|-------------|---------------------|---------|-|-----+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +-+ +-|-----------|-------------|-|-|---------------------+ | | +-|-----------------|-----------|---+ +---------|---------------|-|-|-----------------|-------------|-----|-----|---|---------+ + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | +-|-|-+ | | | | | | | | | +---|-----+ | | | | | | | | | | +-----|-----|-----|---+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | +---+ | | | | | | | +-|---|---|-|-----+ | +-------------|-----------|---+ | | | | | | | | | | | | | +-----------------------|-+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | +---------------------------------------|---|---|---|---------------------|-------------------+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|-+ | +-----|-----------|---|-|-|-------------+ +---|-+ | | | +-----+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | +-|-|-|---+ | | | | | | | | | | +-------------|-----------------|-|---|-|-|---|---------------|-|-|-|-----+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | +---------|-|-----|-+ | | | | | | | | | +-------------------|----------------------C--|---------------+ | | | | | | | | | +-------|-----|-----+ | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | +-----------------|-------|-|---|-|-----------|-----|-|-|-|-----|-----------------|---|---------------------|-----|-----------|-------|-------|-----------|-----------|-----+ | | | | +-|-+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---|-+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | +---------------------|---|---------|---------+ | | | | +---+ | | | | | | | | | | +-|-----------------+ | | | +-------+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---------|-----|-|---+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | +---|---|-+ | | | +---+ | | | | | | | +-----|-----|---|-|-----------------|-----|---+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | +-|---|-------+ | | | | | | | | | | | | | | | | | | | | | | | | +-|-|---------+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | +-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|-|---|-----|---|-|-+ | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | +-----+ +---------|---+ | | | | | | | | | | | | | | | | | | | +-|---+ | +-----|---+ | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---------|-|---------------------------+ | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----------|-----------------------|---------------|-|-----|-----|-|-|-+ + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---|-|-+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|-------------|-----|-----|-----|---------|---------|-|-|-|-------|-----|-+ | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +-------|-----|---|---|-----|-----|-----------|---|-|---|-|-|-----|-----|---------------|-|-----------|-----|-----|-----|---------|-----|-----|-|-|-----|-|-----|---|-|-------+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | +-|---|---------|---|-------------------|-|-|---|-|---|-|-----------------|-----------|-|-----------|-----|-----|---------------------|-----------|---------|-----|---|---------|-+ + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +---|---------|---|---|-----------|-----------------|---|---|------L----|-|-------+ | | | | | | | | | | | +-|-|-|---|-|---|-----|-|---+ | +---+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---------------------|-|-----|-----------|-------|---+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | +-|-----------|-|---+ | +-------------|-----------------|---|-----|-|---|-|-----|---|-|---+ | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | +-------------|---|-------|-----|---------|---|-|-----|-----------+ | | | +-|-------|-------|-----|---+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-------|-|-------------|---|-+ | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | X | | | | | | | | | | | + | | | | | +---|-------|-----------------|---|-|-------------------|---------+ +-----|-------------|-----|-----|-----------------------|-|-------|---|-|---|-|-|-|-------+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +--B--|---------+ | | | | | | | | | | | | | | | | | | | | | | +-|-----------|---+ | | | | | | | | | | +-|---|---------+ | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | +---|-|-----------|---------|-------------|-------|-----|-|-|-----|---|-----------------------|-------|-|-------|-|-----|---|-----|-----|---|-----|-----|-|-----|---+ | +-|-|-|---+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | +-----------------------|-------|-|-|---------------|-------|-|-------+ | | | | | +-+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | +-----|-|-----------|-|---|-------------|---|-------|-----|---|-|---|-----|---------------|-----|-|-|-------|-|-------+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +-------------|-|-|---------|---+ | | | | | | | | | | | | | +-|-----------------|-------+ | | | | | | | | | | | | | +---|---------|-----+ | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +---|-|-|---------|---------------------|---|-------|-----|-|-----|---+ +---|-------------|---|-------------------------|-|-|-----------|---|---------|-|-|---|-|---|---+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | +---|---------------------------------------|---------|-|---|-|---|-----|-----------|-|-----+ | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | +-|-|-----|-|-----------|-------------|-|-|---------|---|-----|-------|-----------|---|-------------+ | | | | | | | | | | | +-----|-|---+ | | +-|-|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +-------|-|-------|-------------------------|---------|---|---------------------------------|---------------------|-|---|-|---|-----|-----|-------------|-|-----|-|-|---|---+ | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | +---------------------|---|-----------------|---------|-|---|---------------|---------|-------|---|---|-----------+ | + | | P | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | +-------------|-----|---|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | +-----|-|-|-|---|---|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | +-----|-----|-------|---|-----------------|-------------------------|---------------|-|---|-------|---|-----|---------|-+ | | | +-----|-|-|---|---------+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|-|-----|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | +---------|---+ | +---|-----|---|-|-------------|-----|-------|-|---------|---+ | +-----|-----|-----|-|-|-------------+ | +---------|-------|---|-|-|-----|-+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | +-+ | | | | | +---------|-----|-|-------|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | +-----------|-----------|-----|-----|---|-|-----|---------|-----|-|-|-------|-|-+ | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | +-------------------|-----|---|-|-|-------------|-----------|---|-----|---+ | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-|-------------------|---------|-|---------------|-----|-|-----|-------|-|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | +-----|------H------+ | | | | | | | | | | +-|-----|---|-+ | | | +-+ | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|---|---------+ | | +-|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | +-----|-----|---------+ | | | | | | | | | | | | | | | | | | | +---------------|-----|-|---|-------------|---|-----|-|-----|-----------------+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | V | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-|-------------|-------+ | | | | | | | | | | | | | | | | | | | | +---------------|-------|-+ | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | +-------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-+ | | | | | | | | +-------------|-------|---|-------+ | | | | +---|-|-|-----------|-|-------+ | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +-----|-|-------------|---|---------------|-------|---|-------|---|-----|---|---------------------|---|---|-------------------|-----|---|-|-------|-------|-------|-+ | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | +---|-------------------|---------+ | | | | | | | +---+ | | +-|-+ | | | | | | | | | | | | +---|---------|-|-----+ | | +---------+ | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | +-------|-------------------+ +---------+ | | +-----|---|---|-+ | | | | | | | | | | +---------|---|---------|---|-+ | | | | | | | +-+ | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | +-|-------|---|---+ +---------|-------------|-|-|-|-----|---|---|-|---------+ +-----|-----------------------------------|-----------|---|---|---|-|-------|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | T | | | | | | | | | | | | | | + +---|-----|-|-------|-------|---------------------------------|---|---------|-|-----|---|-----------------------|---------------|-|-----|---+ | | | | | | | | | | | +-+ | | +-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | +-----|-|-|-----|---|---------|---|-----------------------|-------|-|-----------|-|-|----------E------|-------|---|---+ | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +-------|-----------|---------------------------|-|-|---|---|-----------|---|-----+ | | | | | | | | | | | | | +---|-----------|---------|---+ | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | +-|-|-------------------------------|-|-|-------|-|---|---------|---------------+ | +---------------|---|---------|---------------------|---+ | | | | +-+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | +---------------------------------|-|-|---|---|-|---|-|-------|-----------|-------|-----------|---|-------------|---|-----|---|---|-----|-|-------|---+ | +-+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-----+ +-----+ | | | | | | | | | | | | | | | | | | +---|-+ | | | | | | +-----|-------|---------|-----------|-----+ | +---|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +---------------------------|---+ | | | | | | | | | | +-------|-------|-----------|-------|---|-----------|-|---------------------|-----|-|---+ | +-------|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | +---|-----------|---|-|-----|-------|---|-|-----+ | | +-|---------|---|---------|-|---|-+ | | +-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-----------|-----|-------|---|---------------------------------|-------|---|-------|---------------|-----------|---+ | | | | | | | | | +-----|-+ | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +---------------|-|-|---------|-----------------------------|-----|-|-------|-|---|-|---|---|-------|---------------|-------|---|-|-|---------|---+ | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | +-|---|-+ +-------------------------------+ | | | | | +-----|---|-------|---------------|-------|-------|---+ | | | +-----|-|---|-----------|-|---------------|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-----------|-----|-|---|-|---|-|---+ | | | | | | | | | | | | | | +---|---|---|-|-|-+ | | | | | +---|---------|-|-----|-|---|---+ +-----|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | +---------------|---|-------|---|-|-----|---|-----------|---|-|---------|-------|-|-|---+ | | +---+ | | | | +-+ | +---|-------------+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | +-------+ +-------|-----------------------------|---+ +-|-----------|-------+ | | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +---+ | | +-----|---------|---------|---------------|-------|-----|-+ | | | | | +---------|-----|-------|-------------|---------|-|-----------|-----|---+ | +-|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +---|-----+ | | | | | | | | | | | | | | | +-|---|-----|---|-----------|-------+ +-----|---|-----------------|-----|-------|-|---------------|-------|---+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | +---|---|-|-----|---+ | | | | | +---------|---|-------------------------------------|-|-------------------------|-|---+ | | | | +-------|-|-------+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | | | +---------|---------------|-----------|---|-------------|---------------|-----|-----------|---------+ | +-+ | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-----|-----|---------+ | | | | +---+ | | | +-----------------------|-----------------+ | | | | | | | | | | | | | +---------|---+ +-----|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | +---|-------|---|-+ | | +-------|---------------|-----------------------|---|---|-------------|-|-----------+ | | | | +-------|---|-|-+ | | +---|-----|-----------|---|---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | | +-|-----------------------+ | +-----------|---------------+ | | | +-|-----|-|-------+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +-----|-----------|-------|-------|---------------|-------|-------------+ | +---+ +-|-----|-------------------|-------------|-|-----|---+ +-+ | | | | | | | +---+ +-+ | | +---+ | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | | +---+ | | | | | | | +---------------|-----|-----------------------------------------|---------+ | | | +-------|-----------+ | | | | + | | | | | | | | | | | | | | | | | | | | | | | | | | | | + | +-----------|-------|---------------|-|-----|-------------------------------------|-------------------|-----------+ | +-----+ +-----------------------+ | | | | | | + | | | | | | | | | | | | | | | | | | | | | | | | + | +---------------------------|-----|-------------------------------|-------|-----------------|-------------+ +-------------|-------------+ +-------|---+ | | | + | | | | | | | | | | | | | | | | | | | | | | + +-------------------|-----------------------|-|-----|---------------------------------------------+ +---------|---------------------------+ | | | +---|-+ | | | | | + | | | | | | | | | | | | | | | | | | | | | | + +-------+ +-+ +---------+ +-------------+ +---------|---------------------------|-----|---------------|-----------+ +---|-+ + | | | | | | | | | | + +-------------------------------------+ +-----------------+ +-----|-------------------------------+ | | + | | | | | | | | + +-------------------------------------------------------------------------------------------+ +-+ +---------------+ +-+ + diff --git a/pytudes/data/advent2017/input20.txt b/pytudes/data/advent2017/input20.txt new file mode 100644 index 0000000..391fca8 --- /dev/null +++ b/pytudes/data/advent2017/input20.txt @@ -0,0 +1,1000 @@ +p=<1199,-2918,1457>, v=<-13,115,-8>, a=<-7,8,-10> +p=<2551,2418,-1471>, v=<-106,-108,39>, a=<-6,-5,6> +p=<-73,1626,1321>, v=<58,-118,-8>, a=<-6,2,-9> +p=<-3297,-894,-551>, v=<183,31,-61>, a=<3,3,11> +p=<-1425,4298,617>, v=<32,-166,-32>, a=<7,-12,-1> +p=<-3718,877,1043>, v=<114,7,-20>, a=<10,-6,-4> +p=<-2089,-239,1142>, v=<52,12,3>, a=<7,0,-7> +p=<782,994,3311>, v=<16,-28,-32>, a=<-6,-3,-16> +p=<-937,2596,-109>, v=<-12,-117,-13>, a=<7,-3,2> +p=<-865,-2930,-1387>, v=<60,76,-56>, a=<-1,9,14> +p=<1196,-3308,2564>, v=<-26,59,0>, a=<-4,13,-15> +p=<-271,1957,-2944>, v=<8,-15,40>, a=<1,-10,13> +p=<-964,1228,1583>, v=<18,16,-12>, a=<4,-9,-8> +p=<-1639,1174,1970>, v=<84,-114,-138>, a=<1,5,3> +p=<-1840,1679,-1764>, v=<44,-20,91>, a=<8,-10,2> +p=<1104,-233,140>, v=<-21,-11,-28>, a=<-6,3,2> +p=<1136,-361,-3100>, v=<-40,14,98>, a=<-4,1,11> +p=<1480,-265,-1412>, v=<-36,42,18>, a=<-7,-3,8> +p=<144,-1217,-660>, v=<39,25,56>, a=<-6,6,-2> +p=<360,295,276>, v=<-51,-95,-11>, a=<3,9,-1> +p=<-2656,487,1228>, v=<78,12,-11>, a=<10,-5,-8> +p=<-1400,2295,-204>, v=<-9,-67,53>, a=<11,-9,-5> +p=<-1016,-769,-52>, v=<1,14,120>, a=<7,4,-14> +p=<1536,4167,-940>, v=<-99,-201,82>, a=<0,-7,-3> +p=<2398,3917,2412>, v=<-69,-51,-81>, a=<-3,-10,-2> +p=<-3283,536,733>, v=<46,72,-32>, a=<8,-8,0> +p=<-247,1180,-2901>, v=<46,-52,-18>, a=<-3,0,12> +p=<-2984,-499,-1475>, v=<-3,57,-8>, a=<11,-3,6> +p=<-431,2008,-3890>, v=<54,-40,49>, a=<-3,-4,10> +p=<2904,-775,-3614>, v=<5,-3,97>, a=<-11,3,5> +p=<2697,-1074,3401>, v=<38,70,-28>, a=<-13,-2,-10> +p=<-1259,1456,595>, v=<42,8,34>, a=<1,-6,-5> +p=<-1293,5020,-2110>, v=<-12,-199,93>, a=<7,-5,1> +p=<-1753,-1520,-320>, v=<-10,44,14>, a=<9,3,0> +p=<-2143,1040,-2220>, v=<83,-42,109>, a=<2,-1,0> +p=<-203,3210,-530>, v=<-56,-98,35>, a=<6,-6,-1> +p=<3017,-3820,290>, v=<-154,96,-6>, a=<0,9,-1> +p=<-1195,-180,-289>, v=<93,-30,-2>, a=<1,6,4> +p=<371,1368,953>, v=<-18,-16,-125>, a=<-2,-16,7> +p=<-1777,-426,-523>, v=<187,-16,24>, a=<-6,7,3> +p=<-2635,690,-1177>, v=<148,-83,59>, a=<11,3,6> +p=<431,-366,-1333>, v=<-62,18,124>, a=<4,1,-2> +p=<-2311,-750,143>, v=<147,11,-51>, a=<7,7,6> +p=<-151,354,-85>, v=<97,-29,-84>, a=<-13,-1,14> +p=<-325,-1602,779>, v=<-25,56,-13>, a=<8,11,-8> +p=<-385,-204,467>, v=<-7,37,0>, a=<6,-4,-6> +p=<665,-1272,-1195>, v=<-10,35,80>, a=<-7,10,3> +p=<-2525,7592,-6216>, v=<43,-14,0>, a=<1,-9,8> +p=<-68,4433,8721>, v=<-120,-113,-63>, a=<6,0,-8> +p=<-6971,-91,-561>, v=<-43,3,15>, a=<11,0,0> +p=<-2876,806,-8478>, v=<72,-60,58>, a=<0,2,8> +p=<-7907,4004,258>, v=<61,-42,-46>, a=<7,-3,2> +p=<-4358,6773,5523>, v=<50,-73,39>, a=<3,-5,-9> +p=<1941,1823,224>, v=<-102,-73,-54>, a=<1,-1,4> +p=<-1440,-1768,224>, v=<70,87,67>, a=<0,0,-7> +p=<-1776,3125,2870>, v=<20,-58,-4>, a=<6,-8,-12> +p=<1437,-697,-5635>, v=<-12,25,115>, a=<-5,1,14> +p=<-3603,-151,2366>, v=<30,-89,31>, a=<13,9,-13> +p=<-264,4805,3857>, v=<3,-105,-40>, a=<1,-11,-13> +p=<-831,-823,140>, v=<52,-35,5>, a=<-1,7,-1> +p=<2970,-634,1085>, v=<-52,110,-18>, a=<-8,-7,-3> +p=<1755,-4503,-1198>, v=<-18,102,8>, a=<-4,6,3> +p=<-4945,572,1727>, v=<42,-101,-5>, a=<12,6,-5> +p=<-70,5047,-2023>, v=<3,45,54>, a=<0,-19,2> +p=<-2845,4372,-2598>, v=<75,-110,116>, a=<3,-5,-1> +p=<-345,-228,-1898>, v=<-38,61,88>, a=<4,-4,-1> +p=<-2720,3622,1727>, v=<109,-2,-83>, a=<0,-11,1> +p=<-4045,-3228,-2448>, v=<-7,116,-7>, a=<13,1,8> +p=<580,3347,802>, v=<-10,48,19>, a=<-1,-14,-4> +p=<-1910,2875,1236>, v=<71,-54,88>, a=<-1,-1,-6> +p=<-2963,-6485,2406>, v=<-102,86,-42>, a=<9,4,-1> +p=<-18875,7633,-7890>, v=<86,-76,82>, a=<20,-6,6> +p=<391,9505,4980>, v=<-8,76,-108>, a=<0,-16,-1> +p=<-935,5800,-1533>, v=<-114,-129,59>, a=<7,-1,-1> +p=<-272,-7733,12858>, v=<69,18,10>, a=<-3,9,-17> +p=<-7292,613,12741>, v=<49,-116,-47>, a=<7,5,-14> +p=<3550,-518,-15339>, v=<51,33,73>, a=<-7,-1,16> +p=<4213,-8123,-2157>, v=<14,88,55>, a=<-6,6,0> +p=<-7721,418,-17250>, v=<80,69,2>, a=<6,-4,22> +p=<1738,-2831,-158>, v=<40,35,8>, a=<-12,10,0> +p=<2598,399,782>, v=<-66,10,45>, a=<-6,-3,-8> +p=<3068,129,-1558>, v=<-58,13,57>, a=<-9,-2,2> +p=<-1782,4139,-3628>, v=<-99,-93,171>, a=<18,-11,1> +p=<-1082,-3161,-498>, v=<55,83,67>, a=<0,7,-4> +p=<-5302,-1291,772>, v=<98,42,-70>, a=<16,2,3> +p=<808,979,232>, v=<-50,2,-1>, a=<1,-5,-1> +p=<-152,1479,-8>, v=<-86,61,11>, a=<9,-13,-1> +p=<1292,1700,-858>, v=<-72,-94,96>, a=<-4,-5,-4> +p=<304,-640,-455>, v=<53,-12,72>, a=<-11,9,-5> +p=<486,1063,-689>, v=<-52,-66,27>, a=<2,-2,4> +p=<993,-1823,182>, v=<-84,30,-47>, a=<1,16,5> +p=<-1230,-1615,-312>, v=<52,182,96>, a=<6,-8,-10> +p=<-268,1297,728>, v=<20,-105,-40>, a=<0,1,-2> +p=<1476,1697,875>, v=<5,-87,-71>, a=<-15,-5,1> +p=<1476,1193,-1813>, v=<-85,-51,46>, a=<-3,-5,11> +p=<932,-6376,-4019>, v=<-47,24,-82>, a=<1,12,14> +p=<-12763,29,8401>, v=<177,-19,-62>, a=<16,1,-14> +p=<5087,6059,1936>, v=<-139,-65,76>, a=<-2,-9,-9> +p=<-853,-721,-4889>, v=<28,6,40>, a=<0,1,8> +p=<-1288,329,-11219>, v=<58,33,96>, a=<-1,-3,18> +p=<1352,-286,4051>, v=<-61,38,-10>, a=<1,-2,-8> +p=<2477,-271,-4649>, v=<41,-40,32>, a=<-8,3,8> +p=<-1783,-376,-6944>, v=<59,41,155>, a=<0,-2,5> +p=<-8728,2204,-1514>, v=<27,48,-26>, a=<17,-8,5> +p=<2987,-7276,-1829>, v=<-100,54,-31>, a=<0,12,6> +p=<-86,2277,1643>, v=<48,-108,-103>, a=<-4,0,2> +p=<-1640,-726,3722>, v=<45,24,-48>, a=<3,1,-12> +p=<334,-4947,761>, v=<-82,71,-28>, a=<6,15,-1> +p=<2686,1290,572>, v=<-106,16,-41>, a=<-2,-7,1> +p=<1153,3663,152>, v=<-110,35,45>, a=<5,-19,-5> +p=<-3257,-957,-2620>, v=<45,35,-32>, a=<10,1,14> +p=<-4958,4524,-2179>, v=<16,-127,13>, a=<20,-8,8> +p=<-1913,2844,-898>, v=<47,-135,40>, a=<4,0,0> +p=<-3826,-5200,5502>, v=<-27,-24,31>, a=<8,10,-11> +p=<50,-7529,4380>, v=<34,27,-6>, a=<-2,11,-7> +p=<-362,3,273>, v=<20,20,-5>, a=<3,-4,-4> +p=<-927,-577,-887>, v=<82,89,56>, a=<2,-6,6> +p=<-942,-727,1133>, v=<78,-6,-102>, a=<3,14,-2> +p=<-92,-817,-222>, v=<-73,80,17>, a=<15,0,1> +p=<-1062,-87,-642>, v=<68,7,59>, a=<7,0,1> +p=<-532,-1332,-537>, v=<4,27,65>, a=<9,19,-2> +p=<8,888,968>, v=<-17,-19,-58>, a=<3,-13,-7> +p=<-1188,-1222,249>, v=<-13,12,39>, a=<5,3,-4> +p=<-672,-814,1713>, v=<28,45,3>, a=<0,-1,-6> +p=<612,-4354,3273>, v=<87,30,-87>, a=<-9,12,-4> +p=<3048,-2098,-3435>, v=<-27,86,80>, a=<-8,0,5> +p=<2556,3434,1137>, v=<31,-32,2>, a=<-11,-9,-4> +p=<-372,710,-1851>, v=<-47,-31,-61>, a=<5,0,11> +p=<-648,-2698,705>, v=<2,136,20>, a=<2,-2,-4> +p=<564,146,-2007>, v=<-36,-70,108>, a=<1,5,-2> +p=<2040,662,-6411>, v=<-85,-29,129>, a=<0,0,11> +p=<-5642,-1168,-495>, v=<101,-74,-40>, a=<7,8,4> +p=<-3724,-3058,-1279>, v=<-11,-21,-41>, a=<10,9,6> +p=<-1540,-5046,-2875>, v=<56,79,74>, a=<0,7,2> +p=<336,-3506,345>, v=<47,82,17>, a=<-4,3,-2> +p=<5432,3088,2375>, v=<39,-52,-99>, a=<-16,-4,1> +p=<1792,1716,-2749>, v=<-63,55,26>, a=<0,-8,5> +p=<-1274,316,723>, v=<148,76,-40>, a=<-7,-6,1> +p=<924,-104,4223>, v=<-32,4,-49>, a=<0,0,-7> +p=<1484,-832,107>, v=<-168,30,-18>, a=<8,0,1> +p=<-8594,3021,4906>, v=<21,28,4>, a=<14,-7,-9> +p=<10084,-1137,-5786>, v=<-86,35,90>, a=<-13,0,5> +p=<-5030,5628,-2420>, v=<-2,-170,73>, a=<9,0,0> +p=<-2324,-2952,220>, v=<1,124,44>, a=<4,-2,-3> +p=<2857,2757,55>, v=<-3,2,-36>, a=<-5,-5,2> +p=<3319,-2523,2497>, v=<-34,26,26>, a=<-4,3,-6> +p=<5256,903,-1020>, v=<76,11,65>, a=<-12,-2,-2> +p=<8028,5151,-1038>, v=<-1,-33,84>, a=<-12,-6,-3> +p=<3690,-4065,1266>, v=<-47,75,57>, a=<-3,2,-5> +p=<6606,5403,7026>, v=<-17,-40,-66>, a=<-9,-6,-7> +p=<-1638,1383,1338>, v=<11,-86,-51>, a=<14,-2,-6> +p=<896,1026,-622>, v=<-5,-98,-1>, a=<-8,3,6> +p=<763,1425,309>, v=<-78,-134,0>, a=<3,4,-3> +p=<1001,-619,113>, v=<55,72,44>, a=<-17,-4,-7> +p=<1191,109,1991>, v=<-116,-48,-8>, a=<5,3,-4> +p=<3453,-1718,-5230>, v=<136,60,46>, a=<-17,0,9> +p=<-2666,-2646,-4621>, v=<32,47,40>, a=<4,3,8> +p=<1436,-2829,1966>, v=<-51,-16,-45>, a=<-2,15,-5> +p=<696,2161,-2404>, v=<-35,-108,100>, a=<0,0,2> +p=<2486,2401,-1224>, v=<-9,48,20>, a=<-11,-16,4> +p=<3046,261,1116>, v=<-37,71,-139>, a=<-11,-8,8> +p=<-104,2751,2326>, v=<-121,-85,-42>, a=<12,-5,-7> +p=<-1044,-249,496>, v=<73,-19,-45>, a=<-2,3,2> +p=<556,-289,1826>, v=<-28,-59,67>, a=<0,7,-15> +p=<-274,1131,-44>, v=<-18,-46,45>, a=<3,-1,-4> +p=<2266,1141,-504>, v=<-19,-78,26>, a=<-9,2,0> +p=<-891,-129,1722>, v=<-121,92,-73>, a=<15,-8,-1> +p=<243,-2439,3276>, v=<23,70,-158>, a=<-3,4,0> +p=<-72,-339,399>, v=<-17,3,-10>, a=<2,1,-1> +p=<1461,-759,2205>, v=<-57,-109,-30>, a=<-1,13,-7> +p=<-597,-1536,882>, v=<30,-39,-33>, a=<0,10,-1> +p=<2469,-1683,1533>, v=<49,-10,-152>, a=<-15,8,7> +p=<957,3441,1428>, v=<-143,-1,106>, a=<9,-15,-16> +p=<-2487,-927,-5271>, v=<32,-35,194>, a=<8,7,5> +p=<915,585,1701>, v=<-97,-8,-83>, a=<5,-2,0> +p=<-1975,2665,-1727>, v=<138,-30,49>, a=<-4,-9,3> +p=<-2122,-23,-2945>, v=<24,76,74>, a=<7,-7,6> +p=<150,1353,672>, v=<36,-115,-12>, a=<-5,4,-3> +p=<2139,-1299,1437>, v=<-144,-4,-93>, a=<2,9,1> +p=<-955,3036,298>, v=<74,-79,-8>, a=<-2,-11,-1> +p=<2156,-1418,-1640>, v=<-46,84,34>, a=<-9,0,7> +p=<-938,-1418,808>, v=<82,66,25>, a=<-3,2,-8> +p=<-2179,-109,-382>, v=<146,25,-31>, a=<-2,-2,6> +p=<2139,1727,-280>, v=<-63,-74,-46>, a=<-7,-3,7> +p=<-1006,622,-59>, v=<77,-54,-5>, a=<-2,2,1> +p=<235,894,349>, v=<-113,-79,43>, a=<11,3,-7> +p=<2258,452,1624>, v=<-88,37,-32>, a=<-5,-7,-7> +p=<6485,8607,10076>, v=<-46,61,-99>, a=<-6,-14,-8> +p=<15533,4551,638>, v=<-78,-55,-57>, a=<-16,-3,2> +p=<128,6540,4148>, v=<-3,114,-67>, a=<0,-14,-2> +p=<11555,3186,2081>, v=<-116,0,-114>, a=<-9,-4,3> +p=<9371,-3015,-6031>, v=<20,79,54>, a=<-13,0,5> +p=<-12586,339,-7786>, v=<3,-7,59>, a=<16,0,7> +p=<-2056,-7383,-4705>, v=<-67,11,0>, a=<6,9,6> +p=<1025,2796,-13480>, v=<-126,-70,-15>, a=<5,0,18> +p=<-11416,-1962,-766>, v=<-47,12,39>, a=<17,2,-1> +p=<1103,-558,3212>, v=<-88,-24,-83>, a=<3,2,0> +p=<-56,-3584,3008>, v=<78,86,-151>, a=<-6,5,2> +p=<1072,-5108,-1720>, v=<-44,112,71>, a=<0,8,0> +p=<-1256,1936,-1384>, v=<28,-69,57>, a=<2,-1,0> +p=<1996,-992,1472>, v=<-120,-22,-12>, a=<3,5,-4> +p=<3376,1324,908>, v=<-140,-31,-101>, a=<0,-2,5> +p=<3604,412,6920>, v=<-62,-43,-189>, a=<-7,2,-8> +p=<-176,4384,2204>, v=<-17,-21,-80>, a=<2,-13,-1> +p=<-992,-1196,-3616>, v=<42,49,50>, a=<0,0,8> +p=<-353,-1549,-1122>, v=<-72,-82,26>, a=<6,10,1> +p=<727,-3169,-2337>, v=<0,6,-97>, a=<-2,8,13> +p=<-1973,-1387,-3282>, v=<44,-60,92>, a=<2,8,2> +p=<1159,-118,2712>, v=<96,75,-46>, a=<-10,-5,-4> +p=<-974,260,-2553>, v=<-105,-51,37>, a=<10,3,4> +p=<1645,2069,2388>, v=<50,22,-20>, a=<-8,-7,-5> +p=<1726,2420,-3930>, v=<-79,-19,46>, a=<1,-5,7> +p=<1564,4364,1740>, v=<53,-91,-38>, a=<-8,-5,-2> +p=<6496,8583,-2797>, v=<-129,-57,50>, a=<-4,-12,2> +p=<919,-6234,4727>, v=<74,188,9>, a=<-6,0,-9> +p=<2272,-2736,7796>, v=<-1,-3,-67>, a=<-4,5,-10> +p=<-9674,-558,9809>, v=<72,-52,-26>, a=<13,4,-16> +p=<8542,3765,-124>, v=<-55,89,20>, a=<-12,-12,-1> +p=<1909,3138,1790>, v=<-41,74,-21>, a=<-1,-10,-2> +p=<-1419,1399,-3011>, v=<42,-26,-27>, a=<0,-1,7> +p=<1716,-4244,5569>, v=<-53,-178,-32>, a=<0,18,-8> +p=<6270,211,-10931>, v=<-38,78,60>, a=<-9,-5,16> +p=<-5181,-3452,-338>, v=<71,36,62>, a=<5,4,-3> +p=<-6105,-8402,-5915>, v=<31,-1,27>, a=<9,15,9> +p=<-1848,310,-1097>, v=<4,92,17>, a=<3,-6,1> +p=<2803,-1755,-532>, v=<-71,13,2>, a=<-5,6,2> +p=<691,2348,-785>, v=<48,-24,71>, a=<-7,-7,-3> +p=<-233,4779,-994>, v=<-48,-31,0>, a=<5,-16,4> +p=<119,-4021,238>, v=<-41,93,-10>, a=<3,8,0> +p=<-1168,-3647,-3392>, v=<52,76,132>, a=<0,8,2> +p=<-1845,-443,-822>, v=<-24,-30,1>, a=<11,5,4> +p=<2315,1487,4428>, v=<-64,-53,-83>, a=<-5,-2,-13> +p=<3255,-2683,-772>, v=<-132,82,-12>, a=<-3,5,5> +p=<-1405,487,108>, v=<-25,-45,70>, a=<9,2,-7> +p=<-2315,1877,-1142>, v=<73,1,38>, a=<4,-9,2> +p=<-1975,-2143,-3372>, v=<-28,13,13>, a=<12,9,15> +p=<1945,3157,2138>, v=<28,-147,21>, a=<-12,-1,-12> +p=<-3555,977,708>, v=<114,-59,-2>, a=<6,1,-3> +p=<5865,5127,-4422>, v=<-105,-67,118>, a=<-18,-18,10> +p=<-3264,2343,-3273>, v=<79,-72,127>, a=<11,-6,6> +p=<3387,-2301,1992>, v=<-53,129,15>, a=<-14,0,-13> +p=<2295,5276,1762>, v=<-104,-67,-57>, a=<0,-15,-2> +p=<-2072,-774,1036>, v=<37,-22,68>, a=<5,5,-10> +p=<447,865,1300>, v=<-20,-39,-36>, a=<0,0,-2> +p=<-1467,-1852,2323>, v=<90,50,-117>, a=<-2,3,1> +p=<4473,-664,-1241>, v=<-157,-4,45>, a=<-4,3,1> +p=<1580,-1621,-2572>, v=<32,5,48>, a=<-9,6,6> +p=<9680,-3138,-4267>, v=<-41,22,-84>, a=<-14,4,12> +p=<-4107,4648,2023>, v=<32,3,-59>, a=<5,-8,0> +p=<-673,1860,7004>, v=<36,-55,-48>, a=<-1,0,-9> +p=<8337,7453,2516>, v=<-159,-132,84>, a=<-5,-5,-9> +p=<2276,-3123,-1445>, v=<-62,44,37>, a=<-6,12,4> +p=<-1885,-64,1576>, v=<27,33,-12>, a=<7,-3,-7> +p=<-7265,156,268>, v=<89,-23,-25>, a=<6,1,1> +p=<-9137,3036,826>, v=<104,8,-133>, a=<8,-5,6> +p=<-6167,-1770,-4592>, v=<77,86,73>, a=<5,-2,3> +p=<-1685,-2976,2824>, v=<45,27,-22>, a=<0,3,-3> +p=<5821,-870,5740>, v=<3,-13,-29>, a=<-9,2,-7> +p=<331,1596,232>, v=<-11,-100,-135>, a=<0,3,7> +p=<-1230,1100,-8455>, v=<87,-67,165>, a=<-3,2,6> +p=<-1470,5772,3641>, v=<-21,-81,18>, a=<4,-6,-8> +p=<7026,-2852,1913>, v=<-6,106,6>, a=<-13,-1,-4> +p=<-5422,5132,-5575>, v=<-13,-160,42>, a=<11,0,8> +p=<3792,1660,-43>, v=<-175,-121,15>, a=<-9,1,-2> +p=<42,-620,-778>, v=<3,39,24>, a=<0,0,3> +p=<-318,-1370,1697>, v=<11,137,-85>, a=<2,-6,-4> +p=<1842,130,-613>, v=<-69,-11,-19>, a=<-6,0,7> +p=<-963,3070,-2218>, v=<30,-151,144>, a=<5,-7,0> +p=<2847,-2795,1532>, v=<-112,80,-74>, a=<-9,13,-4> +p=<747,-875,197>, v=<12,56,-17>, a=<-7,0,0> +p=<627,-80,1022>, v=<-36,27,-128>, a=<0,-3,7> +p=<2667,655,1427>, v=<-108,-14,-91>, a=<-8,-4,-1> +p=<1002,-215,962>, v=<35,-28,-108>, a=<-12,5,5> +p=<-849,-4500,291>, v=<-67,65,22>, a=<6,5,-2> +p=<6405,4180,5499>, v=<-125,9,-18>, a=<-5,-9,-10> +p=<4576,-4128,1562>, v=<-66,53,-3>, a=<-5,5,-3> +p=<391,4738,-2189>, v=<37,-89,70>, a=<-3,-4,0> +p=<-1004,863,12>, v=<82,-108,15>, a=<-3,5,-1> +p=<1352,1514,-4390>, v=<-10,-49,13>, a=<-2,0,8> +p=<360,-4748,-81>, v=<-26,73,50>, a=<1,5,-3> +p=<-7297,2320,-6157>, v=<-3,-75,22>, a=<15,0,11> +p=<918,-780,229>, v=<68,-55,-8>, a=<-6,5,0> +p=<422,-7135,5871>, v=<-12,86,-62>, a=<0,9,-8> +p=<2921,-2245,1495>, v=<-93,55,-15>, a=<0,1,-2> +p=<1417,-4757,1367>, v=<-79,84,22>, a=<2,4,-4> +p=<2137,-4133,-5545>, v=<-118,-117,40>, a=<3,15,8> +p=<2761,-3685,-2329>, v=<-121,67,-44>, a=<2,3,7> +p=<3145,3851,3831>, v=<-199,-53,-22>, a=<6,-4,-6> +p=<-807,-1909,-8809>, v=<40,-71,10>, a=<-1,8,16> +p=<-3001,-1007,-4300>, v=<-11,2,69>, a=<11,3,9> +p=<2291,3961,-2416>, v=<-19,-30,28>, a=<-6,-11,6> +p=<1571,-3143,-2428>, v=<-14,66,41>, a=<-4,5,5> +p=<683,3001,6056>, v=<73,-90,-200>, a=<-8,-3,-4> +p=<-205,-759,517>, v=<108,44,50>, a=<-8,-1,-6> +p=<-642,1863,3622>, v=<31,-58,23>, a=<0,-2,-15> +p=<-1562,1449,-4405>, v=<83,8,-12>, a=<-1,-6,17> +p=<853,-1242,3668>, v=<14,-67,-51>, a=<-4,10,-9> +p=<-757,46,-6061>, v=<0,-15,156>, a=<3,1,9> +p=<-3287,-1403,-564>, v=<38,0,-35>, a=<9,5,5> +p=<-849,1840,3001>, v=<124,-33,-106>, a=<-7,-4,-2> +p=<1566,2806,-1162>, v=<43,-39,15>, a=<-9,-7,3> +p=<5706,3174,-5141>, v=<-77,-67,44>, a=<-14,-6,15> +p=<-1444,-4807,1648>, v=<-55,150,-100>, a=<6,0,3> +p=<-2596,2137,-7664>, v=<-19,-67,92>, a=<6,0,9> +p=<-4324,1577,-5456>, v=<35,0,23>, a=<6,-3,9> +p=<-1428,2121,1568>, v=<-39,82,-48>, a=<5,-9,0> +p=<-4884,-7063,-1168>, v=<36,-27,-12>, a=<7,15,3> +p=<-2612,-2871,2352>, v=<-35,-26,43>, a=<7,7,-7> +p=<2492,7737,4832>, v=<-13,22,-51>, a=<-4,-16,-6> +p=<3228,-2455,880>, v=<-102,-39,-10>, a=<0,7,-1> +p=<620,-4183,0>, v=<29,15,1>, a=<-3,7,0> +p=<1549,1698,2535>, v=<-94,-85,-179>, a=<-2,-5,0> +p=<-1643,1068,-202>, v=<29,-25,-66>, a=<12,-7,11> +p=<-229,697,-1756>, v=<48,-51,30>, a=<-4,0,13> +p=<1724,39,1219>, v=<-129,-49,-85>, a=<1,6,0> +p=<361,2678,211>, v=<21,-76,46>, a=<-6,-15,-8> +p=<291,410,3284>, v=<-19,-19,-166>, a=<0,-1,-9> +p=<-1711,-2642,-1098>, v=<79,109,72>, a=<6,11,1> +p=<-12485,-3505,-8183>, v=<17,14,59>, a=<16,4,8> +p=<2449,-351,-4877>, v=<92,9,-28>, a=<-8,0,8> +p=<-2377,1435,1241>, v=<63,40,-72>, a=<0,-4,2> +p=<397,7496,462>, v=<146,-22,46>, a=<-8,-9,-3> +p=<4672,-180,1621>, v=<-25,-15,-121>, a=<-5,1,4> +p=<-667,2442,1165>, v=<57,-45,-31>, a=<-2,-1,0> +p=<-97,-7210,6523>, v=<-75,53,-55>, a=<4,7,-6> +p=<-5911,-5329,-5941>, v=<0,62,39>, a=<8,4,6> +p=<-5132,4133,1583>, v=<38,-31,-42>, a=<5,-4,0> +p=<-797,-449,1945>, v=<68,51,-76>, a=<-2,-3,-7> +p=<2203,496,-620>, v=<-28,-20,55>, a=<-15,-2,-2> +p=<-512,286,-725>, v=<17,-14,46>, a=<2,-1,0> +p=<-317,2701,2845>, v=<92,-135,-88>, a=<-9,-6,-13> +p=<2488,-839,10>, v=<-95,13,-19>, a=<-9,5,2> +p=<-32,-584,-1805>, v=<1,68,54>, a=<0,-4,8> +p=<-1487,841,25>, v=<106,-59,12>, a=<-1,0,-2> +p=<9711,3803,1142>, v=<-7,36,3>, a=<-15,-8,-2> +p=<3306,-1797,722>, v=<-4,34,-183>, a=<-5,1,9> +p=<2050,-1523,1668>, v=<-33,42,148>, a=<-3,1,-15> +p=<2914,-227,-2544>, v=<-9,8,66>, a=<-7,0,2> +p=<4507,-227,-1977>, v=<-152,22,-25>, a=<-1,-1,7> +p=<5452,448,777>, v=<-75,-87,-43>, a=<-9,5,1> +p=<-1217,-3197,-2922>, v=<18,76,-102>, a=<2,3,15> +p=<-1703,-2738,-6>, v=<-6,-39,0>, a=<5,10,0> +p=<-29,-6410,453>, v=<16,83,-73>, a=<-1,11,4> +p=<1591,313,-5028>, v=<40,16,102>, a=<-7,-2,6> +p=<1753,-4823,2921>, v=<-46,-88,-58>, a=<0,11,-1> +p=<3672,-6932,2617>, v=<79,26,-89>, a=<-9,8,1> +p=<-1534,8477,2883>, v=<-135,30,21>, a=<9,-13,-5> +p=<-3187,5532,7994>, v=<45,-29,23>, a=<2,-6,-12> +p=<5249,-776,-2988>, v=<-21,59,-39>, a=<-6,-2,6> +p=<-774,-339,-7244>, v=<1,106,112>, a=<1,-5,4> +p=<-2104,-17268,1420>, v=<-3,64,118>, a=<3,20,-8> +p=<-1306,4335,-24>, v=<15,22,0>, a=<1,-7,0> +p=<-972,2893,110>, v=<-133,420,13>, a=<7,-27,1> +p=<1906,-490,2091>, v=<271,-62,298>, a=<-18,9,-21> +p=<-1422,-2788,323>, v=<-200,-398,44>, a=<14,27,-3> +p=<1079,-21,-2677>, v=<156,-2,-384>, a=<-9,-1,22> +p=<-513,1027,-2732>, v=<-71,147,-392>, a=<5,-13,29> +p=<472,-76,-2799>, v=<67,-14,-399>, a=<-6,5,28> +p=<-478,1841,2426>, v=<-69,269,351>, a=<5,-20,-26> +p=<2254,1465,-1528>, v=<324,211,-218>, a=<-19,-13,17> +p=<-277,1286,2981>, v=<-39,181,423>, a=<-1,-8,-24> +p=<71,2026,2683>, v=<5,285,383>, a=<-3,-20,-25> +p=<-581,-2942,-73>, v=<-79,-423,-11>, a=<4,33,-4> +p=<65,2932,137>, v=<7,418,19>, a=<-1,-29,-1> +p=<-401,582,-3050>, v=<-59,88,-434>, a=<1,-4,30> +p=<2976,-590,-108>, v=<421,-80,-12>, a=<-26,2,4> +p=<-2303,-645,-1751>, v=<-329,-91,-251>, a=<21,6,14> +p=<1140,-2857,662>, v=<164,-410,91>, a=<-11,27,-10> +p=<-2532,-643,1350>, v=<-363,-84,191>, a=<29,4,-20> +p=<1816,1234,-2316>, v=<261,177,-329>, a=<-18,-12,23> +p=<499,-2878,-236>, v=<71,-410,-38>, a=<-2,25,6> +p=<2553,-1482,-988>, v=<361,-214,-139>, a=<-24,14,9> +p=<-2086,-2102,-211>, v=<-300,-301,-31>, a=<12,23,-2> +p=<-256,-1962,-2187>, v=<-38,-280,-313>, a=<1,19,20> +p=<-1353,-1829,1849>, v=<-197,-264,260>, a=<15,19,-18> +p=<2427,-1169,1408>, v=<345,-170,206>, a=<-30,5,-17> +p=<-681,372,-3521>, v=<-98,58,-512>, a=<12,-3,39> +p=<-525,-322,-2723>, v=<-71,-46,-387>, a=<9,-2,33> +p=<-1485,2370,-939>, v=<-212,340,-138>, a=<19,-18,11> +p=<2629,23,1333>, v=<375,2,191>, a=<-24,-1,-13> +p=<-962,2687,-565>, v=<-140,383,-78>, a=<8,-20,5> +p=<990,3391,-1021>, v=<144,480,-152>, a=<-9,-32,8> +p=<-1608,2476,39>, v=<-229,351,3>, a=<17,-24,0> +p=<2455,44,-1459>, v=<350,3,-209>, a=<-26,0,19> +p=<3240,154,-210>, v=<457,20,-33>, a=<-31,1,6> +p=<-2171,-88,-1778>, v=<-309,-8,-254>, a=<19,0,15> +p=<-2277,-926,-1445>, v=<-325,-131,-207>, a=<24,5,11> +p=<-589,-1148,2928>, v=<-80,-170,418>, a=<9,12,-29> +p=<-2241,-1063,1406>, v=<-316,-152,197>, a=<24,16,-19> +p=<2092,-955,950>, v=<298,-136,132>, a=<-24,8,-7> +p=<-466,-2201,-1279>, v=<-62,-310,-180>, a=<-1,23,12> +p=<-468,-2983,-1861>, v=<-66,-425,-260>, a=<8,28,23> +p=<-1070,-2706,-272>, v=<-149,-388,-38>, a=<8,27,0> +p=<-2009,-1830,1787>, v=<-291,-264,248>, a=<20,22,-17> +p=<2822,-85,659>, v=<403,-14,89>, a=<-33,0,-10> +p=<-2363,-1805,-611>, v=<-337,-257,-89>, a=<24,16,12> +p=<-2598,2035,-674>, v=<-373,287,-95>, a=<28,-22,8> +p=<1173,2573,243>, v=<164,367,40>, a=<-14,-23,1> +p=<-836,3312,206>, v=<-118,475,29>, a=<8,-34,-2> +p=<1688,-381,2533>, v=<236,-57,357>, a=<-15,3,-25> +p=<143,1759,-2463>, v=<22,249,-355>, a=<0,-14,27> +p=<-2683,2007,980>, v=<-389,283,140>, a=<25,-23,-12> +p=<-670,-1250,-2411>, v=<-97,-178,-347>, a=<6,15,24> +p=<-1136,2357,985>, v=<-164,334,139>, a=<16,-27,-11> +p=<2096,-1737,638>, v=<298,-251,86>, a=<-20,22,-6> +p=<-2631,-271,1623>, v=<-375,-37,230>, a=<29,1,-18> +p=<2424,1243,1437>, v=<348,177,200>, a=<-26,-10,-19> +p=<2060,1385,938>, v=<294,197,134>, a=<-25,-14,-15> +p=<1331,2651,-818>, v=<193,381,-116>, a=<-13,-30,9> +p=<776,1916,1714>, v=<112,274,249>, a=<-5,-18,-17> +p=<-811,427,-2299>, v=<-117,63,-328>, a=<6,0,27> +p=<1354,2492,-186>, v=<191,355,-27>, a=<-16,-24,2> +p=<474,3023,-673>, v=<69,434,-92>, a=<-4,-25,10> +p=<1520,-2352,670>, v=<215,-334,94>, a=<-16,19,-7> +p=<-1149,-2556,-1447>, v=<-166,-360,-206>, a=<11,23,13> +p=<-37,2330,1867>, v=<-5,328,265>, a=<-2,-22,-14> +p=<-2861,-590,507>, v=<-413,-82,70>, a=<27,1,-2> +p=<3202,-250,647>, v=<462,-35,92>, a=<-24,2,-6> +p=<-2286,-833,-1219>, v=<-326,-122,-173>, a=<22,4,15> +p=<-2215,-1793,861>, v=<-321,-252,125>, a=<18,22,-4> +p=<-156,1321,2884>, v=<-21,191,413>, a=<1,-11,-30> +p=<-804,2418,-838>, v=<-114,340,-125>, a=<8,-26,6> +p=<-1121,-1781,-1869>, v=<-157,-256,-265>, a=<12,19,17> +p=<-1529,565,-2482>, v=<-217,86,-354>, a=<15,-5,29> +p=<87,1773,2467>, v=<17,253,356>, a=<0,-12,-24> +p=<-1370,2134,2591>, v=<-195,304,367>, a=<14,-20,-25> +p=<-14,2076,1747>, v=<-4,294,249>, a=<4,-12,-17> +p=<1935,-1618,1382>, v=<281,-226,197>, a=<-18,19,-13> +p=<-2297,1551,77>, v=<-331,223,10>, a=<16,-13,-2> +p=<-1952,-1430,82>, v=<-276,-199,12>, a=<14,13,0> +p=<-1987,-1518,-1457>, v=<-280,-216,-208>, a=<14,15,17> +p=<-1359,-1392,2060>, v=<-196,-199,295>, a=<12,15,-26> +p=<691,-2517,1578>, v=<98,-359,224>, a=<-9,26,-15> +p=<2671,965,580>, v=<381,131,81>, a=<-31,-14,-7> +p=<-243,614,2906>, v=<-31,84,421>, a=<3,-6,-30> +p=<-1052,646,3333>, v=<-149,95,476>, a=<12,-3,-37> +p=<510,1846,2487>, v=<72,264,351>, a=<-9,-20,-24> +p=<-1990,-1380,1739>, v=<-282,-193,248>, a=<18,9,-15> +p=<133,-2661,-1829>, v=<18,-382,-264>, a=<1,28,18> +p=<815,2490,1020>, v=<122,351,144>, a=<-8,-20,-4> +p=<2465,-1704,-1056>, v=<348,-243,-150>, a=<-24,16,12> +p=<-711,-1825,2020>, v=<-107,-263,293>, a=<3,18,-20> +p=<2090,1861,-455>, v=<295,266,-65>, a=<-16,-18,8> +p=<-76,2995,-1382>, v=<-11,422,-196>, a=<2,-32,12> +p=<2104,-1799,1488>, v=<298,-260,207>, a=<-24,19,-13> +p=<63,2542,2053>, v=<10,365,295>, a=<0,-26,-15> +p=<1575,1481,-1420>, v=<224,211,-200>, a=<-11,-18,14> +p=<-2166,-345,-1387>, v=<-306,-49,-201>, a=<17,-1,10> +p=<-945,2623,29>, v=<-132,371,3>, a=<12,-23,-1> +p=<2590,878,-717>, v=<370,129,-102>, a=<-22,-15,9> +p=<2515,-1076,-679>, v=<357,-154,-101>, a=<-23,6,6> +p=<-1338,-2273,-1604>, v=<-186,-328,-231>, a=<14,22,18> +p=<-353,-2665,-1229>, v=<-46,-379,-172>, a=<3,24,12> +p=<-83,2448,-822>, v=<-13,353,-116>, a=<4,-23,8> +p=<-523,2472,1345>, v=<-73,355,192>, a=<8,-26,-15> +p=<-2443,1609,-1552>, v=<-349,231,-216>, a=<27,-17,22> +p=<1999,-1105,2090>, v=<285,-162,296>, a=<-17,10,-20> +p=<1954,2345,1492>, v=<277,339,213>, a=<-19,-23,-14> +p=<2221,-1016,1120>, v=<316,-141,158>, a=<-24,12,-10> +p=<-3168,-1304,44>, v=<-455,-186,10>, a=<27,16,1> +p=<1622,-980,-2335>, v=<231,-145,-337>, a=<-15,13,21> +p=<2185,209,2262>, v=<311,34,326>, a=<-27,2,-22> +p=<-2551,-307,1547>, v=<-364,-42,223>, a=<22,2,-16> +p=<-908,-1546,2694>, v=<-129,-219,384>, a=<11,12,-29> +p=<3364,248,363>, v=<481,35,47>, a=<-30,-4,3> +p=<-417,2230,1781>, v=<-60,320,254>, a=<5,-24,-15> +p=<-1902,-30,-1618>, v=<-265,-1,-228>, a=<20,0,13> +p=<-693,3041,-63>, v=<-100,434,-9>, a=<1,-29,-2> +p=<-1400,565,-2175>, v=<-200,80,-310>, a=<15,-6,17> +p=<-1416,-2376,-1590>, v=<-205,-341,-226>, a=<17,23,12> +p=<1484,-2148,1957>, v=<212,-311,279>, a=<-18,22,-16> +p=<573,2306,-702>, v=<84,331,-100>, a=<-8,-20,4> +p=<2271,1826,646>, v=<317,255,92>, a=<-21,-19,-6> +p=<-1405,1090,2686>, v=<-200,154,380>, a=<16,-7,-25> +p=<1115,-2148,-2264>, v=<161,-308,-323>, a=<-15,18,22> +p=<1491,2294,-1052>, v=<215,330,-149>, a=<-14,-22,8> +p=<2596,1010,885>, v=<374,145,124>, a=<-24,-8,-10> +p=<-1795,1860,-1144>, v=<-257,267,-164>, a=<24,-20,9> +p=<1277,687,-2336>, v=<184,94,-333>, a=<-7,-6,28> +p=<-347,1880,2125>, v=<-49,269,301>, a=<0,-18,-22> +p=<-18,-2622,-1537>, v=<-2,-370,-219>, a=<-2,29,19> +p=<-1855,-2054,1009>, v=<-264,-297,140>, a=<21,17,-14> +p=<-326,-2183,2149>, v=<-40,-311,306>, a=<0,18,-17> +p=<-980,-864,-2259>, v=<-141,-118,-318>, a=<14,10,17> +p=<-1809,905,-2722>, v=<-258,133,-391>, a=<17,-12,26> +p=<592,1196,-2413>, v=<88,171,-351>, a=<-1,-7,26> +p=<2073,1542,2188>, v=<300,220,318>, a=<-19,-15,-18> +p=<-557,-2458,1007>, v=<-79,-350,142>, a=<11,22,-12> +p=<-2392,2150,1346>, v=<-342,309,192>, a=<24,-23,-12> +p=<994,-2356,833>, v=<142,-338,119>, a=<-9,31,-3> +p=<299,2668,-290>, v=<46,382,-41>, a=<-5,-25,2> +p=<1626,-692,-2134>, v=<238,-101,-303>, a=<-14,6,19> +p=<1605,-1643,-682>, v=<228,-238,-98>, a=<-16,19,6> +p=<2925,-496,-312>, v=<419,-74,-44>, a=<-28,3,5> +p=<1803,-1874,1905>, v=<259,-265,271>, a=<-11,18,-19> +p=<-2236,415,-1699>, v=<-319,57,-246>, a=<22,-6,16> +p=<1843,-488,1798>, v=<259,-69,257>, a=<-26,5,-20> +p=<-2754,1655,331>, v=<-392,240,47>, a=<26,-16,-8> +p=<-834,251,-2722>, v=<-116,33,-386>, a=<3,-5,21> +p=<1021,-1266,3203>, v=<146,-185,456>, a=<-8,12,-36> +p=<-3008,-317,1005>, v=<-426,-45,145>, a=<27,1,-11> +p=<-2940,246,-187>, v=<-420,35,-22>, a=<34,-1,-1> +p=<1801,-1599,-1446>, v=<256,-221,-208>, a=<-15,12,14> +p=<-682,-3221,-349>, v=<-93,-456,-50>, a=<10,31,6> +p=<1654,207,-2009>, v=<238,33,-287>, a=<-20,-10,26> +p=<361,131,3200>, v=<51,15,455>, a=<-4,-1,-32> +p=<-633,-781,-2968>, v=<-91,-114,-422>, a=<5,6,29> +p=<-2215,-1455,1996>, v=<-315,-209,290>, a=<21,17,-15> +p=<-1296,-1166,2232>, v=<-185,-166,322>, a=<10,8,-22> +p=<-506,1002,-2804>, v=<-67,140,-401>, a=<7,-10,31> +p=<886,713,3210>, v=<125,97,458>, a=<-11,-11,-31> +p=<473,1814,2234>, v=<67,258,320>, a=<-6,-21,-19> +p=<-1602,1619,2001>, v=<-225,230,285>, a=<21,-16,-20> +p=<-742,-2555,288>, v=<-107,-365,42>, a=<7,26,-2> +p=<-3147,-1191,643>, v=<-445,-169,93>, a=<36,11,-8> +p=<1263,214,2752>, v=<180,30,395>, a=<-9,-2,-29> +p=<-2143,2199,1241>, v=<-310,308,175>, a=<23,-24,-8> +p=<-2553,928,-1224>, v=<-364,125,-172>, a=<25,-7,9> +p=<-2136,-2245,-1378>, v=<-307,-323,-195>, a=<24,23,13> +p=<889,-1593,2244>, v=<129,-222,323>, a=<-8,17,-23> +p=<-1520,-1646,1398>, v=<-223,-235,199>, a=<21,13,-11> +p=<2628,1000,-86>, v=<374,139,-16>, a=<-27,-16,1> +p=<-2376,-283,-2193>, v=<-336,-38,-314>, a=<29,7,24> +p=<1742,2026,408>, v=<247,292,55>, a=<-17,-23,1> +p=<-2191,-1544,-527>, v=<-312,-215,-75>, a=<20,15,7> +p=<-1704,-1827,1891>, v=<-241,-263,273>, a=<19,22,-18> +p=<-1270,-49,3352>, v=<-181,-13,478>, a=<12,2,-32> +p=<-2569,901,331>, v=<-369,129,47>, a=<26,-4,-4> +p=<1141,2256,1587>, v=<163,320,220>, a=<-13,-22,-18> +p=<1137,-2605,-1860>, v=<159,-373,-265>, a=<-10,24,14> +p=<-34,-1139,-2680>, v=<-3,-162,-383>, a=<0,10,26> +p=<2205,-1859,-418>, v=<318,-263,-57>, a=<-23,19,9> +p=<2263,-885,731>, v=<323,-127,101>, a=<-19,10,-7> +p=<747,-1743,-2548>, v=<107,-251,-360>, a=<-8,19,28> +p=<-2858,-1478,-787>, v=<-404,-214,-111>, a=<31,16,10> +p=<-2627,342,956>, v=<-375,45,136>, a=<26,-6,-12> +p=<-2234,2105,357>, v=<-319,303,51>, a=<19,-20,-4> +p=<1027,-2032,1325>, v=<153,-292,186>, a=<-7,20,-9> +p=<1283,-1286,2609>, v=<185,-183,373>, a=<-10,7,-23> +p=<1360,1947,2379>, v=<197,277,339>, a=<-17,-15,-23> +p=<-860,-679,2987>, v=<-122,-97,427>, a=<3,9,-24> +p=<-1647,2787,-244>, v=<-232,401,-37>, a=<17,-30,1> +p=<837,3170,1198>, v=<119,454,170>, a=<-4,-24,-11> +p=<1266,-1460,2161>, v=<179,-200,308>, a=<-14,10,-21> +p=<1648,1562,-2437>, v=<235,226,-350>, a=<-14,-12,24> +p=<-570,2209,-1513>, v=<-85,316,-215>, a=<1,-21,20> +p=<330,-2321,-199>, v=<47,-329,-28>, a=<-3,24,4> +p=<-2067,1180,1813>, v=<-299,169,263>, a=<20,-8,-15> +p=<-78,-2126,2288>, v=<-5,-307,321>, a=<-2,21,-25> +p=<-1626,281,1926>, v=<-232,40,277>, a=<23,3,-20> +p=<-235,3009,-77>, v=<-32,428,-16>, a=<1,-26,1> +p=<-345,3015,279>, v=<-52,430,42>, a=<0,-21,-1> +p=<2896,-2028,-978>, v=<416,-288,-138>, a=<-32,20,9> +p=<-3125,-612,759>, v=<-449,-87,108>, a=<31,5,-12> +p=<2888,2,384>, v=<414,0,57>, a=<-32,1,-6> +p=<-731,1698,2115>, v=<-106,244,305>, a=<7,-13,-21> +p=<2036,-736,-1453>, v=<294,-107,-208>, a=<-20,6,11> +p=<1652,-2222,234>, v=<236,-319,33>, a=<-18,15,-3> +p=<-515,-3243,235>, v=<-72,-462,30>, a=<3,33,1> +p=<7,-2446,2313>, v=<-3,-346,330>, a=<4,28,-21> +p=<1566,2106,1297>, v=<223,298,187>, a=<-13,-21,-15> +p=<2773,-241,-1939>, v=<393,-34,-277>, a=<-23,3,19> +p=<-1981,-951,1585>, v=<-286,-137,221>, a=<20,8,-18> +p=<-14,2752,627>, v=<-2,392,88>, a=<2,-21,-6> +p=<-2752,-498,2256>, v=<-393,-70,317>, a=<27,1,-23> +p=<-2795,-853,-603>, v=<-406,-121,-86>, a=<25,5,2> +p=<631,-2038,-1425>, v=<90,-293,-206>, a=<-4,20,12> +p=<125,2224,1993>, v=<18,316,291>, a=<4,-21,-25> +p=<-2231,489,-1563>, v=<-322,70,-224>, a=<23,-3,15> +p=<-2139,746,-1996>, v=<-302,109,-279>, a=<21,-5,18> +p=<992,-1201,-2833>, v=<145,-172,-408>, a=<-8,15,24> +p=<-1702,-2598,-45>, v=<-247,-371,-5>, a=<17,28,-2> +p=<-2590,-960,482>, v=<-369,-137,68>, a=<28,7,2> +p=<3216,-233,416>, v=<461,-31,61>, a=<-34,6,-4> +p=<-1121,692,2728>, v=<-162,101,391>, a=<13,-8,-27> +p=<-2671,-146,2193>, v=<-383,-24,313>, a=<22,-3,-22> +p=<763,-241,-3416>, v=<107,-32,-482>, a=<-9,-2,33> +p=<-671,-3065,126>, v=<-94,-437,16>, a=<13,31,-4> +p=<564,-2454,1713>, v=<75,-350,244>, a=<-5,24,-17> +p=<-1735,-2340,-460>, v=<-247,-334,-62>, a=<14,23,4> +p=<6,-2515,1136>, v=<0,-359,163>, a=<0,26,-10> +p=<2952,-18,724>, v=<424,1,103>, a=<-33,2,-9> +p=<-1425,729,2352>, v=<-206,107,337>, a=<17,-7,-23> +p=<-2551,-193,-2026>, v=<-365,-31,-289>, a=<25,3,17> +p=<1329,-2258,-1434>, v=<189,-322,-206>, a=<-18,18,14> +p=<1211,2337,-829>, v=<173,332,-120>, a=<-15,-20,8> +p=<-1528,-2029,2196>, v=<-218,-290,315>, a=<18,18,-19> +p=<2764,2067,855>, v=<391,290,119>, a=<-23,-16,-7> +p=<50,-2547,1000>, v=<8,-363,140>, a=<-1,27,-10> +p=<-1843,-740,-2538>, v=<-258,-105,-364>, a=<20,8,24> +p=<2901,-143,-287>, v=<416,-19,-40>, a=<-32,-3,3> +p=<-745,3115,-349>, v=<-111,448,-51>, a=<7,-34,-3> +p=<1591,264,-2030>, v=<222,37,-288>, a=<-16,-6,19> +p=<166,-48,3636>, v=<23,-10,516>, a=<-1,2,-30> +p=<319,1678,-2277>, v=<46,237,-320>, a=<0,-18,23> +p=<-2171,614,-1695>, v=<-310,87,-242>, a=<21,-4,11> +p=<-1126,665,-2761>, v=<-157,93,-392>, a=<14,-6,29> +p=<1741,2247,1663>, v=<246,324,234>, a=<-17,-16,-20> +p=<1650,-1865,-1148>, v=<236,-268,-164>, a=<-17,14,11> +p=<319,-1899,-1553>, v=<45,-274,-219>, a=<0,18,12> +p=<-319,321,-3639>, v=<-42,45,-518>, a=<5,0,31> +p=<-863,-2811,20>, v=<-123,-397,4>, a=<9,31,-2> +p=<2645,-31,542>, v=<373,-5,73>, a=<-23,1,-4> +p=<-228,-1990,2353>, v=<-35,-287,336>, a=<5,22,-21> +p=<3382,828,-998>, v=<482,123,-143>, a=<-35,-9,7> +p=<-681,-2015,-1438>, v=<-89,-285,-208>, a=<6,19,12> +p=<-2127,-1613,-1494>, v=<-308,-234,-212>, a=<19,16,11> +p=<65,2762,-1780>, v=<9,395,-254>, a=<2,-26,17> +p=<-798,-2143,754>, v=<-112,-311,104>, a=<12,25,-10> +p=<1936,1826,927>, v=<277,263,131>, a=<-15,-20,-10> +p=<-720,-1926,-1387>, v=<-103,-275,-198>, a=<8,16,11> +p=<-2584,-1286,524>, v=<-371,-180,74>, a=<28,15,-9> +p=<286,-3580,426>, v=<39,-510,60>, a=<0,34,-7> +p=<-1940,-1873,-414>, v=<-277,-269,-56>, a=<19,14,6> +p=<2631,-809,-1547>, v=<376,-116,-229>, a=<-30,10,16> +p=<673,2160,-1825>, v=<102,308,-257>, a=<-4,-23,17> +p=<2169,-2413,-1194>, v=<307,-344,-170>, a=<-20,25,16> +p=<603,-3052,-393>, v=<89,-434,-53>, a=<-11,33,1> +p=<-1690,1909,1134>, v=<-241,272,169>, a=<15,-18,-15> +p=<-623,1217,1954>, v=<-93,172,275>, a=<10,-16,-15> +p=<-1697,-316,2170>, v=<-242,-45,310>, a=<20,-3,-19> +p=<-1516,2344,1308>, v=<-216,333,185>, a=<18,-20,-17> +p=<1853,-1625,701>, v=<261,-229,105>, a=<-20,19,-4> +p=<1542,-522,-2138>, v=<220,-70,-305>, a=<-20,8,20> +p=<-1835,-1148,-887>, v=<-257,-165,-126>, a=<22,13,5> +p=<3238,-2064,302>, v=<460,-292,47>, a=<-32,20,0> +p=<1003,-2638,-162>, v=<146,-372,-23>, a=<-10,26,5> +p=<-2709,1375,804>, v=<-385,196,120>, a=<24,-9,-9> +p=<-184,555,2572>, v=<-30,79,367>, a=<1,0,-29> +p=<-754,2751,-299>, v=<-110,393,-47>, a=<9,-28,2> +p=<2362,713,-1616>, v=<332,104,-227>, a=<-23,-7,15> +p=<254,732,-2598>, v=<38,104,-368>, a=<-8,-7,19> +p=<-2364,-799,1470>, v=<-344,-112,211>, a=<23,7,-16> +p=<2519,1937,-284>, v=<360,274,-40>, a=<-32,-22,3> +p=<2368,828,-1323>, v=<333,118,-182>, a=<-27,-5,12> +p=<-1443,-1799,2182>, v=<-204,-257,310>, a=<18,22,-23> +p=<-2230,320,1535>, v=<-319,47,219>, a=<21,-1,-15> +p=<-2176,1006,1711>, v=<-314,138,241>, a=<15,-10,-17> +p=<-2359,-1764,735>, v=<-341,-252,107>, a=<20,19,-6> +p=<-2255,2133,478>, v=<-318,303,67>, a=<21,-23,-4> +p=<1838,2021,-2030>, v=<262,293,-291>, a=<-22,-22,24> +p=<676,2730,-1581>, v=<98,391,-222>, a=<-7,-25,18> +p=<1654,1705,1873>, v=<233,240,270>, a=<-20,-22,-18> +p=<2899,-1228,-768>, v=<414,-171,-110>, a=<-29,10,12> +p=<-1106,-2603,-1038>, v=<-160,-376,-152>, a=<13,33,10> +p=<-2486,-1591,1417>, v=<-352,-223,202>, a=<23,14,-15> +p=<-224,-2723,405>, v=<-31,-392,57>, a=<-4,30,-2> +p=<-990,-385,2834>, v=<-141,-51,401>, a=<11,1,-30> +p=<2393,-1847,-12>, v=<343,-271,-1>, a=<-24,18,0> +p=<897,-1971,2676>, v=<126,-282,379>, a=<-11,19,-26> +p=<-1382,828,2465>, v=<-197,118,354>, a=<12,-11,-24> +p=<2715,-636,-95>, v=<383,-92,-10>, a=<-23,5,2> +p=<-1672,1496,1384>, v=<-238,215,196>, a=<13,-12,-8> +p=<-695,2864,430>, v=<-96,408,66>, a=<13,-28,-9> +p=<-890,2879,152>, v=<-128,419,18>, a=<11,-25,-1> +p=<1150,854,2388>, v=<160,127,344>, a=<-10,-10,-23> +p=<-1328,304,2387>, v=<-189,44,346>, a=<19,0,-20> +p=<1911,1030,2606>, v=<274,147,372>, a=<-21,-5,-22> +p=<-153,1935,1425>, v=<-17,277,204>, a=<-6,-18,-15> +p=<-563,-39,-3152>, v=<-85,-5,-449>, a=<4,0,31> +p=<1376,-434,2342>, v=<194,-58,337>, a=<-11,7,-24> +p=<1328,-3274,1577>, v=<188,-464,224>, a=<-13,32,-11> +p=<-1483,2780,842>, v=<-211,394,122>, a=<14,-27,-4> +p=<-2579,-50,157>, v=<-368,-5,18>, a=<22,0,-2> +p=<-2233,-1101,1703>, v=<-326,-156,244>, a=<23,11,-19> +p=<1576,-2527,660>, v=<225,-364,94>, a=<-14,29,-6> +p=<-920,-2797,-447>, v=<-128,-399,-63>, a=<7,22,4> +p=<-2430,2192,873>, v=<-347,313,128>, a=<25,-21,-11> +p=<616,2820,-591>, v=<84,402,-86>, a=<-5,-28,5> +p=<-544,-1235,2995>, v=<-78,-179,428>, a=<6,12,-29> +p=<-2103,152,1778>, v=<-297,15,262>, a=<21,2,-18> +p=<1499,276,3011>, v=<213,37,435>, a=<-14,-7,-31> +p=<-1913,2443,611>, v=<-270,345,87>, a=<15,-24,-4> +p=<-398,2956,72>, v=<-56,417,10>, a=<1,-31,5> +p=<-1863,1996,-1348>, v=<-266,285,-195>, a=<18,-15,14> +p=<-2302,-248,1303>, v=<-325,-38,181>, a=<17,1,-17> +p=<-591,-341,2548>, v=<-89,-52,364>, a=<4,5,-27> +p=<906,-1426,-2591>, v=<129,-206,-368>, a=<-7,14,19> +p=<-1733,-1479,1564>, v=<-251,-213,222>, a=<18,9,-13> +p=<2526,1103,78>, v=<357,157,11>, a=<-24,-9,-2> +p=<745,1626,2823>, v=<111,228,409>, a=<-6,-17,-23> +p=<-818,43,-2240>, v=<-118,11,-320>, a=<13,1,25> +p=<1837,993,1492>, v=<260,148,213>, a=<-17,-10,-16> +p=<-1099,1353,-2333>, v=<-162,193,-333>, a=<8,-9,22> +p=<467,2292,2372>, v=<66,332,340>, a=<-10,-18,-20> +p=<2035,1594,-773>, v=<290,227,-112>, a=<-18,-8,9> +p=<1663,-1377,1996>, v=<237,-196,283>, a=<-20,14,-16> +p=<-1151,1892,1053>, v=<-163,270,143>, a=<8,-21,-9> +p=<-1985,-1355,-1070>, v=<-283,-192,-151>, a=<22,10,9> +p=<880,-1024,-2847>, v=<121,-146,-401>, a=<-6,10,37> +p=<-2506,-941,-1276>, v=<-359,-141,-182>, a=<25,14,14> +p=<448,-3321,-1237>, v=<65,-469,-174>, a=<-4,31,10> +p=<1082,-384,2456>, v=<154,-55,343>, a=<-4,1,-21> +p=<583,-1175,2602>, v=<80,-167,370>, a=<-5,8,-26> +p=<-2143,1051,-2228>, v=<-306,150,-321>, a=<16,-11,26> +p=<-1351,1113,2530>, v=<-195,156,360>, a=<16,-11,-23> +p=<1289,2415,1068>, v=<186,345,157>, a=<-13,-31,-9> +p=<1829,-441,-2369>, v=<261,-59,-331>, a=<-20,4,25> +p=<-1181,2801,-1204>, v=<-168,406,-169>, a=<11,-25,15> +p=<1789,111,2716>, v=<253,16,391>, a=<-12,-1,-28> +p=<1188,-2396,-1168>, v=<173,-343,-166>, a=<-18,21,11> +p=<-624,-2348,1872>, v=<-87,-331,263>, a=<6,23,-17> +p=<974,2046,1600>, v=<141,293,228>, a=<-10,-20,-20> +p=<1087,-3,2753>, v=<157,4,393>, a=<-10,1,-31> +p=<-1696,2565,1439>, v=<-242,365,200>, a=<15,-21,-14> +p=<-2139,1264,1625>, v=<-308,186,239>, a=<21,-16,-17> +p=<-808,-2806,706>, v=<-116,-402,100>, a=<10,31,-7> +p=<-3344,-671,-1309>, v=<-477,-89,-186>, a=<31,4,12> +p=<-3120,-1016,-1164>, v=<-445,-145,-169>, a=<33,9,11> +p=<-392,1935,-1765>, v=<-54,277,-256>, a=<7,-20,20> +p=<-2772,50,-724>, v=<-398,7,-103>, a=<22,-2,1> +p=<-1135,909,-2293>, v=<-162,123,-325>, a=<11,-2,17> +p=<-2854,-66,-601>, v=<-402,-8,-82>, a=<29,-3,6> +p=<1651,760,1457>, v=<233,111,209>, a=<-16,-9,-14> +p=<-1771,-1151,-2641>, v=<-254,-160,-378>, a=<17,14,27> +p=<-1065,-2133,-2022>, v=<-152,-309,-293>, a=<12,24,14> +p=<1476,2335,-246>, v=<211,333,-32>, a=<-7,-22,0> +p=<-1903,461,2772>, v=<-268,58,396>, a=<21,-2,-25> +p=<765,-2802,769>, v=<112,-398,106>, a=<-3,33,-5> +p=<-3176,954,-234>, v=<-450,133,-36>, a=<29,-9,3> +p=<2177,-558,-2053>, v=<316,-78,-293>, a=<-21,5,19> +p=<394,1915,-2164>, v=<59,277,-313>, a=<-5,-20,21> +p=<1111,2949,1071>, v=<155,421,153>, a=<-10,-29,-12> +p=<-1787,102,2329>, v=<-254,13,332>, a=<14,-3,-20> +p=<-1253,-2502,-882>, v=<-176,-356,-124>, a=<15,24,7> +p=<1524,2539,-1037>, v=<216,362,-148>, a=<-15,-21,5> +p=<1881,745,2344>, v=<266,106,334>, a=<-14,-5,-24> +p=<-824,2492,1274>, v=<-117,355,187>, a=<2,-27,-11> +p=<-2672,-391,-718>, v=<-377,-60,-103>, a=<26,2,7> +p=<1706,-2502,613>, v=<248,-357,87>, a=<-19,23,-9> +p=<2838,442,349>, v=<400,63,52>, a=<-33,-4,-3> +p=<271,1719,-2620>, v=<42,245,-371>, a=<-5,-23,22> +p=<-1158,-1793,1596>, v=<-165,-258,225>, a=<6,10,-14> +p=<2491,-195,-2133>, v=<353,-23,-304>, a=<-22,-4,21> +p=<-119,2896,-1592>, v=<-14,413,-227>, a=<-2,-25,14> +p=<886,-685,2791>, v=<130,-97,398>, a=<-8,6,-26> +p=<1066,-2652,1270>, v=<152,-374,179>, a=<-10,28,-19> +p=<2080,1437,-1544>, v=<290,206,-216>, a=<-23,-15,15> +p=<1863,410,2408>, v=<270,56,345>, a=<-18,-4,-18> +p=<-524,3071,96>, v=<-74,436,11>, a=<7,-33,-4> +p=<580,-948,-2576>, v=<88,-133,-367>, a=<-12,11,22> +p=<-1103,1711,1858>, v=<-154,246,264>, a=<11,-15,-16> +p=<607,-2998,-745>, v=<79,-428,-101>, a=<-11,33,7> +p=<-1900,-1037,-1936>, v=<-269,-150,-275>, a=<16,12,15> +p=<-1155,-491,-2983>, v=<-164,-71,-431>, a=<11,-2,30> +p=<-2544,887,-742>, v=<-363,124,-109>, a=<23,-6,9> +p=<-731,2162,-1216>, v=<-102,311,-170>, a=<7,-19,16> +p=<-2202,-1939,1089>, v=<-320,-277,157>, a=<25,20,-10> +p=<-28,1561,2087>, v=<2,223,300>, a=<0,-16,-20> +p=<-1911,-1149,-1625>, v=<-271,-165,-230>, a=<15,10,12> +p=<-2869,-1090,310>, v=<-414,-155,49>, a=<26,15,-1> +p=<-695,-2254,-1859>, v=<-100,-321,-266>, a=<11,26,13> +p=<-2840,-674,1527>, v=<-405,-95,220>, a=<28,0,-17> +p=<-647,2949,1149>, v=<-91,421,164>, a=<8,-32,-11> +p=<2811,-1286,624>, v=<400,-179,89>, a=<-29,12,-3> +p=<1281,-380,-2752>, v=<182,-55,-391>, a=<-16,8,24> +p=<-2162,-1503,-1690>, v=<-306,-212,-240>, a=<21,15,14> +p=<2629,761,206>, v=<373,108,34>, a=<-27,-7,-7> +p=<-2021,620,2109>, v=<-288,90,301>, a=<20,-12,-22> +p=<-368,-2701,-164>, v=<-52,-380,-20>, a=<6,21,2> +p=<421,-3240,-681>, v=<60,-463,-96>, a=<-5,30,6> +p=<1919,-2148,-570>, v=<273,-304,-84>, a=<-24,24,5> +p=<1869,91,2715>, v=<264,13,389>, a=<-17,-5,-28> +p=<653,2752,1283>, v=<91,393,186>, a=<-3,-26,-15> +p=<-1085,-2377,-504>, v=<-155,-343,-71>, a=<10,23,4> +p=<2790,-724,-1756>, v=<400,-103,-250>, a=<-27,7,20> +p=<2362,670,1049>, v=<341,95,149>, a=<-22,-6,-10> +p=<-3223,261,-688>, v=<-459,42,-99>, a=<29,3,6> +p=<-968,2692,726>, v=<-135,386,100>, a=<9,-27,-6> +p=<763,-873,3032>, v=<108,-128,433>, a=<-7,11,-30> +p=<-397,-2950,-1235>, v=<-54,-417,-179>, a=<-1,30,13> +p=<2644,506,2319>, v=<370,68,328>, a=<-25,-5,-21> +p=<226,1558,2032>, v=<28,223,290>, a=<-2,-18,-18> +p=<-96,-2863,420>, v=<-8,-411,59>, a=<2,29,-1> +p=<2753,-521,644>, v=<389,-74,94>, a=<-25,4,-6> +p=<-2535,604,1696>, v=<-363,84,240>, a=<23,-5,-16> +p=<-1475,-1868,-1676>, v=<-211,-271,-235>, a=<13,20,20> +p=<2257,-411,1855>, v=<326,-61,264>, a=<-19,-2,-19> +p=<2632,1836,822>, v=<376,266,120>, a=<-30,-16,-8> +p=<-1695,1905,-1631>, v=<-243,272,-238>, a=<14,-27,18> +p=<-1726,1459,-2018>, v=<-246,211,-289>, a=<22,-17,23> +p=<2307,2175,489>, v=<328,312,67>, a=<-23,-20,-6> +p=<-1861,2174,-527>, v=<-269,313,-75>, a=<18,-24,5> +p=<-208,1185,2569>, v=<-28,169,371>, a=<-1,-10,-25> +p=<-1923,-300,2216>, v=<-271,-48,315>, a=<19,8,-22> +p=<-428,3024,-1181>, v=<-61,432,-171>, a=<3,-34,14> +p=<549,-2670,-461>, v=<73,-387,-65>, a=<-5,26,3> +p=<-1556,326,-2238>, v=<-221,43,-316>, a=<10,-3,27> +p=<-598,-3422,-454>, v=<-86,-488,-64>, a=<1,35,4> +p=<2143,-443,1333>, v=<302,-66,193>, a=<-20,8,-11> +p=<286,231,2772>, v=<40,35,396>, a=<-7,-1,-30> +p=<362,-2668,9>, v=<51,-379,1>, a=<-1,27,0> +p=<1015,-2626,-85>, v=<142,-376,-11>, a=<-13,33,-2> +p=<-709,904,2451>, v=<-103,130,350>, a=<5,-8,-27> +p=<2081,408,-1170>, v=<298,58,-166>, a=<-15,-7,11> +p=<-482,-2973,-1081>, v=<-69,-420,-151>, a=<2,31,9> +p=<-818,-74,-2792>, v=<-118,-10,-402>, a=<14,-3,32> +p=<2999,-87,-960>, v=<427,-14,-136>, a=<-31,3,6> +p=<2885,-1265,-374>, v=<409,-181,-53>, a=<-29,12,3> +p=<-1572,2938,16>, v=<-221,415,0>, a=<12,-30,0> +p=<-2424,-669,-1204>, v=<-342,-92,-175>, a=<21,8,17> +p=<-1215,1266,-2099>, v=<-173,176,-300>, a=<14,-7,21> +p=<-202,-3331,202>, v=<-33,-475,25>, a=<-1,36,1> +p=<935,2601,-482>, v=<133,370,-68>, a=<-12,-26,4> +p=<-1796,-2630,-1179>, v=<-260,-374,-168>, a=<20,24,10> +p=<-1532,-596,-1900>, v=<-220,-82,-274>, a=<18,5,23> +p=<-1577,-720,-2161>, v=<-228,-100,-303>, a=<17,8,25> +p=<-1215,1584,1974>, v=<-178,226,278>, a=<17,-15,-22> +p=<-3480,-170,1515>, v=<-499,-19,213>, a=<38,-1,-14> +p=<-2436,-111,-929>, v=<-353,-14,-128>, a=<25,0,14> +p=<2047,1023,-2117>, v=<292,149,-304>, a=<-21,-10,21> +p=<1510,-3054,336>, v=<224,-436,55>, a=<-12,35,-2> +p=<-2860,74,1242>, v=<-408,10,177>, a=<29,-2,-11> +p=<423,2218,-2064>, v=<56,316,-290>, a=<-1,-23,19> +p=<-1523,391,2820>, v=<-216,54,401>, a=<16,-3,-25> +p=<2150,822,-2210>, v=<305,114,-314>, a=<-21,-10,22> +p=<980,-2578,716>, v=<140,-368,106>, a=<-13,25,-13> +p=<-2221,-1430,671>, v=<-319,-202,91>, a=<29,20,-6> +p=<71,585,-2438>, v=<13,84,-348>, a=<0,1,24> +p=<-2243,-2418,-28>, v=<-320,-339,-10>, a=<22,23,0> +p=<-1990,1907,1046>, v=<-283,274,147>, a=<14,-22,-10> +p=<646,-563,-2987>, v=<96,-80,-426>, a=<-6,11,28> +p=<1124,-2386,-2399>, v=<166,-340,-342>, a=<-12,28,23> +p=<1269,-527,-2292>, v=<184,-75,-331>, a=<-12,2,24> +p=<-1031,2489,-962>, v=<-147,354,-138>, a=<13,-21,14> +p=<723,-2658,-127>, v=<105,-380,-14>, a=<-6,27,2> +p=<2,1922,2219>, v=<0,278,321>, a=<3,-18,-23> +p=<-2842,1751,-150>, v=<-408,256,-21>, a=<26,-17,-4> +p=<45,-2950,-602>, v=<9,-419,-87>, a=<3,29,6> +p=<-1231,-1203,-2120>, v=<-176,-172,-302>, a=<8,13,18> +p=<1637,-356,-1921>, v=<234,-56,-273>, a=<-14,1,18> +p=<-1712,-1611,-1495>, v=<-246,-229,-213>, a=<16,22,14> +p=<3521,152,-943>, v=<503,23,-134>, a=<-35,6,7> +p=<-2104,-2243,-337>, v=<-302,-320,-51>, a=<19,23,3> +p=<2358,-595,-1456>, v=<336,-91,-213>, a=<-22,8,14> +p=<-525,-1627,2776>, v=<-69,-232,399>, a=<0,14,-32> +p=<1648,963,-1620>, v=<238,134,-231>, a=<-12,-6,15> +p=<-2751,363,-551>, v=<-391,54,-79>, a=<24,-3,9> +p=<300,1792,2155>, v=<47,251,307>, a=<-6,-17,-16> +p=<1106,-214,-2291>, v=<156,-35,-325>, a=<-3,0,23> +p=<-1964,-795,-2331>, v=<-286,-111,-333>, a=<19,15,18> +p=<137,-3166,-572>, v=<21,-452,-82>, a=<0,30,3> +p=<-2691,705,-999>, v=<-388,98,-139>, a=<26,-9,10> +p=<1203,343,-3272>, v=<174,54,-469>, a=<-12,2,32> +p=<3115,-432,-66>, v=<447,-61,-3>, a=<-30,4,0> +p=<2562,-1744,862>, v=<367,-252,123>, a=<-23,17,-5> +p=<1380,-1281,1622>, v=<196,-177,230>, a=<-17,9,-14> +p=<-1200,-844,-2301>, v=<-173,-120,-328>, a=<15,15,20> +p=<-792,-1599,2552>, v=<-111,-231,367>, a=<7,17,-25> +p=<307,2585,-1745>, v=<46,361,-252>, a=<-2,-32,17> +p=<-199,-1278,-2273>, v=<-26,-186,-327>, a=<1,17,22> +p=<1870,-2159,-899>, v=<264,-314,-123>, a=<-18,22,6> +p=<434,1298,2381>, v=<63,185,337>, a=<-4,-11,-23> +p=<-2150,-2011,1077>, v=<-311,-289,157>, a=<15,22,-10> +p=<2355,-966,31>, v=<334,-136,2>, a=<-21,13,1> +p=<880,2467,1228>, v=<131,350,176>, a=<-10,-18,-9> +p=<2696,301,951>, v=<383,47,138>, a=<-29,-3,-10> +p=<50,1466,2481>, v=<4,210,354>, a=<0,-13,-21> +p=<-46,1414,2588>, v=<-3,203,369>, a=<2,-15,-22> +p=<-1343,790,2128>, v=<-191,114,306>, a=<17,-8,-19> +p=<-1893,-320,1958>, v=<-271,-46,278>, a=<18,1,-19> +p=<3013,80,1731>, v=<433,10,244>, a=<-30,0,-12> +p=<-1561,-2177,-1020>, v=<-227,-314,-145>, a=<16,26,16> +p=<-1230,2247,-501>, v=<-169,320,-71>, a=<14,-22,4> +p=<527,-2245,1744>, v=<67,-319,248>, a=<-6,21,-17> +p=<-1513,-166,-2981>, v=<-211,-28,-425>, a=<15,0,29> +p=<440,-823,2548>, v=<63,-116,364>, a=<-4,10,-24> +p=<-1545,-2022,350>, v=<-217,-285,51>, a=<19,18,-6> +p=<-1920,-2099,1374>, v=<-271,-304,197>, a=<18,21,-12> +p=<-1984,2245,966>, v=<-283,325,138>, a=<22,-22,-5> +p=<1286,1145,1885>, v=<186,163,271>, a=<-7,-11,-18> +p=<-2077,-1678,1117>, v=<-294,-243,156>, a=<24,17,-9> +p=<-65,3081,988>, v=<-9,440,141>, a=<-1,-33,-13> +p=<1372,-2516,92>, v=<198,-361,17>, a=<-13,23,0> +p=<574,-2894,-2168>, v=<82,-413,-309>, a=<-1,28,22> +p=<2843,-746,1072>, v=<408,-108,156>, a=<-26,5,-8> +p=<-2673,2015,-608>, v=<-380,287,-87>, a=<29,-14,5> +p=<-1103,-1722,-1992>, v=<-157,-247,-289>, a=<14,19,18> +p=<-619,528,-2863>, v=<-88,75,-410>, a=<5,-7,28> +p=<-1977,2190,1193>, v=<-282,311,167>, a=<17,-19,-13> +p=<860,-3029,253>, v=<123,-433,41>, a=<-8,33,-2> +p=<-1719,1295,-1775>, v=<-245,183,-250>, a=<13,-13,19> +p=<-2978,1898,-292>, v=<-428,271,-47>, a=<30,-18,2> +p=<565,1062,-2232>, v=<80,152,-315>, a=<-4,-10,28> +p=<-1305,1305,-2694>, v=<-183,186,-382>, a=<14,-14,26> +p=<-2484,-273,-1989>, v=<-359,-35,-283>, a=<23,4,18> +p=<1136,-1048,-2857>, v=<166,-150,-410>, a=<-9,9,30> +p=<-442,2206,2090>, v=<-64,315,301>, a=<4,-22,-14> +p=<-23,2898,224>, v=<-3,412,30>, a=<0,-26,1> +p=<2138,959,-1982>, v=<306,140,-283>, a=<-19,-9,17> +p=<-1618,1775,-1360>, v=<-231,253,-191>, a=<22,-18,12> +p=<692,1924,-2492>, v=<99,278,-361>, a=<-6,-17,28> +p=<-1023,2364,-1752>, v=<-142,340,-247>, a=<10,-19,19> +p=<-1750,-2698,1145>, v=<-246,-382,167>, a=<17,25,-11> +p=<3258,1100,-180>, v=<470,158,-26>, a=<-32,-13,0> +p=<-1915,-679,-2235>, v=<-273,-97,-323>, a=<21,9,24> +p=<-1104,-2081,-786>, v=<-155,-297,-113>, a=<11,22,10> +p=<-2858,-640,-706>, v=<-406,-90,-100>, a=<29,5,4> +p=<712,1716,-1986>, v=<102,248,-284>, a=<-7,-17,19> +p=<832,2700,-390>, v=<120,385,-55>, a=<-5,-26,3> +p=<1587,-619,2627>, v=<223,-84,375>, a=<-17,4,-28> +p=<2298,470,2118>, v=<325,62,302>, a=<-16,-8,-19> +p=<-2057,-1407,-2233>, v=<-288,-204,-317>, a=<25,14,26> +p=<-112,-62,2758>, v=<-13,-5,397>, a=<1,-2,-23> +p=<-211,-2054,2162>, v=<-32,-291,309>, a=<6,20,-24> +p=<2083,836,1594>, v=<299,118,228>, a=<-18,-8,-17> +p=<-530,2090,1973>, v=<-76,302,278>, a=<4,-26,-24> +p=<-1080,1942,-1900>, v=<-158,279,-272>, a=<6,-19,19> +p=<-2074,1278,1789>, v=<-301,186,250>, a=<14,-11,-18> +p=<-520,2504,414>, v=<-74,354,60>, a=<-2,-25,-7> +p=<-1176,-2282,-1591>, v=<-170,-326,-228>, a=<16,15,15> +p=<102,2968,990>, v=<12,427,146>, a=<-7,-32,-10> +p=<-2709,1659,-316>, v=<-389,241,-39>, a=<31,-9,1> +p=<-2290,1919,773>, v=<-329,275,105>, a=<22,-16,-12> +p=<615,482,3245>, v=<85,69,463>, a=<-10,0,-27> +p=<1234,2456,-1243>, v=<178,346,-177>, a=<-9,-21,9> +p=<1114,1679,1730>, v=<164,240,248>, a=<-12,-15,-17> +p=<-1422,1522,-1711>, v=<-208,209,-244>, a=<9,-15,21> +p=<2007,-1374,485>, v=<285,-201,69>, a=<-22,17,-4> +p=<-12,2520,544>, v=<-1,362,74>, a=<0,-26,-10> +p=<-474,-1923,2315>, v=<-67,-270,334>, a=<2,18,-21> +p=<1517,-2248,-418>, v=<216,-314,-59>, a=<-14,22,3> +p=<1118,2532,-1334>, v=<159,361,-189>, a=<-12,-25,13> +p=<-1489,-1372,-2353>, v=<-219,-200,-337>, a=<15,18,21> +p=<1056,25,-2775>, v=<149,1,-398>, a=<-17,0,27> +p=<-2726,1082,-1224>, v=<-389,153,-169>, a=<27,-7,12> +p=<751,608,-2592>, v=<102,88,-374>, a=<-6,-7,24> +p=<1945,2317,-136>, v=<276,331,-18>, a=<-23,-24,4> +p=<-3253,69,-228>, v=<-462,11,-36>, a=<36,0,-1> +p=<1255,-2938,-313>, v=<183,-419,-45>, a=<-8,26,7> +p=<-2646,2011,-797>, v=<-380,287,-109>, a=<25,-21,2> +p=<50,-1406,-2557>, v=<5,-198,-362>, a=<6,15,24> +p=<348,-1005,2940>, v=<51,-140,420>, a=<-2,7,-29> +p=<-672,2846,-1419>, v=<-97,402,-207>, a=<6,-28,11> +p=<2859,1440,-24>, v=<408,201,-9>, a=<-27,-21,2> +p=<2157,-1843,429>, v=<313,-263,61>, a=<-22,19,-4> +p=<45,-1064,2940>, v=<6,-158,419>, a=<1,12,-29> +p=<1730,987,-1830>, v=<247,143,-264>, a=<-19,-7,17> +p=<-1122,-1149,2253>, v=<-165,-161,322>, a=<12,11,-25> +p=<2676,-601,-785>, v=<380,-86,-115>, a=<-30,5,8> +p=<2435,-555,-1288>, v=<348,-80,-183>, a=<-24,6,12> +p=<1305,-81,2894>, v=<185,-10,413>, a=<-13,-4,-30> +p=<954,-2008,1396>, v=<140,-292,199>, a=<-9,25,-10> +p=<-133,2590,984>, v=<-19,374,140>, a=<0,-23,-10> +p=<1389,-2086,-2054>, v=<194,-296,-293>, a=<-16,18,19> +p=<-296,-2831,566>, v=<-37,-404,82>, a=<-2,24,1> +p=<-2569,-802,-1287>, v=<-369,-113,-183>, a=<28,10,10> +p=<-1886,1812,-2154>, v=<-266,255,-307>, a=<15,-17,26> +p=<-1719,-1231,1420>, v=<-244,-174,204>, a=<20,14,-18> +p=<-2888,-1394,1274>, v=<-412,-202,183>, a=<28,13,-14> +p=<1984,1660,1284>, v=<287,237,179>, a=<-19,-18,-16> +p=<-41,200,2573>, v=<-4,31,370>, a=<-1,-2,-25> +p=<-3016,34,-1363>, v=<-429,1,-190>, a=<31,-5,13> +p=<-1286,-763,2011>, v=<-183,-107,287>, a=<11,1,-21> +p=<-1848,1908,-618>, v=<-265,274,-87>, a=<19,-22,11> +p=<-688,2384,-207>, v=<-98,336,-29>, a=<7,-22,0> +p=<281,847,-2885>, v=<40,121,-412>, a=<-1,-11,25> +p=<192,-2453,-1601>, v=<31,-355,-222>, a=<-1,24,17> +p=<491,2203,2548>, v=<68,315,367>, a=<-5,-21,-28> +p=<-2321,-624,-555>, v=<-336,-90,-81>, a=<23,6,-1> +p=<-432,-3152,-213>, v=<-63,-450,-31>, a=<-2,31,1> +p=<-1867,1915,-782>, v=<-266,270,-110>, a=<22,-19,7> +p=<-892,-2127,-2359>, v=<-122,-311,-337>, a=<5,25,26> +p=<-941,2518,-1279>, v=<-140,360,-182>, a=<10,-25,11> +p=<1469,340,-3429>, v=<209,48,-490>, a=<-13,0,38> +p=<673,3163,673>, v=<101,451,95>, a=<-8,-34,-1> +p=<800,1337,2614>, v=<114,193,371>, a=<-2,-15,-24> +p=<1261,1722,-2285>, v=<179,249,-326>, a=<-14,-19,19> +p=<1473,-2386,-1740>, v=<210,-340,-248>, a=<-13,21,17> +p=<1905,2345,936>, v=<269,330,128>, a=<-21,-27,-8> +p=<-9,-2986,506>, v=<2,-426,74>, a=<0,29,-4> +p=<1104,2001,1666>, v=<158,286,238>, a=<-11,-20,-14> +p=<-497,-2214,2033>, v=<-66,-314,293>, a=<5,22,-13> +p=<209,-2513,-1928>, v=<29,-361,-273>, a=<-3,23,23> +p=<3148,-137,-45>, v=<452,-16,-6>, a=<-34,1,1> +p=<-738,-382,3098>, v=<-105,-51,440>, a=<8,2,-30> +p=<1401,2701,793>, v=<200,387,112>, a=<-11,-26,-11> +p=<-2116,-937,-1839>, v=<-303,-136,-266>, a=<19,9,20> +p=<686,-763,-3088>, v=<104,-117,-443>, a=<-6,10,27> +p=<-1078,-2695,1808>, v=<-150,-381,252>, a=<7,28,-22> +p=<-1664,-680,2702>, v=<-238,-102,384>, a=<19,8,-26> +p=<-2971,-700,1101>, v=<-431,-98,157>, a=<25,6,-11> +p=<-403,-2013,-1424>, v=<-57,-286,-197>, a=<-1,18,14> +p=<-248,-2160,-1597>, v=<-35,-308,-228>, a=<3,22,15> +p=<-1239,983,-1956>, v=<-175,136,-272>, a=<12,-11,20> +p=<1358,2352,2015>, v=<192,333,283>, a=<-8,-18,-14> +p=<-513,-2703,-1005>, v=<-72,-384,-140>, a=<3,26,14> +p=<1677,2614,-393>, v=<239,372,-55>, a=<-15,-26,2> +p=<568,-2323,1735>, v=<77,-333,241>, a=<-4,20,-10> +p=<2487,1279,-308>, v=<353,188,-42>, a=<-24,-12,9> +p=<1009,316,2729>, v=<136,46,389>, a=<-7,-7,-26> +p=<2442,-775,2407>, v=<345,-111,344>, a=<-25,7,-21> +p=<-936,2174,2023>, v=<-134,305,289>, a=<12,-18,-18> +p=<-731,-714,-2746>, v=<-104,-100,-390>, a=<0,5,30> +p=<422,-3337,-414>, v=<63,-477,-61>, a=<-4,31,4> +p=<1873,1735,-1252>, v=<270,244,-174>, a=<-22,-15,15> +p=<-2135,-1673,-1094>, v=<-306,-239,-155>, a=<21,18,13> +p=<-327,-2234,1998>, v=<-44,-322,283>, a=<1,22,-22> +p=<1599,722,1794>, v=<228,102,260>, a=<-16,-7,-17> +p=<749,-3446,-111>, v=<114,-490,-13>, a=<-9,35,1> diff --git a/pytudes/data/advent2017/input4.txt b/pytudes/data/advent2017/input4.txt new file mode 100644 index 0000000..b9f9e0e --- /dev/null +++ b/pytudes/data/advent2017/input4.txt @@ -0,0 +1,512 @@ +kvvfl kvvfl olud wjqsqa olud frc +slhm rdfm yxb rsobyt rdfm +pib wzfr xyoakcu zoapeze rtdxt rikc jyeps wdyo hawr xyoakcu hawr +ismtq qwoi kzt ktgzoc gnxblp dzfayil ftfx asscba ionxi dzfayil qwoi +dzuhys kfekxe nvdhdtj hzusdy xzhehgc dhtvdnj oxwlvef +gxg qahl aaipx tkmckn hcsuhy jsudcmy kcefhpn kiasaj tkmckn +roan kqnztj edc zpjwb +yzc roc qrygby rsvts nyijgwr xnpqz +jqgj hhgtw tmychia whkm vvxoq tfbzpe ska ldjmvmo +nyeeg omn geyen ngyee rcjt rjuxh +qpq udci tnp fdfk kffd eyzvmg ufppf wfuodj toamfn tkze jzsb +rrcgxyp rbufd tfjmok vpyhej hcnz ftkojm +jnmomfc jnmomfc bkluz izn ovvm flsch bkluz +odisl hzwv hiasrhi hez ihihsra qpbmi ltwjj iknkwxf nbdtq gbo +gjtszl gjtszl fruo fruo +rdapv gaik cqboix sxnizhh uxmpali jdd usqnz advrp dze +flooz flooz qad tcrq yze bnoijff qpqu vup hyagwll +lnazok dze foi tqwjsk hpx qcql euzpj mwfrk +ilb fmviby ivybmf gtx xtg +rpauuu timere gyg wcolt ireetm safi +croe szwmq bbhd lciird vhcci pdax +hnc ykswt qqqmei goe bri wmyai hnc qpgqc pberqf bzs +hsnrb wdvh iezzrq iezzrq rdbmpta iezzrq kemnptg alkjnp wymmz +ngw don ddvyds nlhkoa aaf gptumum ugtpmmu +vmccke qbpag kvf kvf tgrfghb kvf bhpd sglgx +obomgk bkcgo yso ttft vbw ckl wjgk +fli qvw zhin dfpgfjb udsin nihz ovr tiewo +tgmzmph hauzieo jmg tdbtl lvfr qpaayq qapaqy ausioeu jun piygx +jkp guqrnx asdqmxf vmfvtqb tloqgyo ioix gajowri tmek ilc puhipb +uycn zxqm znft ayal znacus kvcyd ekv qqfpnh +fqghur xtbtdd ztjrylr bpuikb ziyk +rvakn uqbl ozitpdh uqbl dsej xehj +laxp haz jyd xnkrb ijldth woy xapl iqgg alpx gnupa ukptmmh +dyiy dyiy ihb qcyxr +wbwkd hdwu zvgkn hdwu wjc sakwhn zxujdo npllzp uyr uyr +fxczpmn cininu akcxs ggslxr riyxe ojisxe +ppbch sampq dnct afikor dnct edsqy pnzyzmc afikor +jnvygtn hijqjxl vsd jnvygtn nqcqv zns odq gkboxrv kolnq wrvd +mroq mroq flsbu flsbu +fyshor xvpaunj qmktlo xoce wkiyfu ukcl srndc ugwylwm ozcwdw mtqcste kpokr +cfh cxjvx cfh cfh uewshh +bpspbap bpspbap fquj mxmn bwls iirhvuk dmpkyt exrn mxmn +tvyvzk ezszod ntxr xtnr och +knfxhy kbnyl knfxhy xhkssx lxru uprh nkxpbx oodolxr tpvyf +nblmysu iwoffs upgof tyagwf aan vovji ajk ywzq oyfi sfulz +aushzkm lcaeki mkuzsah ynxvte rsntd refk pcm +mgguob gobmug dzenpty gmogbu +yvq eepof rgnree nerger fpb stfrln ernger +hrgkbl mzwvswk rsrsbk ieru holco pajvvn ztgsr qkyp fyeg owpcmoj +fowda gmsqdca yugj mcrroxv mqcbojd fjnqfji qdfsc jqs +qnc rvjfz vvxk sjd xrma ucdjvq sbw zydyt dfzww +ocajazv cozaajv tqunkla udwf ecnnmbz lsakqg bki njnda zsdu ccfqw rxpc +qqm qdfya qxyx qmq qfday uqnfttt +rnbirb iapor qet iapor hxkhz dfvzig pedl ybyb +mkgamxg xkniv meb hbzmxjn dhbj zhbxjmn hdjb +ilteux pyutyfx mau lrr bacak +sjjonmn dbbbgs crxyuu jztstgd ezb uiabyaa +tra fle ufzlvf nnaw kec hiwnnlj tei wld iyt syk hjdczb +qmd jtlud dgh dbanock fzp dsjgqru wwvo jwvxwgv xlemfij jcacd +rpkx oxesil snazcgx fly miiyc ikmtmp oefyyn egbw +ypfpeu wldnyd acchppb yqwcaw wldnyd turbz megci nbgxq xkc ypfpeu +iqqv iqqv neui iqqv +ypsxm icqyup zyetrwq nbisrv +viommi toszx dpueq eyy cunjou ffcjc jaeez djefra pxvkj liudlig yye +fhnacbg jghchh ghjhhc iue hwqmo +vbjw lpn cizba ltnsfpz tzoweml irewlc uzckhpd mszal obd +yeos utxkft hflxkfe fxczge qpgigkc ksgr vuumql vhlvv +xzmkv xzmkv krecdi klpem jsbu nwcmik emfzxf cjmpgnj +vtkjo pmiv zou gxo qdiyxsf hwyinjk jhkgf rjq +dyuoc ywiyvch irfgl ywiyvch fxb fxb +tuz onhr syu rqya abkaf bcfx mbknex juwoor zmksl +oheg spjorx ksdy vwtq fxz phvtazk tcze lrxg +hew lbup botaj ltr jpd +dxgc tzinkej gnz hxvvub adsqmc dxgc asgpp rqbdcra goy pmamdua bhiacva +xqv ygb kihxqz vyv pjcny vmyvsdv cgsi nfyx +tqga ssshrw ndq qlbvwh huyd pxbgj qbxk dkkbf jxy chsobw pph +hxl iwph iwph xnr otifm ljhre +zlgvpd kapxpoc dve rklk ogh hgnp rbrmc zzkz hhmcx aklmo +sar gfor nkf hek nkf aql shc aql +dtcrw kfjzcjx qyhi bldson whwdayo mqtgt xhqzp ttqmg +omspdml isze jdl nvwo qrkm wztfg ssfgyh dryj jhp unsmty +jxt cszylng ifht ixtuna azoi xutqlv jtx tjx +usgm azuayp fgkby ezpyq jqwl ezofj +tnhvil nrvg moyrpqs sldx qymoff megflxh pyhqwms xmdw +zomy zcquwnv lzx bvcna yods mjp dgsez +blklyf xokd gpit tiysj yrwfhm tofx +dtig vhdp omuj vhpd +fogwxim qvdwig emdiv jvhl euwbzkg xvxb hwmqo ujdmlp epmykj +sjxll sjxll pedvgb sjxll +drvay gtzhgtx yrt okz nqf +haxfazn pvkovwb pgu tgshw mxcjf pbe nwoymzc mxcjf pbe hydwy jradcr +prjsloa ahylvj okbsj qbdcdjt pmfo pagyoeg vkmhjzt khzmjvt opfm xfrji gyjqyel +lzypt jdbtrad ogr jdbtrad heink +rcoucuq gdxewa rcoucuq whlw zhhm rcoucuq azaqohe mzyli rdvaf +yuag ebcf yuag nsotg qqzuxr jfmao vyucw wmoye +qwvk xemm hgqrr wyxkpp tojndm xlvzypw jus bgnu bgnu nklfwhs +daqi knenmku ccm xkiuy vkexsbc kvvdagx umopitw yaocnx yoakqql mllmsp +mrxgl gywit mfopia ncnsvw vdxek axuiot rsejua nei prndudz mnu +egqn gaa qgen urs mix zbn rhn +ewharq aihy udkdaob kgrdd kgrdd kugbjtj fcef llqb pduxaq wcexmm +dwtiw nelq hppad algxgf gcc upou akm efnb mxmhrud +yxqaa ups okbhgt iet qns tqn rnjqxgp +npmhdm cgds ldexvr typi jyivoqk zkgq vfyxu xgfo +dkwnmr umm dkwnmr okpjw wqx jpztebl eqsib dkwnmr +dxbild wpbup evscivq dxbild dxbild geqp ojfbpl jshvqej +cxdntxs csfocjd pyy tuhws teb boyloz xfw scxh pxhonky +lteucke xrgwy hszgzu hnyrcvb +pfgsgwg dxzh fworek qbstod +usemcrf psczxu gcjtr brls +hjol efxczux bqdn gvrnpey yyoqse gbam ndzyj lbwb bhzn unsezg +bapw xifz blupk qqdk bofvqpp wnbuwyt rnwocu lzwgtt zucag pov +xkre lqvd juf lqvd xio xyg xyg +tzdao ztheib aymcf aorg iyawrch hetcxa iyawrch czdymc ccv +ucgl azlppu jvxqlj pest +dvwlw fuuy mnhmm okrp ualnqlm uyuznba fzyejk yaq crl ctprp +odfq knox mkbcku pxucmuf lpjpol phl +ixongh hfs ruorbd auy qyssl kykwcix aytsm rlj aytsm duq segpqhk +izufsk wedpzh podjkor eamo vqvev ifnz podjkor xrnuqe +twyfps bmdbgtu qye qkwjms +wlav htym vhsnu cocphsj mdsuq vhsnu jflgmrp +opajag itwjhfu purnnvk opajag +hpkopqp vnj aialpt lzrkzfs nwucez nwuezc +mcx hzcjxq zbxr dsx tpknx fva +rlvgm xrejsvn ghawxb efyos xty wdzdgh olahbtn rga efyos vhtm nsr +cni mbab qtgeiow ulttn rckc kmiaju jvbq emyvpew cdlxldn ulttn brhkprx +eykpffp rapik qki fhjgdyu tome ehjuy bibjk htxd vexvag +wrk dpxt gwkuiov gbkif ike gbkif pcd wpj toywyf qzsa aol +yqwzh uujn ujun ujnu +srs ralwxrz yxvvmgp sjhbhk waasid cqtxoxf whcladv jkmaq khjbsh dlavcwh +mdvsjh xaj etvxlsy fxgiy rgjesel rlegesj ptriz ebdyhkp kugxm dxv egljser +lhehwrs mqevb ygmv gri izop qgb ivm +loqqam alojlwg hgen hbyw qlwpun loqqam worgnwk kope +phozre todsknr todsknr ibj mvllsar +wuripy ruwlfbh wukbkey qhq iishw tvtvci xawvxc vxacwx hsiwi ogq +xryq vxwupqa zhqex aquxpwv bnvxrba dtbxki +yvvwh zvsm vqskhp vqskhp ggqqlw bpn wbuv +kqz tdy goqwge ygn jgd +szjjhdk zkpoo nxexz ebicc +wzuemcj oyd qupulju iaakzmt vzkvz +nppahov umm wpzev wxkgfxd owgekp bhhb bbhh dgviiw kdfgxwx wryb +bnc rhes lmbuhhy kwbefga bnc rtxnvz bnc +ani mggxf mcoixh zdd nai hbhzl mes bdpqr +mjn uinoty jjegvze bjgqg yhqsxbt coj obylb hddude xqi rhfbhha alood +cbjzj drmihy tfkrhsd nuhav hihzx bvblqpl tdd szmp gjgfv box +uumhdxd cmwgyf vepr rwqdkj exwk +hwvr ydvw bqefu kghes gvbhp awms iqsqes khgse +mrey jqfw fwvzhps komj dayvs fbui zmtd cofn mrey +dsjds fdpx irjj usndok qcctsvf fgk wvg txwxcl dxs llp zyilwtq +xmkelgk fdukc cye legkxkm wwly +enlny eynln cccku brkz dpof mwfoxcd yftmnqh wpebvyc +ggdn jnysl dsacffw ukj hdae cmzxku +uqhm gcachmn kxndfrl htmfis jfnajz fiqiypr kekho kekho ndcw ckrndub dejfna +keazuq ertql rauwl keazuq obmh rauwl ksrotm +jppp poigqhv repfsje grjk xwkyuh pkx ayzcj hoxzv +yhjw pcuyad icie icie icie hwcsuy wcd yihjh jnrxs +gaug ivvx ceb xujonak hbtfkeb ttciml cctoz +dggyyi dggyyi gqlyumf yasu fwdfa cbb nncn verhq +rhgcw gpcyct kiuhbg kiuhbg gpcyct jlmleo nhumm +wulxxu jyjek hclcp ogob viex wiqcupq +tthu nxgzpid kcnj mss ukapgkp nnc bxjocv qwxs oejwsif aywqtu brahkb +dtde bgvb smu vbbg zhlu +lyo nwjjmep ldbok wgxhto wwuh qfgjknk wnsl +lleyr onha hkwulbm jfg +bybjwd uoxvbh mvj iqfpnxs bybjwd zqtszp wvc lbazjr zkzenja cev +rbuyyr divtslq yuqmyt ajyveb smxsjb nlk tzqhq ims fewg wpjhr gqh +kpewfd beq klilis klisli eeezut +euqh hueq ldoo crqurv lvrwh tmaewp oodl +bqi lzrf jyhvxfh bqi jyhvxfh nbztd lwpdn cuzi +srjylou phavzjd wost uxkaq byh sluryoj +ihrdk bcegkpq nygrs qbcq wyjg dvzme pgzhjl vibg kvv +ijsx iedemek ktlz gtga tbal lbki gtga +vmiaxn kefig kefig vngxz +vrdmfvi qts vlvhq vlvhq dihmq +cfz dyrz zlw qnt vok fwvahg skshbqf hbwozdc ntana jdb uflp +rimbj bxemw sfps krtk umta vnk ewmbx nrlje ymrtqrz mxewb kjxunbt +egnuti ozat eltl ngueti +qtcwoxq rmaf qtcwoxq qtcwoxq +zws gcoa pydruw qsrk lrkybdf ugr wkrxoj nyvf vitwn +tmr hhd dojid zwrj bhsim righ keqlep flzunou +lwoquvy acjowxk tqudk oenvioh nyavyl +rgh dfhgyke iff cpxhuz hui koe iff hui dmukrei +bjiumig lcbmbgh vleipx sfawua rnf +gftfh qwb tfdroe xbno qhgofm vqfoe mux +ljdrr gyfggai iun nju xrucbis mhrcrh fukr obvuqc whlalfe xrucbis nju +nxjmjr egqwg arllu xqaahri lzc ivt uhsti +sqiepba rcmts kvesv nvp +tiksw tiksw rjni gbhvzm ctbq zuqfyvz +ibsnm kfka aoqigwo sqouih rxz +jmymq lxio adtmk umyu sxvzquq bporqnb heol fow +mepa eckq rqviawv dkqoei ifmngpp jiava rtklseu +yuycd jiufjci yuycd uowg yuycd udq izkicbr csxobh +nwu tfsjavb rruoxbn oepcov elxf rruoxbn rruoxbn azglwth jcjm ksqiqpv +dthfwip zqnwa zqnwa zqnwa +gso wruece ufl crgnlxv vllsm dpyfm wpa ctxko +wvpze seodz lpq lpq pmtp wsxs ffppx +yfxquj phvjn rtwieq rtwieq kgxztyu vbjvkc prqqd lyzmdo ojbrt ojbrt qiqjz +esaezr rpggiy jey kbzrhu uthus osr xxaiijd qfxlf auhzbx gkigoqw +yfhcj uvgck cds gjhhrg cmempgj yfhcj cjb +yxi voxvtuw unwg jqqm +igvjr ljz rus sru gbjtjt qfeg ztu zjl +leof ocxns hbkoysh hbkoysh leof +hab lyxmf yhh qeks fwhfxki xmbcak okqjii nfgzyg bhtfgdj lpmjn +mgognh tad herere lvwnzx ixwqs zphmuuc etdjz kczsf +mtej rlolsnn zbl uykek dpkan gmz etxtgj +mihuieo emjgbp jgks mihuieo iexrfw mjdnr bvp mcuzea xkbusvi +jvqpj bwt jvqpj bwt gxr +qpnd fpt tpor bibbpcg hmvguez wqc afl ckviua gpi +dntmcg jglm sxtnu sxtnu sxtnu +fzkbptw cbfwo ozvwov wbv gcdd izqo ovwzov lolewo xikqpw +nkxyxzd kpn datf fki werq mwidqx oiibor zizcjph +xvgyxym zor ijoy lvwsf fjuara idvvq rreit mqyyy ctio tzwqqhj rnpee +maqkfpk maqkfpk xukg sfdmnlg xjopvr xjopvr irf +liujcd vnlkouy dxkwc gto vhjvtw +swhqhj cas aupsd swhqhj cas bvbooii jquck dtdm +igh iqicicf ghi pcxt srcrjx gmf gyscphv +drplj drplj wopgpnk wytag wopgpnk +zexe ilcqoh qiefb txkuv lirfzv +ovvpn ovvpn uqeurqx uwzn hgmucj ovvpn sjxulms +rox silka irhsvym kutus otasof tdneav pcagds +mkja omu tyshbfq onp trxs lxa tftbv bnpl djhnc zdqfs muo +tjj rmmqas cbbkxs qio pikk ykyew gxlxt nhsyl ykyew +frcprg njrz oaxcmhc qben pedm ecvtga nzxwpb ior gaklot dpem +zyt kncau spoe qlchg sqys wkpbng yflju qlchg vkve bzadbpa +qtq pkaicl qtq mfkfqvr dnleiq brrjxsx uoyxh pkaicl yvmlug +firwy imtlp ywl qfa dqrbazz ztzb pcsbwhn zesmlag +ivey ivey mtvc mtvc +lhize acwf moa cdeoazd voktshy qmvqq jvmuvk ljfmq tsanygc +xreiqkc aawrovl pofcsg xreiqkc xreiqkc +cjbzvn ozds iniqu sdoz gqmki bablvll krs vjzcbn +izsod htkeqz entxn qtns prpcwu omfnmoy +kwfb tctzda aztctd tadtcz gyt wunbcub ydiwdin xxk +epnl ijcp giq ltfk zjcabve zfksmz epnl giq xxxbsom +ulyukpa mdjsbn dydko uhkdt qms aaaj hustlwu +zlsbu ohx jcwovf egf zlvpqgx qhejm wrywdmw +uhxqrzr mmu kjxcalj unuohiq rri yzngnb ikvlxry mfiym qbksdx +khqciz som yklmm jceb khqciz jspy jceb +ncwggv njvi nqox krtsn lnm +bgtqme xaxcoq qbtgme obqual vorfk baoqul lgrb +jli tsbb nlxjc pkwzmz dlxrj hmho gzguko ilj iyaasm +wlmw grkumg dynwtyo emxhhqr huluk slpqu uhqcmd absmr ufirmwr +pbs pcammxv dplfr tzvmav nccyy blvyq ffhnz bccutq +hgge ghge vxmvz hqxgjdg zab guo gheg +ylj bucoyoq udndc wpgyrbx ueh udndc gxdsdh hdoz wwgqlg +cjdeh gttyqe kdkm ltzd lfeozse quvjq mnwhokm kdv oojxm nxt +mfkzus knqxt saxkqww njx zumsfk sbmcyad cpt agvbuv +tukn vyco yobvsn bzgnn klrnzy kea thzk pxpwq ryfff nxzm +ylbm lxlz lybm lzxl +wgtxoij zad slgsi cvnxfg iomswwl vmx +hkm yinhnkj kmh kwkw kayknck chur styjif yknakck +rtfwhkq rtfwhkq zsf zsf +sldq zlntr ueegiw kajivqc ozcbm ceft snvugom pdyc elppeed nnqrp prwwf +lhk xjonc muc tudag tsafx mmivb dvrjbp qgrew +hnzer fbgqp aazta aazta lxaz lmgv aazta +victgxu victgxu mlpd ummrnbx cazjgnw isxcyp efy zfa cyusj +gyojxo onzq gyojxo uxufp awi ilhl wefwfxr gcjlt tmliynw uxufp pdcnxah +wjwachn xkuhfbp oky oky ybaeqkr rbuix yreoaw wepmye brvon aasb +kiidorw vxtxiqx wtqvbrv efdth isel qbom vcssyc vxtxiqx wtqvbrv riafzsw mqzsj +eurpjd vkhdamt tmfx czeoot hiz ykz lmixzq tfur jhzr +ipuftpj qbll sqkkdw fwncmiv bri oeeh lehd ioh wag +suima nanngc imrmc krq atxdo woy atxdo akev qlr aezco qlr +cfc efwbzck ozkmcxv moczkvx ccf +bnekky iakrk sask uwgnjp iyi rynev bdnas ldh kass +sicmw vvjbvv cap nsumc xgvrlm wsoo uoqdu psykckm +ugg mtr wnzhmmh tjxc ehwnji lwhu mdsckk yvmk enubrqo +grb oxmxz ohu ytetedv ssx apzlppg fdkamm sxofc jdt ynmu wyejok +umoep rbyqm eqfk twqnog cptbbi dragna ngqs ffb cexxnc rbyqm +utizi ormkel wvwur bdx ecelqbv xiccama aag glfvmj +znb rsuqoa uxo svc +obs lbifa cffi catpd +qkxwian ajlzjz wewduzp bbyv qmt fsr qgiu epinp ghmf +hatg bfgmb aght ghat +kuq inp dun cknbun wmwsu drlmmg kyxc bdl +bddybth swdbf jhi fva qpobio bjwm wjaztp jywi +mgckz vhveu zkemhp zdf xtiqqew mlx wazgd +umbjq pya lvvxf jeavij rhrxvew bwjqgpr piz +xaycpwo vjcuc qksc yuixhni sfbfb dydyaq gdfvb tggg xidphvf bpjdrl goskxym +agxfoip gguif wvo agxfoip ntkbaw fbyggy ooft zxih +nzvsu ffwq uxvfbl qrql olhmhom qhdltg ymwz krtndtx olhmhom nfsv krtndtx +qdp jqk ustz xjripzv mnk grnodk pjwdsj uug zqxjqj +mufrcox zunisfs ocvcge acamm xua vor bsde kxr vor kxr orccxx +ncycbp anvcxay bmm wndmeaw oso knmk mmb wamenwd kmkv ppdd +motdcn xzagzwu vuzt utffrn yuqxzrh uvzt ujttq +tauoqy coiy ybesz tauoqy wpmr trquyne ahxbj jzhems dsdy +aczq ypw pgmzz srfn quatjgf +cih ypapk bfxvr euvhkk gugru auhqui +vyf pssgfvy dnhvbfl xpacme dnhvbfl mzdv iynq hcqu +lbzvbu hhxiq hdfyiiz iyzihfd xhqih uzdqyxr +iapbdll vdr cprmrkk vdr dfjqse mlry flpqk vdr +grrfkq xcpxd grrfkq dxc bjpr prvwh swoc swoc +bopo chvwuhf qhd ieesl xey ieesl fnjcbe +kic fyq hsucnu agwyl pzzmd hqksh psw +mxf uau iti lcoz lpg zbu ocre wqlocmh mxf nidqj lcoz +bypmix ptzxgmf xmtzgpf hrvzzq +lbfw zwusma lbfw tuyyy +lrf uej unswvh obgsb npbl zajr kenea uej qnyjcu wzufim qpzkgya +qcrxj llyu kligt hlm ehwtbx dda lgsvhdt xewfcv uikn +nfzjx izqdbq mfbxs imiuc yqxb xlmvix izqdbq eflqfq wku omgtuu izqdbq +lasdwg hiy btzt eefd eyoep icn nnmhg otml rek luixac nyzgn +vekteds utsuxdx utsuxdx vekteds +feyov qrij zbebwg ijrq seplram wttkwm zewbgb kzuhuh +dmkgtv wohgqo ddtqmv zatahx mym hqowog tkmvdg +vhha wjrmuyx kqh vyyrj xzchbi ejsdq orlxg vyyrj dlrc +yetngqn zdtuqox hkarjei fqpsgh eaqwbg zsssog ghb gddqqzr hbg +obldb zsrhz zxp uxphnev mwnbc pfjft fms xwslk vjm fxy +nfij dbfykv ttq gyjgac igxuyqi gtiioqx ilhdex dbfykv uyp bdiwya gqf +pffzruz vogfosh dcs wje +pohhf fhpoh oon yyz +xxuam afwm qxl lnt syyr bwxhhf sozauq shlhfmz kwnn milav ochq +wefcqrt gejw cwerqtf fttf gjew +jfsvnmr osca epwtle pgfif sxom +exlfzmq nakp rgdnx rrcvth vhrrct aajjdrt ryyg dsozd jdqlqj pakn iruv +rmcvo txszcs xxhyxz hbsozk wshkocf rmcvo rcbnt +kitz yjgney yvkymef nauj hmllsgl kyhm kqr pzsu rcf pzsu qpte +cdinpx bfur mkj naz ihkheyr nohhoe +ylris xeqcgup wap bbfih tgfoj +ina gnlnm zyeqhij cudfuf ipufae bvkdzni aat teqsg cudfuf bjokrbl teqsg +aedx edax dnfwq qndwf +rdngdy jde wvgkhto bdvngf mdup eskuvg ezli opibo mppoc mdup zrasc +qcnc iaw grjfsxe gnf gnf +zbjm snznt zelswrk gkhlnx dqxqn qqxnd dmro +zisecvx ztezof uzbq otnrtj qsjzkwm ewvcp rlir bfghlq tgapdr qxmr +ipnqj opjf vabyoe wkwnd +wyf mfqxnrf apm snarf jqu aaghx pwecbv lvghayg +acncv jmmbwlg oiphlm ifuo cvt +pvmb egansnd zmh gcuzzci rrxpslv ubith +uoleptg xbouzn xbmg cfh cpn wpqi xbouzn xtxis sxzpns +rilybri kurbpq vfmjpck tjyogho hfyxad svfofx lfbbhxj khaerfs iqr +seaebgz wlmtkre qguv qguv wlmtkre +sgo edkxya zdqgwtt gxu nibuu rairqoq mzxli dci qsv +tsol mdhzqr rmaqnru ggvcq arbwkn hlkcnj ljkcuof +mmliphp ocup puoc eijjv +gmajqpb ijki ijki kvz +pmqss unhlpcj dlkll nuhlcjp expe tlurzmv nsy vlumtzr tgseozl +gkvaoni hsba hsba viuedv phyoclp fdq phyoclp febld nqfs +rxvdtw abn pntv qrqfzz slsvv abn lrxix mnu npot +ghlfjp woy xwkbmv bkahpkj jve cncvk jvdype fwgvoju yrkwjp gwfvln mvkv +kmluh mie bby fwer chsinb ojglqr nqk mie +yzmiu igkgca ybnsqja jpfejtp yjddy xsosxfi ingx qwuhb emrkwpx idqjmmm +btrllw mphm dkvo ewdl dchcul yah btrllw kmqi mtvgk wtb +hxsgard yuikc lykt tdee adprp gpougod klnzk mzsmlb +hdn znblw ifoblur bwzln dbv +smofpbs vjuyiro llk lfzesga tybu tybu +gffnpug xaup iqiyz fjkpnkz drrk fwyxw lwzfskz gslwpmv vjxylva tbkyo nib +evydmb nhwuiiu fkerq nkgbuyy uclrs ydjgglh xhotwbm riirgzt +bsub eavbt uvd dpzwyt rhn khrbptt xszckc djnfxju axofhat powmso nvdffrv +xtuykl fjz mbikc xpnx hmey fjz fjz +rkls nwdcsyx rkls rkls +tygml untequ ybdfumz nqffbq uipc sove hfnqj +ytecew vven koqn royynd qsn ksl qsn sdw +hknlw qwho whoq oqwh +lzmmtqu qvhyeo cnofuj utpwkjz gnirz yhhu aodbnd +zsr axw kwtzcv tydzo kwtzcv lkxsm +rbjtqe nihifd gvdxd bpxzy rxteky vgcgllv vbbua anygiup rqo +dpd wblfwp wblfwp wblfwp ygahc tqjbaq +gsw gsw pacgj xmrcz zmxhmch xmrcz +pdq rhe xqmq lgpkhg fyffrot ovnqh wle +tbjavke ypzzrj jizx gdxoh icjsat otfh fmygumv +snch nxlgjgp jeyn sxoqfj jtage jtage iuice +rtb coefuj grwg grwg rtb krhqnma vfhgbr +vhegtl btorwxg szcev kbvkx itsk nlzpbed +hiukrf ilzkm yllhh xsgwkdp zyy kjbv +rfcg tdorci zcj wzftlv rfcg rfcg +lgbc lzizat vsno pau nvv vsno bbr lzizat qhtb gwp +sfwnio tcugjk bsfsz ykyfwg ibkap fsrvy mygk kzunawx zyhyh +mpavlh qps bylh lttjkz rqabgk vewb bwev tlzkjt gzrbxga ktmso prpkj +gpf ims ynh ffrs vpa iemp gofh cgbauje +secys qks mcnfhwh drog kqs pajy zoltkw lfihnb myb ioxptu +ytq nrta ouk ajqblf yuwwcd zdy blyoxbw dakk nvgi bzrhzaa +nkoych sufiia xkdvw crtldee zycl qblab egqhr qblab +nllno muxaf vds qjnitmw zkpj wskyhft kmqct xamuzpw qcai cdjtbt kaxv +qzdytpe osr fuw osr qzdytpe whperd rydwdcl knoa +zkdznhd peh duoygr zamrgl irnvj otpe pltpq jdkecg +byzgw rece iigdug ehif tpgje +ccnn foqdran gbctca tefdjxh ntcr rjciii xip xlss crl wvvhzqm twyohf +dqyii milqqc qjgkojp qjgkojp ryde +tdkyj tbrcud tsba vqtmb cjwxnf +hqhmq wemvrce nagig pwnw nagig epg nagig vlsi +tqgvw luoplw hccti npjm rytdruq cylrsun rytdruq vjsbjl rytdruq ppti +itgt tuwc itgt rvp itgt tigns eipl ksmru +pdw wdhtkn nbdbpn wff zhuuipg rvemv qxr +qgkwdq cjilayh ymeks mrpuzai dwgs stfstgz ucvqhb yout oiq +vpxik ypfr qytimvu qms oxbmw ppyfx +fwwidn gdhd pyuexk snsz iwndfw +lfcb sllxjna lfcb hpzahfg mmvgaa svny jhuzd +unyg gicmzd fwc spkciy toyq wjupckd vzzx iuqgka ytqycb pxsufj +goj tnrcml eyizngj txa xrkiw zvu igduz +wek xrrlkna clyof rrlnxak +cjm rmyuku vjom gtf +buk cfae awstd dywgqp hxo wcxvf laihqw xdqfes wdbh qceh uzlwj +sudguo dxwplto rlebdh bkamu dxwplto +crwkyxm yuz kjtdhom crwkyxm +trhc sduorxr aizfryh rsudxor gbyc +pczkyl bptp qnn nxmpwsx udrg hhlb rubtrmx twzodlp xygnht +jmqct cden yfajtkz fevcw sxonbxz sxonbxz qkzkm hhngr fbv +sdsnm mwvicr wypfi cty ndbowr woiz mrauwzd qlno mwvicr +vteyo fng lvr lxytn txpj milg +wjx ahtmgo cgwcaj kaxae fhlvlqf +ezj eetqhzu upwda iiefwlk vyvby +imalvy yeghqe jwcu mvrod cwju +bxnmsa yhfu npsdar tsbri hfuy sirbt oofxmy +fkndt elbjtn vepqtxt elvpf fpelv bzkgag qttexpv prblwb +rmq iqs yvprnyy iezqrzm wlqsrr +yviovq lekxghj oey qwhzj lxknxw qiyovv ksnt jptz +tyrg cifxt hugqf tyrg ffuiv jmax qyw fozfosq ffuiv +nmg rsl jpzazd qbtlf yxqtsj czwmdfd bamge lbjdof uqy jssc +cbx boozjip pwgvzlq rjz kxy kxy hszacok fvsq jhnir cnsba gafz +sbcuxb wfur nnnfqjj fdwg huhe sbcuxb +icwk qelbxs uevp qped zsnhh wpuok wddxsln ftnzupr ruxol cgxjb jbhh +izcp htykj xxmndoq amnspe htykj +vverol oixwlny vqd tvfzu henc gnyrwr +ytxio etytsx choynep zqapo hfjit +lkvgr oyzfa taiqr jok djatvy ckif tmdw oyzfa zroy +jlgpyp kkqysg oqjki hjohoug hbhta muilz zft +sumfyu wftcu bwwdcy lezimwa qwvxv zwh mqyv bmfot aii torcol rnt +tpdj xrw ccsbnh fhptv fwkxjfm dmqaokd bjci +zxi vmf vmf dpyg +sfzxysw lcms bkojtv bkojtv +opywo qll ipkitr mtwp tudrr svhyp huz bxsdpn xomfy +gkod luo qrosbp orbd rpsjzyd rlh gdok tze +nusiuq nusiuq zeys ahufexc +veno jntg avtmtdn qojxru zegdcql odfcetz pgehau +uqun vigjm ykac ozlelj danmji bibugox +rpuozh ajwru rbvuevv uhzsq +iawoe tyb aewio ymf byt inijv ctu fcys micsgzl pbby alt +gktyxp ris mqpfm bkqsfl nrg idbbcxg jhcf +qibt invvv qibt luitx rnm eby hrfbmwl wnap sgkzvb qlwc hrfbmwl +jwkv qecsjbw lycgldd wjvk tjcp dycldgl pzrvr zrlcf kji +nzsrmiq nmhse ilivrk kqv +besmyzi imkgpt iekbjax abxeijk uvzs wwv +jdocl uki ltswp tjkljc ymce iuepze qygqxzs tei lkry +hhyfy gvzd mqksxlq czn afe mesnag eep frwgekg mqksxlq phpy +ehg connnza ekt ddgokw +mpbsoms uzhzl xevww ztt uzhzl +lftybr firc awsud dsxdkk ltf ipjv dtx lcymth +vkcpb gxtxq yioeq fexj xxgqt +srvca fslnnvf nfmkpvt egw wemumq jie vznf dzsjw cukf kcvyir +yxjkl lyjkx jyxlk kgc xtz +tpoe xzov csp leleoqo noyre tdhf cyib sjgtdx raehdw nmcxp +qvt uhznqe bpvos vtq ddlebtd tqv +xlw utsxs gpia rvlvnts elkxr dddihy tnrslvv ibf wlx bxg +cwqnnrt rkkqyf dye yde fzl pthanj +boc rqjenpp xjqte jteqx pvoofc pidqe ruoucy gvnro ognrv +qhalb gnazwc fhl iuti +clnbjfo nnfs nnfs heymvr oarew oarew nxu +lwtrotg hiaxwj ymzbly nvhzjhj zlsaheg nvhzjhj ymzbly +rrvi tsjp tsjp tsjp killji +rpx hiclj cmwq ibhj nfd +pvwymn iebkd xmpw vuhhkap ksw zigzy mzzyyxy rmuh iwwhea cglfq +rlwelgy sffml jin qsdzro xlsty mgqzuu etxjuo emzd jgnoyq tkjuy vfvb +tkctdj hhkuc viskmy obw +zvjkuj akeky ikj jqd hfhzbwe bkc +btev nrdo hcyiuph stf qharfg vpmel mpfz nvs ytgbbc +ieepn ndueuw svmdr tcvumw mceyrn mrjwhyl tbdj mgrgvz +uxrs ckyi xpmqm czzrkl cjp +nlliwd wrqkrkz yjmng nlliwd zirde hcjjn wco ysf mgl +dxti lcahe ommare izlwf ramsfb nzgfvo ijvm fwymrdu bndq +isxy jpvuzu tdduyhw dixp cfa fkzbteg ytoi kepk ysf yqcpi +qmeprfj soqo ncgeor cqsuuj grzy wogxy vyblnbg slvtry vdols kka +ltykfp gtzl olrp gxend vapee deq +emywfbn dbfiut rkt wvwe dbfiut bwffhea yuzcxv gogpicp wvwe +vqvmrp ofbk dlfabd jwllzxk obx vqpwjj umvng tqwis fstxy fstxy +miha zgvyux rmraszo xwf +kjaagk btm kjaagk wkewjrg kjaagk +lbmli aizs omrdr gzktnx asiz ptanzpa xlo ljre ckyb wob +svz dlk rijagg avxmg fkzwhk uro gegm +dzplum temdw jqnm tvxcww bmg tftttpp deuw comxey xfimzjx caluczi nqn +uwvhxa ztkd nlsdyt vihl julkwwv uzch dwakhs +wkhuihh ycrc cxff vzcfhpp uegfd gaok kcnvz lhzogq lwa tyrypvu +idp zmrrzp zmrrzp nktp xsnx rjsxn +eybrnib ivgntl vaxsbpi eybrnib +nzvnq xvbfa pbhwwh ylju runvsj imlx vztesn +nfdohd nfdohd gtevnky pivjyct ihvd fzcsrq lko fmqk +kwpkks ecikxu bcxswlt qvrxm sbcqmh +kdjrmj piuh kdjrmj vnaf gyedkg vptxgm xezssxx zsg qjzpo zsg +oqo sley aqx qmpqb fgmylbj egd zivj kepxizv kuakyn lunbnd +hmcf hmcf xlhgc hmcf cdlm buofnx +onjcj yluonz kzmk phqo phqo phqo +ohaafy efl bnkkjww wwjnyoj dxeaig ywnjjwo slk hrbebw ohlyju elf +msohiqz aunk njki bfktdgi htmyrj mgx +numlzrl rmnlulz glb ltt fhbajz gqxpu +gko hco oai ryq xwy sdqosft spjkiu cxfhg ycwpglh noy rah +btzpjem brpk vqr atxu rhlh rqv jmg fvyus +phmxxgj ejx xje qtk hsb kqt npwj gqt +hujyjp nwmsd ant zipuya lrkahww uwqal vzlo qmbo twkjkse ufivi +zfbnyz fwvh xrnrw usn zin daq iwjzj +yykyg iwypfy hehqnl cjvk cevdrec +gui muuto wsta glqmx gfo rdmbv mxwz gffzt eejpw gion +lpng nduid iqbpu nduid knrqd +xwxn oefpckv gjaua ugaaj gjuaa +qxk aeql trqdmqc crzlinj crzlinj trqdmqc rijcne ewyf +rfv qmbe fvr bmeq +upqyfw lowzq wpen upqyfw gfskbil sljuzh wpen +bdcara qyhx rtaez qyq gbyr +evzls qxtxq clzd svbgqi zxlzgss vtrre fko eebo qjyl +zaapeo kpwhz tygknau nyd pch trp xqe +ypzcafg rnqmbh qtteg sncu ssojhhm zonfym thir xmgheb wqj gpjg ssojhhm +wvcwyn xrf muozyya lasdp xpjgu kpqv zkiihiv ifje cbdlavg xbied hfnaa +qqqb rettz rycukl ihpkhh +dnxzxqv znb znb fbxj azxtezb xvxa +peqkd xlzqkov esgnw ucku hrwpfxd xtd vnig vlmfp ajte qswr kqoj +dpwy oavzkk dwyp ehij upqxgii pydw +amfc hfv xmqa nqvn cal rqmcq oej amqx cla ntxj +hqhhe qkbhwli wmhlcq xaczs peywuo +vcr xfv xfv kymo qpszwzo xfv +nmrbur tswo xbo ljlrzo bmhpgc pev zovkznz lok wbbhtkk +tojj lxqgr rhjavrm ndsdup gdbjwaq cqpnl wfaxivl rfry ryfr udspnd +beffod sknlph amb feobdf +mldgn jxovw yuawcvz kzgzwht rxqhzev fsdnvu vluuo eycoh cugf qjugo +tlnd qcxj ker fdir cgkpo nrqhyq raef uqadf iahy rxx +mhvisju lhmdbs tcxied xeidtc ujry cditex gvqpqm +cgc jazrp crgnna uvuokl uvuokl uoiwl sknmc sknmc +rvbu czwpdit vmlihg spz lfaxxev zslfuto oog dvoksub diff --git a/pytudes/data/advent2017/input5.txt b/pytudes/data/advent2017/input5.txt new file mode 100644 index 0000000..d9555ca --- /dev/null +++ b/pytudes/data/advent2017/input5.txt @@ -0,0 +1,1074 @@ +0 +2 +0 +0 +-2 +-2 +-1 +-4 +-5 +-6 +0 +1 +-5 +-3 +-10 +-8 +-2 +-13 +-14 +-15 +-8 +-5 +-13 +-16 +-21 +-3 +-14 +-23 +-9 +-11 +-19 +-29 +-2 +-20 +-28 +1 +-3 +-35 +1 +-20 +-4 +-37 +-11 +-27 +-33 +-43 +-20 +-5 +-9 +-22 +-47 +-5 +-49 +-13 +-22 +-2 +-2 +-51 +-53 +-22 +-38 +-16 +-37 +-30 +-49 +-48 +-35 +-5 +-42 +-21 +-31 +-61 +-43 +-31 +-72 +-35 +-3 +-31 +-65 +-78 +2 +-17 +-80 +-10 +-6 +-68 +-69 +-44 +-71 +-78 +-89 +-19 +-22 +-28 +-21 +-7 +-54 +-63 +-48 +-70 +-73 +-52 +-47 +-49 +-2 +-91 +-65 +-76 +-58 +-47 +-45 +-21 +-11 +-112 +-80 +-93 +-98 +-41 +-54 +-105 +-36 +-102 +-75 +-102 +-67 +-100 +-41 +-56 +-19 +-90 +-5 +-66 +-41 +-3 +-32 +-95 +-65 +-44 +-1 +1 +-62 +-7 +-29 +-61 +-7 +1 +-63 +0 +-20 +-58 +-58 +-7 +-54 +-80 +-48 +-51 +-151 +-141 +-37 +-122 +-130 +-132 +-158 +-117 +-63 +-103 +-130 +-116 +-130 +-63 +-134 +-131 +-59 +-30 +-33 +-38 +-127 +-31 +-76 +-35 +-162 +-132 +-121 +-31 +-28 +-2 +-29 +-148 +-156 +-168 +2 +-33 +-85 +-25 +-18 +-167 +-152 +-22 +-38 +-136 +-83 +-46 +-73 +-139 +-15 +-185 +-197 +-125 +-159 +-80 +-161 +-158 +-82 +-36 +-52 +-210 +-200 +-90 +-199 +-70 +-135 +-195 +-54 +-156 +-46 +-74 +-73 +-221 +-96 +-37 +-189 +-27 +-209 +-30 +-50 +-4 +-74 +-15 +-184 +2 +-78 +-33 +-37 +-99 +-65 +-196 +-32 +-36 +-188 +-62 +-5 +-244 +-116 +-150 +-118 +-124 +-54 +-28 +-43 +-208 +-205 +-95 +-90 +-129 +-242 +-70 +-144 +-64 +-247 +-170 +-213 +-40 +-173 +-90 +-77 +-139 +-56 +-70 +-120 +-9 +-68 +-78 +-7 +-123 +-103 +-173 +-254 +-249 +-246 +-139 +-192 +-92 +-204 +-71 +-199 +-56 +-63 +-231 +-23 +-115 +-240 +-51 +-200 +-184 +-287 +-98 +-7 +-81 +-275 +-262 +-260 +-32 +-99 +-28 +-199 +-160 +-176 +-210 +-244 +-162 +-82 +-35 +-276 +-71 +-114 +-222 +-294 +-28 +-122 +-110 +-178 +-264 +-239 +-104 +-85 +-11 +-117 +-15 +-69 +-275 +-289 +-212 +1 +-296 +-285 +-9 +-95 +-149 +-197 +-152 +-141 +-148 +-138 +-173 +-224 +-297 +-299 +-53 +-335 +-36 +-17 +-291 +-25 +-211 +-175 +-104 +-328 +-58 +-15 +-198 +-102 +-122 +-211 +-74 +-117 +-205 +-143 +-353 +-187 +-323 +-172 +-133 +-170 +-41 +-92 +-84 +-72 +-352 +-278 +-164 +-124 +-175 +-113 +-175 +-152 +-160 +-33 +-126 +-226 +-237 +-135 +-156 +-190 +-378 +-168 +-271 +-240 +-111 +-398 +-91 +-243 +-336 +-311 +-368 +-396 +-202 +-262 +-18 +-303 +-363 +-67 +-36 +-284 +-404 +-120 +-97 +-387 +-26 +-135 +-112 +-325 +-82 +-53 +-307 +-410 +-276 +-384 +-64 +-60 +-412 +-335 +-356 +-82 +-134 +-251 +-408 +-342 +-9 +-73 +-27 +-388 +-434 +-80 +-231 +-114 +0 +-64 +-325 +-251 +-153 +-109 +1 +-92 +-167 +-89 +-454 +-154 +-13 +-283 +-231 +-357 +-244 +-324 +-134 +-41 +-380 +-169 +-247 +-301 +-297 +-388 +-304 +-135 +-403 +-168 +-314 +-117 +-281 +-76 +-473 +-281 +-322 +-79 +-39 +-129 +-432 +-452 +-183 +-164 +-76 +-382 +-306 +-58 +-126 +-141 +-4 +-3 +-201 +-480 +-443 +-313 +-361 +-279 +-250 +-38 +-1 +-340 +-138 +-69 +-462 +-32 +-68 +-19 +-31 +-271 +-86 +-141 +-331 +-412 +-29 +-369 +-518 +-103 +-502 +-24 +-67 +-130 +-247 +-331 +-535 +-77 +-305 +-153 +-44 +-382 +-309 +-162 +-430 +-480 +-25 +-431 +-78 +-442 +-549 +-184 +-523 +-94 +-380 +-227 +-526 +-209 +-508 +-129 +-36 +-510 +-310 +-133 +-145 +-146 +-244 +-245 +-541 +-362 +-7 +-103 +-565 +-209 +2 +-140 +-51 +-572 +-28 +-354 +-525 +-148 +-79 +-176 +-34 +-396 +-162 +-374 +-448 +-76 +-87 +-136 +-584 +-179 +-230 +-490 +-361 +-333 +-328 +-34 +-524 +-273 +-195 +-32 +-520 +-260 +-506 +-576 +-422 +-115 +-65 +-285 +-314 +-322 +-146 +-287 +-251 +-585 +-326 +-77 +-250 +-321 +-334 +-560 +-455 +-523 +-90 +-234 +-343 +-457 +-395 +-173 +-560 +-474 +-118 +-244 +-263 +-493 +-597 +-232 +-237 +-619 +-372 +-416 +-142 +-93 +-546 +-538 +-198 +-574 +-250 +-491 +-168 +-47 +-247 +-127 +-641 +-228 +-192 +-545 +-543 +-172 +-220 +-277 +-647 +-87 +-198 +-450 +-247 +-15 +-406 +-562 +-335 +-436 +-665 +-362 +-211 +-582 +-178 +-523 +-232 +-287 +-635 +-33 +-666 +-577 +-54 +-509 +-271 +-561 +-491 +-512 +-212 +-269 +-473 +-460 +-587 +-209 +-538 +-14 +-303 +-360 +-275 +-125 +-373 +-108 +-31 +-314 +-639 +-220 +-52 +-378 +-398 +-369 +-594 +-204 +-423 +-441 +-447 +-27 +-495 +-595 +-352 +-388 +-127 +-424 +-609 +-435 +-626 +-191 +-46 +-363 +-15 +-557 +-433 +-53 +-680 +-129 +-462 +-40 +-598 +-246 +-468 +-600 +-351 +-409 +-89 +-732 +-178 +-472 +-335 +-622 +-563 +-322 +-261 +-63 +-671 +-291 +-591 +-518 +-373 +-615 +-727 +-553 +-166 +-108 +-723 +-77 +-736 +-364 +-765 +-49 +-41 +-99 +-134 +-684 +-281 +-530 +-545 +-372 +-570 +-48 +-288 +-583 +-421 +-601 +-162 +-176 +-414 +-735 +-195 +-786 +-656 +-488 +-744 +-256 +-345 +-152 +-44 +-29 +1 +-582 +-30 +-351 +-379 +-23 +-48 +-737 +-293 +-525 +-73 +-79 +-531 +-775 +-706 +-59 +-74 +-805 +-311 +-544 +-33 +-603 +-454 +-700 +-506 +-489 +-617 +-485 +-267 +-794 +-13 +-707 +-557 +-368 +-730 +-696 +-728 +-167 +-413 +-639 +-705 +-391 +-11 +-195 +-416 +-788 +-295 +-768 +-192 +-2 +-771 +-675 +-687 +-198 +-568 +-663 +-302 +-732 +-265 +-796 +-370 +-18 +-579 +-771 +-349 +-365 +-214 +-598 +-314 +-752 +-315 +-815 +-487 +-511 +-126 +-6 +-146 +-353 +-787 +-204 +-330 +-517 +-456 +-805 +-4 +-500 +-150 +-242 +-833 +-804 +-663 +-554 +-41 +-607 +-121 +-762 +-892 +-249 +-405 +-403 +-255 +-457 +-613 +-91 +-157 +-890 +-631 +-908 +-544 +-487 +-813 +-541 +-108 +-147 +-702 +-301 +-430 +-66 +-492 +-902 +-284 +-464 +-784 +-312 +-762 +-588 +-17 +-809 +-436 +-483 +-16 +-410 +-180 +-568 +-37 +-687 +-444 +-619 +-211 +-386 +-673 +-600 +-155 +-558 +-849 +-37 +-717 +-867 +-236 +-98 +-165 +-579 +-677 +-691 +-602 +-878 +-555 +-893 +-773 +-395 +-942 +-661 +-850 +-881 +-485 +-312 +-689 +-258 +-899 +-120 +-227 +-349 +-467 +-404 +-45 +-919 +-329 +-365 +-22 +-462 +-632 +-498 +-873 +-288 +-901 +-655 +-321 +-922 +-882 +-416 +-946 +-320 +-5 +-57 +-352 +-711 +-197 +-705 +-737 +-439 +-39 +-252 +-1002 +-617 +-373 +-605 +-887 +-451 +-824 +-455 +-66 +-619 +-18 +-404 +-64 +-736 +-44 +-381 +-447 +-567 +-877 +-411 +-216 +-635 +-598 +-419 +-577 +-142 +-189 +-917 +-692 +-153 +-2 +-116 +-172 +-423 +-886 +-454 +-492 +-491 +-656 +-832 +-1036 +-468 +-23 +-709 +-292 +-668 +-454 +-478 +-302 +-182 +-677 +-904 +-648 +-513 +-901 +-331 +-750 +-445 +-758 +-842 +-372 +-471 +-109 +-239 +-704 +-817 +-340 +-591 +-40 diff --git a/pytudes/data/advent2017/input7.txt b/pytudes/data/advent2017/input7.txt new file mode 100644 index 0000000..e43ac95 --- /dev/null +++ b/pytudes/data/advent2017/input7.txt @@ -0,0 +1,1337 @@ +ifyzcgi (14) +axjvvur (50) +tcmdaji (40) -> wjbdxln, amtqhf +yjzqr (73) +smascq (97) +hyehtm (7) +oylvq (136) -> witry, cvlod +csyiik (34) +zivjpfo (23) -> lcchgb, bhqlq +ggfmiv (94) +vpltn (41) +gzxnn (171) -> mqodhde, djvkd +bsfygp (75) +dnrjb (9) +ohdnhx (261) -> tgiou, lndczw +frcrd (56) +cldaag (31) -> orbcuzi, teyakvf +vphlxz (26) +nljmcv (47) +xcxqa (6759) -> znely, rtsbgwx, hilafgl +hywzja (81) +ytxcti (60) +igzvp (68) +uzvsml (34) +keusrg (27) +tlmfw (45) -> pehflc, lefxyzt +hjmtrw (6772) -> cblhmk, zzflc, xsztla, iitbuxz, tckyc +ahjlf (1474) -> ejvipa, xhzyzer, pzwtjfj +egszxz (14) +skmuo (1607) -> rxsihsa, vsslzfp +ifyja (32) -> rvixnmq, aumrixf, wbenaek, jkkwtd, ywnsmem, mmhtyd, xmzzrgs +dwnokzu (311) -> xinfpy, lwvfsu +txbgfm (33) +roqfxg (62) -> wrhnq, rskara +autjn (29) +hnedp (10) +owxawf (60) -> twoyl, sikmtaj, lvptmrf +jensj (281) +sglkjsh (66) +eeziziu (34) +qjuuu (83) +iebulx (297) -> mqcflzv, nafrmeo +lhfuku (159) -> syzcti, ynhvfvx, ckegba +mxnlv (61) +emtjcx (60) +jspui (58) -> chlpx, xjkquk, afyxhh +nmikggy (64) +vatflrk (6) -> uxbhu, gekygl, xdyrvy, wesoooi, esphpt +jfcoc (41) +gyepcnc (6) +atbiby (80) -> aqtog, qjsvs +ygnkwn (52) +piexct (65) +uitfx (39) +rdvciwk (55) +jkgnvbn (23) +xpewzk (45) +vlqyxe (337) -> rosfnb, vphlxz +bmdgthp (215) -> kyfuyaf, tzrqqk +czafdho (24) +emuwzd (102) -> ifyzcgi, edotax +fwabsk (14) +uftnfv (53) +ndkcn (39) -> mkjuq, ghcgz, cxpwfir, lxwvf, nsghrq, vyvrn +srzfd (77) +gqhnstx (870) -> xmedt, brzucfh, layqazp +bdnjn (57) +pbckxv (14) +fbpbs (74) +zwutlym (92) +lzeud (290) -> igkrktn, oixlcn +gjctf (27) +azmneyd (60) +wbenaek (253) -> gdunxee, vgiqvsi, bmlkhaf +orpjw (72) +dgyulo (9) +qklqozd (125) -> otikjx, wuvhyc, dwejsn +waiwj (47) +bnevesk (256) -> dmglcj, blnwcb +yqnjd (50) +vvkkkpb (39) +ciprksz (84) +hblux (91) +dfywz (60) +jeiqx (26) +zdissfg (7) +mriqcjy (66) +eydak (49) +qwxwd (49) +plhlj (64) +nqgbp (67) +ewwfzg (70) +djzjiwd (44600) -> zszzkl, hrnrjrt, hjmtrw +mtflvu (71) +shesfq (143) -> ohdnhx, uhnqr, zdglrh, ripilxo, gfszte +huzokb (298) -> mnqii, mieqti +ohuvsf (83) +wcdibhx (196) -> xvwvc, ncmad, jkgnvbn +fxlbc (184) -> mdqeh, kmvcmg, sonvcww, pcckqq +lnknp (91) +swugafb (504) -> ryazls, vmkeu, fewrzd +pmadd (97) +mprgtb (42) +lorxjw (62) +welidg (97) +zzbad (30) -> npccgnv, yqnjd +dwejsn (40) +fvivo (225) -> worqh, yjzqr +zuawuo (111) -> jktlfu, uhvtpfy, ivlus +ikaol (26) +mmhtyd (220) -> yekmflj, nmikggy, xepgx +hujjten (37) +htqps (36) +dlobfkw (44) +fxrijc (57) +xgfad (33) -> zivlnu, ipsst +pafiy (17) -> dhtxpbb, dgcecu +cblhmk (1108) -> ggmhxx, tysdkgl, rrvbwb +kioga (93) +ljhlxc (83) +qsvbb (56) +uaffk (61) +lvptmrf (58) +hebhue (11) +eefyyr (10) +wyylpt (184) -> oneoorw, cfbaj +vmboh (90) +ghcgz (195) -> tajfmq, yzufk +jjhrmi (190) -> qhubjd, uycop +teduvv (25) +xjadrfg (28) +ugcccv (67) -> wehdeq, gyepcnc +psdzpg (38) +hyhbu (593) -> sblfh, ekvdv, iicpkf, xidtz +satjdgz (60) +cjbdxts (34) +gdunxee (53) +fqswta (47) +iwouvid (81) +iqbdxb (67) +ozbjpiq (16) +ysafyj (97) +lcchgb (82) +wkamonm (19) +waqca (61) +bbeyl (9) +rkfspx (17) +nggtuh (64) +jmypc (20) +yfegso (122) -> yhsmjfq, jzmacb, autjn, werkz +zirysk (72) +rtsbgwx (251) -> cbmqx, hvmlb, rsstvn, jtyurkp, gmkvgf, qkawtfu, ggwtf +yxgwsj (14) +xmgqmv (84) +lncmhi (48) +orclyi (30) +bjwny (94) +zehkwy (69) +mzajj (92) -> nljmcv, waiwj +ffsehyc (17) +agelbfq (343) -> iuchai, qynrx +dgcecu (86) +wtqxei (61) -> afywb, dqbfloz +vlmihf (32) +lovox (77) +cmvofka (30) +ttbuzrh (96) +vsunxw (196) -> pdbykx, dnynny, pqjua, jhnujj +skfnp (97) +upuybrd (300) -> dnrjb, rfknc, bbeyl +cpmebw (60) +wkmtw (59) +rpvwtq (5) +jenfafh (58) +pubtxq (51) +xlkwyg (55) +iltoh (22) +ctaazgn (103) -> hywzja, pywmbis +zxhqlfy (26) +dklujy (76) +khgvmj (66) +yfnkp (33) +edsjbi (37) +brtomr (75) +siqcu (15) +kxdehcg (13) +vmkeu (315) +momda (90) +pocvrcs (6) +sonvcww (17) +nemrt (91) +ldbkyg (75) +jsrrt (22) +ifuvyo (180) -> zvszwl, utewfcr, dtmbf +kfzqw (80) +iyfyi (41) +tykwy (44) +twgjdmg (24) +qface (27) +ygkdmh (74) +sblfh (120) -> gglxj, fqswta +gbldz (49) -> xitcp, jpynea +hmjpa (122) -> elovaun, uijgiu, apxgf, nlacdac +wsixz (14) +vgegr (83) +fggyk (46) +kjoru (16) +ixqrl (22) +gklehu (84) -> sazbmjz, piexct +xxego (33) +jxfimbl (95) -> nvpdisw, kioga +vymmkdf (116) -> ofqbu, sboms, obbpd, czafdho +jpwtbds (1608) -> zwutlym, qntzr +xsztla (828) -> cmdizw, qxkhq, nfcbi, rtutzu +wtfliw (87) +lbxrh (94) +ybioco (29) +yvdhwyh (102) -> xpewzk, hdxrbzc, vsaejz, pudso +eauxeyl (53) +skuazsw (70) +jlcie (99) +ckmftuc (21) -> khixdho, ihzsljz, uvkxner +yuikqm (68) +dqbfloz (87) +zofjia (133) -> gshsx, ntkpthi +vyvrn (173) -> lrjbgd, vwojto +tszockk (729) -> ctaazgn, gqbwc, wcdibhx, cujimpt +ydqqgrw (15) +hcxwql (398) -> lpoejf, cmvofka +gjedup (5) +arelp (195) +aonfn (235) -> kzkfcn, eefyyr +lsgbe (99) +gunvu (99) +kasaf (34) +imohij (13) +khwbzl (1131) -> zlbnkdc, ljmrml, roqfxg +nwikfyc (80) +khtegw (91) +epggt (90) +yapaib (175) -> gunvu, ymdmn +saawhdk (12641) -> vwvowk, ilcsp, vatflrk, iajts +qoetrb (15) +ztmmr (147) -> ypkhqlq, uitfx +uqfbnlo (69) +sgrhs (249) -> zymggc, wnvrg +hqjinj (101) -> skuazsw, ewwfzg +vmpnccn (73) -> bidhw, qriyeb, xsyzhcf, ehjjbu +vqddcl (71) +yffeit (76) +xvzinl (99) +znzbkh (16) -> swnan, tbioyr +gnjit (23) -> dhfagjw, xxnpoe +qojhhod (1789) -> sjdanf, hmjpa, szglq +aluqao (313) -> lyhlx, ouhuptm +ipysrdj (222) +worqh (73) +tsxfibs (46) -> yfnkp, edjlm, txbgfm +pcumn (420) -> qwcyozf, dskuj, anoxh, dkmkdfd, fkapr +mejwrm (139) -> oxsewk, zsknxq +aynpyne (44) +sikmtaj (58) +sbfprua (70) +wwofru (53) +nmuxe (88) +uuvtlk (74) +rqisvrh (2703) -> bvmgt, gbxxpd, ffinat, ympbbx, uimoc, shesfq +ehjjbu (89) +cbmqx (163) -> bnlbs, psdzpg +naekrk (70) +cvnrr (17) +pwnqyt (133) -> zijzutq, yvdhwyh, vbmyyrh +sagyrje (49) +efuysje (97) +pzwtjfj (74) -> oyienb, ozbjpiq +ggmhxx (42) -> fhhgts, cepxc, zwzxy +bhfui (13) +chlpx (87) +hmlbrz (55) +oneoorw (90) +kyfuyaf (79) +kiylza (88) +fghxbc (99) -> fozagvz, wqgssb, kqqsq, oijwjli +qgxgzo (14) +cubqfzc (184) -> qwmqci, dmvcduz +lcqfe (61) +xypffi (11) +qntzr (92) +mkjuq (181) -> jdiczst, edsjbi +dhtii (62) -> kfzqw, lbozpy +amtqhf (99) +ixknk (37) +iuapj (162) -> gzfrn, wqtuhe, fndyvvn, zjveu, iebulx, agelbfq +khtooum (53) +aecsfp (72) +fcdcdh (88) +junfev (18) +pxfrz (91) +xratfed (6) +gwbfat (26) +cvcblhv (73) -> jbnns, glkjrrs +sdfvrod (114) -> lcqfe, uigcn +xkfkucf (951) -> skbrota, pwvahdb, odpqjr +okkvefs (820) -> fpuscxk, zhdioii, gzxnn, koxnez +dgosy (59) +yhvndwy (27) +pefzsea (86) +xaogy (131) -> ixknk, ykvss, hujjten +nvpdisw (93) +lmkwafp (56) +cwnvk (51) -> tvdsktm, pwzsq, plhlj, ayqbj +phbtrm (171) -> hmmjjct, xzvln +mrmbyj (53) +jibemf (87) +tysdkgl (20) -> mrwbv, llkaoeh +fpuscxk (147) -> ypdumo, lvdrrk +ejkumeu (235) -> xypffi, nvcafwu, cvdows +uijgiu (38) +cjjynt (264) -> rkwhbhr, axjvvur +nobfn (236) +svanha (62) +nuxxmd (53) -> lybaepp, eolqn +vsaejz (45) +hbbpuc (238) -> thrvlt, ziiqv +tbley (31) -> nvfca, nojly, nguafeb +bkkwe (70) +tywzxwb (24) -> lbhlxqa, dklujy, vzxktth +ezqeusd (71) +qwcyozf (115) -> igzvp, vtefqb +xpwxo (80) +layqazp (39) +hwdtvvc (40) +pwnxw (69) +jobwpao (181) -> pqgiox, uloppmh +wrhnq (87) +amsfvm (53) -> nqgbp, bcldmsg +dfxjjzr (190) -> udaitd, sdktm +cnwzxpy (65) +kpvbt (85) +ifbhg (62) +cpeonw (27) +rsizei (20) +gmkvgf (63) -> tykwy, dlobfkw, aynpyne, vaovit +bjiuus (56) +bwpeux (17) +szrkuzi (27) +ygvpk (33701) -> saawhdk, svthizp, abamn +mjtji (35) +rqvvv (50) -> pzbxpou, rxzfdg +pozua (128) -> vljjqbw, hmlbrz +hmjueiq (79) +hdxrbzc (45) +twway (181) -> orclyi, hmdxion +jocmdmv (72) +lacddy (68) +lsxjl (94) +edotax (14) +gmirjhi (62) +iwicpur (10) +uigcn (61) +ynhvfvx (32) +ugavy (91) +jbgxcj (48) +zdglrh (239) -> csrww, haqaohl, gskveo, qoetrb +lmlsog (62) +sazbmjz (65) +ymeoz (24) -> lbxrh, lsxjl +hhqmsd (34) +ykmfoah (245) +lfdefc (30) +qynrx (53) +znely (919) -> qcmnpm, yjutt, yqgesx +cauig (58) +gvamhux (71) +hqqingt (13) +fiynt (72) +tyysd (63) -> cjjynt, lzeud, wyylpt, pewxc, ibevwow, fvmeeas, uksnrfx +igkrktn (37) +pzbxpou (87) +dllzp (59) +iblvki (11) +vaovit (44) +tcpduh (212) +btpvxq (56) -> urktg, ifnkl, hbbpuc, casmwo, ylqvuk, dblmcye, zvpboy +xxnpoe (67) +sboms (24) +whvvemg (83) -> tafss, vnfigul +ljjyy (64) +qvdid (70) +koxnez (71) -> bolpsk, pefzsea +elgtk (40) +wesoooi (87) -> pmadd, welidg +tiikt (92) +eadvs (797) -> ofnewz, neywe, qklqozd, ykmfoah +sreke (34) +clqqyi (51) +kuufl (1074) -> aonfn, cgrima, lhfuku +qswoy (7) -> bklfmch, xpwxo, eoustfr +rakfg (91) -> fiynt, opdtk, qkhvu +zvgsa (59) +gskveo (15) +clbbi (27) +ilcsp (844) -> pafiy, phbtrm, nwupf +blnwcb (17) +udaitd (23) +aewmad (73) +tvdsktm (64) +zavcu (25) +gglxj (47) +jmrlaxf (48) +sppxnti (48) +zhdioii (243) +olepfo (98) +ezsnmw (14) +hsmjm (25) +xmuxsr (44) -> bjiuus, qqjly +kmvcmg (17) +zuoeh (7782) -> hbaxtai, pmefov, zfteizz +sqxrad (80) -> marord, jbgxcj, xsmyok +vrbcn (34) +ibevwow (308) -> cvnabd, pbckxv, xrunic, ezsnmw +rqilp (25) -> quwfos, vekxdqh +ojfzokk (99) +bjwvw (209) +sygjhzp (36) -> hsxhyf, knqxdq +pjvnmqn (43) -> azoutv, jwhcmc +qqjly (56) +iezyfwf (20) +wrlkfij (55) +wuvhyc (40) +aqgtml (51) -> wywxu, tiikt, uwnwp +fhjysp (164) -> czvyrzi, nbmnwsq +rmlru (71) +bdiiv (15) +tlxekcp (42) +lbozpy (80) +uksnrfx (224) -> bkkwe, sbfprua +gmuwpyi (90) +zsqzm (64) +evhhfo (5) +xdyrvy (189) -> wyois, cwkdlil +gbxxpd (82) -> rynmge, hngao, vlqyxe, jhyjqxq +nzhqepw (60) +zfteizz (59) -> ytvjxq, vhoasjq, fwwub, xglsp, cubqfzc, nfucnzx +ulragq (39) +jgrsa (269) -> ukfsn, kptjhtd +uisnk (2228) -> tbley, eqkot, tlmfw, gnjit +chyhykz (59) +zjveu (437) -> qhyfphs, bfwnv +syliku (78) +syzcti (32) +nnmayb (85) +zdqmuey (209) -> ibkfqok, lhmgw +myopc (16) +cifdyio (74) +nguafeb (42) +dbczwnr (15) +vxede (10) +ouhuptm (52) +sdyox (93) +slahk (43) +skbrota (217) -> toeyz, gjcibb +hbaxtai (851) -> zynpp, ylbaxtu, rfwaq +hvdfq (112) -> imohij, pwetqid +zgfqdv (15) +dpqxfp (209) +arskvgv (88) +bqywl (157) -> ooufod, clqqyi +ymataqq (22) +krwgy (109) -> dllzp, xqpfvwx +ohsyhln (53) +ofqbu (24) +ccpnopa (59) +bfkbp (156) +bolpsk (86) +tckyc (456) -> dzfclsm, sqxrad, qkrpzl, ppcsoo, rqvvv +qbftkij (204) -> rtcfcyn, vlmihf +bpcnzi (82) +rhacrz (27) +wzbqh (306) -> xratfed, fjcobs, enlctw, pklcmix +qqnmzb (1723) -> mzyqoc, soirl, dhtii, ahbcl +tuvehcz (17) +yzufk (30) +xsmyok (48) +tgiou (19) +izvtqsa (84) +ooufod (51) +rfwaq (80) -> nmuxe, ttofoep +lpoejf (30) +oykwsk (76) +wdipy (92) +jbnns (93) +qcxiehu (312) -> eeune, gbldz, ztmmr +vsslzfp (91) +uimoc (30) -> crhojk, ejkumeu, lovaf, fhjysp, uxbrs, qbftkij +phtghp (3945) -> rpjozji, swnafht, swugafb, guyrnpn, evbtz, hyhbu +svthizp (1149) -> saddwx, olhnx, uisnk, iuapj, btpvxq, iovxjv +xvwvc (23) +ovpzt (139) -> dfywz, emtjcx +uatlbrq (17) +hmpisyb (41) -> igdtz, lnmhw, ttpmzgm, dkxzsaq +pehflc (56) +iedfk (49) -> ydqqgrw, bdiiv +nomeb (112) -> mmfuve, lxudoaz +ffuqr (90) +gsgwqk (204) -> ddraicf, dgyulo +igqle (222) +jhcwkl (41) +yfusbw (76) +lpsafeq (51) +lklqxg (83) +lofayaa (22) +itqwz (113) -> rhacrz, keusrg +xbidr (74) -> pozua, gisiv, skpux, tcmdaji, gorpw, yfegso, waakcx +pnouux (9) +ryazls (221) -> zhpfgzv, rvpxob +bxwng (53) +xwkyrer (8691) -> srnnjbb, qcxiehu, gqhnstx, ghdbwu +nbmnwsq (52) +cxfsoh (53) +gdylf (74) -> jlcie, hewatw, sdpsl +vksyy (96) -> wfpzhfz, phsmt, zuwaw +qekxzsx (87) +qzglav (42) -> ubxvdq, aqvtgi +xsoqzbe (1068) -> llgbz, itqwz, yxzlpnj +lndczw (19) +perzy (46) +oigsk (38) +uytsra (106) -> hkgxpgh, gzxddd +zszzkl (72) -> ifyja, cdqdm, rwmdbn, exwzzr, leyikdx +wfvjnxf (93) +pklcmix (6) +cvpuwrb (82) +ileugiu (225) +defbun (57) +fbzvm (72) -> vgexqw, cejtpyf +aduikk (133) -> kmfel, paopwt, hdjzg, qckzqv +shlfz (3932) -> swcvn, obwkzhc, pcumn +yhjhgu (57) +vgiqvsi (53) +iajts (451) -> izzzyqd, fegaac, jagdwg, mblvpm +kxwbdvm (1104) -> mzajj, ubuge, ddguar, znzbkh +rynmge (25) -> ecwjaw, zdqsmv, aodoc, pxfrz +bqxnoid (31) -> aqgtml, qprenhy, upuybrd, sgrhs, flptbw, mxwbp, boszym +kqqsq (37) +xrunic (14) +vqnyvr (57) +lvdrrk (48) +bamxvq (86) -> zywvdda, ygnkwn, taxrkif +xkzvo (33) +vhoasjq (226) -> uogva, tuvehcz +hkgxpgh (46) +zocwx (35) +qhyfphs (6) +coselm (44) +ypbrxyq (206) -> siqcu, kqicqf +ffgzg (151) +ujuunj (64) +iuchai (53) +ykvss (37) +ovszp (64) +helyfoo (65) +pryhgj (81) +fxhqq (29) +eeshl (30) +qzftgbx (44) +ppcsoo (26) -> gwqgewp, lsgbe +xinfpy (53) +ddraicf (9) +xidtz (126) -> azuoza, coselm +ipsst (23) +wzvzgg (60) +fqqyipa (200) -> eeshl, cxqeyt, qkhqrq +jpyvpw (20) +xhzyzer (82) -> pawvr, dckbvlg +boszym (129) -> rqrhrnz, beewze, evqibrc +kabqu (38) +sdpsl (99) +bekguie (31) +klovr (30) -> kihqh, wafjqj +zklbfdg (47) +ccter (84) +wzqanwj (240) -> zavcu, hsmjm +uxbrs (94) -> qekxzsx, odqns +dzxpqj (22) +csrww (15) +wwxak (108) -> vbmqj, ugavy +etfbuu (22) +miwst (40) +iiugq (15) +cuprzhk (40) +waakcx (238) +faijmsh (35) -> rwakmo, nwikfyc +cvlod (76) +sjgvkg (1566) -> cldaag, bjwvw, dpqxfp, dgdtt, ujbzq +ixxww (61) +mipqe (91) +xitcp (88) +lxudoaz (51) +ibkfqok (19) +ulchkal (55) +qubli (60) +tsamaj (1171) -> axgndac, vbuvkx, uqeag, qyurm, lzypz +mmpnppi (60) +prlvn (63) +ddwursx (245) -> sdwrx, jtfylv +aljgr (62) +glkjrrs (93) +vwftcva (46) +ylbaxtu (144) -> frcrd, shjxje +jqpdpr (14) +yzhvrx (90) -> viqvtzw, twway, zwzzce, hqjinj, mejwrm, yyursb, gfigt +iqoxkhd (91) +locrtxl (2681) -> xsoqzbe, oxoocfp, ndkcn, vmeubf +fbmajm (58) +rylaxjf (90) -> ojfzokk, iksaub +wyois (46) +ecwjaw (91) +alhlvth (36) -> zirysk, orpjw, zdxscz +jlofqwz (13) +sdktm (23) +bjvuicy (217) -> xjyyfe, rahgf, qqllir +hepkop (7311) -> xkfkucf, xbidr, yvgkdi +gqbwc (25) -> ytxcti, qubli, cpmebw, wzvzgg +yojcz (201) -> rkjuz, rmlru +obwkzhc (86) -> vksnq, tijwlva, szcozjr, krwgy, pnhpv, ydiicdl, kskts +cdqdm (2502) -> wnfqsa, jbqmy, hvdfq +gjcibb (23) +igdtz (83) +phsmt (112) -> jqpdpr, bmnsmqz +hdjzg (77) +jukxlr (29) +oajdx (61) +ktayld (179) -> skfnp, xwjmsjr +dkxzsaq (83) +utewfcr (50) +jljjai (14) -> fhycptc, olepfo, armfpvt +gnughzp (5) +oyienb (16) +kqicqf (15) +ggvwlp (80) +vlbivgc (13370) -> xcxqa, aeatvub, pwmrau, rqisvrh, hepkop, ogmoqb +kczlit (64) +mblvpm (124) -> fbmajm, ofwbsgp +wehdeq (6) +fegaac (206) -> ffsehyc, sapwhr +qpsirr (15) +gisiv (80) -> hmjueiq, unqui +xjkquk (87) +rsdub (61) +gzxddd (46) +oxsewk (51) +ahfdt (234) +wafjqj (80) +mhjeza (93) +bljkg (12) -> yivjj, cxcyrd, lorxjw +fkapr (39) -> wwofru, weyfsg, khtooum, ohsyhln +dtfdn (71) +zxgrq (25) +rlfqf (63) +hvisx (68) +laopkn (40) +zvszwl (50) +gorpw (55) -> jnrnwos, rsdub, uaffk +skmbdhz (54) -> scqtkga, xdojlm +ecaiau (424) -> rakfg, ddwursx, nsbzfgy +bfwnv (6) +uhvtpfy (47) +zafggcz (17) +qkrpzl (170) -> kjonvut, clbbi +bvmgrs (75) +iicpkf (16) -> vhkydm, htecpc +rbuwrpw (17) +funnv (5679) -> cdlzi, fpfpv, bqxnoid +flkkr (74) +brzucfh (39) +lfavcfd (72) +dmvcduz (38) +izdhn (1183) -> uytsra, xxmtvr, bljkg +hrnrjrt (9135) -> kuufl, khwbzl, tocvooe +eiatt (291) -> gfhummb, jsmde +czvyrzi (52) +ypkhqlq (39) +egxzjn (81) +qzzlmw (319) -> szrkuzi, cpeonw +xepgx (64) +iftyxdd (79) -> xmaqelf, htqps +rskara (87) +uytsdd (292) -> hyehtm, zdissfg +mqodhde (36) +ylqvuk (48) -> shdgsk, fcdcdh, kiylza, arskvgv +gisrnfs (23) +vntsex (77) +rwmdbn (2136) -> xmuxsr, bfkbp, ibjdru, ttvfha, zhohes +fhhgts (38) +opdtk (72) +beewze (66) +leyikdx (1995) -> ewswf, gaashgh, cwnvk +kcbwrrr (631) -> wzbqh, sysdxvb, huzokb, ifuvyo, ghakp, rqqlzs +jwhcmc (72) +mqcflzv (76) +ofwbsgp (58) +hiyswbt (889) -> ileugiu, suuhqpd, yffhk, htstksc +armfpvt (98) +zsknxq (51) +pewxc (246) -> rmexd, wkmtw +lhmgw (19) +qwmqci (38) +hioofm (319) +cujimpt (137) -> ovszp, zsqzm +htstksc (169) -> wsixz, egszxz, gzjut, rutqzk +quwfos (85) +tcjqw (81) +orbcuzi (89) +sybpg (49) -> sdyox, dwrwuoq +qyhvc (16) +sadnqcp (62) +zihpcn (232) -> jukxlr, louebj +zxygs (208) -> njvkdrp, hqqingt +gyoqtcg (77) +emwblax (49) +hewatw (99) +qxkvfid (53) +kglsx (74) +yhfpq (56) -> cxyfam, mjumixz +zivlnu (23) +xsyzhcf (89) +howlyws (206) -> gwyljq, xhhwwso +uycop (59) +yhxlzc (91) +isqvoex (30) +bklfmch (80) +tvrxaw (106) -> qdqtw, qpsirr, dbczwnr +lkreb (72) +kxyfb (90) +jnrnwos (61) +mxbrva (72) +qkhqrq (30) +gfhummb (40) +zwzzce (221) -> ahqfu, gjedup, evhhfo, rpvwtq +rrvbwb (34) -> wcmyn, haclvfu +enlctw (6) +yeaic (61) +otipr (480) -> gdrxgji, fonrd, wqoae +qxkhq (143) -> ixqrl, jsrrt +wbqeo (22) +iugsida (64) +azuoza (44) +yxemuyq (19) +fyouz (18) +bnlbs (38) +hilafgl (59) -> hmpisyb, ktayld, yapaib, bmdgthp, qzzlmw +shdgsk (88) +rnqgy (34) +kmwxj (92) +hmmjjct (9) +mefmo (46) +lwvfsu (53) +fixwkec (84) +haclvfu (61) +werkz (29) +iovxjv (1204) -> uhwnr, ypbrxyq, dfxjjzr, pxkypf, nobfn, tkdvenx, sdfvrod +dmglcj (17) +qprenhy (221) -> cxfsoh, mrmbyj +qmwmbsk (804) -> tmoui, amtayi, wgqpt, xaycmtu, kztkif +zywvdda (52) +ntkpthi (6) +jkkqxfr (1135) -> nomeb, fbzvm, gklehu +muptknj (66) +uwnwp (92) +ggwtf (213) -> vkaay, kxdehcg +afywb (87) +xglsp (94) -> ljhlxc, htpblzv +elovaun (38) +qhubjd (59) +exwzzr (1542) -> bchixdc, fphmu, hcxwql +xhhwwso (43) +uevxbyn (170) -> ucaee, yuikqm +pqgiox (50) +edjlm (33) +ypdumo (48) +ehhbjt (26) +cxyfam (98) +bhqlq (82) +abamn (8) -> tsamaj, qojhhod, kcbwrrr, ttfyrk, qqnmzb, tyysd, sjgvkg +sjdanf (49) -> ldbkyg, brtomr, qwfvm +wcjnjpf (57) +xzvln (9) +citaywz (64) +aqtog (66) +khdbe (9) +vksnq (85) -> vqddcl, ezqeusd +fkwbo (91) +jefjzvl (73) +azoutv (72) +aqvtgi (90) +vlyof (97) +gwyljq (43) +xmedt (39) +rsstvn (75) -> bpcnzi, cvpuwrb +vekxdqh (85) +toeyz (23) +pvyvx (99) +pwmrau (9594) -> roogi, ajcbzv, pwnqyt +qahzrif (63) +gzjut (14) +mzyqoc (194) -> yxgwsj, fwabsk +tkdvenx (44) -> sppxnti, lncmhi, jmrlaxf, qmati +vtefqb (68) +yekmflj (64) +pdbykx (14) +fpgyyu (67) +qjbbyb (26) +izzzyqd (186) -> djvfa, qrrvi, junfev +lsire (61685) -> locrtxl, shlfz, ycpcv +vbuvkx (204) -> tlxekcp, pxdkes +ahqfu (5) +cjxyp (81) +aeatvub (10983) -> hghjsk, vksyy, otipr +jhnujj (14) +cxpwfir (63) -> mhpzrw, txwzysl +gcydgf (22) +zlbnkdc (92) -> lfavcfd, lkreb +lrjbgd (41) +casmwo (246) -> nsbnixe, vntsex +rqqlzs (270) -> lfdefc, isqvoex +xtqthxs (44) +kjonvut (27) +mptovq (19) +dwrwuoq (93) +ziiqv (81) +vnfigul (38) +jpynea (88) +rplcrt (90) +flptbw (159) -> xmgqmv, ciprksz +nojly (42) +jbqmy (86) -> zxhqlfy, ehhbjt +ozhydny (40) +zzflc (92) -> rnyndr, eiatt, fvivo, gdylf +jktlfu (47) +njvkdrp (13) +qyurm (76) -> eauxeyl, nrwmjk, qxkvfid, rjmuly +bjyraf (7) +zhpfgzv (47) +qfcetm (30) -> iqoxkhd, gptyqwd +dhfagjw (67) +qriyeb (89) +ucaee (68) +djvkd (36) +scqtkga (54) +yvgkdi (992) -> pjvnmqn, kgoyufq, zivjpfo, amsfvm +zsukqjo (90) +hfmaqp (94) +gxsxqwt (20) +marord (48) +uloppmh (50) +iktmpdq (34) +wnvrg (39) +cxiturs (95) -> ttoer, jpwtbds, yykkph, yffpvf, ahjlf, yoxetv, okkvefs +fewrzd (24) -> efuysje, olrgu, rtmiw +swnan (85) +xdojlm (54) +dhtxpbb (86) +roogi (100) -> cesnj, wsvfkr, hzhcl +yffhk (143) -> jfcoc, vpltn +ffinat (630) -> avyoy, tywzxwb, zuawuo, vsunxw +txrfl (81) +eoustfr (80) +bxmcg (249) -> epggt, gfjsie +kdeqm (99) -> qjbbyb, ikaol +lfsvtih (97) -> aylxc, bekguie +qkhvu (72) +zzfcq (7259) -> balknnd, iiqzvha, kzzfvt, ecaiau +kebhn (106) -> iktmpdq, sreke, cjbdxts, ehlnex +ljmrml (178) -> fxhqq, ybioco +asozcan (96) +ceeotg (53) +fonrd (12) +fvmeeas (88) -> wdipy, khnjt, kmwxj +cejtpyf (71) +wsvfkr (193) -> liznr, yytpewc +evdwf (31) +wqgssb (37) +uhnqr (247) -> oncexf, jeiqx +xzmdis (24) -> yhjhgu, vqnyvr, taacpu +tafhilv (11) +mhpzrw (96) +cgrima (79) -> xvayjwv, eyxccr, xtqthxs, qzftgbx +nrwmjk (53) +yjutt (47) -> jocmdmv, iaoyb, aecsfp, mxbrva +cxcyrd (62) +fwwub (146) -> defbun, wcjnjpf +sapwhr (17) +ihzsljz (46) +zmkwnv (66) +yytpewc (50) +xdctkbj (83) -> zuoeh, tnqram, funnv, zzfcq, xwkyrer, cxiturs, phtghp +kptjhtd (86) +pcecbrn (66) +sdwrx (31) +dfiyju (49) +gxddhu (133) -> itlwpm, bdnjn +zvpboy (76) -> txrfl, egxzjn, iwouvid, cjxyp +fndyvvn (85) -> khtegw, aocfuj, mipqe, lnknp +ozvtqp (53) +kxizh (74) -> yojcz, uafhv, wnpnfiv, kivyltn, jxaorvd +zwzxy (38) +rkjuz (71) +jagdwg (46) -> ytiljvt, smascq +rutqzk (14) +zymggc (39) +afbzsz (148) -> vzcklke, ggvwlp +ymdmn (99) +twoyl (58) +lqcutyt (74) +nlacdac (38) +otikjx (40) +rxzfdg (87) +huvihu (49) +cfbaj (90) +lqlyf (59) +apxgf (38) +nqicerc (62) +iksaub (99) +avyoy (252) +kzzfvt (94) -> aluqao, oherzyz, dwnokzu +uqeag (162) -> prlvn, xtaoisd +crhojk (40) -> yffeit, yfusbw, oykwsk +oxoocfp (237) -> igqle, eukgf, qzglav, ipysrdj, gsgwqk, kevlq +aylxc (31) +khnjt (92) +ytvjxq (260) +xkxqc (64) +ogmoqb (8) -> uqmgmst, hiyswbt, qmwmbsk, skmuo, tszockk, kxizh, thbwh +nvfca (42) +xaycmtu (67) -> cnwzxpy, helyfoo +kklbcs (74) +wqtuhe (341) -> myookpi, gqikhhw +unqui (79) +vhkydm (99) +zcomxf (40) +hsxhyf (63) +rwakmo (80) +uogva (17) +cesnj (57) -> hrokzl, rtgobsq, kmfsmp, chyhykz +rtcfcyn (32) +qckzqv (77) +oixlcn (37) +iaoyb (72) +idrror (34) +bcldmsg (67) +lbxdtms (281) +adbxp (35) +qsjqlp (74) +mjumixz (98) +rtmiw (97) +jzmacb (29) +umgch (64) +rpjozji (279) -> faijmsh, xzmdis, arelp, guvke, rqilp, eqpuuzs +xvayjwv (44) +vgemekb (53) +odpqjr (263) +hekibe (63) +xmaqelf (36) +ivlus (47) +rkwhbhr (50) +pawvr (12) +crcrimv (57) +ukfsn (86) +nfcbi (117) -> zocwx, mjtji +qwfvm (75) +jfieeor (96) +eolqn (91) +bgehlas (6) +ruozk (10) +gqikhhw (54) +pqjua (14) +jtyurkp (239) +wjbdxln (99) +paopwt (77) +fefuzon (126) -> jenfafh, cauig +ifualyn (93) +npccgnv (50) +nvcafwu (11) +htecpc (99) +uxbhu (175) -> bxwng, ozvtqp +gzfrn (365) -> mprgtb, qkicc +qlwhsix (71) -> bjwny, ghapm +uvkxner (46) +kmfel (77) +ytiljvt (97) +cxqeyt (30) +yyursb (93) -> lqcutyt, uuvtlk +mpijr (88) +rpqbv (23) +oginzo (24) +sydjg (10) +ehlnex (34) +ukqmhyc (25) +gshsx (6) +nafrmeo (76) +ifwmfdm (114) -> jibemf, wtfliw +rmexd (59) +ujbzq (41) -> izvtqsa, ssnhc +scxdo (56) +bvmgt (1203) -> xqncgyu, tsxfibs, zofjia +vkaay (13) +pxdkes (42) +witry (76) +ttpmzgm (83) +pxgkg (69) +vwojto (41) +jcise (35) +tbioyr (85) +wnpnfiv (55) -> tehat, ttbuzrh, jfieeor +ejxib (53) +htpblzv (83) +dgdtt (155) -> qface, yhvndwy +weyfsg (53) +aodoc (91) +vmeubf (759) -> sygjhzp, ilhib, ldgyqh, uewdyd, skmbdhz +pwetqid (13) +pudso (45) +ibjdru (136) -> dzqqgbm, qivxs +rtgobsq (59) +kqiuy (81) -> ffuqr, rplcrt, gmuwpyi, zsukqjo +gfszte (23) -> pxgkg, zehkwy, pwnxw, uqfbnlo +ngxtfhu (25) +fphmu (62) -> jpvxzcn, xvzinl, pvyvx, lxgvhy +yxzlpnj (85) -> iyfyi, jhcwkl +khixdho (46) +pjjmau (353) -> hktzoq, oigsk +ttofoep (88) +fhycptc (98) +nsghrq (105) -> bvmgrs, bsfygp +hmdxion (30) +nsbzfgy (167) -> mplhwo, qvdid +hngao (361) -> olhfbr, qgxgzo +iitbuxz (1186) -> eexmf, emuwzd, zzbad +ywnsmem (246) -> qjuuu, ohuvsf +qjsvs (66) +uuyfecv (9) +uafhv (223) -> azmneyd, mmpnppi +aocfuj (91) +kaghlc (34) +eionkb (1079) -> hxmcaoy, sybpg, jfhqrla +hzhcl (127) -> vgegr, lklqxg +ssnhc (84) +ttfyrk (2158) -> xnxsdq, ffgzg, tvrxaw +nvfqmkw (96) +qrrvi (18) +ajcbzv (55) -> jjhrmi, jljjai, afbzsz +ydiicdl (93) -> iqbdxb, fpgyyu +eyxccr (44) +gdkjoit (56) +urktg (196) -> pxgcbfi, lacddy, hvisx +wuclmu (64) +rosfnb (26) +osjsm (87) +kgoyufq (133) -> holen, gjctf +kihqh (80) +xjyyfe (25) +gyfbgkr (16) -> gyoqtcg, lovox, srzfd +bidhw (89) +wfpzhfz (78) -> zyfwjxs, evdwf +rnyndr (149) -> kklbcs, ygkdmh, cifdyio +xqncgyu (25) -> nzhqepw, satjdgz +hvmlb (141) -> qwxwd, huvihu +txwzysl (96) +suuhqpd (48) -> ccpnopa, lqlyf, fxpoal +djviima (31) -> qyhvc, kjoru, myopc +ddguar (116) -> adbxp, jcise +wptyd (87) +obbpd (24) +anoxh (63) -> hfmaqp, ggfmiv +llgbz (167) +mhxheb (167) -> rkfspx, uatlbrq, cvnrr, bwpeux +yybnbso (89) +lxgvhy (99) +yffpvf (1698) -> pwoyfeh, zklbfdg +ttvfha (156) +tocvooe (99) -> fqqyipa, zihpcn, wzqanwj, wajnseu, bnevesk, wwxak +taxrkif (52) +rvixnmq (376) -> fyouz, nsnqedk +uhwnr (60) -> zjzgs, mpijr +djvfa (18) +rjmuly (53) +pnhpv (227) +sjaax (190) +amtayi (29) -> qsvbb, scxdo, inlrm +vbmyyrh (142) -> uwjowb, naekrk +gomcbqb (203) -> lofayaa, iltoh +oijwjli (37) +wajnseu (20) -> kxyfb, vmboh, zguzlx +hghjsk (348) -> fixwkec, gcowt +dzqqgbm (10) +guvke (19) -> brjgwq, kejtzg +jpvxzcn (99) +mplhwo (70) +dblmcye (325) -> bffnszc, zxgrq, ngxtfhu +ahbcl (178) -> hebhue, edlved, tafhilv, iblvki +liznr (50) +pwoyfeh (47) +jdiczst (37) +ejvipa (38) -> kpayh, uzvsml +oherzyz (53) -> yhxlzc, fkwbo, ziyyc, dlfmj +kivyltn (303) -> vxede, pjazwiy, ruozk, sydjg +szcmb (176) -> bjyraf, bvypab +ofxzyhr (22) +xmzzrgs (266) -> aewmad, jefjzvl +gdrxgji (12) +ziyyc (91) +wgqpt (29) -> evcveie, ccter +yykkph (63) -> gyfbgkr, fghxbc, qswoy, gomcbqb, tubhp, zdqmuey, gxddhu +yoxetv (1724) -> eeziziu, kaghlc +xqpfvwx (59) +fxaglf (49) +shjxje (56) +cdlzi (1615) -> wtqxei, mhxheb, nuxxmd +zytau (43) +ghakp (232) -> sagyrje, fxaglf +lbhlxqa (76) +bchixdc (431) -> khdbe, uuyfecv, pnouux +olhnx (1796) -> vymmkdf, qfcetm, atbiby, tcpduh, ymeoz +bvypab (7) +hregcx (66) +aucjw (62) +bmqhvfv (40) +fpfpv (1564) -> fxlbc, alhlvth, yhfpq +lzypz (220) -> rnqgy, csyiik +ujjoydl (38) +rfcbs (197) -> oajdx, yeaic +cmdizw (31) -> ydzibri, syliku +iiqzvha (1325) -> hnedp, iwicpur +zdqsmv (91) +neywe (59) -> lmlsog, svanha, sadnqcp +teyakvf (89) +inlrm (56) +kpayh (34) +spwqxpy (79) +ofnewz (83) -> pryhgj, tcjqw +knqxdq (63) +jtfylv (31) +jhyjqxq (363) -> jlofqwz, bhfui +kmfsmp (59) +kskts (115) -> gdkjoit, lmkwafp +hktzoq (38) +tajfmq (30) +zdxscz (72) +pywmbis (81) +yhsmjfq (29) +kzkfcn (10) +mieqti (16) +mxwbp (235) -> fggyk, mefmo +thrvlt (81) +wqoae (12) +yivjj (62) +aumrixf (40) -> ifualyn, kgqzrt, mhjeza, wfvjnxf +gfigt (211) -> iiugq, zgfqdv +cepxc (38) +vzxktth (76) +locto (240) -> oginzo, twgjdmg +vopqzha (10) -> kglsx, qsjqlp, flkkr, fbpbs +lxwvf (72) -> ixxww, mxnlv, waqca +zuwaw (84) -> tbaads, xjadrfg +oothjv (71) +tubhp (141) -> uftnfv, vgemekb +wywxu (92) +uwjowb (70) +pwzsq (64) +eexmf (130) +ldgyqh (30) -> mriqcjy, khgvmj +ewswf (307) +tbaads (28) +rxsihsa (91) +dtmbf (50) +tzhwvzt (89) +qivxs (10) +nfucnzx (68) -> nvfqmkw, asozcan +znwmvr (63) -> ymataqq, etfbuu, wbqeo, gcydgf +kejtzg (88) +eukgf (112) -> rdvciwk, ulchkal +skpux (146) -> vwftcva, perzy +uewdyd (152) -> uamqx, gnughzp +dnynny (14) +guyrnpn (413) -> bqywl, cvcblhv, ovpzt, qlwhsix +lnmhw (83) +llkaoeh (68) +ydzibri (78) +gaashgh (307) +vbmqj (91) +uqmgmst (1336) -> kdeqm, znwmvr, iftyxdd +tijwlva (187) -> gxsxqwt, yjrfr +fozagvz (37) +tafss (38) +dckbvlg (12) +oncexf (26) +jkkwtd (142) -> jhwrcb, pbkplz, momda +evqibrc (66) +mrwbv (68) +hrokzl (59) +soirl (206) -> uqjfarv, myqre +ubuge (186) +rtutzu (73) -> crcrimv, fxrijc +pmefov (983) -> gibdxij, whvvemg, lfsvtih, ckmftuc +tnqram (7095) -> kxwbdvm, rhcxf, nihiexp +dzfclsm (186) -> yxemuyq, mptovq +pjazwiy (10) +mnqii (16) +uqjfarv (8) +xnxsdq (76) -> ukqmhyc, teduvv, lmhamlz +lnwcryv (62) +lovaf (94) -> osjsm, wptyd +rhcxf (84) -> jgrsa, egtruqh, kqiuy, aduikk +evcveie (84) +lyhlx (52) +zjzgs (88) +brjgwq (88) +wnfqsa (138) +balknnd (377) -> kebhn, bamxvq, xaogy, fefuzon +ayqbj (64) +zynpp (67) -> qahzrif, rlfqf, hekibe +szglq (194) -> iezyfwf, jmypc, rsizei, jpyvpw +ocppbp (26) +wuknah (36) -> kczlit, nggtuh, umgch, xkxqc +ifnkl (324) -> kabqu, ujjoydl +eqkot (33) -> aljgr, lnwcryv +yjrfr (20) +cvdows (11) +lybaepp (91) +jxaorvd (343) +zkpfzio (145) -> vrbcn, kasaf, hhqmsd, idrror +evbtz (297) -> ifwmfdm, rylaxjf, oylvq, locto +srnnjbb (51) -> zxygs, rkwquj, owxawf, ahfdt +viqvtzw (117) -> gmirjhi, aucjw +nsnqedk (18) +wiapj (55) -> djzjiwd, lsire, vlbivgc, xdctkbj, ygvpk +jhwrcb (90) +zdnypzo (66) +eqpuuzs (149) -> gisrnfs, rpqbv +kevlq (156) -> xkzvo, xxego +fxpoal (59) +dlfmj (91) +pbkplz (90) +qdqtw (15) +qkicc (42) +axgndac (156) -> zdnypzo, sglkjsh +gptyqwd (91) +cwkdlil (46) +tmoui (91) -> ceeotg, ejxib +xxmtvr (154) -> ofxzyhr, dzxpqj +zijzutq (90) -> wuclmu, citaywz, ljjyy +xtaoisd (63) +szcozjr (215) -> bgehlas, pocvrcs +jfhqrla (155) -> miwst, elgtk +nsbnixe (77) +haqaohl (15) +eeune (31) -> ysafyj, vlyof +vgexqw (71) +ghapm (94) +swcvn (1105) -> sjaax, szcmb, klovr +lmhamlz (25) +louebj (29) +fjcobs (6) +holen (27) +qryui (49) +olhfbr (14) +wcmyn (61) +dkmkdfd (173) -> vvkkkpb, ulragq +odqns (87) +xwjmsjr (97) +rqrhrnz (66) +uamqx (5) +rkwquj (92) -> gvamhux, dtfdn +ncmad (23) +lefxyzt (56) +qcmnpm (335) +kgqzrt (93) +ttoer (916) -> howlyws, wuknah, bjvuicy +rahgf (25) +mdqeh (17) +ghdbwu (863) -> ifbhg, nqicerc +thbwh (832) -> rfcbs, hioofm, jspui +gfjsie (90) +mmfuve (51) +vzcklke (80) +bffnszc (25) +saddwx (1569) -> bxmcg, vmpnccn, pjjmau +bmnsmqz (14) +qkawtfu (111) -> ujuunj, iugsida +edlved (11) +pxgcbfi (68) +gekygl (247) -> zafggcz, rbuwrpw +egtruqh (389) -> ocppbp, gwbfat +rvpxob (47) +ympbbx (1243) -> spwqxpy, iedfk, ugcccv, djviima, xgfad +pxkypf (54) -> hblux, nemrt +qqllir (25) +tehat (96) +gibdxij (121) -> ohsvn, wkamonm +itlwpm (57) +rfknc (9) +ekvdv (44) -> kpvbt, nnmayb +gwqgewp (99) +cvnabd (14) +dskuj (165) -> slahk, zytau +yqgesx (175) -> zcomxf, bmqhvfv, hwdtvvc, laopkn +vljjqbw (55) +qmati (48) +afyxhh (87) +ubxvdq (90) +ckegba (32) +sysdxvb (66) -> zmkwnv, pcecbrn, hregcx, muptknj +nihiexp (930) -> vopqzha, uytsdd, uevxbyn +myqre (8) +nwupf (109) -> cuprzhk, ozhydny +tzrqqk (79) +pwvahdb (85) -> yybnbso, tzhwvzt +gcowt (84) +ohsvn (19) +zhohes (46) -> wrlkfij, xlkwyg +ripilxo (299) +vwvowk (1293) -> dgosy, zvgsa +bmlkhaf (53) +kztkif (55) -> mtflvu, oothjv +ycpcv (72) -> izdhn, yzhvrx, eionkb, eadvs, jkkqxfr +zyfwjxs (31) +esphpt (85) -> emwblax, dfiyju, qryui, eydak +jsmde (40) +zguzlx (90) +pcckqq (17) +hxmcaoy (235) +taacpu (57) +ilhib (60) -> pubtxq, lpsafeq +myookpi (54) +olrgu (97) +swnafht (44) -> lbxdtms, jensj, zkpfzio, jobwpao, jxfimbl diff --git a/pytudes/data/advent2017/input8.txt b/pytudes/data/advent2017/input8.txt new file mode 100644 index 0000000..b41d8f3 --- /dev/null +++ b/pytudes/data/advent2017/input8.txt @@ -0,0 +1,1000 @@ +utc dec -736 if p > -7 +tn inc -876 if qlm == 4 +uz dec 294 if l < 10 +a inc -904 if me >= -7 +tn inc 622 if ppl <= 6 +fr dec 17 if ufk > -10 +hkt inc -511 if mdk == 0 +t inc -290 if xxh <= -1 +l dec 727 if ufk < 7 +tn inc -576 if l == -727 +z inc 464 if dea >= -2 +ufk inc 755 if utc >= 735 +utc dec -720 if qlm <= 5 +a dec -277 if ufk <= 755 +xxh dec -640 if u == 0 +hkt inc 875 if m != -6 +ny inc -351 if p >= -4 +l inc 674 if dea > -7 +ufk dec -826 if p == 0 +mdk inc 377 if utc == 1456 +ppl dec 793 if q <= 4 +z dec 114 if mdk > 368 +ny dec -412 if ny >= -353 +utc dec 176 if a != -620 +utc dec -610 if p <= 1 +l inc -541 if xxh <= 635 +l inc 102 if ny < 66 +qlm dec 700 if l >= 43 +dea dec -202 if tn <= 38 +a inc 785 if a <= -629 +ny inc 414 if fr <= -21 +l inc 250 if hw <= -10 +l inc -516 if l > 41 +utc dec 358 if mdk > 373 +p dec -38 if z == 350 +uz dec -71 if a == -627 +t inc -713 if fr > -13 +l inc 242 if tn <= 53 +dea dec 600 if hw <= 8 +hw dec -92 if fr != -19 +hkt dec 67 if l <= -232 +qlm dec 523 if hw == 92 +utc dec -608 if q != -8 +m dec 314 if me < 9 +xxh inc -937 if xxh >= 638 +qlm dec 494 if m <= -313 +fr dec -590 if m <= -306 +utc inc -539 if tn == 46 +hkt dec 831 if p >= 43 +dea inc 510 if a > -627 +p inc 319 if m > -305 +m inc 736 if xxh >= -302 +ppl inc -712 if mdk == 377 +ny inc 21 if p <= 41 +hw inc -569 if hw != 92 +ppl inc 150 if dea < -595 +xxh dec -953 if z != 356 +ppl inc 578 if qlm <= -1714 +uz dec -733 if p >= 35 +xxh inc 100 if xxh >= 660 +hw dec -491 if ppl < -767 +t dec -64 if z < 347 +me dec 802 if dea > -601 +hkt inc 431 if hkt > 359 +utc inc -600 if q != 0 +u inc -223 if tn < 48 +tn inc 443 if uz <= 513 +l inc -349 if ny == 82 +utc inc -499 if xxh <= 661 +a inc 600 if hw >= 578 +z dec -636 if utc > 1099 +tn inc 75 if z == 986 +hkt dec 364 if mdk < 377 +ufk inc 249 if fr == 573 +l inc -429 if uz > 507 +hw dec -621 if ppl == -778 +l inc -620 if z != 980 +l inc 319 if tn == 564 +q dec -478 if ny <= 82 +utc dec -169 if uz < 519 +fr inc 124 if dea >= -607 +m dec -674 if p != 28 +m dec 744 if p != 44 +l dec -620 if hw <= 582 +utc dec -950 if p >= 37 +uz dec -122 if xxh < 660 +l inc -563 if z < 996 +hkt inc -514 if m <= 361 +l dec 525 if mdk == 377 +xxh inc -666 if u != -228 +a inc 934 if a <= -23 +a inc 817 if xxh >= -11 +me inc 450 if tn < 563 +hw inc 475 if xxh < -1 +fr dec 493 if xxh < -8 +uz inc -985 if qlm > -1724 +ppl inc 856 if qlm >= -1720 +hw inc -368 if me > -804 +ny dec -219 if p != 38 +u inc 1000 if ny > 79 +q dec 551 if hkt == 281 +uz dec 317 if dea >= -600 +uz inc -916 if qlm <= -1726 +hkt dec 915 if mdk != 380 +mdk inc 484 if l == -2392 +xxh inc 326 if dea > -607 +u dec -803 if me > -811 +q dec 689 if tn != 565 +hw dec 908 if p == 38 +z inc -173 if ppl > 72 +z dec 371 if tn < 565 +p inc 185 if u > 1571 +a inc 490 if mdk != 864 +tn dec -27 if u == 1580 +qlm inc 77 if m > 345 +p dec 364 if ufk <= 1836 +dea dec 308 if me == -802 +a inc -345 if hw == -218 +ny inc 603 if p <= -138 +fr inc -4 if utc > 2217 +me inc 118 if hkt <= -626 +hw inc -590 if z < 443 +me dec 279 if q <= -756 +me inc -50 if dea == -908 +ppl inc 708 if u <= 1586 +t inc -429 if mdk >= 854 +m dec -372 if uz > -676 +fr dec -840 if ppl == 787 +qlm dec -442 if tn != 584 +u dec 227 if l == -2402 +m inc 279 if z <= 446 +xxh inc -951 if t > -421 +t dec 530 if xxh != 317 +fr inc -621 if mdk <= 869 +a dec 480 if fr < 424 +q inc 988 if l == -2384 +u inc 313 if q < -757 +hw dec 237 if hkt == -634 +mdk dec 945 if t > -969 +me inc 631 if ny >= 679 +ny dec -740 if uz == -670 +t inc -310 if utc > 2213 +p dec -453 if utc >= 2218 +mdk inc -266 if hw == -1045 +a inc -887 if qlm == -1198 +ppl dec 521 if t >= -1270 +dea dec -685 if xxh != 310 +l inc -472 if m < 1013 +ufk inc -920 if l <= -2860 +u dec -503 if me <= -373 +ufk inc 547 if m > 998 +l inc -287 if p <= 309 +qlm dec -173 if q <= -755 +u dec -928 if z > 437 +hw inc 43 if hkt < -626 +utc inc -694 if me == -382 +fr dec -938 if tn > 584 +q inc 9 if mdk == -350 +dea inc 119 if m < 1012 +ny dec 210 if ufk <= 1465 +xxh inc 352 if q > -758 +dea inc 483 if hkt >= -639 +tn inc -652 if t >= -1266 +ufk inc 674 if ny >= 1207 +ppl dec 311 if z >= 442 +qlm inc 655 if m < 1005 +z dec 580 if uz < -661 +utc inc -977 if ppl <= -36 +xxh inc -25 if l == -2864 +me dec 252 if uz > -674 +mdk dec -98 if z <= -129 +p inc -276 if utc < 541 +hw dec 796 if xxh <= 649 +q inc -726 if z != -137 +fr dec 433 if ufk <= 2140 +hw inc -701 if z < -131 +hw dec 587 if mdk <= -244 +ny dec -734 if mdk <= -249 +qlm dec -311 if utc != 546 +ufk dec -405 if q > -1481 +p dec 97 if t != -1275 +t dec 597 if qlm >= -49 +ufk dec 389 if uz < -660 +l inc 765 if a < 504 +fr dec -948 if tn >= 586 +qlm dec 79 if m > 997 +ny inc 764 if p < 225 +a dec 419 if m != 1003 +q dec -860 if q != -1475 +fr inc 426 if hw > -3080 +ufk inc 0 if ppl != -36 +utc inc 939 if p >= 206 +m inc 830 if xxh < 650 +m inc -511 if hw > -3091 +u inc -720 if qlm > -134 +dea inc -147 if a <= 503 +u inc -322 if tn != 591 +ny dec 900 if ny != 2713 +ny inc -737 if me == -634 +fr inc -494 if l != -2097 +mdk inc -363 if ny != 1976 +l inc 991 if hkt > -636 +l dec 179 if dea != 232 +q dec -264 if ny != 1977 +l dec -976 if uz > -667 +tn inc 791 if hkt > -637 +ppl dec 225 if utc < 1495 +uz dec -527 if m > 1317 +a inc -644 if me < -624 +uz inc 160 if q >= -361 +u inc 577 if xxh > 650 +q inc 124 if xxh < 653 +l inc 268 if dea > 222 +hw inc 795 if uz < 10 +uz dec 934 if uz < 26 +tn inc 966 if ufk == 2150 +me dec -71 if p <= 222 +me inc 186 if ppl > -270 +m dec -377 if xxh <= 649 +ny dec 275 if mdk > -248 +qlm dec -574 if fr != 1371 +utc dec 78 if xxh > 638 +l inc 494 if u > 3315 +tn dec -595 if qlm > 435 +tn dec 113 if a <= -140 +fr inc -610 if ufk < 2148 +uz inc -791 if u != 3334 +uz inc 356 if t < -1276 +l dec -463 if utc < 1414 +tn inc -266 if a < -137 +p inc 747 if utc >= 1402 +z inc -671 if hkt == -634 +tn inc -441 if u != 3324 +fr inc 172 if hkt > -638 +tn dec -558 if qlm < 439 +a dec -234 if tn <= 2155 +t inc -325 if l >= 126 +t dec -685 if l > 110 +ufk inc -912 if z < -805 +ufk dec 0 if fr < 941 +fr dec 276 if a == -142 +xxh inc -972 if p < 967 +ufk inc 188 if mdk >= -245 +me inc -255 if t > -583 +qlm inc 451 if uz > -1710 +fr inc -921 if z >= -814 +q inc 272 if uz < -1705 +u dec 216 if p <= 956 +a inc 30 if z > -812 +tn dec -202 if dea == 232 +m inc 792 if ny != 1976 +uz dec -867 if z == -809 +ppl inc -765 if qlm != 894 +hkt inc 301 if xxh < -322 +p dec -839 if dea == 232 +utc dec -920 if m > 1694 +a inc -206 if mdk == -252 +ny dec -545 if ppl <= -1029 +me dec -860 if q >= 39 +ufk inc 644 if tn <= 2359 +hw dec 959 if t == -584 +qlm dec 667 if xxh != -321 +ufk inc 598 if a > -323 +ppl dec -514 if hw <= -4039 +uz dec 708 if p == 1801 +hw inc -902 if hkt != -333 +qlm dec 249 if tn != 2366 +mdk inc -570 if z > -812 +fr inc -47 if tn > 2350 +me inc -62 if hw != -4037 +qlm dec 796 if dea > 239 +q dec -201 if ppl == -521 +z inc 265 if ufk != 2481 +hw dec 597 if q >= 239 +ny dec 417 if uz > -1540 +hkt dec -866 if m <= 1704 +m inc 103 if m == 1699 +ufk inc -733 if qlm <= -28 +mdk dec -416 if z > -546 +ufk dec 477 if z < -543 +l dec 224 if m < 1799 +q inc 646 if u < 3327 +hkt dec -501 if qlm != -29 +ppl inc 321 if p > 1797 +a dec 678 if ufk == 1268 +u inc -878 if fr > -302 +t dec 523 if uz != -1552 +mdk dec -490 if fr != -304 +p dec -603 if ufk >= 1264 +tn inc -234 if qlm > -33 +mdk dec -51 if q <= 881 +a inc 672 if me < 244 +z dec 473 if m != 1797 +mdk dec -727 if utc == 2331 +ppl inc -59 if me == 235 +a dec -937 if uz <= -1547 +uz dec -352 if m >= 1798 +fr inc 693 if utc < 2333 +t inc 493 if hkt != 526 +hw inc 86 if hkt >= 533 +t dec 49 if ny != 2512 +utc inc 273 if me != 235 +xxh inc -871 if dea == 232 +z dec -707 if dea != 234 +mdk dec 362 if ny > 2528 +tn inc -825 if t <= -658 +uz dec 655 if xxh < -1195 +dea dec 231 if me < 242 +mdk dec -260 if xxh != -1200 +ppl dec -842 if mdk != 321 +l inc -957 if qlm == -23 +m dec 393 if ny > 2515 +ufk inc -648 if me < 243 +dea inc -251 if fr < 399 +a inc 772 if mdk < 323 +hkt inc 997 if fr > 383 +l dec 13 if dea == -240 +hkt dec -935 if tn >= 1291 +uz dec 992 if u < 3324 +hw dec -970 if t <= -655 +m inc 132 if mdk == 321 +hw inc 908 if hkt > 2464 +me inc -975 if l != 119 +ny dec -76 if dea >= -251 +ppl dec -844 if u >= 3322 +qlm dec 286 if ny >= 2597 +xxh dec 903 if uz != -1843 +u dec 992 if hkt <= 2471 +tn dec -663 if me > -735 +ny dec -598 if ppl >= 583 +m inc 84 if mdk != 318 +ufk inc -260 if t <= -668 +u dec -443 if fr >= 388 +l dec -116 if hw <= -2670 +m inc 816 if dea < -240 +t inc 319 if mdk != 317 +me inc -681 if z < -301 +m inc 451 if uz != -1845 +t inc 472 if mdk <= 330 +qlm inc -125 if z == -310 +ufk inc -419 if p > 2401 +l dec -7 if xxh <= -2096 +m dec 325 if fr < 380 +mdk inc -391 if hkt <= 2465 +xxh inc 491 if z != -315 +p inc -832 if utc > 2324 +t dec 304 if a > 2056 +xxh dec 107 if dea < -243 +l inc 220 if hw < -2681 +p dec -316 if p > 1565 +mdk inc 333 if utc == 2332 +ppl dec 961 if a >= 2055 +fr inc 230 if z <= -310 +hkt dec -715 if fr >= 615 +l inc -466 if p <= 1888 +qlm inc 185 if xxh >= -1725 +u inc -710 if t == -168 +z inc 15 if ppl < -371 +utc inc 422 if hw < -2683 +fr dec 688 if t > -181 +mdk dec 606 if a < 2064 +me dec 323 if z <= -289 +ppl dec 150 if uz > -1844 +t inc 617 if q > 879 +hw inc -212 if qlm != -255 +a inc 338 if m <= 2901 +utc dec 545 if l < -228 +tn dec 407 if z > -303 +mdk dec 784 if ppl >= -378 +q inc -352 if z == -295 +uz inc -644 if ppl <= -372 +fr dec 209 if dea < -242 +tn dec -605 if p >= 1879 +hkt dec 77 if mdk != -1470 +hw dec -280 if hw < -2676 +ufk dec 375 if qlm >= -248 +p inc -958 if xxh <= -1710 +a inc 653 if z != -295 +utc inc 493 if qlm == -255 +xxh dec -649 if q > 530 +z inc -993 if me != -1749 +t inc 119 if mdk <= -1451 +ufk dec 883 if utc <= 2825 +m inc -545 if qlm == -255 +tn inc 626 if dea != -253 +tn dec -111 if p > 923 +tn inc -719 if u <= 2780 +u inc 976 if u != 2767 +z inc -495 if ppl != -368 +z dec 481 if dea != -246 +ppl dec 539 if ppl >= -381 +uz dec 213 if uz >= -2504 +a inc -9 if tn < 1509 +ny dec 719 if u < 3757 +uz inc 718 if hkt <= 3103 +ny dec 378 if u >= 3748 +me dec 163 if xxh >= -1076 +t dec -569 if hkt > 3105 +fr inc -280 if a <= 2407 +l dec -908 if q != 527 +a inc -13 if me < -1912 +dea dec 584 if mdk <= -1464 +hw inc -988 if l >= 692 +tn dec 847 if mdk < -1451 +hw inc 568 if utc > 2822 +t dec 133 if tn < 659 +z inc 271 if q <= 539 +mdk inc -33 if q <= 545 +l inc 185 if dea >= -259 +xxh inc 36 if xxh != -1064 +a dec 70 if xxh >= -1042 +z inc 956 if p > 931 +utc inc -778 if dea != -244 +dea inc -868 if z > -1985 +t dec -872 if u >= 3750 +ppl dec 420 if u < 3747 +dea inc 372 if xxh >= -1043 +hkt dec 32 if u != 3759 +t inc 23 if uz == -1985 +ny dec 106 if ufk == -683 +dea dec -794 if t == 1441 +hkt dec -233 if t < 1435 +q dec -186 if ufk == -683 +u dec 328 if a >= 2331 +xxh inc -179 if z <= -1991 +utc inc -614 if qlm > -254 +fr dec 136 if m != 2349 +uz inc -942 if uz >= -2000 +me inc 391 if m >= 2340 +l dec -448 if utc > 2054 +me dec -64 if fr > -696 +utc dec -621 if qlm > -256 +z dec -622 if dea == 132 +a dec -228 if ny == 1992 +qlm inc 957 if a <= 2563 +t dec 178 if hkt == 3304 +me dec -583 if uz >= -2940 +xxh dec 22 if ny >= 1988 +ufk dec 294 if fr <= -690 +l dec 666 if a != 2559 +tn dec 135 if qlm >= 704 +hkt inc 524 if q == 722 +uz inc 448 if dea > 118 +q inc 299 if hkt >= 3832 +u dec 502 if p <= 931 +qlm dec -530 if l > 863 +m dec -677 if m > 2344 +uz inc -254 if qlm < 1236 +p inc 164 if tn != 663 +ny inc -208 if me >= -874 +hw inc 688 if ny >= 1775 +q dec -90 if ny < 1787 +qlm inc 602 if l <= 874 +xxh inc 442 if uz == -2739 +mdk inc 235 if xxh == -793 +a dec -225 if u > 2911 +m dec -706 if hkt <= 3831 +a dec 229 if ufk <= -977 +ppl dec 256 if xxh == -788 +t inc 1000 if p < 1087 +hw inc -970 if a <= 2564 +hw dec 398 if ny >= 1779 +ppl inc 984 if ufk != -968 +utc inc -979 if ufk != -967 +hw dec -383 if utc > 1678 +p dec 283 if xxh == -793 +hw inc -434 if ny <= 1786 +u dec -226 if l == 868 +l dec 943 if tn > 675 +xxh inc -64 if p >= 807 +ppl inc 577 if fr == -694 +dea inc 629 if ppl > 636 +u dec 113 if ufk != -984 +a inc 482 if dea < 760 +dea dec -232 if xxh == -857 +ny inc -952 if ufk < -967 +hkt inc 159 if p < 811 +z inc 530 if mdk == -1258 +m dec -745 if dea <= 988 +m inc -554 if mdk >= -1258 +fr inc -798 if xxh >= -864 +q dec -139 if utc > 1690 +m dec 962 if p < 808 +a inc -409 if u <= 2809 +u dec -30 if ppl > 643 +uz dec 502 if u < 2834 +l dec -653 if qlm == 1834 +qlm inc 732 if me <= -869 +tn dec 200 if fr >= -1495 +ny inc -26 if a <= 2632 +hkt inc -601 if ppl < 656 +t inc -277 if l <= 1521 +a inc -86 if xxh < -847 +hkt dec -42 if qlm >= 2566 +dea dec 218 if p >= 807 +ufk dec 870 if q > 815 +z inc 141 if z == -1463 +l dec 873 if mdk > -1263 +u dec 897 if ppl <= 653 +dea inc -239 if p < 809 +xxh inc 525 if uz >= -2746 +dea inc 827 if mdk > -1266 +dea dec -988 if ppl != 636 +ny dec 330 if m < 3923 +q inc -413 if hw > -2554 +hw inc 983 if mdk < -1250 +mdk dec 932 if hw >= -1573 +fr inc -984 if u >= 1934 +xxh dec -344 if qlm > 2566 +p dec 189 if tn != 464 +hw inc -986 if ny < 473 +m dec 233 if z > -1323 +mdk inc -803 if a >= 2542 +u dec -858 if dea > 2570 +me dec 215 if dea >= 2590 +q inc 945 if dea >= 2589 +z inc 55 if ny >= 471 +xxh dec -63 if a <= 2544 +fr dec -864 if ufk != -969 +me dec -330 if me <= -861 +ufk inc -96 if dea <= 2586 +fr inc 348 if uz >= -2739 +qlm inc -249 if q <= 805 +qlm dec -752 if uz < -2736 +hkt dec -389 if q < 818 +dea inc -169 if ppl == 646 +xxh inc -689 if z <= -1268 +tn inc 911 if m <= 3697 +ppl inc -390 if a != 2551 +a inc 87 if ufk != -1074 +z inc 413 if ppl == 262 +p inc 476 if mdk < -2052 +p dec -570 if z != -1257 +uz inc 266 if hkt <= 3654 +ppl inc -29 if ny <= 474 +ny inc -154 if ppl <= 264 +ufk inc -614 if uz < -2741 +dea dec -627 if xxh == -269 +me inc 553 if p < 1670 +q inc -413 if a > 2636 +q dec 754 if utc == 1688 +p dec 857 if m == 3688 +dea dec 883 if ufk >= -1074 +uz inc -485 if l == 647 +dea dec -979 if me <= 15 +hkt dec 738 if l > 642 +xxh inc 298 if tn < 1372 +uz dec 235 if l != 651 +m dec -170 if tn > 1379 +hkt inc 902 if a > 2619 +hkt inc 354 if hw < -1573 +qlm dec 512 if uz != -3462 +u inc -676 if t != 984 +a inc 635 if z == -1267 +ppl inc -756 if q <= 60 +t inc 662 if mdk == -2061 +qlm dec -900 if p > 807 +z dec 877 if hkt == 4176 +a dec -841 if uz > -3466 +dea inc 141 if u != 2115 +q inc 917 if dea != 3270 +ppl inc -582 if tn >= 1375 +dea dec -309 if xxh < -271 +utc inc -353 if hw <= -1578 +mdk dec 643 if q != 979 +hw inc -595 if fr != -1254 +xxh inc 736 if ny != 325 +hkt inc -692 if z == -2144 +p dec 500 if hw < -2170 +uz dec -168 if ppl >= -1083 +u dec 419 if hw > -2181 +fr inc -653 if u != 1704 +m inc -677 if qlm < 3716 +qlm dec -341 if u >= 1704 +me dec -926 if utc >= 1329 +qlm dec -462 if hw != -2174 +fr dec 604 if hw != -2173 +p dec -826 if uz >= -3291 +hkt inc -855 if ny <= 315 +utc dec -647 if dea > 3269 +xxh inc 483 if z < -2143 +l dec 93 if utc >= 1979 +dea inc -680 if fr != -1264 +me inc -293 if ufk != -1063 +uz dec 279 if t == 1636 +xxh inc -145 if u <= 1705 +q inc 269 if a > 4097 +ufk dec 734 if l >= 552 +z dec -270 if utc > 1977 +tn inc -154 if t <= 1645 +mdk inc 455 if uz < -3283 +dea inc 350 if utc < 1992 +hw dec -300 if ppl <= -1085 +ufk inc 337 if u >= 1699 +ppl inc -634 if l != 558 +t dec -583 if xxh == 805 +t dec 384 if dea >= 3620 +p dec -873 if m == 3011 +ufk inc -710 if uz < -3287 +hw inc -808 if hkt <= 3490 +hw dec -464 if u > 1702 +m dec -102 if mdk > -2256 +fr dec 579 if t > 1829 +dea dec -839 if qlm < 4519 +ufk dec -741 if l <= 545 +me inc -520 if z <= -1865 +mdk dec 824 if hkt < 3493 +qlm inc -703 if q <= 1243 +t dec 284 if qlm < 4517 +fr dec -527 if ufk == -2183 +me dec -995 if xxh == 805 +utc inc 498 if hw < -2525 +hw dec -350 if ufk <= -2174 +dea inc 143 if mdk == -3073 +utc dec 812 if l < 552 +ufk dec 679 if hkt <= 3490 +a inc -464 if ny < 317 +ufk inc 116 if hkt > 3483 +hw inc 77 if mdk < -3063 +hkt dec 851 if ny < 329 +uz dec -37 if uz != -3287 +hkt dec 45 if xxh == 805 +uz dec -682 if fr <= -1850 +dea inc 695 if hkt > 2582 +p dec 857 if hkt <= 2592 +fr inc 114 if dea < 5309 +q dec -714 if p < 1158 +utc dec 896 if ufk != -2752 +uz dec -937 if ufk < -2741 +p inc -807 if tn <= 1232 +ufk inc 788 if fr >= -1730 +ufk dec 519 if l > 558 +ufk dec 142 if tn < 1227 +ppl dec -561 if ufk > -2103 +dea dec 463 if fr >= -1728 +m inc 139 if tn != 1218 +fr dec -606 if q >= 1951 +qlm inc 934 if fr >= -1122 +a dec -910 if xxh < 815 +hw dec -564 if a <= 5015 +u dec -648 if hw > -1532 +hkt dec 601 if hkt <= 2588 +q dec -480 if hkt < 1997 +uz dec 596 if hkt >= 1983 +p dec -971 if u > 2347 +z dec 790 if m == 3252 +fr inc 281 if hw <= -1517 +uz dec 636 if hw == -1516 +l dec -582 if ny > 315 +ny inc 202 if dea < 5306 +mdk inc -251 if ppl > -1147 +me dec 826 if p == 1317 +qlm dec -11 if p == 1317 +z inc -166 if a >= 5011 +ny inc 455 if l >= 1127 +utc dec -156 if qlm < 4525 +q dec -147 if l <= 1129 +ufk inc 36 if ny < 978 +ppl dec -871 if uz < -2907 +fr inc 776 if t >= 1548 +qlm inc -510 if u != 2352 +z inc 373 if dea >= 5294 +uz dec -975 if fr <= -59 +fr dec -670 if z < -2459 +utc dec 322 if q != 2428 +l dec 3 if ppl != -282 +uz dec 728 if ny > 971 +ny dec -396 if p > 1308 +a inc -502 if mdk <= -3067 +ny dec -492 if uz <= -2666 +ppl inc -720 if t >= 1554 +uz inc -323 if hw != -1533 +ppl inc 805 if m >= 3252 +p inc 310 if qlm != 4520 +m dec 743 if dea >= 5299 +ppl inc 847 if t <= 1546 +p dec 89 if u != 2352 +a inc 472 if z < -2455 +me dec 301 if utc > 914 +ppl inc 740 if q < 2434 +ufk inc -633 if l > 1138 +ppl inc -51 if hw > -1529 +u dec -714 if fr >= -56 +z dec 510 if me >= 0 +l inc 664 if mdk != -3073 +qlm dec -742 if l < 1142 +ny dec -473 if tn == 1225 +fr inc -805 if ufk > -2093 +xxh dec -151 if fr > -74 +hw inc -734 if hw <= -1528 +p dec 976 if uz >= -2990 +mdk inc 523 if m == 2509 +u dec -176 if utc < 923 +me inc 766 if hkt != 1987 +ppl dec -392 if mdk != -2557 +l inc -756 if u > 2527 +fr inc -990 if xxh > 955 +l inc 901 if ufk > -2100 +xxh dec -856 if ppl >= 137 +hkt dec -989 if t == 1561 +p dec 846 if p > 339 +hkt inc -429 if dea != 5302 +u dec 534 if hw <= -1517 +uz dec 178 if xxh > 1803 +z dec 655 if m <= 2516 +xxh inc -340 if ny < 2334 +u inc -545 if dea != 5295 +p inc -996 if uz > -3172 +dea dec -140 if hkt != 1984 +q inc -764 if a <= 4985 +z inc 263 if uz == -3167 +l dec -929 if a <= 4985 +p inc -214 if uz >= -3170 +uz inc 393 if hw >= -1533 +tn inc -624 if me == -5 +me inc -474 if ufk != -2106 +ppl dec 475 if l <= 2214 +qlm inc 417 if u != 1449 +p inc -490 if qlm > 5257 +a inc 526 if u <= 1452 +ny inc -347 if u <= 1454 +p dec 397 if uz < -2765 +t dec 548 if u <= 1448 +ufk dec 514 if ufk > -2102 +l dec 744 if uz != -2782 +fr dec 810 if ppl == -333 +ppl dec -338 if qlm > 5258 +qlm dec 272 if q > 1665 +m dec 521 if ufk >= -2614 +uz dec 558 if me < -477 +p inc -632 if m >= 1987 +dea inc -237 if fr != -1864 +mdk dec 3 if utc > 917 +l inc -406 if dea >= 5213 +dea inc -268 if z == -2849 +utc inc 675 if q > 1664 +me dec -905 if p < -3230 +ufk inc -799 if u != 1439 +xxh inc 718 if hkt != 1987 +tn inc 156 if qlm >= 4984 +p inc -680 if fr == -1866 +ppl inc 423 if hkt >= 1980 +p inc -759 if ufk != -3405 +me inc 496 if qlm <= 4995 +m dec 111 if mdk != -2545 +u dec 351 if z < -2843 +uz dec -405 if xxh != 1804 +ny dec -634 if utc == 1592 +qlm inc 294 if l == 1463 +xxh inc -994 if a <= 5511 +a inc 460 if uz == -2927 +t inc -313 if u != 1093 +l inc 254 if hkt > 1978 +dea dec -290 if ppl <= 429 +ny inc 190 if z <= -2844 +ppl inc -865 if dea == 5220 +z dec 372 if utc <= 1595 +l dec -563 if u < 1104 +z inc -283 if xxh < 821 +q inc 967 if utc == 1595 +q dec -621 if ppl > 433 +l dec -221 if tn > 757 +l dec -935 if a >= 5962 +l inc -62 if l != 3225 +hkt dec -654 if t > 1240 +dea inc 87 if p == -4673 +l dec -166 if u <= 1098 +dea dec 183 if hw != -1529 +q dec 70 if p == -4667 +a dec -673 if ny < 2188 +q dec 295 if mdk != -2563 +m dec -26 if a == 6644 +qlm inc 378 if xxh != 816 +a dec 174 if l <= 3320 +fr inc 117 if dea >= 5131 +hkt dec -732 if hkt >= 2634 +ufk inc -838 if mdk != -2547 +ny inc -964 if a >= 6461 +hw dec -264 if a == 6470 +z dec -834 if ufk >= -4251 +l inc -658 if m > 1897 +xxh inc 400 if fr >= -1753 +hw dec 380 if hw <= -1265 +t inc -608 if utc < 1597 +ppl dec 352 if a > 6467 +l dec -355 if utc > 1591 +l dec 846 if dea <= 5128 +ppl dec 756 if fr < -1746 +utc dec 259 if p == -4673 +tn dec 160 if hw < -1257 +t inc -625 if t != 640 +xxh dec 804 if dea > 5130 +ny dec 227 if z <= -2665 +ppl dec 306 if uz != -2922 +q dec -671 if hw < -1262 +tn dec 149 if ufk == -4248 +p dec -583 if mdk == -2553 +hw inc 312 if uz <= -2919 +hkt inc 111 if tn >= 456 +q dec -23 if uz > -2918 +hw inc -291 if l > 3008 +me inc -744 if utc > 1327 +uz dec 188 if utc >= 1336 +hw dec -575 if z < -2663 +ppl dec 977 if ny != 988 +l dec -84 if dea < 5135 +p inc 905 if uz == -3115 +m inc 636 if m == 1903 +hkt dec 95 if p < -3178 +u inc 249 if utc > 1331 +uz dec -196 if qlm == 5662 +hkt inc -621 if fr > -1750 +z inc -859 if l < 3093 +l inc -789 if ppl > -1957 +me inc 916 if tn >= 457 +uz dec -115 if xxh != 406 +z dec -353 if z <= -2669 +hw inc -965 if ppl != -1960 +t inc 333 if qlm == 5662 +t dec 860 if z == -2310 +p dec -841 if l > 3104 +qlm inc 225 if t == 341 +utc inc -937 if p <= -3185 +qlm inc -191 if xxh < 424 +m dec 607 if q != 2354 +uz inc 807 if p >= -3178 +fr dec -431 if uz == -2804 +ppl dec -312 if t <= 341 +a dec -764 if mdk >= -2557 +utc dec 505 if a >= 7228 +ufk dec -148 if tn != 449 +utc dec -371 if utc != -100 +dea dec -11 if utc < 272 +ufk inc 329 if utc != 261 +utc dec -484 if z <= -2312 +m dec 784 if ppl == -1651 +xxh dec 669 if m <= 1147 +xxh inc -798 if me == 178 +p dec -832 if ppl == -1651 +ufk inc 266 if fr > -1318 +a inc -993 if fr >= -1319 +xxh inc 25 if ppl != -1652 +u inc -353 if hw == -1631 +p inc -338 if q >= 2340 +p dec 517 if utc >= 741 +ppl dec -221 if dea > 5137 +hw dec 949 if mdk < -2544 +tn inc 201 if ufk != -3781 +mdk inc 855 if t > 334 +m dec 604 if q <= 2353 +me inc 268 if tn <= 644 +tn inc -372 if m > 540 +l dec 275 if qlm >= 5687 +mdk dec -13 if p == -3199 +z dec -725 if tn > 286 +dea inc -843 if dea == 5142 +hw inc -603 if a >= 6234 +ppl inc 850 if tn <= 279 +l inc -601 if uz == -2804 +m inc 10 if z >= -2319 +fr inc -412 if xxh != -351 +me dec 726 if tn >= 277 +ny dec -719 if me < -544 +hw dec 413 if q > 2349 +a dec -229 if hkt == 2651 +t inc 620 if t != 347 +uz inc -216 if t <= 963 +fr inc 614 if me != -549 +xxh inc 536 if z < -2309 +q inc 974 if me < -548 +q inc -131 if ny == 1711 +tn dec 110 if tn > 274 +l inc 47 if p == -3208 +xxh inc -872 if dea >= 4295 +tn inc -667 if tn <= 169 +q dec 562 if mdk >= -1700 +a inc -16 if xxh != -685 +hw dec 649 if xxh == -695 +ufk inc 239 if l != 2268 +t dec 935 if ppl <= -576 +m dec 1000 if fr > -1120 +hkt inc -167 if xxh == -695 +ny inc 926 if uz > -3027 +m inc -729 if xxh > -693 +m inc -677 if a > 6221 +p dec -412 if qlm >= 5691 +m dec -678 if ufk < -3526 +ppl inc 206 if z < -2308 +m inc -961 if m != -445 +t inc -989 if mdk > -1701 +ppl dec 43 if q <= 1654 +xxh inc -619 if ny == 2637 +ppl dec 168 if xxh < -1312 +t inc 191 if xxh > -1320 +me inc 387 if hw >= -3826 +p inc 517 if q <= 1648 +q dec 577 if ppl > -589 +u dec -841 if fr <= -1115 +dea dec -791 if p <= -2793 +hkt inc 216 if tn != -500 +uz dec -333 if hkt >= 2490 +dea inc 46 if a > 6217 +mdk inc -168 if fr > -1117 +t inc -606 if fr > -1122 +me inc 662 if hkt != 2491 +uz dec 384 if p > -2806 +uz inc -848 if xxh < -1308 +ny inc 617 if tn < -497 +fr dec -359 if utc != 750 +m dec -911 if ufk <= -3530 +ppl dec -190 if mdk != -1858 +u dec -400 if t > -1388 +me inc -381 if u == 2235 +hw inc -548 if m == 466 +qlm inc -940 if mdk <= -1860 +dea dec 180 if z <= -2316 +hw inc 17 if tn != -504 +fr dec -769 if me > -277 +ppl inc -630 if hkt == 2482 +hw inc 825 if xxh == -1314 +utc dec -38 if hw < -3529 +q dec 851 if uz <= -3918 +me dec -417 if me > -274 +q inc 505 if ny < 3248 +ny dec 299 if fr > 9 +utc dec 996 if z == -2317 +z inc 157 if ppl == -395 +mdk inc -11 if mdk == -1866 +t dec -222 if ny <= 2964 +q dec 1000 if u <= 2244 +tn dec -704 if ppl >= -399 +l inc 666 if utc > -212 +q inc 890 if dea >= 4951 +tn inc 255 if xxh > -1324 +me dec -317 if p == -2796 +utc dec 651 if m >= 460 +dea dec -945 if q > 110 +ny inc -755 if z > -2169 +a inc 1 if utc < -858 +uz dec 840 if utc >= -861 +l dec 131 if ufk != -3542 +hkt inc -442 if u > 2236 +mdk dec -156 if hw == -3531 +ufk dec 380 if uz != -4756 +xxh dec 198 if p == -2796 +fr inc -946 if z != -2165 +q dec -736 if dea < 5898 +qlm inc -284 if fr == -934 +z dec 895 if t < -1152 +me dec -370 if l != 2806 +a dec -949 if dea >= 5906 +l inc -913 if uz <= -4758 +uz inc 15 if t > -1158 +m inc 535 if xxh > -1516 +me inc -896 if u > 2228 +m inc -821 if fr == -934 +me dec 754 if m <= 189 +xxh inc 685 if p >= -2802 +utc inc 149 if uz == -4744 +ufk dec -486 if hw <= -3535 +tn dec 617 if u != 2228 +fr inc -971 if ny < 2191 +l dec 933 if z < -3053 +q dec 269 if qlm > 4467 +me inc 449 if l < 968 +utc inc -359 if l <= 965 +tn inc -465 if p <= -2798 +xxh dec -811 if t <= -1149 +fr dec -106 if m <= 182 +uz inc 603 if p < -2794 +uz inc 310 if z <= -3064 +ny inc -764 if hw >= -3538 +mdk dec -843 if ufk < -3416 +a inc 49 if tn != -158 +dea inc 129 if ufk >= -3433 +ny dec 515 if ny < 1438 +q inc -603 if ufk < -3419 +tn dec 470 if hkt < 2496 +m inc -669 if utc <= -1067 +dea inc 401 if ny >= 912 +p inc 129 if tn >= -631 +p dec -708 if hw != -3540 +dea inc 932 if mdk == -1024 +tn dec -244 if ufk == -3426 +ny dec 632 if utc >= -1075 +ny dec -958 if z > -3063 +me dec -67 if hkt == 2490 +fr inc 431 if mdk > -1038 +ny dec -435 if z < -3052 +ny inc 997 if ny != 1686 +dea inc 397 if hw < -3537 +hw dec 232 if xxh == -16 +q inc 826 if p > -1960 +q inc -807 if z < -3045 +uz dec -645 if a < 6227 +me inc -725 if qlm < 4477 +xxh dec -440 if z == -3055 +mdk inc 647 if m <= -489 +t dec -497 if dea != 6827 +hkt dec -874 if hkt == 2490 diff --git a/pytudes/data/advent2017/input9.txt b/pytudes/data/advent2017/input9.txt new file mode 100644 index 0000000..a29e6c6 --- /dev/null +++ b/pytudes/data/advent2017/input9.txt @@ -0,0 +1 @@ +{{{{{{{<>},<},<,>},{{,!!ouu}i>},!i!!!>!!!{>}},{{{{!!!>!!"!!o">}},{{{{{},!>},<>}}},{}},},!!o!!!!ee!!!!io!!!>!>!>},<'>},{{{{,},>},{<"a!>!>,'>,{{{},,}}}}},},},},<,!>,!>a,>},{{{<>}},{{},},,}}}}},{{!o{a"i!u{}!>,<{!!!>,!a>,{}},{{},,},e>},{}}}},{{{{{}}},{}},{{{{},>},{}},{{{<i'!"a!!!>!>>}},{{{},<}{e}},<>},{},!!!!!!!>!!!>},<>}},{<"e!>},<,o!!"!>e!>}"!>,<}a>}},{{}}},{{<,!!{ai{,ou!>},,,<>},{{{<'o!!!>u,!!!>!>},,<>}},{{{{<>}},{{{"!!o"!!!!!>aioo,>},!!!>,{i!!!>},},{<{!>},<}!>,!!i}!!{!!!>>}}},{{{{},},{<},,<'}u,!e}!>},">}}},{{{<>}},{{}}}}}}},{{{},{{},<}!eu}"},!a,a>}},{{{{,},<"">},{}}},<,{>}},{{{}},{!>},},<{>}},{{},{{<,,i!!!!u!!'!'{"ei{">},{}}},{{{,<}},,!!e}">}},{{!eu"!{!ua{>}}}}},{{{{},{}}},{{!},,<<>},{{{{},{,}},{{{},{{u,a{!!!>,>}}}}}},{{<}!>u!>},},<>}}},{},{{{}}}},{{{{},{{{<{"o!!o!><'!!!>>},{{},<'!!,'},!>,!>,>},{},u!!!>!>,}}}},{{{{},{<<',!oi!>},,!>},}},{{}}}}}},{{{},{{{{}},{{},{},!!!>"}}},{{{!>},!>},!">,!!ee>},{{<{!!!>'e!!,,<'!{>}}},{{<}u,!,!!!>!>},!"i{!!!>,>}},{{<"{!!!>ioua!!!>u!ouu!>a!!u>}}},{{}},{{{{},{},{{!!!!!!!>,<"!!!>ea},<'!!!>ue!'>}}},{{{{,},},}},{{{{{},{},,!>},<"oa<>}}},{{,}}},{<",o!!!>e,!>,},},<",!!!i>,{}},{,{>}},{},!'o>}},{},{{{<'>},{<>}}}},{{{{{},<>},{<{!oo"!>},<<"e!>,"{o!}!!!>},>}},{,<,"e!!i{ii!!!!a}u>,!>,<'o{!>!>,,<,>},{{<'!!!>!i!!!>"!>},,'!>,},<}>}}},{},<"}!>},,,<>},{{{},<'u!>},<>},'a!!!>!o!!}">},{{>}}}},{{<},,},<>,!!a{>},{{{{<>}},{}},{,<"<<}},{{{},{}}}}},{{{<{}a!u!>},},{!!'>},!!!!!>oo''<>},{{},,},<'>},{{!!!>!>},{>}}}},{},{{{{{},{,oio!}!>,a!!'u!>},<'!!>}},{,!!!>},<}!>!!!>!!!!<{!!io!>!!!>},},{{!!!>>}}},{,},!!"'"{!!,>},{{<,"!!a!>},,},},>},<{!!ou'!!!,a>}},{{},{}},{{{},o{u"!!!!!!!!!!>}},{>}}}}},{{{},},{{},{,!>,<>,{{,>,{!!!>!>!!!>!>},}},<}!!e>}}}}},{},{{},{{},{}}},{{<}!>},,!!!>a!!"!!'>},{<{'!>},i!>,'!>},<'!!>,<>},{},,{,>}}}}},{{{{{{<""!!!>!>,<'!o!!!>>},{}}},{<'!"o!!!>}!>},<>,{<'>}},{{<,a!i"!}i!!!>"a"!!!!{u!!,i>},{},},<{io!>e!>,,<>,{{}}}}},{{!!a,eeia,>},{<>}}},{{{<>}},{{},<}>},{}},{{<},<{!>!ia!>},<{o!>}!!!>},<>}}},{{{'o"a}euu!!!>ua>},{{<"!>},<{!>a!>},,},<>},{<}!!e!a!!>}}},{{},,,,,,<,,<"!!!>,},}!u!>},,}},{{<>,{}},{{{<}i!'",!>!,!!e!u>}},{}},{>,{,<"'!'e!!!>!>},},!!<{>,{,'!>},<'!!!!a{{!!!>!>e}a}!>},,<>}}}}},{{{!>,},{!,!>},u''<>}}}},{{{{{e"a>}}},{!!}!>,<'o!!!>,}""o{u!!!>>}},{{{},<{!!e,o!>!ou>},{{{}},{}},{{<"'!'{>},},}},{{{,<'a,!eo,!!>},<""!>,},,},{{!!!>ii!>},,,{}}},{{},{{,},},},{uo"!!!>,}e!>u>}}}},{{{{<}!!}!>}'!!<{!a!>,}}}},{{{<{"},<"!ii"'}!!!>!!},<<>,<,!!!!!!!!!>"{!!"eu,!!!>,,},{}},{},{{},{{{u},,}">},<""e}<,!>!o!!!>}!!o>},{<{>}}},{{{{{}},{{{<,o!>},!>,a}ee>},{{<{,!!,!>},a>},<'!!u{i>}},},<}},{{},},<"{o<>},{},,<>}},{<}oio>,{{'!>},},{,a!>!>},,<}>}}}},{{<{,ei!e{'{!{">,{,o!",a}!>,}},{{<",'!>{!"iu!!!>!>},},>,{<"a!!!>!>!>},<}{!,!!!!ou}{>}},u}!!!>>}},{{<"!>,,},a!!a,!>,<">,{!>,!>},},},<'>}}}}}}}},{{{{{},},},<"o!>!>},<'!!!>,},},{{{{!>,},{<"!}!i!!!>},},!>},<{>}}}}},{{{"!!ua!>},<"!!!>!!!>{'ie{'}>},,!!!!!>},!!u"{'o>},{{!>},,,{o'ui!!!><{>}},{{},{,<{o!!}"!>},<{}e">,{}}}}},{{{!>},},{{{{,<>}}},{}}},{{<}!>,<'!>,,!>a>},{!>,<",<},{!>,,<{!!"eo>}},{{},{{o!io!>},'},<'i,!>iea!!!!!>"!!!'>}},{{{{,<}!!"!>,<}},{},<,'!>,}},{{,}!!'!>},},<{>},{>}},{{{{'!!"i!!!>!"o!!!>!!!>ii'>}}},{},,!!!!!>!>,,<{}}}},{{{a}">}},{{a!>!>,<{!!!!i!!!>,,{>},{},<'}}!>,}}}},{{{{{{},{},<'{!!>}},{!!{!>o!!e!!"'!!!>},<"o!!<>}},{{>,,!>,<}!!<{!io}>},<'"!>,!!!>!>},,>},{{aa!!!>eau,'>,}}}},{},{},{{{,{}},{{<,{},<>},{}},{{{}},!>!!"'!!u!a!!,a>}},{{},{oo"!!!>,{>,'>},{!!!>!!'{''!>{i{!>},<>}},{{{,<"!!'i"ui>},{}}},{{{{<'<{},},<{a!!!>>}},!!{!!o>},{{},!!!!e!>}!!!>!!!!!>'">},<>},{{<'{!!}a">}}}}},{{{{{<,<"!>},},,}},{<,!!!>},},,<>,<,!>},,},{}},{{},,<>},{{{{{ua,!}'<,>},},o"!>},<">},{{{},{}}}},{{},{{<>},},},}}},{},{{{{!'>},{<'!!!>!!!>},"ioa!!!>}!!!>'>}},{}}}}}},{{<,!o'e{!!""!e',a!>!!!>},<>},{{},{,<<{o!!u>}}},{{{}},{{<{>},,},o!>a,>},{o!>e'!!!>},,{{}}}}}},{{},{{{<,!!"}!>},,<>},{{}},{,{},,,<,<}!!!!!>e"{!!<,'!>!>!!!>"!ee{!>},<>}}},{{{,},<>}}},{{{{,},<,e!!!>}'!!'uei>},{<"{i>}},},<"!>,eu!<{a>}}},{{{{<{"!oi>,{}},{{<}!>},<"au>,{,<}},{}}},{{{i!!!!}'e!!!>"},{<!!!>>,<>}},{},},!o!>,<>,,<}!>},!!!>!!!>!>},<>}},{}},{{{{{},{}}},{{',ua'!!a{{>},{{>}},{{<}!>aai!!'"}!!!},{{{},<{!!e!>},,,<>},<>}}}},{{{},e!!{'"oi!>>}}},{{{!!i,o!>},>},{{},{,<"!!!>}!>},}}}}},{}},{{}}},{{{o!e,!!>,{{},{}}},{{},<}!>},oeee>}},{{{i"e{!>},}},{}},{{{},{u'!!!o}a!>,<>}},{{{{<,oo!!!>o<"ao!!!>,<'!}!u!!,,{>}},{{},<},>},},},},,!>{>},{{{{<}"""e!>ei"!"}!!e'!!>}},{},<{<}}ieoai!",!>,},{{{},<'}!}u{,!}{e!!>,{<,}}!>!>!,i!>},}},{o,ua!!!>,},<"!!!!a!}a!!!>},<{!!!>!>,<>}}}}}}},{!>},},o}!!!>,<{!!<}u>,!!}}!>!>},}},{{!>,},},<{!!!!!>'o!>,<>},{{{<,'>},{}},!!},!!!>'>}}}},{{{{{{>,{!},,,<>}},{{},a,!!}!"i{!!!>,<>}},{{,}!!!!>}}},{{{{{},{,}!!!>,,}},{{e!>!>i!!}!>,<>},{,<,!!ou!!}},{{}}},{{<}u'!!!>},<,!!!e>}},{}},{{,},<}u""!!!>io!!!>},},{{>,{}}},{{}},{{{o,!!e''i},>}},{a!>,,<>,<,!,}>},{o'!>e>,{}}}},{{{{}}},{{{,{}}},{{{!>>}},{<'o}'!>,,,{a!!i'>}},{{},{{{<,!>},},,,}},{{u!!!>o!>ei,!}!!!!!!!>!!!>!>,<>},<'o!}'>}},{{{,<<>}},{{},},},,},!!!>ae!>,<>},u!>,<<'{!>!!"}!>,<<>}},{{{},<,!o!!u!!!}'i!!>,},{{{},{}},{}},{}},{{{}},{{<"u!e!!,!,!>},},,a!>},<"!>,>},u!>},!>,<}!!i!>,}},{{{{{{{},<}}},!,>}}}},{{{},<>,{{!!!>!!a",!>},}}},{"!>a!!,!>},<>}},{<"!!!>},<,!u!!!{!>},<,<,o'!>,<"!"{!>,<>,!e"!!!!!>!!!!}"<'o!>},<"!>},<}u>},{{{{<,!>,!}}},{{}}}},{{{}},{,}!>},<,i{!>},>,{{},{i!>,!>!!i!{!>,},>}}}}}}}}},{{{<>}},{{<>},{,,,<>}}},{{},<}!!!>!>>,,!!>},{!>},!>!!!>},!e!!!>!>!>o!!"!a>,{,>,{<'>}}}}},{{{!!,e!!>}}},{{},{{},<{ia!!}e"!>},,}},{,!>},u!'!!i!!!"!<>,!!ua}{}>}}},{{{{{{{},<>},{!!!>!!a!>,<>},{{{<,,ua!>,<<"!i!{"!>},,{<>}},{<}}!!!>!>o!!!>!!a!!{i}},<,},!!!>}!!'!!!!!>,}}},{},{{{,<>}}}},{{!!!>,,},,!>}>,},<<,e!!u!!{<>},{{,,<{!>},!'!>},<'{,">,{},<<,ue!!,},}}},{{{"!!e!>,,<{!>,<>},},<'a"!!!,!>},},<'"uo{e!!{!!!>i"!>!{!>},<,i{>}},{{{}},{{{!>,<>,!!!>!>,!>},<>}},{}},{{},},i,<>}}}},{{<,oa!>o"!>},},{<'!>},,{<,u>}},{{,,!<'>},{{}}}},{{<>}},{{{},{{},<!!!!!!!>},},!!'>},},{}},{{<"!i!!ii!!!>,<,!!!>'{,'u<>}},{{<},<>},{<,!e!>!!!>i!>,,},!}!>!>},}}}},{{{{<<>}},{{!!u!!!!},!>},',!>},},,>}},{{{{<}{a!>},},},<,"ia!'!!,e'i>}},{{},{},<{!>,},!>,<">}}},{,<{"!>!>,>}},{{{{}},{},{{{{!!"a!>,<>,{}}},{},}}}},{{,{>}},{{{{{<}"!!!>!>u!!!>}}i!>,<}'a!{{>},<,!>!>!},},},{{{{<>}}},{,,{}},{{a!,ei!!!>!>"!>>}}}},{!>},!>}}""},<>,{!>},},{}},{{},!>},},,{,!>},<>}}},{{},!!!>'}eu!>,!!!>!!!>!!!>"}!e>}},{{{{!>,},{{,<{!{i!>}!}a",oo!>,,<>,{<,!e'>}},},},a!!!!'<'!!!>,<>}},{{},}},{{,},,},},<"i!!e!>},},}}},{{{{}"!!!>},,<"!>},{{},<>,{},<{"!}!!oo!!!>'!>,,<'>}}}},{{{},!>},},},<{!>,},,,<<>},{{}}}}}},{{{{},<,<"!>,}>},,{'!>},,>},{{,<}i!{>}}},{{{{{},{}}},{{{>,,!!!u!>>}}},{}},{{},{},{}}},{{{{{,},}},{{}},{}},{{},{{},{{{}},{{<},<,'!!a!>},'!!!>>,',!>,!!'!>},<>},{{{'!!!>!>},ue!e"!!!>},<"o>},{oe}{'!!<>}},{<>}},{{},<'!>},u>}},{<>}},{{{{},{{{<,a!>e!!!>!!!>}o!>},,<>}},{{<}!!!!!!!>o<>}}}}}},{{{},{<{!!!>'!!u!!!>'>,{{'!!!!e!"i>}}}},{{{,,<>}}},{{{{{{}!>},},o''"u>},{{{!!a!>,<'{!>,,<>}},<},ii!,!!e>}},{}},{{},<{i}!>},!"}},{{{{}},{<,!>i!!i,a!>},<"!>u!aoe>,{<,}}},!>,<'!ua!o!>,}},{{{!>},!!oie"!i>,{!!!>'{{>}},{{{{!!o!>i!!!>},<,}}},{},{{},},>}},{{{<'!!!!!>o!!!!!>!>,},>,{<}!!!!!!u!!!>},,>}},{<>,{'>}}},{{{ee}i!a!!!>!!!>},<}!!,!!!>!>!!i!>,}},{{{{},{}}},{{{{e{uo{u>,!!!>,<{!>}!u>},'>},<,!!u!>,,>}}},{{}}},{}}},{{<,{{>},{{<,!>},iu{}!>,!!!>!!!>{!{a,>,{{!aa>},},o!!'!,>}},{{},<"'ai!!!>'ia>}},{{{},{},<"!!!'!>!!!!}!>},!!!>,,<>}},},<}'!>,!!,>}},{{{"}>},{,<}}ieo!!o!>,!!!>>}},{<"!>!e!!!>!>},,,!<>,{<>}},{},,!<}{'>,}}},{{{{,,},{{,},o!!<>,{}}}}},{{<}'!!!!'!>}},{<,u!!{!!!!!>"!!e>,},<}"}!!{o!!!>o!ie!!!>>}}}},{{},i!>e!,,},<,>,},},{{<}ei!>,!}u!>},},,},<>},{},i!>},u}u>}},{}},{{{{{{<"io!>},,<"}!"!!!>}}>},{<>}},{}},{{{{!>},,,o!{>},{!u}},{{,}}},{},e'!!!!'!a!>},<}i>,{{},{<,<},},!!a"e>}}},{{},{,<>,<'ai!">}}}},{{a}}!"!!e!!o,e!>,,<{},{!!>}}},{,,<},{{{},<''!!!>!!{!!!>},},<'!!!!!>},<>},{}},{{uea>},{}}}}},{{}},{{{{{{}},{{},{<}!!!>,}},{{{u!{io!>,{{>},{{<}!ea!>>}}},{,}!!!!!>!!!},!>,<,!!{'!!!o''<>}}}},{{{{{},{{}}},{}}}},{{{}},{},{<'u!!!>!!!!!>},e}{io>,{}}},{{{{}},{}},{{},{{{{},{{}}}}},{{{},{{}},{<{!!!"!!!>!ea!!!<>,{}}}}}}}}},{{{{{,!>!"}!!>}},!!!!!!!"!"i,!>,<>},{i!!!>{e!>a'i{!!!>},{}},{}}},{{},{{{},,{}},{,<,'aa{!!!>},!>},},{{},e>}}},{<{!!!>!>!!>}},{{,<"{oo{!!!>,!>},>,{a'!!!!}!>,ii!!"!>>}},{{{<'oo"}!!!>},{e!!"!>,},},},{!!}uu!>},}},{{{}},<{},u},!>,<,{<,{>}},{{{{{}},<}o!{<}eoe!>'{a!>,},<>},{{{<{!>,!}!!!!}>,{,},},o!!'!>,}},<"!>!>e!>},<"">},{,!!a'},},<{"!!!>!!>,!!{>},{{{}},,'!>,!!!>},,}},{}},{{{{<"'"},'}!>},<"!,!!!>!>,!>,}},{}},{{},{!>},ie!>,},<>}}}}}},{{{{{au>,{!>{"!>,},<{{a'a"{,o!!!>!!<>}},{},{}},{{<>}}}},{{{!!!>!!!>>,>},{{{<"ei!!!>,u>},{<<,ia!>},"">}}},{{{{,},},{{{},<>},!!!>i,!!!>o"ao!>,}}},{<'!!o">}},{{{<>},a>},{{,,,<}>,,,<>}}},{<'},,,,<<<"!!<>,{!!'!>{!>},<'i!!!>>}}}},{{{{<'e}u"}a!!!>!!!>,},<}!!!>>},{<}e!!!!}a{i>}},},{{<,!>!i!!!>},,{{{}!!"!>},!!!>!!!>"!!!!>}}}},{{<}!!>},{},}}},{{{,!!!>!!!>,<}!!>},},},},!}"o,>}}},{},{{{{},,<,eeu!>,<,"u'"!>},<">},{{{,,},,,<>}},{}},{{{{{}},{{oo!>o!!!!!!!>{!!u"'">}}},{},}}}},{{{<>,<'a,}!!!!!<'!!!>},,{!!"!>!>},},{{},{},},},},,"!!<{!!o>}}},{{e}{!{!>,,<{u}e!>e!ua>},{{<"}'!>,{,!>}}{!!!!!>,}}}},{{{},{{},{<'!!!>}!>},},,,,!!>}}},{{{},!>,<,}},{{{<>}},{,"'!><{>},{<,!!,!!!!!>"!!!>!>},<"!!!>!>>,{,},<,!>},}!!"!>,},<<u'>}}},{{{<}{!>,<<"!!!>!!{!>,<>},{{},{<"!>},<{e}>}},{<"a!>},},<'{!!!!!>i!>,>,{,{,!!!>!!a!>},},<>}}}}}}}} diff --git a/pytudes/ipynb/.ipynb_checkpoints/Advent 2017-checkpoint.ipynb b/pytudes/ipynb/.ipynb_checkpoints/Advent 2017-checkpoint.ipynb new file mode 100644 index 0000000..1b5e6de --- /dev/null +++ b/pytudes/ipynb/.ipynb_checkpoints/Advent 2017-checkpoint.ipynb @@ -0,0 +1,3667 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# December 2017: Advent of Code Solutions\n", + "\n", + "Peter Norvig\n", + "\n", + "I'm doing the [Advent of Code](https://adventofcode.com) puzzles, just like [last year](https://github.com/norvig/pytudes/blob/master/ipynb/Advent%20of%20Code.ipynb). This time, my terms of engagement are:\n", + "\n", + "* I won't write a summary of each day's puzzle description. Follow the links in the section headers (e.g. **[Day 1](https://adventofcode.com/2017/day/1)**) to understand what each puzzle is asking. \n", + "* What you see is mostly the algorithm I first came up with first, although sometimes I go back and refactor if I think the original is unclear.\n", + "* I do clean up the code a bit even after I solve the puzzle: adding docstrings, changing variable names, changing input boxes to `assert` statements.\n", + "* I will describe my errors that slowed me down.\n", + "* Some days I start on time and try to code very quickly (although I know that people at the top of the leader board will be much faster than me); other days I end up starting late and don't worry about going quickly.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "# Day 0: Imports and Utility Functions\n", + "\n", + "I might need these:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Python 3.x Utility Functions\n", + "\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import re\n", + "import numpy as np\n", + "import math\n", + "import random\n", + "\n", + "from collections import Counter, defaultdict, namedtuple, deque, abc, OrderedDict\n", + "from functools import lru_cache\n", + "from statistics import mean, median, mode, stdev, variance\n", + "from itertools import (permutations, combinations, chain, cycle, product, islice, \n", + " takewhile, zip_longest, count as count_from)\n", + "from heapq import heappop, heappush\n", + "from numba import jit\n", + "\n", + "identity = lambda x: x\n", + "letters = 'abcdefghijklmnopqrstuvwxyz'\n", + "\n", + "cache = lru_cache(None)\n", + "\n", + "cat = ''.join\n", + "\n", + "Ø = frozenset() # Empty set\n", + "inf = float('inf')\n", + "BIG = 10 ** 999\n", + "\n", + "################ Functions for Input, Parsing\n", + "\n", + "def Input(day, year=2017):\n", + " \"Open this day's input file.\"\n", + " return open('data/advent{}/input{}.txt'.format(year, day))\n", + "\n", + "def Inputstr(day, year=2017): \n", + " \"The contents of this day's input file as a str.\"\n", + " return Input(day, year).read().rstrip('\\n')\n", + " \n", + "def Array(lines):\n", + " \"Parse an iterable of str lines into a 2-D array. If `lines` is a str, splitlines.\"\n", + " if isinstance(lines, str): lines = lines.splitlines()\n", + " return mapt(Vector, lines)\n", + "\n", + "def Vector(line):\n", + " \"Parse a str into a tuple of atoms (numbers or str tokens).\"\n", + " return mapt(Atom, line.replace(',', ' ').split())\n", + "\n", + "def Integers(text): \n", + " \"Return a tuple of all integers in a string.\"\n", + " return mapt(int, re.findall(r'-?\\b\\d+\\b', text))\n", + "\n", + "def Atom(token):\n", + " \"Parse a str token into a number, or leave it as a str.\"\n", + " try:\n", + " return int(token)\n", + " except ValueError:\n", + " try:\n", + " return float(token)\n", + " except ValueError:\n", + " return token\n", + " \n", + "def error(err=RuntimeError, *args): raise err(*args)\n", + "\n", + "################ Functions on Iterables\n", + "\n", + "def first(iterable, default=None): \n", + " \"The first item in an iterable, or default if it is empty.\"\n", + " return next(iter(iterable), default)\n", + "\n", + "def first_true(iterable, pred=None, default=None):\n", + " \"\"\"Returns the first true value in the iterable.\n", + " If no true value is found, returns *default*\n", + " If *pred* is not None, returns the first item\n", + " for which pred(item) is true.\"\"\"\n", + " # first_true([a,b,c], default=x) --> a or b or c or x\n", + " # first_true([a,b], fn, x) --> a if fn(a) else b if fn(b) else x\n", + " return next(filter(pred, iterable), default)\n", + "\n", + "def nth(iterable, n, default=None):\n", + " \"Returns the nth item of iterable, or a default value\"\n", + " return next(islice(iterable, n, None), default)\n", + "\n", + "def upto(iterable, maxval):\n", + " \"From a monotonically increasing iterable, generate all the values <= maxval.\"\n", + " # Why <= maxval rather than < maxval? In part because that's how Ruby's upto does it.\n", + " return takewhile(lambda x: x <= maxval, iterable)\n", + "\n", + "def groupby(iterable, key=identity):\n", + " \"Return a dict of {key(item): [items...]} grouping all items in iterable by keys.\"\n", + " groups = defaultdict(list)\n", + " for item in iterable:\n", + " groups[key(item)].append(item)\n", + " return groups\n", + "\n", + "def grouper(iterable, n, fillvalue=None):\n", + " \"\"\"Collect data into fixed-length chunks:\n", + " grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx\"\"\"\n", + " args = [iter(iterable)] * n\n", + " return zip_longest(*args, fillvalue=fillvalue)\n", + "\n", + "def overlapping(iterable, n):\n", + " \"\"\"Generate all (overlapping) n-element subsequences of iterable.\n", + " overlapping('ABCDEFG', 3) --> ABC BCD CDE DEF EFG\"\"\"\n", + " if isinstance(iterable, abc.Sequence):\n", + " yield from (iterable[i:i+n] for i in range(len(iterable) + 1 - n))\n", + " else:\n", + " result = deque(maxlen=n)\n", + " for x in iterable:\n", + " result.append(x)\n", + " if len(result) == n:\n", + " yield tuple(result)\n", + " \n", + "def pairwise(iterable):\n", + " \"s -> (s0,s1), (s1,s2), (s2, s3), ...\"\n", + " return overlapping(iterable, 2)\n", + "\n", + "def sequence(iterable, type=tuple):\n", + " \"Coerce iterable to sequence: leave alone if already a sequence, else make it `type`.\"\n", + " return iterable if isinstance(iterable, abc.Sequence) else type(iterable)\n", + "\n", + "def join(iterable, sep=''):\n", + " \"Join the items in iterable, converting each to a string first.\"\n", + " return sep.join(map(str, iterable))\n", + " \n", + "def powerset(iterable):\n", + " \"Yield all subsets of items.\"\n", + " items = list(iterable)\n", + " for r in range(len(items)+1):\n", + " for c in combinations(items, r):\n", + " yield c\n", + " \n", + "def quantify(ite1rable, pred=bool):\n", + " \"Count how many times the predicate is true.\"\n", + " return sum(map(pred, iterable))\n", + "\n", + "def length(iterable):\n", + " \"Same as len(list(iterable)), but without consuming memory.\"\n", + " return sum(1 for _ in iterable)\n", + "\n", + "def shuffled(iterable):\n", + " \"Create a new list out of iterable, and shuffle it.\"\n", + " new = list(iterable)\n", + " random.shuffle(new)\n", + " return new\n", + " \n", + "flatten = chain.from_iterable\n", + "\n", + "def repeat(n, fn, arg):\n", + " \"Repeat arg=fn(arg) n times.\"\n", + " for i in range(n):\n", + " arg = fn(arg)\n", + " return arg\n", + "\n", + "################ Making immutable objects\n", + " \n", + "class Set(frozenset):\n", + " \"A frozenset, but with a prettier printer.\"\n", + " def __repr__(self): return '{' + join(sorted(self), ', ') + '}'\n", + " \n", + "def canon(items, typ=None):\n", + " \"Canonicalize these order-independent items into a hashable canonical form.\"\n", + " typ = typ or (cat if isinstance(items, str) else tuple)\n", + " return typ(sorted(items))\n", + "\n", + "def mapt(fn, *args): \n", + " \"Do a map, and make the results into a tuple.\"\n", + " return tuple(map(fn, *args))\n", + " \n", + "################ Math Functions\n", + " \n", + "def transpose(matrix): return tuple(zip(*matrix))\n", + "\n", + "def isqrt(n):\n", + " \"Integer square root (rounds down).\"\n", + " return int(n ** 0.5)\n", + "\n", + "def ints(start, end):\n", + " \"The integers from start to end, inclusive: range(start, end+1)\"\n", + " return range(start, end + 1)\n", + "\n", + "def floats(start, end, step=1.0):\n", + " \"Yield floats from start to end (inclusive), by increments of step.\"\n", + " m = (1.0 if step >= 0 else -1.0)\n", + " while start * m <= end * m:\n", + " yield start\n", + " start += step\n", + " \n", + "def multiply(numbers):\n", + " \"Multiply all the numbers together.\"\n", + " result = 1\n", + " for n in numbers:\n", + " result *= n\n", + " return result\n", + "\n", + "import operator as op\n", + "\n", + "operations = {'>': op.gt, '>=': op.ge, '==': op.eq,\n", + " '<': op.lt, '<=': op.le, '!=': op.ne,\n", + " '+': op.add, '-': op.sub, '*': op.mul, \n", + " '/': op.truediv, '**': op.pow}\n", + "\n", + "################ 2-D points implemented using (x, y) tuples\n", + "\n", + "def X(point): x, y = point; return x\n", + "def Y(point): x, y = point; return y\n", + "\n", + "origin = (0, 0)\n", + "UP, DOWN, LEFT, RIGHT = (0, 1), (0, -1), (-1, 0), (1, 0)\n", + "\n", + "def neighbors4(point): \n", + " \"The four neighboring squares.\"\n", + " x, y = point\n", + " return ( (x, y-1),\n", + " (x-1, y), (x+1, y), \n", + " (x, y+1))\n", + "\n", + "def neighbors8(point): \n", + " \"The eight neighboring squares.\"\n", + " x, y = point \n", + " return ((x-1, y-1), (x, y-1), (x+1, y-1),\n", + " (x-1, y), (x+1, y),\n", + " (x-1, y+1), (x, y+1), (x+1, y+1))\n", + "\n", + "def cityblock_distance(P, Q=origin): \n", + " \"Manhatten distance between two points.\"\n", + " return sum(abs(p - q) for p, q in zip(P, Q))\n", + "\n", + "def distance(P, Q=origin): \n", + " \"Hypotenuse distance between two points.\"\n", + " return sum((p - q) ** 2 for p, q in zip(P, Q)) ** 0.5\n", + "\n", + "################ Debugging \n", + "\n", + "def trace1(f):\n", + " \"Print a trace of the input and output of a function on one line.\"\n", + " def traced_f(*args):\n", + " result = f(*args)\n", + " print('{}({}) = {}'.format(f.__name__, ', '.join(map(str, args)), result))\n", + " return result\n", + " return traced_f\n", + "\n", + "def grep(pattern, iterable):\n", + " \"Print lines from iterable that match pattern.\"\n", + " for line in iterable:\n", + " if re.search(pattern, line):\n", + " print(line)\n", + " \n", + "class Struct:\n", + " \"A structure that can have any fields defined.\"\n", + " def __init__(self, **entries): self.__dict__.update(entries)\n", + " def __repr__(self): \n", + " fields = ['{}={}'.format(f, self.__dict__[f]) \n", + " for f in sorted(self.__dict__)]\n", + " return 'Struct({})'.format(', '.join(fields))\n", + "\n", + "################ A* and Breadth-First Search (tracking states, not actions)\n", + "\n", + "def always(value): return (lambda *args: value)\n", + "\n", + "def Astar(start, moves_func, h_func, cost_func=always(1)):\n", + " \"Find a shortest sequence of states from start to a goal state (where h_func(s) == 0).\"\n", + " frontier = [(h_func(start), start)] # A priority queue, ordered by path length, f = g + h\n", + " previous = {start: None} # start state has no previous state; other states will\n", + " path_cost = {start: 0} # The cost of the best path to a state.\n", + " Path = lambda s: ([] if (s is None) else Path(previous[s]) + [s])\n", + " while frontier:\n", + " (f, s) = heappop(frontier)\n", + " if h_func(s) == 0:\n", + " return Path(s)\n", + " for s2 in moves_func(s):\n", + " g = path_cost[s] + cost_func(s, s2)\n", + " if s2 not in path_cost or g < path_cost[s2]:\n", + " heappush(frontier, (g + h_func(s2), s2))\n", + " path_cost[s2] = g\n", + " previous[s2] = s\n", + "\n", + "def bfs(start, moves_func, goals):\n", + " \"Breadth-first search\"\n", + " goal_func = (goals if callable(goals) else lambda s: s in goals)\n", + " return Astar(start, moves_func, lambda s: (0 if goal_func(s) else 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'pass'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " # Functions for Input, Parsing\n", + " assert Array('''1 2 3\n", + " 4 5 6''') == ((1, 2, 3), \n", + " (4, 5, 6))\n", + " assert Vector('testing 1 2 3.') == ('testing', 1, 2, 3.0)\n", + " \n", + " # Functions on Iterables\n", + " assert first('abc') == first(['a', 'b', 'c']) == 'a'\n", + " assert first_true([0, None, False, {}, 42, 43]) == 42\n", + " assert nth('abc', 1) == nth(iter('abc'), 1) == 'b'\n", + " assert cat(upto('abcdef', 'd')) == 'abcd'\n", + " assert cat(['do', 'g']) == 'dog'\n", + " assert groupby([-3, -2, -1, 1, 2], abs) == {1: [-1, 1], 2: [-2, 2], 3: [-3]}\n", + " assert list(grouper(range(8), 3)) == [(0, 1, 2), (3, 4, 5), (6, 7, None)]\n", + " assert list(overlapping((0, 1, 2, 3, 4), 3)) == [(0, 1, 2), (1, 2, 3), (2, 3, 4)]\n", + " assert list(overlapping('abcdefg', 4)) == ['abcd', 'bcde', 'cdef', 'defg'] \n", + " assert list(pairwise((0, 1, 2, 3, 4))) == [(0, 1), (1, 2), (2, 3), (3, 4)]\n", + " assert sequence('seq') == 'seq'\n", + " assert sequence((i**2 for i in range(5))) == (0, 1, 4, 9, 16)\n", + " assert join(range(5)) == '01234'\n", + " assert join(range(5), ', ') == '0, 1, 2, 3, 4'\n", + " assert multiply([1, 2, 3, 4]) == 24\n", + " assert transpose(((1, 2, 3), (4, 5, 6))) == ((1, 4), (2, 5), (3, 6))\n", + " assert isqrt(9) == 3 == isqrt(10)\n", + " assert ints(1, 100) == range(1, 101)\n", + " assert identity('anything') == 'anything'\n", + " assert set(powerset({1, 2, 3})) == {\n", + " (), (1,), (1, 2), (1, 2, 3), (1, 3), (2,), (2, 3), (3,)}\n", + " assert quantify(['testing', 1, 2, 3, int, len], callable) == 2 # int and len are callable\n", + " assert quantify([0, False, None, '', [], (), {}, 42]) == 1 # Only 42 is truish\n", + " assert set(shuffled('abc')) == set('abc')\n", + " assert canon('abecedarian') == 'aaabcdeeinr'\n", + " assert canon([9, 1, 4]) == canon({1, 4, 9}) == (1, 4, 9)\n", + " assert mapt(math.sqrt, [1, 9, 4]) == (1, 3, 2)\n", + " \n", + " # Math\n", + " assert transpose([(1, 2, 3), (4, 5, 6)]) == ((1, 4), (2, 5), (3, 6))\n", + " assert isqrt(10) == isqrt(9) == 3\n", + " assert ints(1, 5) == range(1, 6)\n", + " assert list(floats(1, 5)) == [1., 2., 3., 4., 5.]\n", + " assert multiply(ints(1, 10)) == math.factorial(10) == 3628800\n", + " \n", + " # 2-D points\n", + " P = (3, 4)\n", + " assert X(P) == 3 and Y(P) == 4\n", + " assert cityblock_distance(P) == cityblock_distance(P, origin) == 7\n", + " assert distance(P) == distance(P, origin) == 5\n", + " \n", + " # Search\n", + " assert Astar((4, 4), neighbors8, distance) == [(4, 4), (3, 3), (2, 2), (1, 1), (0, 0)]\n", + " assert bfs((4, 4), neighbors8, {origin}) == [(4, 4), (3, 3), (2, 2), (1, 1), (0, 0)]\n", + " forty2 = always(42)\n", + " assert forty2() == forty2('?') == forty2(4, 2) == 42\n", + "\n", + " return 'pass'\n", + "\n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 1](https://adventofcode.com/2017/day/1): Inverse Captcha\n", + "\n", + "This was easier than I remember last year's puzzles being:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2014, (3, 2, 9, 4, 1, 9, 9, 4, 7, 1))" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "digits = mapt(int, Inputstr(1))\n", + "N = len(digits)\n", + "\n", + "N, digits[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1158" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(digits[i] \n", + " for i in range(N) \n", + " if digits[i] == digits[i - 1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1132" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(digits[i] \n", + " for i in range(N) \n", + " if digits[i] == digits[i - N // 2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 2](https://adventofcode.com/2017/day/2): Corruption Checksum\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "rows2 = Array('''790\t99\t345\t1080\t32\t143\t1085\t984\t553\t98\t123\t97\t197\t886\t125\t947\n", + "302\t463\t59\t58\t55\t87\t508\t54\t472\t63\t469\t419\t424\t331\t337\t72\n", + "899\t962\t77\t1127\t62\t530\t78\t880\t129\t1014\t93\t148\t239\t288\t357\t424\n", + "2417\t2755\t254\t3886\t5336\t3655\t5798\t3273\t5016\t178\t270\t6511\t223\t5391\t1342\t2377\n", + "68\t3002\t3307\t166\t275\t1989\t1611\t364\t157\t144\t3771\t1267\t3188\t3149\t156\t3454\n", + "1088\t1261\t21\t1063\t1173\t278\t1164\t207\t237\t1230\t1185\t431\t232\t660\t195\t1246\n", + "49\t1100\t136\t1491\t647\t1486\t112\t1278\t53\t1564\t1147\t1068\t809\t1638\t138\t117\n", + "158\t3216\t1972\t2646\t3181\t785\t2937\t365\t611\t1977\t1199\t2972\t201\t2432\t186\t160\n", + "244\t86\t61\t38\t58\t71\t243\t52\t245\t264\t209\t265\t308\t80\t126\t129\n", + "1317\t792\t74\t111\t1721\t252\t1082\t1881\t1349\t94\t891\t1458\t331\t1691\t89\t1724\n", + "3798\t202\t3140\t3468\t1486\t2073\t3872\t3190\t3481\t3760\t2876\t182\t2772\t226\t3753\t188\n", + "2272\t6876\t6759\t218\t272\t4095\t4712\t6244\t4889\t2037\t234\t223\t6858\t3499\t2358\t439\n", + "792\t230\t886\t824\t762\t895\t99\t799\t94\t110\t747\t635\t91\t406\t89\t157\n", + "2074\t237\t1668\t1961\t170\t2292\t2079\t1371\t1909\t221\t2039\t1022\t193\t2195\t1395\t2123\n", + "8447\t203\t1806\t6777\t278\t2850\t1232\t6369\t398\t235\t212\t992\t7520\t7304\t7852\t520\n", + "3928\t107\t3406\t123\t2111\t2749\t223\t125\t134\t146\t3875\t1357\t508\t1534\t4002\t4417''')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "46402" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(abs(max(row) - min(row)) for row in rows2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "265" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def evendiv(row): \n", + " return first(a // b for a in row for b in row if a > b and a // b == a / b)\n", + "\n", + "sum(map(evendiv, rows2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This day was also very easy. It was nice that my pre-defined `array` function did the whole job of parsing the input. In Part One, I was slowed down by a typo: I had `\"=\"` instead of `\"-\"` in `\"max(row) - min(row)\"`. I was confused by Python's misleading error message, which said `\"SyntaxError: keyword can't be an expression\"`. Later on, Alex Martelli explained to me that the message meant that in `abs(max(row)=...)` it thought that `max(row)` was a keyword argument to `abs`, as in `abs(x=-1)`.\n", + "\n", + "In Part Two, note that to check that `a/b` is an exact integer, I used `a // b == a / b`, which I think is more clear than the marginally-faster expression one would typically use here, `a % b == 0`, which requires you to think about two things: division and the modulus operator (is it `a % b` or `b % a`?)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 3](https://adventofcode.com/2017/day/3): Spiral Memory\n", + "\n", + "For today the data is just one number:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "M = 277678" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This puzzle takes some thinking, not just fast typing. I decided to break the problem into three parts:\n", + "- Generate a spiral (by writing a new function called `spiral`).\n", + "- Find the Nth square on the spiral (with my function `nth`).\n", + "- Find the distance from that square to the center (with my function `cityblock_distance`).\n", + "\n", + "I suspect many people will do all three of these in one function. That's probably the best way to get the answer really quickly, but I'd rather be clear than quick (and I'm anticipating that `spiral` will come in handy in Part Two), so I'll factor out each part, obeying the *single responsibility principle*. \n", + "\n", + "Now I need to make `spiral()` generate the coordinates of squares on an infinite spiral, in order, going out from the center square, `(0, 0)`. After the center square, the spiral goes 1 square right, then 1 square up, then 2 square left, then 2 square down, thus completing one revolution; then it does subsequent revolutions. In general if the previous revolution ended with *s* squares down, then the next revolution consists of *s*+1 squares right, *s*+1 squares up, *s*+2 squares left and *s*+2 down. A small test confirms that this matches the example diagram in the puzzle description (although I had a bug on my first try because I only incremented `s` once per revolution, not twice):" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, 0),\n", + " (0, 1),\n", + " (-1, 1),\n", + " (-1, 0),\n", + " (-1, -1),\n", + " (0, -1),\n", + " (1, -1),\n", + " (1, 0),\n", + " (1, 1),\n", + " (1, 2)]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def spiral():\n", + " \"Yield successive (x, y) coordinates of squares on a spiral.\"\n", + " x = y = s = 0 # (x, y) is the position; s is the side length.\n", + " yield (x, y)\n", + " while True:\n", + " for (dx, dy) in (RIGHT, UP, LEFT, DOWN):\n", + " if dy: s += 1 # Increment side length before RIGHT and LEFT\n", + " for _ in range(s):\n", + " x += dx; y += dy\n", + " yield (x, y)\n", + "\n", + "list(islice(spiral(), 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can find the `N`th square. As this is Python, indexes start at 0, whereas the puzzle description starts counting at 1, so I have to subtract 1. Then I can find the distance to the origin:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(263, 212)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nth(spiral(), M - 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "475" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cityblock_distance(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For **Part Two** I can re-use my `spiral` generator, yay! Here's a function to sum the neighboring squares (I can use my `neighbors8` function, yay!):" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def spiralsums():\n", + " \"Yield the values of a spiral where each square has the sum of the 8 neighbors.\"\n", + " value = defaultdict(int)\n", + " for p in spiral():\n", + " value[p] = sum(value[q] for q in neighbors8(p)) or 1\n", + " yield value[p]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 1, 2, 4, 5, 10, 11, 23, 25, 26, 54, 57]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(islice(spiralsums(), 12))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looks good, so let's get the answer:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "279138" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "first(x for x in spiralsums() if x > M)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 4](https://adventofcode.com/2017/day/4): High-Entropy Passphrases\n", + "\n", + "This is the first time I will have to store an input file and read it with the function `Input`. It should be straightforward, though:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "337" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def is_valid(line): return is_unique(line.split())\n", + "\n", + "def is_unique(items): return len(items) == len(set(items))\n", + "\n", + "quantify(Input(4), is_valid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "231" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def is_valid2(line): return is_unique(mapt(canon, line.split()))\n", + "\n", + "quantify(Input(4), is_valid2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy, and I started on time, but the leaders were still three times faster than me!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 5](https://adventofcode.com/2017/day/5): A Maze of Twisty Trampolines, All Alike\n", + "\n", + "Let's first make sure we can read the data/program okay:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0, 2, 0, 0, -2, -2, -1, -4, -5, -6)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program = mapt(int, Input(5))\n", + "\n", + "program[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I'll make a little interpreter, `run`, which takes a program, loads it into memory,\n", + " and executes the instruction, maintaining a program counter, `pc`, and doing the incrementing/branching as described in the puzzle,\n", + "until the program counter no longer points to a location in memory:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "364539" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run(program):\n", + " memory = list(program)\n", + " pc = steps = 0\n", + " M = len(memory)\n", + " while 0 <= pc < M:\n", + " steps += 1\n", + " oldpc = pc\n", + " pc += memory[pc]\n", + " memory[oldpc] += 1\n", + " return steps\n", + " \n", + "run(program)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "Part Two seems tricky, so I'll include an optional argument, `verbose`, and check if the printout it produces matches the example in the puzzle description:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 0 [1, 3, 0, 1, -3]\n", + "2 1 [2, 3, 0, 1, -3]\n", + "3 4 [2, 2, 0, 1, -3]\n", + "4 1 [2, 2, 0, 1, -2]\n", + "5 3 [2, 3, 0, 1, -2]\n", + "6 4 [2, 3, 0, 2, -2]\n", + "7 2 [2, 3, 0, 2, -1]\n", + "8 2 [2, 3, 1, 2, -1]\n", + "9 3 [2, 3, 2, 2, -1]\n", + "10 5 [2, 3, 2, 3, -1]\n" + ] + }, + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run2(program, verbose=False):\n", + " memory = list(program)\n", + " pc = steps = 0\n", + " M = len(memory)\n", + " while 0 <= pc < M:\n", + " steps += 1\n", + " oldpc = pc\n", + " pc += memory[pc]\n", + " memory[oldpc] += (-1 if memory[oldpc] >= 3 else 1)\n", + " if verbose: print(steps, pc, memory)\n", + " return steps\n", + " \n", + "run2([0, 3, 0, 1, -3], True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks right, so I can solve the puzzle:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 6.2 s, sys: 8.37 ms, total: 6.21 s\n", + "Wall time: 6.21 s\n" + ] + }, + { + "data": { + "text/plain": [ + "27477714" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time run2(program)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Thanks to [Clement Sreeves](https://github.com/ClementSreeves) for the suggestion of making a distinction between the `program` and the `memory`. In my first version, `run` would mutate the argument, which was OK for a short exercise, but not best practice for a reliable API. And thanks to [Max Albert](https://github.com/maxalbert) for speeding up the loop by pulling the `len(memory)` out of the loop." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 6](https://adventofcode.com/2017/day/6): Memory Reallocation " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I had to read the puzzle description carefully, but then it is pretty clear what to do. I'll keep a set of previously seen configurations, which will all be tuples. But in the function `spread`, I want to mutate the configuration of banks, so I will convert to a list at the start, then convert back to a tuple at the end." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "banks = Vector('4\t10\t4\t1\t8\t4\t9\t14\t5\t1\t14\t15\t0\t15\t3\t5')\n", + "\n", + "def realloc(banks):\n", + " \"How many cycles until we reach a configuration we've seen before?\"\n", + " seen = {banks}\n", + " for cycles in count_from(1):\n", + " banks = spread(banks)\n", + " if banks in seen:\n", + " return cycles\n", + " seen.add(banks)\n", + " \n", + "def spread(banks):\n", + " \"Find the area with the most blocks, and spread them evenly to following areas.\"\n", + " banks = list(banks)\n", + " maxi = max(range(len(banks)), key=lambda i: banks[i])\n", + " blocks = banks[maxi]\n", + " banks[maxi] = 0\n", + " for i in range(maxi + 1, maxi + 1 + blocks):\n", + " banks[i % len(banks)] += 1\n", + " return tuple(banks)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2, 4, 1, 2)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spread((0, 2, 7, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "realloc((0, 2, 7, 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These tests look good; let's solve the problem:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12841" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "realloc(banks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:** Here I will just replace the `set` of `seen` banks with a `dict` of `{bank: cycle_number}`; everything else is the same, and the final result is the current cycle number minus the cycle number of the previously-seen tuple of banks." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def realloc2(banks):\n", + " \"When we hit a cycle, what is the length of the cycle?\"\n", + " seen = {banks: 0}\n", + " for cycles in count_from(1):\n", + " banks = spread(banks)\n", + " if banks in seen:\n", + " return cycles - seen[banks]\n", + " seen[banks] = cycles\n", + "\n", + "realloc2((0, 2, 7, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8038" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "realloc2(banks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 7](https://adventofcode.com/2017/day/7): Recursive Circus" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First I'll read the data into two dicts as follows: the input line:\n", + "\n", + " tcmdaji (40) -> wjbdxln, amtqhf\n", + " \n", + "creates:\n", + "\n", + " weight['tcmdaji'] = 40\n", + " above['tcmdaji'] = ['wjbdxln', 'amtqhf']" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def towers(lines):\n", + " \"Return (weight, above) dicts.\"\n", + " weight = {}\n", + " above = {}\n", + " for line in lines:\n", + " name, w, *rest = re.findall(r'\\w+', line)\n", + " weight[name] = int(w)\n", + " above[name] = set(rest)\n", + " return weight, above\n", + "\n", + "weight, above = towers(Input(7))\n", + "\n", + "programs = set(above)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the root progam is the one that is not above anything:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'wiapj'}" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "programs - set(flatten(above.values()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "A program is *wrong* if it is the bottom of a tower that is a different weight from all its sibling towers:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def wrong(p): return tower_weight(p) not in map(tower_weight, siblings(p))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we define `tower_weight`, `siblings`, and the `below` dict:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def tower_weight(p): \n", + " \"Total weight for the tower whose root (bottom) is p.\"\n", + " return weight[p] + sum(map(tower_weight, above[p]))\n", + "\n", + "def siblings(p): \n", + " \"The other programs at the same level as this one.\"\n", + " if p not in below:\n", + " return Ø # the root has no siblings\n", + " else:\n", + " return above[below[p]] - {p}\n", + "\n", + "below = {a: b for b in programs for a in above[b]}" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'eionkb', 'lsire', 'wiapj', 'ycpcv'}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(filter(wrong, programs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So these four programs are wrong. Which one should we correct? The one that is wrong, and has no wrong program above it:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'eionkb'" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wrongest(programs):\n", + " return first(p for p in programs\n", + " if wrong(p) \n", + " and not any(wrong(p2) for p2 in above[p]))\n", + "\n", + "wrongest(programs) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now what should we correct it to? To the weight that makes it the same weight as the sibling towers:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1072" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def correct(p):\n", + " \"Return the weight that would make p's tower's weight the same as its sibling towers.\"\n", + " delta = tower_weight(first(siblings(p))) - tower_weight(p) \n", + " return weight[p] + delta\n", + "\n", + "correct(wrongest(programs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 8](https://adventofcode.com/2017/day/8): Memory Reallocation \n", + "\n", + "This one looks easy: a simple interpreter for straight-line code where each instruction has 7 tokens. It is nice that my `Array` function parses the whole program." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6828" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program8 = Array(Input(8))\n", + "\n", + "def run8(program):\n", + " \"Run the program and return final value of registers.\"\n", + " registers = defaultdict(int)\n", + " for (r, inc, delta, _if, r2, cmp, amount) in program:\n", + " if operations[cmp](registers[r2], amount):\n", + " registers[r] += delta * (+1 if inc == 'inc' else -1)\n", + " return registers\n", + "\n", + "max(run8(program8).values())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "Here I modify the interpreter to keep track of the highest value of any register at any time." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "7234" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run8_2(program):\n", + " registers = defaultdict(int)\n", + " highest = 0\n", + " for (r, inc, delta, _if, r2, cmp, amount) in program:\n", + " if operations[cmp](registers[r2], amount):\n", + " registers[r] += delta * (+1 if inc == 'inc' else -1)\n", + " highest = max(highest, registers[r])\n", + " return highest\n", + "\n", + "run8_2(program8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 9](https://adventofcode.com/2017/day/9): Stream Processing\n", + "\n", + "For this problem I could have a single finite-state machine that handles all five magic characters, `'{}'`, but I think it is easier to first clean up the garbage, using regular expressions:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'{{{{{{{},},{{},}},{{{{}},{{{{{}}},{}},},{{{{},{,{{{}}}}},},{{{}},{{}}}'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text1 = re.sub(r'!.', '', Inputstr(9)) # Delete canceled characters\n", + "text2 = re.sub(r'<.*?>', '', text1) # Delete garbage\n", + "\n", + "text2[:70]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can deal with the nested braces (which can't be handled with regular expressions). The puzzle says \"*Each group is assigned a score which is one more than the score of the group that immediately contains it,*\" which is the same as saying that a group's score is its nesting level, a quantity that increases with each open-brace character, and decreases with each close-brace:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9662" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def total_score(text):\n", + " \"Total of group scores; each group scores one more than the group it is nested in.\"\n", + " total = 0\n", + " level = 0 # Level of nesting\n", + " for c in text:\n", + " if c == '{':\n", + " level += 1\n", + " total += level\n", + " elif c == '}':\n", + " level -= 1\n", + " return total\n", + "\n", + "total_score(text2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "At first I thought that the amount of garbage is just the difference in lengths of `text2` and `text3`:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5989" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(text1) - len(text2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this turned out to be wrong; it counts the angle brackets themselves s being deleted, whereas the puzzle is actually asking how many character between the angle brackets are deleted. So that would be:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4903" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text3 = re.sub(r'<.*?>', '<>', text1) # Delete garbage inside brackets, but not brackets\n", + "\n", + "len(text1) - len(text3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 10](https://adventofcode.com/2017/day/10): Stream Processing" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I have to do a bunch of reversals of substrings of `stream`. It looks complicated so I will include a `verbose` argument to `knothash` and confirm it works on the example puzzle. I break out the reversal into a separate function, `rev`. The way I handle reversal interacting with wraparound is that I first move all the items before the reversal position to the end of the list, then I do the reversal, then I move them back." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "stream = (63,144,180,149,1,255,167,84,125,65,188,0,2,254,229,24)\n", + "\n", + "def knothash(lengths, N=256, verbose=False):\n", + " \"Do a reversal for each of the numbers in `lengths`.\"\n", + " nums = list(range(N))\n", + " pos = skip = 0\n", + " for L in lengths:\n", + " nums = rev(nums, pos, L)\n", + " if verbose: print(nums)\n", + " pos = (pos + L + skip) % N\n", + " skip += 1\n", + " return nums[0] * nums[1]\n", + " \n", + "def rev(nums, pos, L):\n", + " \"Reverse nums[pos:pos+L], handling wrap-around.\"\n", + " # Move first pos elements to end, reverse first L, move pos elements back\n", + " nums = nums[pos:] + nums[:pos]\n", + " nums[:L] = reversed(nums[:L])\n", + " nums = nums[-pos:] + nums[:-pos]\n", + " return nums" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Reverse [0, 1, 2]:\n", + "assert rev(list(range(5)), 0, 3) == [2, 1, 0, 3, 4]" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Reverse [4, 0, 1], wrapping around:\n", + "assert rev(list(range(5)), 4, 3) == [0, 4, 2, 3, 1]" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 1, 0, 3, 4]\n", + "[4, 3, 0, 1, 2]\n", + "[4, 3, 0, 1, 2]\n", + "[3, 4, 2, 1, 0]\n" + ] + } + ], + "source": [ + "# Duplicate the example output\n", + "assert knothash((3, 4, 1, 5), N=5, verbose=True) == 12" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's correct, but the first time through I got it wrong because I forgot the `\"% N\"` on the update of `pos`." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4480" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "knothash(stream)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**:\n", + "\n", + "Now it gets *really* complicated: string processing, the suffix, hex string output, and dense hashing. But just take them one at a time:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'c500ffe015c83b60fad2e4b7d59dabc4'" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stream2 = '63,144,180,149,1,255,167,84,125,65,188,0,2,254,229,24'\n", + "\n", + "def knothash2(lengthstr, N=256, rounds=64, suffix=(17, 31, 73, 47, 23),\n", + " verbose=False):\n", + " \"Do a reversal for each length; repeat `rounds` times.\"\n", + " nums = list(range(N))\n", + " lengths = mapt(ord, lengthstr) + suffix\n", + " pos = skip = 0\n", + " for round in range(rounds):\n", + " for L in lengths:\n", + " nums = rev(nums, pos, L)\n", + " if verbose: print(nums)\n", + " pos = (pos + L + skip) % N\n", + " skip += 1\n", + " return hexstr(dense_hash(nums))\n", + "\n", + "def hexstr(nums): \n", + " \"Convert a sequence of (0 to 255) ints into a hex str.\"\n", + " return cat(map('{:02x}'.format, nums))\n", + " \n", + "def dense_hash(nums, blocksize=16): \n", + " \"XOR each block of nums, return the list of them.\"\n", + " return [XOR(block) for block in grouper(nums, blocksize)]\n", + "\n", + "def XOR(nums):\n", + " \"Exclusive-or all the numbers together.\"\n", + " result = 0\n", + " for n in nums:\n", + " result ^= n\n", + " return result\n", + " \n", + "assert XOR([65, 27, 9, 1, 4, 3, 40, 50, 91, 7, 6, 0, 2, 5, 68, 22]) == 64\n", + "assert hexstr([255, 0, 17]) == 'ff0011'\n", + "\n", + "assert knothash2('') == 'a2582a3a0e66e6e86e3812dcb672a272'\n", + "\n", + "knothash2(stream2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I had a bug: originally I used `'{:x}'` as the format instead of `'{:02x}'`; the later correctly formats `0` as `'00'`, not `'0'`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 11](https://adventofcode.com/2017/day/11): Hex Ed\n", + "\n", + "The first thing I did was search [`[hex coordinates]`](https://www.google.com/search?source=hp&ei=Ft4xWoOqKcy4jAOs76a4CQ&q=hex+coordinates), and the #1 result (as I expected) was Amit Patel's \"[Hexagonal Grids](https://www.redblobgames.com/grids/hexagons/)\" page. I chose his \"odd-q vertical layout\" to define the six directions as (dx, dy) deltas:" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "directions6 = dict(n=(0, -1), ne=(1, 0), se=(1, 1), s=(0, 1), sw=(-1, 0), nw=(-1, -1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can read the path, follow it, and see where it ends up. If the end point is `(x, y)`, then it will take `max(abs(x), abs(y))` steps to get back to the origin, because each step can increment or decrement either `x` or `y` or both." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "705" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path = Vector(Inputstr(11))\n", + "\n", + "def follow(path):\n", + " \"Follow each step of the path; return final distance to origin.\"\n", + " x, y = (0, 0)\n", + " for (dx, dy) in map(directions6.get, path):\n", + " x += dx; y += dy\n", + " return max(abs(x), abs(y))\n", + "\n", + "follow(path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This one seemed so easy that I didn't bother testing it on the simple examples in the puzzle; all I did was confirm that the answer for my puzzle input was correct.\n", + "\n", + "**Part Two:**\n", + "\n", + "This looks pretty easy; repeat Part One, but keep track of the maximum number of steps we get from the origin at any point in the path:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1469" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def follow2(path):\n", + " \"Follow each step of the path; return max steps to origin.\"\n", + " x = y = maxsteps = 0\n", + " for (dx, dy) in map(directions6.get, path):\n", + " x += dx; y += dy\n", + " maxsteps = max(maxsteps, abs(x), abs(y))\n", + " return maxsteps\n", + "\n", + "follow2(path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, no tests, just the final answer.\n", + "\n", + "# [Day 12](https://adventofcode.com/2017/day/12): Digital Plumber\n", + "\n", + "First I'll parse the data, creating a dict of `{program: direct_group_of_programs}`:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def groups(lines):\n", + " \"Dict of {i: {directly_connected_to_i}\"\n", + " return {lhs: {lhs} | set(rhs)\n", + " for (lhs, _, *rhs) in Array(lines)}\n", + " \n", + "assert groups(Input(12))[0] == {0, 659, 737}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks good. I recognize this as a [Union-Find](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) problem, for which there are efficient algorithms. But for this small example, I don't need efficiency, I need clarity and simplicity. So I'll write `merge` to take a dict and merge together the sets that are connected:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def merge(G):\n", + " \"Merge all indirectly connected groups together.\"\n", + " for i in G:\n", + " for j in list(G[i]):\n", + " if G[i] != G[j]:\n", + " G[i].update(G[j])\n", + " G[j] = G[i]\n", + " return G\n", + "\n", + "G = merge(groups(Input(12)))" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "115" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(G[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the answer for Part One.\n", + "\n", + "**Part Two**\n", + "\n", + "I did almost all the work; I just need to count the number of distinct groups. That's a set of sets, and regular `set`s are not hashable, so I use my `Set` class:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "221" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len({Set(G[i]) for i in G})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 13](https://adventofcode.com/2017/day/13): Packet Scanners\n", + "\n", + "First thing: The puzzle says the data is *depth: range*, but `range` has a meaning in Python, so I'll use the term *width* instead.\n", + "\n", + "Second thing: I misread the puzzle description and mistakenly thought the scanners were going in a circular route,\n", + "so that they'd be at the top at any time that is 0 mod *width*. That gave the wrong answer and I realized the scanners are actually going back-and-forth, so with a width of size *n*, it takes *n* - 1 steps to get to the bottom, and *n* - 1 steps to get back to the top, so the scanner will be \n", + "at the top at times that are multiples of 2(*n* - 1). For example, with width 3, that would be times 0, 4, 8, ... " + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def trip_severity(scanners): \n", + " \"The sum of sevrities for each time the packet is caught.\"\n", + " return sum((d * w if caught(d, w) else 0) \n", + " for (d, w) in scanners)\n", + "\n", + "def caught(depth, width):\n", + " \"Does the scanner at this depth/width catch the packet?\"\n", + " return depth % (2 * (width - 1)) == 0\n", + "\n", + "example = ((0, 3), (1, 2), (4, 4), (6, 4))\n", + "assert trip_severity(example) == 24" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 3), (1, 2), (2, 4), (4, 6), (6, 4))" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scanners = mapt(Integers, Input(13))\n", + "scanners[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1504" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trip_severity(scanners)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "A packet is safe if no scanner catches it. We now have the possibility of a delay, so I update `caught` to allow for an optional delay, and define `safe_delay`: " + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def caught(depth, width, delay=0):\n", + " \"Does the scanner at this depth/width catch the packet with this delay?\"\n", + " return (depth + delay) % (2 * (width - 1)) == 0 \n", + "\n", + "def safe_delay(scanners):\n", + " \"Find the first delay such that no scanner catches the packet.\"\n", + " safe = lambda delay: not any(caught(d, w, delay) for (d, w) in scanners)\n", + " return first(filter(safe, count_from(0)))\n", + "\n", + "safe_delay(example)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3823370" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "safe_delay(scanners)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 14](https://adventofcode.com/2017/day/14): Disk Defragmentation\n", + "\n", + "I found this puzzle description confusing: are they talking about what I call `knothash`, or is it `knothash2`? I decided for the latter, which turned out to be right:" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "key = 'ljoxqyyw'" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8316" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def bits(key, i):\n", + " \"The bits in the hash of this key with this row number.\"\n", + " hash = knothash2(key + '-' + str(i))\n", + " return format(int(hash, base=16), '0128b')\n", + "\n", + "sum(bits(key, i).count('1') for i in range(128))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "So as not to worry about running off the edge of the grid, I'll surround the grid with `'0'` bits:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Grid(key, N=128+2):\n", + " \"Make a grid, with a border around it.\"\n", + " return border('0', (list(bits(key, i)) for i in range(128)))\n", + "\n", + "def border(fill, grid):\n", + " \"Surround a grid with a border of fill cells.\"\n", + " rows = [[fill] + list(row) + [fill] \n", + " for row in grid]\n", + " empty = [fill] * len(rows[0])\n", + " return [empty] + rows + [empty]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To find a region, start at some `(x, y)` position and [flood fill](https://en.wikipedia.org/wiki/Flood_fill) to neighbors that have the same value (a `'1'` bit)." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def flood(grid, x, y, val, R):\n", + " \"For all cells with value val connected to grid[x][y], give them region number R.\"\n", + " if grid[y][x] == val:\n", + " grid[y][x] = R\n", + " for x2, y2 in neighbors4((x, y)):\n", + " flood(grid, x2, y2, val, R)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def flood_all(grid, val='1'):\n", + " \"Label all regions with consecutive ints starting at 1.\"\n", + " R = 0 # R is the region number\n", + " for y in range(1, len(grid) - 1):\n", + " for x in range(1, len(grid) - 1):\n", + " if grid[y][x] == val:\n", + " R += 1\n", + " flood(grid, x, y, val, R)\n", + " return R " + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1074" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flood_all(Grid(key))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 15](https://adventofcode.com/2017/day/15): Dueling Generators\n", + "\n", + "My personalized inputs for this puzzle are `516` and `190`; the other numbers are shared by all puzzle-solvers. I decided to make infinite generators of numbers, using `gen`:" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15.1 s, sys: 26.4 ms, total: 15.1 s\n", + "Wall time: 15.2 s\n" + ] + }, + { + "data": { + "text/plain": [ + "597" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@jit # This was the slowest solution; @jit helps a bit.\n", + "def gen(prev, factor, m=2147483647):\n", + " \"Generate a sequence of numbers according to the rules; stop at 0.\"\n", + " while prev:\n", + " prev = (prev * factor) % m\n", + " yield prev\n", + " \n", + "def judge(A, B, N=40*10**6, mask=2**16-1): \n", + " \"How many of the first N numbers from A and B agree in the masked bits (default last 16)?\"\n", + " return quantify(a & mask == b & mask\n", + " for (a, b, _) in zip(A, B, range(N)))\n", + "\n", + "def A(): return gen(516, 16807)\n", + "def B(): return gen(190, 48271)\n", + "\n", + "%time judge(A(), B())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice I also decided to use `@jit` (i.e. `numba.jit`) to speed things up, since this is the slowest-running day yet.\n", + "\n", + "**Part Two**\n", + "\n", + "A small change: only consider numbers that match the **criteria** of being divisible by 4 or 8, respectively;" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 9.39 s, sys: 8.62 ms, total: 9.4 s\n", + "Wall time: 9.4 s\n" + ] + }, + { + "data": { + "text/plain": [ + "303" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def criteria(m, iterable): \n", + " \"Elements of iterable that are divisible by m\"\n", + " return (n for n in iterable if n % m == 0)\n", + " \n", + "%time judge(criteria(4, A()), criteria(8, B()), 5*10**6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 16](https://adventofcode.com/2017/day/16): Permutation Promenade\n", + "\n", + "Let's read the input and check that it looks reasonable:" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('x5/15',\n", + " 's15',\n", + " 'x1/3',\n", + " 'pn/f',\n", + " 'x11/2',\n", + " 's13',\n", + " 'x6/3',\n", + " 'pe/a',\n", + " 'x14/12',\n", + " 's15')" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dance = Vector(Inputstr(16))\n", + "dance[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10000" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(dance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I'll define `perform` to perform the dance:" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'lbdiomkhgcjanefp'" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dancers = 'abcdefghijklmnop'\n", + "\n", + "def perform(dance, dancers=dancers):\n", + " D = deque(dancers)\n", + " def swap(i, j): D[i], D[j] = D[j], D[i]\n", + " for move in dance:\n", + " op, arg = move[0], move[1:]\n", + " if op == 's': D.rotate(int(arg))\n", + " elif op == 'x': swap(*Integers(arg))\n", + " elif op == 'p': swap(D.index(arg[0]), D.index(arg[2]))\n", + " return cat(D)\n", + " \n", + "perform(dance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the right answer.\n", + "\n", + "**Part Two**\n", + "\n", + "My first thought was to define a dance as a permutation: a list of numbers `[11, 1, 9, ...]` which says that the net effect of the dance is that the first dancer (`a`) ends up in position, the second (`b`) stays in position 1, and so on. Applying that permutation once is a lot faster than interpreting all 10,000 moves of the dance, and it is feasible to apply the permutation a billion times. I tried that (code not shown here), but that was a mistake: it took 15 minutes to run, and it got the wrong answer. The problem is that a dance is *not* just a permutation, because a dance can reference dancer *names*, not just positions.\n", + "\n", + "It would take about 10,000 times 20 minutes to perform a billion repetitions of the dance, so that's out. But even though the dance is not a permutation, it might repeat after a short period. Let's check:" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "abcdefghijklmnop is seen in iterations (0, 56)\n" + ] + } + ], + "source": [ + "seen = {dancers: 0}\n", + "d = dancers\n", + "for i in range(1, 1000):\n", + " d = perform(dance, d)\n", + " if d in seen:\n", + " print(d, 'is seen in iterations', (seen[d], i))\n", + " break" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So we get back to the start position after 56 repetitions of the dance. What happens after a billion repetitions?" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "48" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1000000000 % 56" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The end position after a billion repetitions is the same as after 48:" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ejkflpgnamhdcboi'" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def whole(N, dance, dancers=dancers):\n", + " \"Repeat `perform(dance)` N times.\"\n", + " for i in range(N):\n", + " dancers = perform(dance, dancers)\n", + " return dancers\n", + " \n", + "whole(48, dance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# [Day 17](https://adventofcode.com/2017/day/17): Spinlock\n", + "\n", + "This one looks pretty easy:" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "355" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step = 314\n", + "\n", + "def spinlock(step=step, N=2017):\n", + " \"Make N inserts into the buffer, skipping ahead by `step` each time.\"\n", + " buf = [0]\n", + " pos = 0\n", + " for i in ints(1, N):\n", + " pos = (pos + step) % i + 1\n", + " buf[pos:pos] = [i]\n", + " return buf\n", + " \n", + "buf = spinlock()\n", + "\n", + "buf[buf.index(2017)+1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the right answer.\n", + "\n", + "**Part Two**\n", + "\n", + "But Part Two is not so easy, if we care about the run time. Insertion into a `list` has to move all the elements after the insertion down, so insertion is O(N) and `spinlock` is O(N2). That's no problem when N = 2017, but when N is 50 million? We're gonna need a bigger boat, where by \"boat\" I mean algorithm or data structure. My first thought is a (circular) linked list, because insertion is O(1). I can implement the three key methods: `skip` to move ahead, `insert` to add a new node after the current one, and `find` to find a piece of data (with a linear search):" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Node:\n", + " \"A Node in a singly-linked list\"\n", + " \n", + " __slots__ = ('data', 'next') # Declaring slots makes it more efficient\n", + " \n", + " def __init__(self, data, next): self.data, self.next = data, next\n", + " \n", + " def skip(self, n):\n", + " \"Skip ahead n nodes, and return that node.\"\n", + " node = self\n", + " for i in range(n):\n", + " node = node.next\n", + " return node\n", + " \n", + " def insert(self, value):\n", + " \"Insert a new node with the given value after this node.\"\n", + " self.next = Node(value, self.next)\n", + " return self.next\n", + " \n", + " def find(self, value):\n", + " \"Find the node with the given data value.\"\n", + " node = self\n", + " while node.data != value:\n", + " node = node.next\n", + " return node" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can rewrite `spinlock` to use this class:" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def spinlock2(step=step, N=2017):\n", + " node = Node(0, None)\n", + " node.next = node # Make node be a circular linked list\n", + " for i in ints(1, N):\n", + " node = node.skip(step).insert(i)\n", + " return node" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's replicate the Part One results:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "355" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spinlock2().find(2017).next.data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Good news! We get the same answer. But how fast/slow is it?" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.35 s, sys: 5.54 ms, total: 1.35 s\n", + "Wall time: 1.35 s\n" + ] + }, + { + "data": { + "text/plain": [ + "<__main__.Node at 0x110c44be0>" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time spinlock2(N=100000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Bad news! It takes over a second to do just 100,000 insertions, which means about 10 minutes for 50 million insertions. I did in fact try\n", + "\n", + " spinlock2(N=50000000).find(0).next.data\n", + " \n", + "and it eventually gave the right answer, but while it was running I had plenty of time to think.\n", + "I realized that, if we go back to the original `spinlock` version, the value `0` will always be in `buf[0]`, and the value we are looking for will always be in `buf[1]`. So I can create a version of `spinlock` that only keeps track of `buf[0:2]`. That should run in a few seconds, not minutes:" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5.47 s, sys: 6.62 ms, total: 5.48 s\n", + "Wall time: 5.48 s\n" + ] + }, + { + "data": { + "text/plain": [ + "6154117" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def spinlock3(step=step, N=2017):\n", + " \"Make N inserts into a simulated buffer, but ignore all except buf[0:2].\"\n", + " pos = 0\n", + " buf = [0, 0]\n", + " for i in ints(1, N):\n", + " pos = (pos + step) % i + 1\n", + " if pos <= 1:\n", + " buf[pos] = i\n", + " return buf\n", + "\n", + "%time spinlock3(N=50000000)[1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The moral of the story is *keep your eyes on the prize*. I got distracted because I asked the wrong question. I asked myself \"how can I make my solution in `spinlock` faster?\" and answered myself \"insertion is O(N2) and it should be O(N).\" I knew how to do that, with a linked list, but that was the right answer to the wrong question. I should have asked myself \"how do I solve Part Two quickly,\" concentrating on solving the actual problem. Once I did that, I realized I didn't need all those insertions: not doing them at all is a better idea than doing them faster." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 18](https://adventofcode.com/2017/day/17): Duet\n", + "\n", + "First, read the input, and take a peak at it:" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(('set', 'i', 31),\n", + " ('set', 'a', 1),\n", + " ('mul', 'p', 17),\n", + " ('jgz', 'p', 'p'),\n", + " ('mul', 'a', 2),\n", + " ('add', 'i', -1),\n", + " ('jgz', 'i', -2),\n", + " ('add', 'a', -1),\n", + " ('set', 'i', 127),\n", + " ('set', 'p', 826))" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program18 = Array(Input(18))\n", + "program18[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now write an interpreter for the assembly language:" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "7071" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run18(program):\n", + " \"Interpret the assembly language program; return recovered `snd`.\"\n", + " regs = defaultdict(int)\n", + " pc = snd = 0\n", + " while True:\n", + " instr = program[pc]\n", + " pc += 1\n", + " op, x, y = instr[0], instr[1], instr[-1]\n", + " vy = value(regs, y)\n", + " if op == 'snd': snd = regs[x]\n", + " elif op == 'set': regs[x] = vy\n", + " elif op == 'add': regs[x] += vy\n", + " elif op == 'mul': regs[x] *= vy\n", + " elif op == 'mod': regs[x] %= vy\n", + " elif op == 'jgz' and regs[x] > 0: pc += vy - 1\n", + " elif op == 'rcv' and regs[x] != 0: return snd\n", + " \n", + "def value(regs, y): return (y if isinstance(y, int) else regs[y])\n", + "\n", + "run18(program18)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy. (One tricky bit: the `pc` is incremented by 1 every time through the loop, regardless of the instruction. Therefore, the `'jgz'` jump instruction increments by \"`vy - 1`\" so that the net increment is \"`vy`\".)\n", + "\n", + "**Part Two**\n", + "\n", + "In Part Two we have to run two copies of the program, and send messages between them. I'll break up the loop in `run18` into\n", + "two functions. First, `run18_2`, creates (in `ps`) two structures to hold the state variables necessary to run a program:\n", + "- `id`: The id number (0 or 1) of this copy of the program.\n", + "- `pc`: The program counter.\n", + "- `sends`: A count of the number of `snd` instructions executed.\n", + "- `regs`: A dict of the program registers (`a` to `z`).\n", + "- `status`: A program has a status which can be:\n", + " * `'run'` when it is ready to execute an instruction, \n", + " * `'wait'` when it is waiting for a value to arrive in its input queue, or \n", + " * `'end'` when the `pc` has run off the end of the program and it has terminated.\n", + "\n", + "`run18_2` repeatedly calls the second function, `step18(program, p)` to execute one instruction of `program` with the state variables in `p`. I choose randomly which of the two programs to step on each iteration. The function exits when neither copy of the program can run, according to their status. " + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run18_2(program):\n", + " \"Run two copies of program, with different state variables. Return final states.\"\n", + " Qs = [deque(), deque()]\n", + " ps = [Struct(id=id, pc=0, sends=0, regs=defaultdict(int, p=id), status='run')\n", + " for id in (0, 1)]\n", + " while any(p.status == 'run' for p in ps):\n", + " step18(program, Qs, random.choice(ps))\n", + " return ps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`step18` has most of the guts of thee previous `run18` function, but with a few changes:\n", + "- State variables are accessed indirectly: `p.pc` instead of just `pc`.\n", + "- If the `pc` is out of bounds, the program terminates; the status is set to `'end'`.\n", + "- The `snd` instruction sends a value to the other program's queue.\n", + "- The `rcv` instruction pops a value off the queue if there is one, otherwise the status is set to `'wait'`.\n", + "- The \"`X`\" in \"`jgz X Y`\" might be an integer, not a register name, so use `vx = value(p.regs, x)`. I was stuck for a *long* time before I realized this. Finally I tried the strategy of *look carefully at the input*. I noticed the instruction `\"jgz 1 3\"`, and it was a simple change to make the program work." + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8001" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def step18(program, Qs, p):\n", + " \"Execute one instruction in program, using state variables in p.\"\n", + " if p.pc < 0 or p.pc > len(program):\n", + " p.status = 'end'\n", + " else:\n", + " instr = program[p.pc]\n", + " op, x, y = instr[0], instr[1], instr[-1]\n", + " vx, vy = value(p.regs, x), value(p.regs, y)\n", + " if op == 'snd': Qs[1-p.id].append(vy); p.sends += 1\n", + " elif op == 'set': p.regs[x] = vy\n", + " elif op == 'add': p.regs[x] += vy\n", + " elif op == 'mul': p.regs[x] *= vy\n", + " elif op == 'mod': p.regs[x] %= vy\n", + " elif op == 'jgz' and vx > 0: p.pc += vy - 1\n", + " elif op == 'rcv': \n", + " if not Qs[p.id]:\n", + " p.status = 'wait'\n", + " return # don't update pc; try again next time\n", + " else:\n", + " p.regs[x] = Qs[p.id].popleft()\n", + " p.status = 'run'\n", + " p.pc += 1\n", + " \n", + "run18_2(program18)[1].sends" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 19](https://adventofcode.com/2017/day/19): A Series of Tubes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At first I was confused; I thought this was a maze-following problem where I had to make a choice of directions at every turn. Actually, the direction is always determined: keep going in the current direction as long as possible, but when we hit a `'+'` character, find the new direction to go in (there will only be one possibility). Leave breadcrumbs (the `'.'` character) so that we don't back up along a previously-followed path. As in Day 14, the grid is surrounded by a border of space characters so that we don't have to worry about `(x, y)` going off the edge." + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "diagram = Inputstr(19)\n", + "\n", + "def follow_tubes(diagram):\n", + " \"Follow [-+|] lines, yielding characters along the path.\"\n", + " grid = border(' ', diagram.splitlines())\n", + " x, y = grid[1].index('|'), 1\n", + " dx, dy = 0, 1\n", + " while grid[y][x] != ' ':\n", + " yield grid[y][x]\n", + " if grid[y][x] == '+':\n", + " dx, dy = new_direction(grid, x, y)\n", + " grid[y][x] = '.' # Leave a breadcrumb\n", + " x += dx; y += dy\n", + " \n", + "def new_direction(grid, x, y):\n", + " \"Find a direction that continues the path.\"\n", + " for (dx, dy) in (UP, DOWN, RIGHT, LEFT):\n", + " if grid[y+dy][x+dx] not in (' ', '.'):\n", + " return dx, dy" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'VEBTPXCHLI'" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(filter(str.isalpha, follow_tubes(diagram)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the right answer.\n", + "\n", + "**Part Two**\n", + "\n", + "This is a surprisingly easy Part Two; I already generated the characters in the path; all I have to do is count them: " + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "18702" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "length(follow_tubes(diagram))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 20](https://adventofcode.com/2017/day/20): Particle Swarm\n", + "\n", + "I'll create structures for particles, each will have fields for particle's number (`id`), position (`p`), velocity(`v`), and acceleration (`a`):" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Struct(a=(-7, 8, -10), id=0, p=(1199, -2918, 1457), v=(-13, 115, -8)),\n", + " Struct(a=(-6, -5, 6), id=1, p=(2551, 2418, -1471), v=(-106, -108, 39)),\n", + " Struct(a=(-6, 2, -9), id=2, p=(-73, 1626, 1321), v=(58, -118, -8)),\n", + " Struct(a=(3, 3, 11), id=3, p=(-3297, -894, -551), v=(183, 31, -61)),\n", + " Struct(a=(7, -12, -1), id=4, p=(-1425, 4298, 617), v=(32, -166, -32))]" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def particles(lines=list(Input(20))):\n", + " \"Parse the list of particles.\"\n", + " return [Particle(id, *grouper(Integers(line), 3)) \n", + " for id, line in enumerate(lines)]\n", + "\n", + "def Particle(id, p, v, a): return Struct(id=id, p=p, v=v, a=a) \n", + "\n", + "particles()[:5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I'm not quite sure how to determine what \"in the long run\" means, so I'll just interpret it as meaning \"after 1000 time steps.\" On each step we update velocity and position of each particle. At the end, we determine the id number of the particle closest to the origin. Note that `evolve` generates an infinite sequence of particles, and we use `nth` to pick out the 1000th generation." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "243" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def evolve(particles):\n", + " \"Continually update particles, yielding them after each time step.\"\n", + " while True:\n", + " yield particles\n", + " for p in particles:\n", + " p.v = add(p.v, p.a)\n", + " p.p = add(p.p, p.v)\n", + " \n", + "def add(A, B): \n", + " \"Add two n-dimensional vectors.\"\n", + " return mapt(sum, zip(A, B))\n", + "\n", + "def closest(particles):\n", + " \"Find the particle closest to origin.\"\n", + " return min(particles, key=lambda p: sum(map(abs, p.p)))\n", + "\n", + "# Answer: the id of the particle closest to origin in the 1000th generation of `evolve`\n", + "closest(nth(evolve(particles()), 1000)).id" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "I can still use `evolve` unchanged, and I will add the function `remove_collisions` to eliminate particles that are in the same position as another particle. I use `map` to apply this to every generation. Note that `remove_collisions` both mutates the argument, `particles`, and also returns it. " + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "648" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def remove_collisions(particles):\n", + " \"Mutate (and return) particles, keep only ones that have a unique position.\"\n", + " poscount = Counter(p.p for p in particles)\n", + " particles[:] = [p for p in particles if poscount[p.p] == 1]\n", + " return particles\n", + " \n", + "# Answer: remove collisions from every generation of evolving particles, \n", + "# select the 1000th generation, and say how many particles are in that generation.\n", + "len(nth(map(remove_collisions, evolve(particles())), 1000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 21](https://adventofcode.com/2017/day/21): Fractal Art\n", + "\n", + "First I'll create a `dict` of enhancement rules. I'll translate `'#'` and `'.'` pixels to 1 and 0, and represent a grid as a tuple of tuples (e.g. `((0, 0), (1, 1))`), so that it can be a `dict` key. I have to deal with rotations and flips; I could do that at lookup time, but it will be faster to do it at rule creation time:" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Enhancements(lines):\n", + " \"Create a dict of {square: enhanced_square}\"\n", + " enhancements = {}\n", + " for line in lines:\n", + " lhs, rhs = map(Key, line.split('=>'))\n", + " for r in range(4):\n", + " enhancements[lhs] = enhancements[flip(lhs)] = rhs\n", + " lhs = rotate(lhs)\n", + " return enhancements\n", + " \n", + "def Key(line): \n", + " \"Key('../##') => ((0, 0), (1, 1))\"\n", + " bits = {'#': 1, '.': 0}\n", + " return tuple(tuple(bits[p] for p in row.strip())\n", + " for row in line.split('/'))\n", + " \n", + "def rotate(key): return tuple(zip(*reversed(key)))\n", + "\n", + "def flip(L): return tuple(tuple(reversed(row)) for row in L)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's test this on just the enhancement rules with 2x2 squares; with rotations and flips there should be 16 entries:" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{((0, 0), (0, 0)): ((0, 0, 0), (0, 1, 0), (0, 1, 0)),\n", + " ((0, 0), (0, 1)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((0, 0), (1, 0)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((0, 0), (1, 1)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((0, 1), (0, 0)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((0, 1), (0, 1)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((0, 1), (1, 0)): ((1, 1, 0), (1, 1, 0), (0, 0, 0)),\n", + " ((0, 1), (1, 1)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 0), (0, 0)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((1, 0), (0, 1)): ((1, 1, 0), (1, 1, 0), (0, 0, 0)),\n", + " ((1, 0), (1, 0)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((1, 0), (1, 1)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 1), (0, 0)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((1, 1), (0, 1)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 1), (1, 0)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 1), (1, 1)): ((0, 1, 1), (1, 0, 0), (1, 1, 0))}" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Enhancements('''\n", + "../.. => .../.#./.#.\n", + "#./.. => .../#../#..\n", + "##/.. => #.#/.#./.#.\n", + ".#/#. => ##./##./...\n", + "##/#. => .##/###/#..\n", + "##/## => .##/#../##.\n", + "'''.strip().splitlines())" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "16" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looks good; let's create my complete table. There should be 24 + 29 entries:" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enhancements = Enhancements(Input(21))\n", + "\n", + "assert len(enhancements) == 2 ** 4 + 2 ** 9" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now on each iteration we `enhance` the grid by first `expand`-ing it (looking up each `slice` in the `enhancements` rules) and then `stitch` the pieces together:" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def enhance(grid): \n", + " \"Expand small pieces into bigger ones and stitch them together.\"\n", + " return stitch(expand(grid))\n", + "\n", + "def expand(grid):\n", + " \"Slice the grid into d x d pieces and enhance each piece.\"\n", + " N = len(grid[0])\n", + " d = (2 if N % 2 == 0 else 3 if N % 3 == 0 else error())\n", + " return [[enhancements[slice(grid, r, c, d)]\n", + " for c in range(0, N, d)]\n", + " for r in range(0, N, d)]\n", + "\n", + "def stitch(pieces): \n", + " \"Stitch the pieces back into one big grid.\"\n", + " N = sum(map(len, pieces[0]))\n", + " return tuple(tuple(get(pieces, r, c) \n", + " for c in range(N))\n", + " for r in range(N))\n", + "\n", + "def get(pieces, r, c):\n", + " \"The pixel at location (r, c), from a matrix of d x d pieces.\"\n", + " d = len(pieces[0][0])\n", + " row = pieces[r // d]\n", + " cell = row[c // d]\n", + " return cell[r % d][c % d]\n", + "\n", + "def slice(grid, r, c, d):\n", + " \"The d x d slice of grid starting at position (r, c)\"\n", + " return tuple(row[c:c+d] for row in grid[r:r+d])" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 1, 0), (0, 0, 1), (1, 1, 1))" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid = Key('.#./..#/###')\n", + "grid" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[((1, 0, 1, 0), (0, 0, 1, 0), (0, 1, 0, 1), (0, 1, 0, 0))]]" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expand(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((1, 0, 1, 0), (0, 0, 1, 0), (0, 1, 0, 1), (0, 1, 0, 0))" + ] + }, + "execution_count": 96, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stitch(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[((0, 0, 0), (1, 0, 0), (1, 0, 0)), ((1, 0, 1), (0, 1, 0), (0, 1, 0))],\n", + " [((1, 0, 1), (0, 1, 0), (0, 1, 0)), ((0, 0, 0), (1, 0, 0), (1, 0, 0))]]" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expand(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 0, 0, 1, 0, 1),\n", + " (1, 0, 0, 0, 1, 0),\n", + " (1, 0, 0, 0, 1, 0),\n", + " (1, 0, 1, 0, 0, 0),\n", + " (0, 1, 0, 1, 0, 0),\n", + " (0, 1, 0, 1, 0, 0))" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stitch(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(flatten(_))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks right; Let's try to solve the puzzle:" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "147" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(flatten(repeat(5, enhance, grid)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "It looked like I didn't need to change any code to do Part Two, just change the `5` to an `18`. I ran it, and got an answer in a few seconds—but the answer was wrong. I went back and carefully looked over my code, and realized there was a place in `expand` where I had swapped the order of `r` and `c` (the code there is fixed now). Apparently there is some symmetry over the first 5 enhancements that yields the correct answer either way, but that breaks down over 18 enhancements. (Also: if I had guessed that `sum(flatten(repeat(n, enhance, grid)))` would be used in both parts, I probably would have created a function for it. But I was guessing that Part Two would involve `enhance`, but not necessarily in the same way as Part One.)" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1936582" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(flatten(repeat(18, enhance, grid)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Note on Reuse\n", + "\n", + "One interesting question about these two-part problems: how does the code in Part Two use the code in Part One? \n", + "Here are my answers:\n", + "\n", + "* **All new**: All the code for Part Two (except possibly reading and parsing the input) is brand new: \n", + "
Days 1, 2, 4, 7\n", + "\n", + "* **Reuse as is**: The major function defined in Part One is called again in Part Two (and some new code\n", + "is also written):\n", + "
Days 3 (`spiral`), 6 (`spread`, but `realloc2` is copy-paste-edit), 9, 12, 14 (`bits`), \n", + "15 (`A, B, gen, judge`), 16 (`perform`), 19 (`follow_tubes`), 20 (`evolve, particles`), 21 (`expands`, `gridsum`)\n", + "\n", + "* **Generalize**: A major function from Part One is generalized in Part Two (e.g. by adding an optional parameter):\n", + "
Days 13 (`caught`)\n", + "\n", + "* **Copy-paste-edit**: The major function from Part One is copied and edited for Part Two:\n", + "
Days 5 (`run2`), 8 (`run82`), 10 (`knothash2`), 11 (`follow2`), 17 (`spinlock2`), 18 (`step18`)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Wrapping Up: Verification and Timing\n", + "\n", + "Here is a little test harness to verify that I still get the right answers (even if I refactor some of the code):" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 54.6 s, sys: 156 ms, total: 54.7 s\n", + "Wall time: 54.9 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "def day(d, compute1, answer1, compute2, answer2):\n", + " \"Assert that we get the right answers for this day.\"\n", + " assert compute1 == answer1\n", + " assert compute2 == answer2\n", + "\n", + "day(1, sum(digits[i] for i in range(N) if digits[i] == digits[i - 1]), 1158,\n", + " sum(digits[i] for i in range(N) if digits[i] == digits[i - N // 2]), 1132)\n", + "day(2, sum(abs(max(row) - min(row)) for row in rows2), 46402, \n", + " sum(map(evendiv, rows2)), 265)\n", + "day(3, cityblock_distance(nth(spiral(), M - 1)), 475, \n", + " first(x for x in spiralsums() if x > M), 279138)\n", + "day(4, quantify(Input(4), is_valid), 337, \n", + " quantify(Input(4), is_valid2), 231)\n", + "day(5, run(program), 364539, \n", + " run2(program), 27477714)\n", + "day(6, realloc(banks), 12841, \n", + " realloc2(banks), 8038)\n", + "day(7, first(programs - set(flatten(above.values()))), 'wiapj', \n", + " correct(wrongest(programs)), 1072)\n", + "day(8, max(run8(program8).values()), 6828, \n", + " run8_2(program8), 7234)\n", + "day(9, total_score(text2), 9662, \n", + " len(text1) - len(text3), 4903)\n", + "day(10, knothash(stream), 4480, \n", + " knothash2(stream2), 'c500ffe015c83b60fad2e4b7d59dabc4')\n", + "day(11, follow(path), 705, \n", + " follow2(path), 1469)\n", + "day(12, len(G[0]), 115, \n", + " len({Set(G[i]) for i in G}), 221)\n", + "day(13, trip_severity(scanners), 1504, \n", + " safe_delay(scanners), 3823370)\n", + "day(14, sum(bits(key, i).count('1') for i in range(128)), 8316, \n", + " flood_all(Grid(key)), 1074)\n", + "day(15, judge(A(), B()), 597, \n", + " judge(criteria(4, A()), criteria(8, B()), 5*10**6), 303)\n", + "day(16, perform(dance), 'lbdiomkhgcjanefp', \n", + " whole(48, dance), 'ejkflpgnamhdcboi')\n", + "day(17, spinlock2().find(2017).next.data, 355,\n", + " spinlock3(N=50*10**6)[1], 6154117)\n", + "day(18, run18(program18), 7071, \n", + " run18_2(program18)[1].sends, 8001)\n", + "day(19, cat(filter(str.isalpha, follow_tubes(diagram))), 'VEBTPXCHLI', \n", + " quantify(follow_tubes(diagram)), 18702)\n", + "day(20, closest(nth(evolve(particles()), 1000)).id, 243,\n", + " len(nth(map(remove_collisions, evolve(particles())), 1000)), 648)\n", + "day(21, sum(flatten(repeat(5, enhance, grid))), 147,\n", + " sum(flatten(repeat(18, enhance, grid))), 1936582)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here is a plot of the time taken to program solutions to both parts of each puzzle each day, for me, the first person to finish, and the hundredth person. On days when I started late, the times are my estimates, not official times (these include days 1, 3, 8, 13, 14, 17, 18, 21)." + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_times(times):\n", + " plt.style.use('seaborn-whitegrid')\n", + " X = ints(1, len(times[0]) - 2)\n", + " for (label, mark, *Y) in times:\n", + " plt.plot(X, Y, mark, label=label)\n", + " plt.xlabel('Day Number'); plt.ylabel('Minutes to Solve Both Parts')\n", + " plt.legend(loc='upper left')\n", + "\n", + "x = None\n", + "plot_times([\n", + " ('Me', 'd:', 4, 6, 20, 5, 12, 30, 33, 10, 21, 40, 13, 12, 30, 41, 13, 64, 54, 74, 50, 18, 40),\n", + " ('100th', 'v:', 6, 6, 23, 4, 5, 9, 25, 8, 12, 25, 12, 9, 22, 25, 10, 27, 16, 41, 18, 21, 45),\n", + " ('1st', '^:', 1, 1, 4, 1, 2, 3, 10, 3, 4, 6, 3, 2, 6, 5, 2, 5, 5, 10, 5, 7, 10)])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Advent 2017.ipynb b/pytudes/ipynb/Advent 2017.ipynb new file mode 100644 index 0000000..1b5e6de --- /dev/null +++ b/pytudes/ipynb/Advent 2017.ipynb @@ -0,0 +1,3667 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# December 2017: Advent of Code Solutions\n", + "\n", + "Peter Norvig\n", + "\n", + "I'm doing the [Advent of Code](https://adventofcode.com) puzzles, just like [last year](https://github.com/norvig/pytudes/blob/master/ipynb/Advent%20of%20Code.ipynb). This time, my terms of engagement are:\n", + "\n", + "* I won't write a summary of each day's puzzle description. Follow the links in the section headers (e.g. **[Day 1](https://adventofcode.com/2017/day/1)**) to understand what each puzzle is asking. \n", + "* What you see is mostly the algorithm I first came up with first, although sometimes I go back and refactor if I think the original is unclear.\n", + "* I do clean up the code a bit even after I solve the puzzle: adding docstrings, changing variable names, changing input boxes to `assert` statements.\n", + "* I will describe my errors that slowed me down.\n", + "* Some days I start on time and try to code very quickly (although I know that people at the top of the leader board will be much faster than me); other days I end up starting late and don't worry about going quickly.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "# Day 0: Imports and Utility Functions\n", + "\n", + "I might need these:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Python 3.x Utility Functions\n", + "\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import re\n", + "import numpy as np\n", + "import math\n", + "import random\n", + "\n", + "from collections import Counter, defaultdict, namedtuple, deque, abc, OrderedDict\n", + "from functools import lru_cache\n", + "from statistics import mean, median, mode, stdev, variance\n", + "from itertools import (permutations, combinations, chain, cycle, product, islice, \n", + " takewhile, zip_longest, count as count_from)\n", + "from heapq import heappop, heappush\n", + "from numba import jit\n", + "\n", + "identity = lambda x: x\n", + "letters = 'abcdefghijklmnopqrstuvwxyz'\n", + "\n", + "cache = lru_cache(None)\n", + "\n", + "cat = ''.join\n", + "\n", + "Ø = frozenset() # Empty set\n", + "inf = float('inf')\n", + "BIG = 10 ** 999\n", + "\n", + "################ Functions for Input, Parsing\n", + "\n", + "def Input(day, year=2017):\n", + " \"Open this day's input file.\"\n", + " return open('data/advent{}/input{}.txt'.format(year, day))\n", + "\n", + "def Inputstr(day, year=2017): \n", + " \"The contents of this day's input file as a str.\"\n", + " return Input(day, year).read().rstrip('\\n')\n", + " \n", + "def Array(lines):\n", + " \"Parse an iterable of str lines into a 2-D array. If `lines` is a str, splitlines.\"\n", + " if isinstance(lines, str): lines = lines.splitlines()\n", + " return mapt(Vector, lines)\n", + "\n", + "def Vector(line):\n", + " \"Parse a str into a tuple of atoms (numbers or str tokens).\"\n", + " return mapt(Atom, line.replace(',', ' ').split())\n", + "\n", + "def Integers(text): \n", + " \"Return a tuple of all integers in a string.\"\n", + " return mapt(int, re.findall(r'-?\\b\\d+\\b', text))\n", + "\n", + "def Atom(token):\n", + " \"Parse a str token into a number, or leave it as a str.\"\n", + " try:\n", + " return int(token)\n", + " except ValueError:\n", + " try:\n", + " return float(token)\n", + " except ValueError:\n", + " return token\n", + " \n", + "def error(err=RuntimeError, *args): raise err(*args)\n", + "\n", + "################ Functions on Iterables\n", + "\n", + "def first(iterable, default=None): \n", + " \"The first item in an iterable, or default if it is empty.\"\n", + " return next(iter(iterable), default)\n", + "\n", + "def first_true(iterable, pred=None, default=None):\n", + " \"\"\"Returns the first true value in the iterable.\n", + " If no true value is found, returns *default*\n", + " If *pred* is not None, returns the first item\n", + " for which pred(item) is true.\"\"\"\n", + " # first_true([a,b,c], default=x) --> a or b or c or x\n", + " # first_true([a,b], fn, x) --> a if fn(a) else b if fn(b) else x\n", + " return next(filter(pred, iterable), default)\n", + "\n", + "def nth(iterable, n, default=None):\n", + " \"Returns the nth item of iterable, or a default value\"\n", + " return next(islice(iterable, n, None), default)\n", + "\n", + "def upto(iterable, maxval):\n", + " \"From a monotonically increasing iterable, generate all the values <= maxval.\"\n", + " # Why <= maxval rather than < maxval? In part because that's how Ruby's upto does it.\n", + " return takewhile(lambda x: x <= maxval, iterable)\n", + "\n", + "def groupby(iterable, key=identity):\n", + " \"Return a dict of {key(item): [items...]} grouping all items in iterable by keys.\"\n", + " groups = defaultdict(list)\n", + " for item in iterable:\n", + " groups[key(item)].append(item)\n", + " return groups\n", + "\n", + "def grouper(iterable, n, fillvalue=None):\n", + " \"\"\"Collect data into fixed-length chunks:\n", + " grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx\"\"\"\n", + " args = [iter(iterable)] * n\n", + " return zip_longest(*args, fillvalue=fillvalue)\n", + "\n", + "def overlapping(iterable, n):\n", + " \"\"\"Generate all (overlapping) n-element subsequences of iterable.\n", + " overlapping('ABCDEFG', 3) --> ABC BCD CDE DEF EFG\"\"\"\n", + " if isinstance(iterable, abc.Sequence):\n", + " yield from (iterable[i:i+n] for i in range(len(iterable) + 1 - n))\n", + " else:\n", + " result = deque(maxlen=n)\n", + " for x in iterable:\n", + " result.append(x)\n", + " if len(result) == n:\n", + " yield tuple(result)\n", + " \n", + "def pairwise(iterable):\n", + " \"s -> (s0,s1), (s1,s2), (s2, s3), ...\"\n", + " return overlapping(iterable, 2)\n", + "\n", + "def sequence(iterable, type=tuple):\n", + " \"Coerce iterable to sequence: leave alone if already a sequence, else make it `type`.\"\n", + " return iterable if isinstance(iterable, abc.Sequence) else type(iterable)\n", + "\n", + "def join(iterable, sep=''):\n", + " \"Join the items in iterable, converting each to a string first.\"\n", + " return sep.join(map(str, iterable))\n", + " \n", + "def powerset(iterable):\n", + " \"Yield all subsets of items.\"\n", + " items = list(iterable)\n", + " for r in range(len(items)+1):\n", + " for c in combinations(items, r):\n", + " yield c\n", + " \n", + "def quantify(ite1rable, pred=bool):\n", + " \"Count how many times the predicate is true.\"\n", + " return sum(map(pred, iterable))\n", + "\n", + "def length(iterable):\n", + " \"Same as len(list(iterable)), but without consuming memory.\"\n", + " return sum(1 for _ in iterable)\n", + "\n", + "def shuffled(iterable):\n", + " \"Create a new list out of iterable, and shuffle it.\"\n", + " new = list(iterable)\n", + " random.shuffle(new)\n", + " return new\n", + " \n", + "flatten = chain.from_iterable\n", + "\n", + "def repeat(n, fn, arg):\n", + " \"Repeat arg=fn(arg) n times.\"\n", + " for i in range(n):\n", + " arg = fn(arg)\n", + " return arg\n", + "\n", + "################ Making immutable objects\n", + " \n", + "class Set(frozenset):\n", + " \"A frozenset, but with a prettier printer.\"\n", + " def __repr__(self): return '{' + join(sorted(self), ', ') + '}'\n", + " \n", + "def canon(items, typ=None):\n", + " \"Canonicalize these order-independent items into a hashable canonical form.\"\n", + " typ = typ or (cat if isinstance(items, str) else tuple)\n", + " return typ(sorted(items))\n", + "\n", + "def mapt(fn, *args): \n", + " \"Do a map, and make the results into a tuple.\"\n", + " return tuple(map(fn, *args))\n", + " \n", + "################ Math Functions\n", + " \n", + "def transpose(matrix): return tuple(zip(*matrix))\n", + "\n", + "def isqrt(n):\n", + " \"Integer square root (rounds down).\"\n", + " return int(n ** 0.5)\n", + "\n", + "def ints(start, end):\n", + " \"The integers from start to end, inclusive: range(start, end+1)\"\n", + " return range(start, end + 1)\n", + "\n", + "def floats(start, end, step=1.0):\n", + " \"Yield floats from start to end (inclusive), by increments of step.\"\n", + " m = (1.0 if step >= 0 else -1.0)\n", + " while start * m <= end * m:\n", + " yield start\n", + " start += step\n", + " \n", + "def multiply(numbers):\n", + " \"Multiply all the numbers together.\"\n", + " result = 1\n", + " for n in numbers:\n", + " result *= n\n", + " return result\n", + "\n", + "import operator as op\n", + "\n", + "operations = {'>': op.gt, '>=': op.ge, '==': op.eq,\n", + " '<': op.lt, '<=': op.le, '!=': op.ne,\n", + " '+': op.add, '-': op.sub, '*': op.mul, \n", + " '/': op.truediv, '**': op.pow}\n", + "\n", + "################ 2-D points implemented using (x, y) tuples\n", + "\n", + "def X(point): x, y = point; return x\n", + "def Y(point): x, y = point; return y\n", + "\n", + "origin = (0, 0)\n", + "UP, DOWN, LEFT, RIGHT = (0, 1), (0, -1), (-1, 0), (1, 0)\n", + "\n", + "def neighbors4(point): \n", + " \"The four neighboring squares.\"\n", + " x, y = point\n", + " return ( (x, y-1),\n", + " (x-1, y), (x+1, y), \n", + " (x, y+1))\n", + "\n", + "def neighbors8(point): \n", + " \"The eight neighboring squares.\"\n", + " x, y = point \n", + " return ((x-1, y-1), (x, y-1), (x+1, y-1),\n", + " (x-1, y), (x+1, y),\n", + " (x-1, y+1), (x, y+1), (x+1, y+1))\n", + "\n", + "def cityblock_distance(P, Q=origin): \n", + " \"Manhatten distance between two points.\"\n", + " return sum(abs(p - q) for p, q in zip(P, Q))\n", + "\n", + "def distance(P, Q=origin): \n", + " \"Hypotenuse distance between two points.\"\n", + " return sum((p - q) ** 2 for p, q in zip(P, Q)) ** 0.5\n", + "\n", + "################ Debugging \n", + "\n", + "def trace1(f):\n", + " \"Print a trace of the input and output of a function on one line.\"\n", + " def traced_f(*args):\n", + " result = f(*args)\n", + " print('{}({}) = {}'.format(f.__name__, ', '.join(map(str, args)), result))\n", + " return result\n", + " return traced_f\n", + "\n", + "def grep(pattern, iterable):\n", + " \"Print lines from iterable that match pattern.\"\n", + " for line in iterable:\n", + " if re.search(pattern, line):\n", + " print(line)\n", + " \n", + "class Struct:\n", + " \"A structure that can have any fields defined.\"\n", + " def __init__(self, **entries): self.__dict__.update(entries)\n", + " def __repr__(self): \n", + " fields = ['{}={}'.format(f, self.__dict__[f]) \n", + " for f in sorted(self.__dict__)]\n", + " return 'Struct({})'.format(', '.join(fields))\n", + "\n", + "################ A* and Breadth-First Search (tracking states, not actions)\n", + "\n", + "def always(value): return (lambda *args: value)\n", + "\n", + "def Astar(start, moves_func, h_func, cost_func=always(1)):\n", + " \"Find a shortest sequence of states from start to a goal state (where h_func(s) == 0).\"\n", + " frontier = [(h_func(start), start)] # A priority queue, ordered by path length, f = g + h\n", + " previous = {start: None} # start state has no previous state; other states will\n", + " path_cost = {start: 0} # The cost of the best path to a state.\n", + " Path = lambda s: ([] if (s is None) else Path(previous[s]) + [s])\n", + " while frontier:\n", + " (f, s) = heappop(frontier)\n", + " if h_func(s) == 0:\n", + " return Path(s)\n", + " for s2 in moves_func(s):\n", + " g = path_cost[s] + cost_func(s, s2)\n", + " if s2 not in path_cost or g < path_cost[s2]:\n", + " heappush(frontier, (g + h_func(s2), s2))\n", + " path_cost[s2] = g\n", + " previous[s2] = s\n", + "\n", + "def bfs(start, moves_func, goals):\n", + " \"Breadth-first search\"\n", + " goal_func = (goals if callable(goals) else lambda s: s in goals)\n", + " return Astar(start, moves_func, lambda s: (0 if goal_func(s) else 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'pass'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " # Functions for Input, Parsing\n", + " assert Array('''1 2 3\n", + " 4 5 6''') == ((1, 2, 3), \n", + " (4, 5, 6))\n", + " assert Vector('testing 1 2 3.') == ('testing', 1, 2, 3.0)\n", + " \n", + " # Functions on Iterables\n", + " assert first('abc') == first(['a', 'b', 'c']) == 'a'\n", + " assert first_true([0, None, False, {}, 42, 43]) == 42\n", + " assert nth('abc', 1) == nth(iter('abc'), 1) == 'b'\n", + " assert cat(upto('abcdef', 'd')) == 'abcd'\n", + " assert cat(['do', 'g']) == 'dog'\n", + " assert groupby([-3, -2, -1, 1, 2], abs) == {1: [-1, 1], 2: [-2, 2], 3: [-3]}\n", + " assert list(grouper(range(8), 3)) == [(0, 1, 2), (3, 4, 5), (6, 7, None)]\n", + " assert list(overlapping((0, 1, 2, 3, 4), 3)) == [(0, 1, 2), (1, 2, 3), (2, 3, 4)]\n", + " assert list(overlapping('abcdefg', 4)) == ['abcd', 'bcde', 'cdef', 'defg'] \n", + " assert list(pairwise((0, 1, 2, 3, 4))) == [(0, 1), (1, 2), (2, 3), (3, 4)]\n", + " assert sequence('seq') == 'seq'\n", + " assert sequence((i**2 for i in range(5))) == (0, 1, 4, 9, 16)\n", + " assert join(range(5)) == '01234'\n", + " assert join(range(5), ', ') == '0, 1, 2, 3, 4'\n", + " assert multiply([1, 2, 3, 4]) == 24\n", + " assert transpose(((1, 2, 3), (4, 5, 6))) == ((1, 4), (2, 5), (3, 6))\n", + " assert isqrt(9) == 3 == isqrt(10)\n", + " assert ints(1, 100) == range(1, 101)\n", + " assert identity('anything') == 'anything'\n", + " assert set(powerset({1, 2, 3})) == {\n", + " (), (1,), (1, 2), (1, 2, 3), (1, 3), (2,), (2, 3), (3,)}\n", + " assert quantify(['testing', 1, 2, 3, int, len], callable) == 2 # int and len are callable\n", + " assert quantify([0, False, None, '', [], (), {}, 42]) == 1 # Only 42 is truish\n", + " assert set(shuffled('abc')) == set('abc')\n", + " assert canon('abecedarian') == 'aaabcdeeinr'\n", + " assert canon([9, 1, 4]) == canon({1, 4, 9}) == (1, 4, 9)\n", + " assert mapt(math.sqrt, [1, 9, 4]) == (1, 3, 2)\n", + " \n", + " # Math\n", + " assert transpose([(1, 2, 3), (4, 5, 6)]) == ((1, 4), (2, 5), (3, 6))\n", + " assert isqrt(10) == isqrt(9) == 3\n", + " assert ints(1, 5) == range(1, 6)\n", + " assert list(floats(1, 5)) == [1., 2., 3., 4., 5.]\n", + " assert multiply(ints(1, 10)) == math.factorial(10) == 3628800\n", + " \n", + " # 2-D points\n", + " P = (3, 4)\n", + " assert X(P) == 3 and Y(P) == 4\n", + " assert cityblock_distance(P) == cityblock_distance(P, origin) == 7\n", + " assert distance(P) == distance(P, origin) == 5\n", + " \n", + " # Search\n", + " assert Astar((4, 4), neighbors8, distance) == [(4, 4), (3, 3), (2, 2), (1, 1), (0, 0)]\n", + " assert bfs((4, 4), neighbors8, {origin}) == [(4, 4), (3, 3), (2, 2), (1, 1), (0, 0)]\n", + " forty2 = always(42)\n", + " assert forty2() == forty2('?') == forty2(4, 2) == 42\n", + "\n", + " return 'pass'\n", + "\n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 1](https://adventofcode.com/2017/day/1): Inverse Captcha\n", + "\n", + "This was easier than I remember last year's puzzles being:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2014, (3, 2, 9, 4, 1, 9, 9, 4, 7, 1))" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "digits = mapt(int, Inputstr(1))\n", + "N = len(digits)\n", + "\n", + "N, digits[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1158" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(digits[i] \n", + " for i in range(N) \n", + " if digits[i] == digits[i - 1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1132" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(digits[i] \n", + " for i in range(N) \n", + " if digits[i] == digits[i - N // 2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 2](https://adventofcode.com/2017/day/2): Corruption Checksum\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "rows2 = Array('''790\t99\t345\t1080\t32\t143\t1085\t984\t553\t98\t123\t97\t197\t886\t125\t947\n", + "302\t463\t59\t58\t55\t87\t508\t54\t472\t63\t469\t419\t424\t331\t337\t72\n", + "899\t962\t77\t1127\t62\t530\t78\t880\t129\t1014\t93\t148\t239\t288\t357\t424\n", + "2417\t2755\t254\t3886\t5336\t3655\t5798\t3273\t5016\t178\t270\t6511\t223\t5391\t1342\t2377\n", + "68\t3002\t3307\t166\t275\t1989\t1611\t364\t157\t144\t3771\t1267\t3188\t3149\t156\t3454\n", + "1088\t1261\t21\t1063\t1173\t278\t1164\t207\t237\t1230\t1185\t431\t232\t660\t195\t1246\n", + "49\t1100\t136\t1491\t647\t1486\t112\t1278\t53\t1564\t1147\t1068\t809\t1638\t138\t117\n", + "158\t3216\t1972\t2646\t3181\t785\t2937\t365\t611\t1977\t1199\t2972\t201\t2432\t186\t160\n", + "244\t86\t61\t38\t58\t71\t243\t52\t245\t264\t209\t265\t308\t80\t126\t129\n", + "1317\t792\t74\t111\t1721\t252\t1082\t1881\t1349\t94\t891\t1458\t331\t1691\t89\t1724\n", + "3798\t202\t3140\t3468\t1486\t2073\t3872\t3190\t3481\t3760\t2876\t182\t2772\t226\t3753\t188\n", + "2272\t6876\t6759\t218\t272\t4095\t4712\t6244\t4889\t2037\t234\t223\t6858\t3499\t2358\t439\n", + "792\t230\t886\t824\t762\t895\t99\t799\t94\t110\t747\t635\t91\t406\t89\t157\n", + "2074\t237\t1668\t1961\t170\t2292\t2079\t1371\t1909\t221\t2039\t1022\t193\t2195\t1395\t2123\n", + "8447\t203\t1806\t6777\t278\t2850\t1232\t6369\t398\t235\t212\t992\t7520\t7304\t7852\t520\n", + "3928\t107\t3406\t123\t2111\t2749\t223\t125\t134\t146\t3875\t1357\t508\t1534\t4002\t4417''')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "46402" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(abs(max(row) - min(row)) for row in rows2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "265" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def evendiv(row): \n", + " return first(a // b for a in row for b in row if a > b and a // b == a / b)\n", + "\n", + "sum(map(evendiv, rows2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This day was also very easy. It was nice that my pre-defined `array` function did the whole job of parsing the input. In Part One, I was slowed down by a typo: I had `\"=\"` instead of `\"-\"` in `\"max(row) - min(row)\"`. I was confused by Python's misleading error message, which said `\"SyntaxError: keyword can't be an expression\"`. Later on, Alex Martelli explained to me that the message meant that in `abs(max(row)=...)` it thought that `max(row)` was a keyword argument to `abs`, as in `abs(x=-1)`.\n", + "\n", + "In Part Two, note that to check that `a/b` is an exact integer, I used `a // b == a / b`, which I think is more clear than the marginally-faster expression one would typically use here, `a % b == 0`, which requires you to think about two things: division and the modulus operator (is it `a % b` or `b % a`?)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 3](https://adventofcode.com/2017/day/3): Spiral Memory\n", + "\n", + "For today the data is just one number:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "M = 277678" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This puzzle takes some thinking, not just fast typing. I decided to break the problem into three parts:\n", + "- Generate a spiral (by writing a new function called `spiral`).\n", + "- Find the Nth square on the spiral (with my function `nth`).\n", + "- Find the distance from that square to the center (with my function `cityblock_distance`).\n", + "\n", + "I suspect many people will do all three of these in one function. That's probably the best way to get the answer really quickly, but I'd rather be clear than quick (and I'm anticipating that `spiral` will come in handy in Part Two), so I'll factor out each part, obeying the *single responsibility principle*. \n", + "\n", + "Now I need to make `spiral()` generate the coordinates of squares on an infinite spiral, in order, going out from the center square, `(0, 0)`. After the center square, the spiral goes 1 square right, then 1 square up, then 2 square left, then 2 square down, thus completing one revolution; then it does subsequent revolutions. In general if the previous revolution ended with *s* squares down, then the next revolution consists of *s*+1 squares right, *s*+1 squares up, *s*+2 squares left and *s*+2 down. A small test confirms that this matches the example diagram in the puzzle description (although I had a bug on my first try because I only incremented `s` once per revolution, not twice):" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, 0),\n", + " (0, 1),\n", + " (-1, 1),\n", + " (-1, 0),\n", + " (-1, -1),\n", + " (0, -1),\n", + " (1, -1),\n", + " (1, 0),\n", + " (1, 1),\n", + " (1, 2)]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def spiral():\n", + " \"Yield successive (x, y) coordinates of squares on a spiral.\"\n", + " x = y = s = 0 # (x, y) is the position; s is the side length.\n", + " yield (x, y)\n", + " while True:\n", + " for (dx, dy) in (RIGHT, UP, LEFT, DOWN):\n", + " if dy: s += 1 # Increment side length before RIGHT and LEFT\n", + " for _ in range(s):\n", + " x += dx; y += dy\n", + " yield (x, y)\n", + "\n", + "list(islice(spiral(), 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can find the `N`th square. As this is Python, indexes start at 0, whereas the puzzle description starts counting at 1, so I have to subtract 1. Then I can find the distance to the origin:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(263, 212)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nth(spiral(), M - 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "475" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cityblock_distance(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For **Part Two** I can re-use my `spiral` generator, yay! Here's a function to sum the neighboring squares (I can use my `neighbors8` function, yay!):" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def spiralsums():\n", + " \"Yield the values of a spiral where each square has the sum of the 8 neighbors.\"\n", + " value = defaultdict(int)\n", + " for p in spiral():\n", + " value[p] = sum(value[q] for q in neighbors8(p)) or 1\n", + " yield value[p]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 1, 2, 4, 5, 10, 11, 23, 25, 26, 54, 57]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(islice(spiralsums(), 12))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looks good, so let's get the answer:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "279138" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "first(x for x in spiralsums() if x > M)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 4](https://adventofcode.com/2017/day/4): High-Entropy Passphrases\n", + "\n", + "This is the first time I will have to store an input file and read it with the function `Input`. It should be straightforward, though:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "337" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def is_valid(line): return is_unique(line.split())\n", + "\n", + "def is_unique(items): return len(items) == len(set(items))\n", + "\n", + "quantify(Input(4), is_valid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "231" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def is_valid2(line): return is_unique(mapt(canon, line.split()))\n", + "\n", + "quantify(Input(4), is_valid2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy, and I started on time, but the leaders were still three times faster than me!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 5](https://adventofcode.com/2017/day/5): A Maze of Twisty Trampolines, All Alike\n", + "\n", + "Let's first make sure we can read the data/program okay:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0, 2, 0, 0, -2, -2, -1, -4, -5, -6)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program = mapt(int, Input(5))\n", + "\n", + "program[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I'll make a little interpreter, `run`, which takes a program, loads it into memory,\n", + " and executes the instruction, maintaining a program counter, `pc`, and doing the incrementing/branching as described in the puzzle,\n", + "until the program counter no longer points to a location in memory:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "364539" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run(program):\n", + " memory = list(program)\n", + " pc = steps = 0\n", + " M = len(memory)\n", + " while 0 <= pc < M:\n", + " steps += 1\n", + " oldpc = pc\n", + " pc += memory[pc]\n", + " memory[oldpc] += 1\n", + " return steps\n", + " \n", + "run(program)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "Part Two seems tricky, so I'll include an optional argument, `verbose`, and check if the printout it produces matches the example in the puzzle description:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 0 [1, 3, 0, 1, -3]\n", + "2 1 [2, 3, 0, 1, -3]\n", + "3 4 [2, 2, 0, 1, -3]\n", + "4 1 [2, 2, 0, 1, -2]\n", + "5 3 [2, 3, 0, 1, -2]\n", + "6 4 [2, 3, 0, 2, -2]\n", + "7 2 [2, 3, 0, 2, -1]\n", + "8 2 [2, 3, 1, 2, -1]\n", + "9 3 [2, 3, 2, 2, -1]\n", + "10 5 [2, 3, 2, 3, -1]\n" + ] + }, + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run2(program, verbose=False):\n", + " memory = list(program)\n", + " pc = steps = 0\n", + " M = len(memory)\n", + " while 0 <= pc < M:\n", + " steps += 1\n", + " oldpc = pc\n", + " pc += memory[pc]\n", + " memory[oldpc] += (-1 if memory[oldpc] >= 3 else 1)\n", + " if verbose: print(steps, pc, memory)\n", + " return steps\n", + " \n", + "run2([0, 3, 0, 1, -3], True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks right, so I can solve the puzzle:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 6.2 s, sys: 8.37 ms, total: 6.21 s\n", + "Wall time: 6.21 s\n" + ] + }, + { + "data": { + "text/plain": [ + "27477714" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time run2(program)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Thanks to [Clement Sreeves](https://github.com/ClementSreeves) for the suggestion of making a distinction between the `program` and the `memory`. In my first version, `run` would mutate the argument, which was OK for a short exercise, but not best practice for a reliable API. And thanks to [Max Albert](https://github.com/maxalbert) for speeding up the loop by pulling the `len(memory)` out of the loop." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 6](https://adventofcode.com/2017/day/6): Memory Reallocation " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I had to read the puzzle description carefully, but then it is pretty clear what to do. I'll keep a set of previously seen configurations, which will all be tuples. But in the function `spread`, I want to mutate the configuration of banks, so I will convert to a list at the start, then convert back to a tuple at the end." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "banks = Vector('4\t10\t4\t1\t8\t4\t9\t14\t5\t1\t14\t15\t0\t15\t3\t5')\n", + "\n", + "def realloc(banks):\n", + " \"How many cycles until we reach a configuration we've seen before?\"\n", + " seen = {banks}\n", + " for cycles in count_from(1):\n", + " banks = spread(banks)\n", + " if banks in seen:\n", + " return cycles\n", + " seen.add(banks)\n", + " \n", + "def spread(banks):\n", + " \"Find the area with the most blocks, and spread them evenly to following areas.\"\n", + " banks = list(banks)\n", + " maxi = max(range(len(banks)), key=lambda i: banks[i])\n", + " blocks = banks[maxi]\n", + " banks[maxi] = 0\n", + " for i in range(maxi + 1, maxi + 1 + blocks):\n", + " banks[i % len(banks)] += 1\n", + " return tuple(banks)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2, 4, 1, 2)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spread((0, 2, 7, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "realloc((0, 2, 7, 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These tests look good; let's solve the problem:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12841" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "realloc(banks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:** Here I will just replace the `set` of `seen` banks with a `dict` of `{bank: cycle_number}`; everything else is the same, and the final result is the current cycle number minus the cycle number of the previously-seen tuple of banks." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def realloc2(banks):\n", + " \"When we hit a cycle, what is the length of the cycle?\"\n", + " seen = {banks: 0}\n", + " for cycles in count_from(1):\n", + " banks = spread(banks)\n", + " if banks in seen:\n", + " return cycles - seen[banks]\n", + " seen[banks] = cycles\n", + "\n", + "realloc2((0, 2, 7, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8038" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "realloc2(banks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 7](https://adventofcode.com/2017/day/7): Recursive Circus" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First I'll read the data into two dicts as follows: the input line:\n", + "\n", + " tcmdaji (40) -> wjbdxln, amtqhf\n", + " \n", + "creates:\n", + "\n", + " weight['tcmdaji'] = 40\n", + " above['tcmdaji'] = ['wjbdxln', 'amtqhf']" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def towers(lines):\n", + " \"Return (weight, above) dicts.\"\n", + " weight = {}\n", + " above = {}\n", + " for line in lines:\n", + " name, w, *rest = re.findall(r'\\w+', line)\n", + " weight[name] = int(w)\n", + " above[name] = set(rest)\n", + " return weight, above\n", + "\n", + "weight, above = towers(Input(7))\n", + "\n", + "programs = set(above)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the root progam is the one that is not above anything:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'wiapj'}" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "programs - set(flatten(above.values()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "A program is *wrong* if it is the bottom of a tower that is a different weight from all its sibling towers:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def wrong(p): return tower_weight(p) not in map(tower_weight, siblings(p))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we define `tower_weight`, `siblings`, and the `below` dict:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def tower_weight(p): \n", + " \"Total weight for the tower whose root (bottom) is p.\"\n", + " return weight[p] + sum(map(tower_weight, above[p]))\n", + "\n", + "def siblings(p): \n", + " \"The other programs at the same level as this one.\"\n", + " if p not in below:\n", + " return Ø # the root has no siblings\n", + " else:\n", + " return above[below[p]] - {p}\n", + "\n", + "below = {a: b for b in programs for a in above[b]}" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'eionkb', 'lsire', 'wiapj', 'ycpcv'}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(filter(wrong, programs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So these four programs are wrong. Which one should we correct? The one that is wrong, and has no wrong program above it:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'eionkb'" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wrongest(programs):\n", + " return first(p for p in programs\n", + " if wrong(p) \n", + " and not any(wrong(p2) for p2 in above[p]))\n", + "\n", + "wrongest(programs) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now what should we correct it to? To the weight that makes it the same weight as the sibling towers:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1072" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def correct(p):\n", + " \"Return the weight that would make p's tower's weight the same as its sibling towers.\"\n", + " delta = tower_weight(first(siblings(p))) - tower_weight(p) \n", + " return weight[p] + delta\n", + "\n", + "correct(wrongest(programs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 8](https://adventofcode.com/2017/day/8): Memory Reallocation \n", + "\n", + "This one looks easy: a simple interpreter for straight-line code where each instruction has 7 tokens. It is nice that my `Array` function parses the whole program." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6828" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program8 = Array(Input(8))\n", + "\n", + "def run8(program):\n", + " \"Run the program and return final value of registers.\"\n", + " registers = defaultdict(int)\n", + " for (r, inc, delta, _if, r2, cmp, amount) in program:\n", + " if operations[cmp](registers[r2], amount):\n", + " registers[r] += delta * (+1 if inc == 'inc' else -1)\n", + " return registers\n", + "\n", + "max(run8(program8).values())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "Here I modify the interpreter to keep track of the highest value of any register at any time." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "7234" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run8_2(program):\n", + " registers = defaultdict(int)\n", + " highest = 0\n", + " for (r, inc, delta, _if, r2, cmp, amount) in program:\n", + " if operations[cmp](registers[r2], amount):\n", + " registers[r] += delta * (+1 if inc == 'inc' else -1)\n", + " highest = max(highest, registers[r])\n", + " return highest\n", + "\n", + "run8_2(program8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 9](https://adventofcode.com/2017/day/9): Stream Processing\n", + "\n", + "For this problem I could have a single finite-state machine that handles all five magic characters, `'{}'`, but I think it is easier to first clean up the garbage, using regular expressions:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'{{{{{{{},},{{},}},{{{{}},{{{{{}}},{}},},{{{{},{,{{{}}}}},},{{{}},{{}}}'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text1 = re.sub(r'!.', '', Inputstr(9)) # Delete canceled characters\n", + "text2 = re.sub(r'<.*?>', '', text1) # Delete garbage\n", + "\n", + "text2[:70]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can deal with the nested braces (which can't be handled with regular expressions). The puzzle says \"*Each group is assigned a score which is one more than the score of the group that immediately contains it,*\" which is the same as saying that a group's score is its nesting level, a quantity that increases with each open-brace character, and decreases with each close-brace:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9662" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def total_score(text):\n", + " \"Total of group scores; each group scores one more than the group it is nested in.\"\n", + " total = 0\n", + " level = 0 # Level of nesting\n", + " for c in text:\n", + " if c == '{':\n", + " level += 1\n", + " total += level\n", + " elif c == '}':\n", + " level -= 1\n", + " return total\n", + "\n", + "total_score(text2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two:**\n", + "\n", + "At first I thought that the amount of garbage is just the difference in lengths of `text2` and `text3`:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5989" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(text1) - len(text2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this turned out to be wrong; it counts the angle brackets themselves s being deleted, whereas the puzzle is actually asking how many character between the angle brackets are deleted. So that would be:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4903" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text3 = re.sub(r'<.*?>', '<>', text1) # Delete garbage inside brackets, but not brackets\n", + "\n", + "len(text1) - len(text3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 10](https://adventofcode.com/2017/day/10): Stream Processing" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I have to do a bunch of reversals of substrings of `stream`. It looks complicated so I will include a `verbose` argument to `knothash` and confirm it works on the example puzzle. I break out the reversal into a separate function, `rev`. The way I handle reversal interacting with wraparound is that I first move all the items before the reversal position to the end of the list, then I do the reversal, then I move them back." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "stream = (63,144,180,149,1,255,167,84,125,65,188,0,2,254,229,24)\n", + "\n", + "def knothash(lengths, N=256, verbose=False):\n", + " \"Do a reversal for each of the numbers in `lengths`.\"\n", + " nums = list(range(N))\n", + " pos = skip = 0\n", + " for L in lengths:\n", + " nums = rev(nums, pos, L)\n", + " if verbose: print(nums)\n", + " pos = (pos + L + skip) % N\n", + " skip += 1\n", + " return nums[0] * nums[1]\n", + " \n", + "def rev(nums, pos, L):\n", + " \"Reverse nums[pos:pos+L], handling wrap-around.\"\n", + " # Move first pos elements to end, reverse first L, move pos elements back\n", + " nums = nums[pos:] + nums[:pos]\n", + " nums[:L] = reversed(nums[:L])\n", + " nums = nums[-pos:] + nums[:-pos]\n", + " return nums" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Reverse [0, 1, 2]:\n", + "assert rev(list(range(5)), 0, 3) == [2, 1, 0, 3, 4]" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Reverse [4, 0, 1], wrapping around:\n", + "assert rev(list(range(5)), 4, 3) == [0, 4, 2, 3, 1]" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 1, 0, 3, 4]\n", + "[4, 3, 0, 1, 2]\n", + "[4, 3, 0, 1, 2]\n", + "[3, 4, 2, 1, 0]\n" + ] + } + ], + "source": [ + "# Duplicate the example output\n", + "assert knothash((3, 4, 1, 5), N=5, verbose=True) == 12" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's correct, but the first time through I got it wrong because I forgot the `\"% N\"` on the update of `pos`." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4480" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "knothash(stream)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**:\n", + "\n", + "Now it gets *really* complicated: string processing, the suffix, hex string output, and dense hashing. But just take them one at a time:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'c500ffe015c83b60fad2e4b7d59dabc4'" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stream2 = '63,144,180,149,1,255,167,84,125,65,188,0,2,254,229,24'\n", + "\n", + "def knothash2(lengthstr, N=256, rounds=64, suffix=(17, 31, 73, 47, 23),\n", + " verbose=False):\n", + " \"Do a reversal for each length; repeat `rounds` times.\"\n", + " nums = list(range(N))\n", + " lengths = mapt(ord, lengthstr) + suffix\n", + " pos = skip = 0\n", + " for round in range(rounds):\n", + " for L in lengths:\n", + " nums = rev(nums, pos, L)\n", + " if verbose: print(nums)\n", + " pos = (pos + L + skip) % N\n", + " skip += 1\n", + " return hexstr(dense_hash(nums))\n", + "\n", + "def hexstr(nums): \n", + " \"Convert a sequence of (0 to 255) ints into a hex str.\"\n", + " return cat(map('{:02x}'.format, nums))\n", + " \n", + "def dense_hash(nums, blocksize=16): \n", + " \"XOR each block of nums, return the list of them.\"\n", + " return [XOR(block) for block in grouper(nums, blocksize)]\n", + "\n", + "def XOR(nums):\n", + " \"Exclusive-or all the numbers together.\"\n", + " result = 0\n", + " for n in nums:\n", + " result ^= n\n", + " return result\n", + " \n", + "assert XOR([65, 27, 9, 1, 4, 3, 40, 50, 91, 7, 6, 0, 2, 5, 68, 22]) == 64\n", + "assert hexstr([255, 0, 17]) == 'ff0011'\n", + "\n", + "assert knothash2('') == 'a2582a3a0e66e6e86e3812dcb672a272'\n", + "\n", + "knothash2(stream2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I had a bug: originally I used `'{:x}'` as the format instead of `'{:02x}'`; the later correctly formats `0` as `'00'`, not `'0'`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 11](https://adventofcode.com/2017/day/11): Hex Ed\n", + "\n", + "The first thing I did was search [`[hex coordinates]`](https://www.google.com/search?source=hp&ei=Ft4xWoOqKcy4jAOs76a4CQ&q=hex+coordinates), and the #1 result (as I expected) was Amit Patel's \"[Hexagonal Grids](https://www.redblobgames.com/grids/hexagons/)\" page. I chose his \"odd-q vertical layout\" to define the six directions as (dx, dy) deltas:" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "directions6 = dict(n=(0, -1), ne=(1, 0), se=(1, 1), s=(0, 1), sw=(-1, 0), nw=(-1, -1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can read the path, follow it, and see where it ends up. If the end point is `(x, y)`, then it will take `max(abs(x), abs(y))` steps to get back to the origin, because each step can increment or decrement either `x` or `y` or both." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "705" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path = Vector(Inputstr(11))\n", + "\n", + "def follow(path):\n", + " \"Follow each step of the path; return final distance to origin.\"\n", + " x, y = (0, 0)\n", + " for (dx, dy) in map(directions6.get, path):\n", + " x += dx; y += dy\n", + " return max(abs(x), abs(y))\n", + "\n", + "follow(path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This one seemed so easy that I didn't bother testing it on the simple examples in the puzzle; all I did was confirm that the answer for my puzzle input was correct.\n", + "\n", + "**Part Two:**\n", + "\n", + "This looks pretty easy; repeat Part One, but keep track of the maximum number of steps we get from the origin at any point in the path:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1469" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def follow2(path):\n", + " \"Follow each step of the path; return max steps to origin.\"\n", + " x = y = maxsteps = 0\n", + " for (dx, dy) in map(directions6.get, path):\n", + " x += dx; y += dy\n", + " maxsteps = max(maxsteps, abs(x), abs(y))\n", + " return maxsteps\n", + "\n", + "follow2(path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, no tests, just the final answer.\n", + "\n", + "# [Day 12](https://adventofcode.com/2017/day/12): Digital Plumber\n", + "\n", + "First I'll parse the data, creating a dict of `{program: direct_group_of_programs}`:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def groups(lines):\n", + " \"Dict of {i: {directly_connected_to_i}\"\n", + " return {lhs: {lhs} | set(rhs)\n", + " for (lhs, _, *rhs) in Array(lines)}\n", + " \n", + "assert groups(Input(12))[0] == {0, 659, 737}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks good. I recognize this as a [Union-Find](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) problem, for which there are efficient algorithms. But for this small example, I don't need efficiency, I need clarity and simplicity. So I'll write `merge` to take a dict and merge together the sets that are connected:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def merge(G):\n", + " \"Merge all indirectly connected groups together.\"\n", + " for i in G:\n", + " for j in list(G[i]):\n", + " if G[i] != G[j]:\n", + " G[i].update(G[j])\n", + " G[j] = G[i]\n", + " return G\n", + "\n", + "G = merge(groups(Input(12)))" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "115" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(G[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the answer for Part One.\n", + "\n", + "**Part Two**\n", + "\n", + "I did almost all the work; I just need to count the number of distinct groups. That's a set of sets, and regular `set`s are not hashable, so I use my `Set` class:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "221" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len({Set(G[i]) for i in G})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 13](https://adventofcode.com/2017/day/13): Packet Scanners\n", + "\n", + "First thing: The puzzle says the data is *depth: range*, but `range` has a meaning in Python, so I'll use the term *width* instead.\n", + "\n", + "Second thing: I misread the puzzle description and mistakenly thought the scanners were going in a circular route,\n", + "so that they'd be at the top at any time that is 0 mod *width*. That gave the wrong answer and I realized the scanners are actually going back-and-forth, so with a width of size *n*, it takes *n* - 1 steps to get to the bottom, and *n* - 1 steps to get back to the top, so the scanner will be \n", + "at the top at times that are multiples of 2(*n* - 1). For example, with width 3, that would be times 0, 4, 8, ... " + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def trip_severity(scanners): \n", + " \"The sum of sevrities for each time the packet is caught.\"\n", + " return sum((d * w if caught(d, w) else 0) \n", + " for (d, w) in scanners)\n", + "\n", + "def caught(depth, width):\n", + " \"Does the scanner at this depth/width catch the packet?\"\n", + " return depth % (2 * (width - 1)) == 0\n", + "\n", + "example = ((0, 3), (1, 2), (4, 4), (6, 4))\n", + "assert trip_severity(example) == 24" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 3), (1, 2), (2, 4), (4, 6), (6, 4))" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scanners = mapt(Integers, Input(13))\n", + "scanners[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1504" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trip_severity(scanners)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "A packet is safe if no scanner catches it. We now have the possibility of a delay, so I update `caught` to allow for an optional delay, and define `safe_delay`: " + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def caught(depth, width, delay=0):\n", + " \"Does the scanner at this depth/width catch the packet with this delay?\"\n", + " return (depth + delay) % (2 * (width - 1)) == 0 \n", + "\n", + "def safe_delay(scanners):\n", + " \"Find the first delay such that no scanner catches the packet.\"\n", + " safe = lambda delay: not any(caught(d, w, delay) for (d, w) in scanners)\n", + " return first(filter(safe, count_from(0)))\n", + "\n", + "safe_delay(example)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3823370" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "safe_delay(scanners)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 14](https://adventofcode.com/2017/day/14): Disk Defragmentation\n", + "\n", + "I found this puzzle description confusing: are they talking about what I call `knothash`, or is it `knothash2`? I decided for the latter, which turned out to be right:" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "key = 'ljoxqyyw'" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8316" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def bits(key, i):\n", + " \"The bits in the hash of this key with this row number.\"\n", + " hash = knothash2(key + '-' + str(i))\n", + " return format(int(hash, base=16), '0128b')\n", + "\n", + "sum(bits(key, i).count('1') for i in range(128))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "So as not to worry about running off the edge of the grid, I'll surround the grid with `'0'` bits:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Grid(key, N=128+2):\n", + " \"Make a grid, with a border around it.\"\n", + " return border('0', (list(bits(key, i)) for i in range(128)))\n", + "\n", + "def border(fill, grid):\n", + " \"Surround a grid with a border of fill cells.\"\n", + " rows = [[fill] + list(row) + [fill] \n", + " for row in grid]\n", + " empty = [fill] * len(rows[0])\n", + " return [empty] + rows + [empty]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To find a region, start at some `(x, y)` position and [flood fill](https://en.wikipedia.org/wiki/Flood_fill) to neighbors that have the same value (a `'1'` bit)." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def flood(grid, x, y, val, R):\n", + " \"For all cells with value val connected to grid[x][y], give them region number R.\"\n", + " if grid[y][x] == val:\n", + " grid[y][x] = R\n", + " for x2, y2 in neighbors4((x, y)):\n", + " flood(grid, x2, y2, val, R)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def flood_all(grid, val='1'):\n", + " \"Label all regions with consecutive ints starting at 1.\"\n", + " R = 0 # R is the region number\n", + " for y in range(1, len(grid) - 1):\n", + " for x in range(1, len(grid) - 1):\n", + " if grid[y][x] == val:\n", + " R += 1\n", + " flood(grid, x, y, val, R)\n", + " return R " + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1074" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flood_all(Grid(key))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 15](https://adventofcode.com/2017/day/15): Dueling Generators\n", + "\n", + "My personalized inputs for this puzzle are `516` and `190`; the other numbers are shared by all puzzle-solvers. I decided to make infinite generators of numbers, using `gen`:" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15.1 s, sys: 26.4 ms, total: 15.1 s\n", + "Wall time: 15.2 s\n" + ] + }, + { + "data": { + "text/plain": [ + "597" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@jit # This was the slowest solution; @jit helps a bit.\n", + "def gen(prev, factor, m=2147483647):\n", + " \"Generate a sequence of numbers according to the rules; stop at 0.\"\n", + " while prev:\n", + " prev = (prev * factor) % m\n", + " yield prev\n", + " \n", + "def judge(A, B, N=40*10**6, mask=2**16-1): \n", + " \"How many of the first N numbers from A and B agree in the masked bits (default last 16)?\"\n", + " return quantify(a & mask == b & mask\n", + " for (a, b, _) in zip(A, B, range(N)))\n", + "\n", + "def A(): return gen(516, 16807)\n", + "def B(): return gen(190, 48271)\n", + "\n", + "%time judge(A(), B())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Notice I also decided to use `@jit` (i.e. `numba.jit`) to speed things up, since this is the slowest-running day yet.\n", + "\n", + "**Part Two**\n", + "\n", + "A small change: only consider numbers that match the **criteria** of being divisible by 4 or 8, respectively;" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 9.39 s, sys: 8.62 ms, total: 9.4 s\n", + "Wall time: 9.4 s\n" + ] + }, + { + "data": { + "text/plain": [ + "303" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def criteria(m, iterable): \n", + " \"Elements of iterable that are divisible by m\"\n", + " return (n for n in iterable if n % m == 0)\n", + " \n", + "%time judge(criteria(4, A()), criteria(8, B()), 5*10**6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 16](https://adventofcode.com/2017/day/16): Permutation Promenade\n", + "\n", + "Let's read the input and check that it looks reasonable:" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('x5/15',\n", + " 's15',\n", + " 'x1/3',\n", + " 'pn/f',\n", + " 'x11/2',\n", + " 's13',\n", + " 'x6/3',\n", + " 'pe/a',\n", + " 'x14/12',\n", + " 's15')" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dance = Vector(Inputstr(16))\n", + "dance[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10000" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(dance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I'll define `perform` to perform the dance:" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'lbdiomkhgcjanefp'" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dancers = 'abcdefghijklmnop'\n", + "\n", + "def perform(dance, dancers=dancers):\n", + " D = deque(dancers)\n", + " def swap(i, j): D[i], D[j] = D[j], D[i]\n", + " for move in dance:\n", + " op, arg = move[0], move[1:]\n", + " if op == 's': D.rotate(int(arg))\n", + " elif op == 'x': swap(*Integers(arg))\n", + " elif op == 'p': swap(D.index(arg[0]), D.index(arg[2]))\n", + " return cat(D)\n", + " \n", + "perform(dance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the right answer.\n", + "\n", + "**Part Two**\n", + "\n", + "My first thought was to define a dance as a permutation: a list of numbers `[11, 1, 9, ...]` which says that the net effect of the dance is that the first dancer (`a`) ends up in position, the second (`b`) stays in position 1, and so on. Applying that permutation once is a lot faster than interpreting all 10,000 moves of the dance, and it is feasible to apply the permutation a billion times. I tried that (code not shown here), but that was a mistake: it took 15 minutes to run, and it got the wrong answer. The problem is that a dance is *not* just a permutation, because a dance can reference dancer *names*, not just positions.\n", + "\n", + "It would take about 10,000 times 20 minutes to perform a billion repetitions of the dance, so that's out. But even though the dance is not a permutation, it might repeat after a short period. Let's check:" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "abcdefghijklmnop is seen in iterations (0, 56)\n" + ] + } + ], + "source": [ + "seen = {dancers: 0}\n", + "d = dancers\n", + "for i in range(1, 1000):\n", + " d = perform(dance, d)\n", + " if d in seen:\n", + " print(d, 'is seen in iterations', (seen[d], i))\n", + " break" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So we get back to the start position after 56 repetitions of the dance. What happens after a billion repetitions?" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "48" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1000000000 % 56" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The end position after a billion repetitions is the same as after 48:" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ejkflpgnamhdcboi'" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def whole(N, dance, dancers=dancers):\n", + " \"Repeat `perform(dance)` N times.\"\n", + " for i in range(N):\n", + " dancers = perform(dance, dancers)\n", + " return dancers\n", + " \n", + "whole(48, dance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# [Day 17](https://adventofcode.com/2017/day/17): Spinlock\n", + "\n", + "This one looks pretty easy:" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "355" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step = 314\n", + "\n", + "def spinlock(step=step, N=2017):\n", + " \"Make N inserts into the buffer, skipping ahead by `step` each time.\"\n", + " buf = [0]\n", + " pos = 0\n", + " for i in ints(1, N):\n", + " pos = (pos + step) % i + 1\n", + " buf[pos:pos] = [i]\n", + " return buf\n", + " \n", + "buf = spinlock()\n", + "\n", + "buf[buf.index(2017)+1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the right answer.\n", + "\n", + "**Part Two**\n", + "\n", + "But Part Two is not so easy, if we care about the run time. Insertion into a `list` has to move all the elements after the insertion down, so insertion is O(N) and `spinlock` is O(N2). That's no problem when N = 2017, but when N is 50 million? We're gonna need a bigger boat, where by \"boat\" I mean algorithm or data structure. My first thought is a (circular) linked list, because insertion is O(1). I can implement the three key methods: `skip` to move ahead, `insert` to add a new node after the current one, and `find` to find a piece of data (with a linear search):" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Node:\n", + " \"A Node in a singly-linked list\"\n", + " \n", + " __slots__ = ('data', 'next') # Declaring slots makes it more efficient\n", + " \n", + " def __init__(self, data, next): self.data, self.next = data, next\n", + " \n", + " def skip(self, n):\n", + " \"Skip ahead n nodes, and return that node.\"\n", + " node = self\n", + " for i in range(n):\n", + " node = node.next\n", + " return node\n", + " \n", + " def insert(self, value):\n", + " \"Insert a new node with the given value after this node.\"\n", + " self.next = Node(value, self.next)\n", + " return self.next\n", + " \n", + " def find(self, value):\n", + " \"Find the node with the given data value.\"\n", + " node = self\n", + " while node.data != value:\n", + " node = node.next\n", + " return node" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can rewrite `spinlock` to use this class:" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def spinlock2(step=step, N=2017):\n", + " node = Node(0, None)\n", + " node.next = node # Make node be a circular linked list\n", + " for i in ints(1, N):\n", + " node = node.skip(step).insert(i)\n", + " return node" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's replicate the Part One results:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "355" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spinlock2().find(2017).next.data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Good news! We get the same answer. But how fast/slow is it?" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.35 s, sys: 5.54 ms, total: 1.35 s\n", + "Wall time: 1.35 s\n" + ] + }, + { + "data": { + "text/plain": [ + "<__main__.Node at 0x110c44be0>" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time spinlock2(N=100000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Bad news! It takes over a second to do just 100,000 insertions, which means about 10 minutes for 50 million insertions. I did in fact try\n", + "\n", + " spinlock2(N=50000000).find(0).next.data\n", + " \n", + "and it eventually gave the right answer, but while it was running I had plenty of time to think.\n", + "I realized that, if we go back to the original `spinlock` version, the value `0` will always be in `buf[0]`, and the value we are looking for will always be in `buf[1]`. So I can create a version of `spinlock` that only keeps track of `buf[0:2]`. That should run in a few seconds, not minutes:" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5.47 s, sys: 6.62 ms, total: 5.48 s\n", + "Wall time: 5.48 s\n" + ] + }, + { + "data": { + "text/plain": [ + "6154117" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def spinlock3(step=step, N=2017):\n", + " \"Make N inserts into a simulated buffer, but ignore all except buf[0:2].\"\n", + " pos = 0\n", + " buf = [0, 0]\n", + " for i in ints(1, N):\n", + " pos = (pos + step) % i + 1\n", + " if pos <= 1:\n", + " buf[pos] = i\n", + " return buf\n", + "\n", + "%time spinlock3(N=50000000)[1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The moral of the story is *keep your eyes on the prize*. I got distracted because I asked the wrong question. I asked myself \"how can I make my solution in `spinlock` faster?\" and answered myself \"insertion is O(N2) and it should be O(N).\" I knew how to do that, with a linked list, but that was the right answer to the wrong question. I should have asked myself \"how do I solve Part Two quickly,\" concentrating on solving the actual problem. Once I did that, I realized I didn't need all those insertions: not doing them at all is a better idea than doing them faster." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 18](https://adventofcode.com/2017/day/17): Duet\n", + "\n", + "First, read the input, and take a peak at it:" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(('set', 'i', 31),\n", + " ('set', 'a', 1),\n", + " ('mul', 'p', 17),\n", + " ('jgz', 'p', 'p'),\n", + " ('mul', 'a', 2),\n", + " ('add', 'i', -1),\n", + " ('jgz', 'i', -2),\n", + " ('add', 'a', -1),\n", + " ('set', 'i', 127),\n", + " ('set', 'p', 826))" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program18 = Array(Input(18))\n", + "program18[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now write an interpreter for the assembly language:" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "7071" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def run18(program):\n", + " \"Interpret the assembly language program; return recovered `snd`.\"\n", + " regs = defaultdict(int)\n", + " pc = snd = 0\n", + " while True:\n", + " instr = program[pc]\n", + " pc += 1\n", + " op, x, y = instr[0], instr[1], instr[-1]\n", + " vy = value(regs, y)\n", + " if op == 'snd': snd = regs[x]\n", + " elif op == 'set': regs[x] = vy\n", + " elif op == 'add': regs[x] += vy\n", + " elif op == 'mul': regs[x] *= vy\n", + " elif op == 'mod': regs[x] %= vy\n", + " elif op == 'jgz' and regs[x] > 0: pc += vy - 1\n", + " elif op == 'rcv' and regs[x] != 0: return snd\n", + " \n", + "def value(regs, y): return (y if isinstance(y, int) else regs[y])\n", + "\n", + "run18(program18)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy. (One tricky bit: the `pc` is incremented by 1 every time through the loop, regardless of the instruction. Therefore, the `'jgz'` jump instruction increments by \"`vy - 1`\" so that the net increment is \"`vy`\".)\n", + "\n", + "**Part Two**\n", + "\n", + "In Part Two we have to run two copies of the program, and send messages between them. I'll break up the loop in `run18` into\n", + "two functions. First, `run18_2`, creates (in `ps`) two structures to hold the state variables necessary to run a program:\n", + "- `id`: The id number (0 or 1) of this copy of the program.\n", + "- `pc`: The program counter.\n", + "- `sends`: A count of the number of `snd` instructions executed.\n", + "- `regs`: A dict of the program registers (`a` to `z`).\n", + "- `status`: A program has a status which can be:\n", + " * `'run'` when it is ready to execute an instruction, \n", + " * `'wait'` when it is waiting for a value to arrive in its input queue, or \n", + " * `'end'` when the `pc` has run off the end of the program and it has terminated.\n", + "\n", + "`run18_2` repeatedly calls the second function, `step18(program, p)` to execute one instruction of `program` with the state variables in `p`. I choose randomly which of the two programs to step on each iteration. The function exits when neither copy of the program can run, according to their status. " + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run18_2(program):\n", + " \"Run two copies of program, with different state variables. Return final states.\"\n", + " Qs = [deque(), deque()]\n", + " ps = [Struct(id=id, pc=0, sends=0, regs=defaultdict(int, p=id), status='run')\n", + " for id in (0, 1)]\n", + " while any(p.status == 'run' for p in ps):\n", + " step18(program, Qs, random.choice(ps))\n", + " return ps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`step18` has most of the guts of thee previous `run18` function, but with a few changes:\n", + "- State variables are accessed indirectly: `p.pc` instead of just `pc`.\n", + "- If the `pc` is out of bounds, the program terminates; the status is set to `'end'`.\n", + "- The `snd` instruction sends a value to the other program's queue.\n", + "- The `rcv` instruction pops a value off the queue if there is one, otherwise the status is set to `'wait'`.\n", + "- The \"`X`\" in \"`jgz X Y`\" might be an integer, not a register name, so use `vx = value(p.regs, x)`. I was stuck for a *long* time before I realized this. Finally I tried the strategy of *look carefully at the input*. I noticed the instruction `\"jgz 1 3\"`, and it was a simple change to make the program work." + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8001" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def step18(program, Qs, p):\n", + " \"Execute one instruction in program, using state variables in p.\"\n", + " if p.pc < 0 or p.pc > len(program):\n", + " p.status = 'end'\n", + " else:\n", + " instr = program[p.pc]\n", + " op, x, y = instr[0], instr[1], instr[-1]\n", + " vx, vy = value(p.regs, x), value(p.regs, y)\n", + " if op == 'snd': Qs[1-p.id].append(vy); p.sends += 1\n", + " elif op == 'set': p.regs[x] = vy\n", + " elif op == 'add': p.regs[x] += vy\n", + " elif op == 'mul': p.regs[x] *= vy\n", + " elif op == 'mod': p.regs[x] %= vy\n", + " elif op == 'jgz' and vx > 0: p.pc += vy - 1\n", + " elif op == 'rcv': \n", + " if not Qs[p.id]:\n", + " p.status = 'wait'\n", + " return # don't update pc; try again next time\n", + " else:\n", + " p.regs[x] = Qs[p.id].popleft()\n", + " p.status = 'run'\n", + " p.pc += 1\n", + " \n", + "run18_2(program18)[1].sends" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 19](https://adventofcode.com/2017/day/19): A Series of Tubes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At first I was confused; I thought this was a maze-following problem where I had to make a choice of directions at every turn. Actually, the direction is always determined: keep going in the current direction as long as possible, but when we hit a `'+'` character, find the new direction to go in (there will only be one possibility). Leave breadcrumbs (the `'.'` character) so that we don't back up along a previously-followed path. As in Day 14, the grid is surrounded by a border of space characters so that we don't have to worry about `(x, y)` going off the edge." + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "diagram = Inputstr(19)\n", + "\n", + "def follow_tubes(diagram):\n", + " \"Follow [-+|] lines, yielding characters along the path.\"\n", + " grid = border(' ', diagram.splitlines())\n", + " x, y = grid[1].index('|'), 1\n", + " dx, dy = 0, 1\n", + " while grid[y][x] != ' ':\n", + " yield grid[y][x]\n", + " if grid[y][x] == '+':\n", + " dx, dy = new_direction(grid, x, y)\n", + " grid[y][x] = '.' # Leave a breadcrumb\n", + " x += dx; y += dy\n", + " \n", + "def new_direction(grid, x, y):\n", + " \"Find a direction that continues the path.\"\n", + " for (dx, dy) in (UP, DOWN, RIGHT, LEFT):\n", + " if grid[y+dy][x+dx] not in (' ', '.'):\n", + " return dx, dy" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'VEBTPXCHLI'" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(filter(str.isalpha, follow_tubes(diagram)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the right answer.\n", + "\n", + "**Part Two**\n", + "\n", + "This is a surprisingly easy Part Two; I already generated the characters in the path; all I have to do is count them: " + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "18702" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "length(follow_tubes(diagram))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 20](https://adventofcode.com/2017/day/20): Particle Swarm\n", + "\n", + "I'll create structures for particles, each will have fields for particle's number (`id`), position (`p`), velocity(`v`), and acceleration (`a`):" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Struct(a=(-7, 8, -10), id=0, p=(1199, -2918, 1457), v=(-13, 115, -8)),\n", + " Struct(a=(-6, -5, 6), id=1, p=(2551, 2418, -1471), v=(-106, -108, 39)),\n", + " Struct(a=(-6, 2, -9), id=2, p=(-73, 1626, 1321), v=(58, -118, -8)),\n", + " Struct(a=(3, 3, 11), id=3, p=(-3297, -894, -551), v=(183, 31, -61)),\n", + " Struct(a=(7, -12, -1), id=4, p=(-1425, 4298, 617), v=(32, -166, -32))]" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def particles(lines=list(Input(20))):\n", + " \"Parse the list of particles.\"\n", + " return [Particle(id, *grouper(Integers(line), 3)) \n", + " for id, line in enumerate(lines)]\n", + "\n", + "def Particle(id, p, v, a): return Struct(id=id, p=p, v=v, a=a) \n", + "\n", + "particles()[:5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I'm not quite sure how to determine what \"in the long run\" means, so I'll just interpret it as meaning \"after 1000 time steps.\" On each step we update velocity and position of each particle. At the end, we determine the id number of the particle closest to the origin. Note that `evolve` generates an infinite sequence of particles, and we use `nth` to pick out the 1000th generation." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "243" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def evolve(particles):\n", + " \"Continually update particles, yielding them after each time step.\"\n", + " while True:\n", + " yield particles\n", + " for p in particles:\n", + " p.v = add(p.v, p.a)\n", + " p.p = add(p.p, p.v)\n", + " \n", + "def add(A, B): \n", + " \"Add two n-dimensional vectors.\"\n", + " return mapt(sum, zip(A, B))\n", + "\n", + "def closest(particles):\n", + " \"Find the particle closest to origin.\"\n", + " return min(particles, key=lambda p: sum(map(abs, p.p)))\n", + "\n", + "# Answer: the id of the particle closest to origin in the 1000th generation of `evolve`\n", + "closest(nth(evolve(particles()), 1000)).id" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "I can still use `evolve` unchanged, and I will add the function `remove_collisions` to eliminate particles that are in the same position as another particle. I use `map` to apply this to every generation. Note that `remove_collisions` both mutates the argument, `particles`, and also returns it. " + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "648" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def remove_collisions(particles):\n", + " \"Mutate (and return) particles, keep only ones that have a unique position.\"\n", + " poscount = Counter(p.p for p in particles)\n", + " particles[:] = [p for p in particles if poscount[p.p] == 1]\n", + " return particles\n", + " \n", + "# Answer: remove collisions from every generation of evolving particles, \n", + "# select the 1000th generation, and say how many particles are in that generation.\n", + "len(nth(map(remove_collisions, evolve(particles())), 1000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 21](https://adventofcode.com/2017/day/21): Fractal Art\n", + "\n", + "First I'll create a `dict` of enhancement rules. I'll translate `'#'` and `'.'` pixels to 1 and 0, and represent a grid as a tuple of tuples (e.g. `((0, 0), (1, 1))`), so that it can be a `dict` key. I have to deal with rotations and flips; I could do that at lookup time, but it will be faster to do it at rule creation time:" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Enhancements(lines):\n", + " \"Create a dict of {square: enhanced_square}\"\n", + " enhancements = {}\n", + " for line in lines:\n", + " lhs, rhs = map(Key, line.split('=>'))\n", + " for r in range(4):\n", + " enhancements[lhs] = enhancements[flip(lhs)] = rhs\n", + " lhs = rotate(lhs)\n", + " return enhancements\n", + " \n", + "def Key(line): \n", + " \"Key('../##') => ((0, 0), (1, 1))\"\n", + " bits = {'#': 1, '.': 0}\n", + " return tuple(tuple(bits[p] for p in row.strip())\n", + " for row in line.split('/'))\n", + " \n", + "def rotate(key): return tuple(zip(*reversed(key)))\n", + "\n", + "def flip(L): return tuple(tuple(reversed(row)) for row in L)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's test this on just the enhancement rules with 2x2 squares; with rotations and flips there should be 16 entries:" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{((0, 0), (0, 0)): ((0, 0, 0), (0, 1, 0), (0, 1, 0)),\n", + " ((0, 0), (0, 1)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((0, 0), (1, 0)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((0, 0), (1, 1)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((0, 1), (0, 0)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((0, 1), (0, 1)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((0, 1), (1, 0)): ((1, 1, 0), (1, 1, 0), (0, 0, 0)),\n", + " ((0, 1), (1, 1)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 0), (0, 0)): ((0, 0, 0), (1, 0, 0), (1, 0, 0)),\n", + " ((1, 0), (0, 1)): ((1, 1, 0), (1, 1, 0), (0, 0, 0)),\n", + " ((1, 0), (1, 0)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((1, 0), (1, 1)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 1), (0, 0)): ((1, 0, 1), (0, 1, 0), (0, 1, 0)),\n", + " ((1, 1), (0, 1)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 1), (1, 0)): ((0, 1, 1), (1, 1, 1), (1, 0, 0)),\n", + " ((1, 1), (1, 1)): ((0, 1, 1), (1, 0, 0), (1, 1, 0))}" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Enhancements('''\n", + "../.. => .../.#./.#.\n", + "#./.. => .../#../#..\n", + "##/.. => #.#/.#./.#.\n", + ".#/#. => ##./##./...\n", + "##/#. => .##/###/#..\n", + "##/## => .##/#../##.\n", + "'''.strip().splitlines())" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "16" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looks good; let's create my complete table. There should be 24 + 29 entries:" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enhancements = Enhancements(Input(21))\n", + "\n", + "assert len(enhancements) == 2 ** 4 + 2 ** 9" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now on each iteration we `enhance` the grid by first `expand`-ing it (looking up each `slice` in the `enhancements` rules) and then `stitch` the pieces together:" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def enhance(grid): \n", + " \"Expand small pieces into bigger ones and stitch them together.\"\n", + " return stitch(expand(grid))\n", + "\n", + "def expand(grid):\n", + " \"Slice the grid into d x d pieces and enhance each piece.\"\n", + " N = len(grid[0])\n", + " d = (2 if N % 2 == 0 else 3 if N % 3 == 0 else error())\n", + " return [[enhancements[slice(grid, r, c, d)]\n", + " for c in range(0, N, d)]\n", + " for r in range(0, N, d)]\n", + "\n", + "def stitch(pieces): \n", + " \"Stitch the pieces back into one big grid.\"\n", + " N = sum(map(len, pieces[0]))\n", + " return tuple(tuple(get(pieces, r, c) \n", + " for c in range(N))\n", + " for r in range(N))\n", + "\n", + "def get(pieces, r, c):\n", + " \"The pixel at location (r, c), from a matrix of d x d pieces.\"\n", + " d = len(pieces[0][0])\n", + " row = pieces[r // d]\n", + " cell = row[c // d]\n", + " return cell[r % d][c % d]\n", + "\n", + "def slice(grid, r, c, d):\n", + " \"The d x d slice of grid starting at position (r, c)\"\n", + " return tuple(row[c:c+d] for row in grid[r:r+d])" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 1, 0), (0, 0, 1), (1, 1, 1))" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid = Key('.#./..#/###')\n", + "grid" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[((1, 0, 1, 0), (0, 0, 1, 0), (0, 1, 0, 1), (0, 1, 0, 0))]]" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expand(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((1, 0, 1, 0), (0, 0, 1, 0), (0, 1, 0, 1), (0, 1, 0, 0))" + ] + }, + "execution_count": 96, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stitch(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[((0, 0, 0), (1, 0, 0), (1, 0, 0)), ((1, 0, 1), (0, 1, 0), (0, 1, 0))],\n", + " [((1, 0, 1), (0, 1, 0), (0, 1, 0)), ((0, 0, 0), (1, 0, 0), (1, 0, 0))]]" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expand(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 0, 0, 1, 0, 1),\n", + " (1, 0, 0, 0, 1, 0),\n", + " (1, 0, 0, 0, 1, 0),\n", + " (1, 0, 1, 0, 0, 0),\n", + " (0, 1, 0, 1, 0, 0),\n", + " (0, 1, 0, 1, 0, 0))" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stitch(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(flatten(_))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks right; Let's try to solve the puzzle:" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "147" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(flatten(repeat(5, enhance, grid)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Part Two**\n", + "\n", + "It looked like I didn't need to change any code to do Part Two, just change the `5` to an `18`. I ran it, and got an answer in a few seconds—but the answer was wrong. I went back and carefully looked over my code, and realized there was a place in `expand` where I had swapped the order of `r` and `c` (the code there is fixed now). Apparently there is some symmetry over the first 5 enhancements that yields the correct answer either way, but that breaks down over 18 enhancements. (Also: if I had guessed that `sum(flatten(repeat(n, enhance, grid)))` would be used in both parts, I probably would have created a function for it. But I was guessing that Part Two would involve `enhance`, but not necessarily in the same way as Part One.)" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1936582" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(flatten(repeat(18, enhance, grid)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Note on Reuse\n", + "\n", + "One interesting question about these two-part problems: how does the code in Part Two use the code in Part One? \n", + "Here are my answers:\n", + "\n", + "* **All new**: All the code for Part Two (except possibly reading and parsing the input) is brand new: \n", + "
Days 1, 2, 4, 7\n", + "\n", + "* **Reuse as is**: The major function defined in Part One is called again in Part Two (and some new code\n", + "is also written):\n", + "
Days 3 (`spiral`), 6 (`spread`, but `realloc2` is copy-paste-edit), 9, 12, 14 (`bits`), \n", + "15 (`A, B, gen, judge`), 16 (`perform`), 19 (`follow_tubes`), 20 (`evolve, particles`), 21 (`expands`, `gridsum`)\n", + "\n", + "* **Generalize**: A major function from Part One is generalized in Part Two (e.g. by adding an optional parameter):\n", + "
Days 13 (`caught`)\n", + "\n", + "* **Copy-paste-edit**: The major function from Part One is copied and edited for Part Two:\n", + "
Days 5 (`run2`), 8 (`run82`), 10 (`knothash2`), 11 (`follow2`), 17 (`spinlock2`), 18 (`step18`)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Wrapping Up: Verification and Timing\n", + "\n", + "Here is a little test harness to verify that I still get the right answers (even if I refactor some of the code):" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 54.6 s, sys: 156 ms, total: 54.7 s\n", + "Wall time: 54.9 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "def day(d, compute1, answer1, compute2, answer2):\n", + " \"Assert that we get the right answers for this day.\"\n", + " assert compute1 == answer1\n", + " assert compute2 == answer2\n", + "\n", + "day(1, sum(digits[i] for i in range(N) if digits[i] == digits[i - 1]), 1158,\n", + " sum(digits[i] for i in range(N) if digits[i] == digits[i - N // 2]), 1132)\n", + "day(2, sum(abs(max(row) - min(row)) for row in rows2), 46402, \n", + " sum(map(evendiv, rows2)), 265)\n", + "day(3, cityblock_distance(nth(spiral(), M - 1)), 475, \n", + " first(x for x in spiralsums() if x > M), 279138)\n", + "day(4, quantify(Input(4), is_valid), 337, \n", + " quantify(Input(4), is_valid2), 231)\n", + "day(5, run(program), 364539, \n", + " run2(program), 27477714)\n", + "day(6, realloc(banks), 12841, \n", + " realloc2(banks), 8038)\n", + "day(7, first(programs - set(flatten(above.values()))), 'wiapj', \n", + " correct(wrongest(programs)), 1072)\n", + "day(8, max(run8(program8).values()), 6828, \n", + " run8_2(program8), 7234)\n", + "day(9, total_score(text2), 9662, \n", + " len(text1) - len(text3), 4903)\n", + "day(10, knothash(stream), 4480, \n", + " knothash2(stream2), 'c500ffe015c83b60fad2e4b7d59dabc4')\n", + "day(11, follow(path), 705, \n", + " follow2(path), 1469)\n", + "day(12, len(G[0]), 115, \n", + " len({Set(G[i]) for i in G}), 221)\n", + "day(13, trip_severity(scanners), 1504, \n", + " safe_delay(scanners), 3823370)\n", + "day(14, sum(bits(key, i).count('1') for i in range(128)), 8316, \n", + " flood_all(Grid(key)), 1074)\n", + "day(15, judge(A(), B()), 597, \n", + " judge(criteria(4, A()), criteria(8, B()), 5*10**6), 303)\n", + "day(16, perform(dance), 'lbdiomkhgcjanefp', \n", + " whole(48, dance), 'ejkflpgnamhdcboi')\n", + "day(17, spinlock2().find(2017).next.data, 355,\n", + " spinlock3(N=50*10**6)[1], 6154117)\n", + "day(18, run18(program18), 7071, \n", + " run18_2(program18)[1].sends, 8001)\n", + "day(19, cat(filter(str.isalpha, follow_tubes(diagram))), 'VEBTPXCHLI', \n", + " quantify(follow_tubes(diagram)), 18702)\n", + "day(20, closest(nth(evolve(particles()), 1000)).id, 243,\n", + " len(nth(map(remove_collisions, evolve(particles())), 1000)), 648)\n", + "day(21, sum(flatten(repeat(5, enhance, grid))), 147,\n", + " sum(flatten(repeat(18, enhance, grid))), 1936582)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here is a plot of the time taken to program solutions to both parts of each puzzle each day, for me, the first person to finish, and the hundredth person. On days when I started late, the times are my estimates, not official times (these include days 1, 3, 8, 13, 14, 17, 18, 21)." + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_times(times):\n", + " plt.style.use('seaborn-whitegrid')\n", + " X = ints(1, len(times[0]) - 2)\n", + " for (label, mark, *Y) in times:\n", + " plt.plot(X, Y, mark, label=label)\n", + " plt.xlabel('Day Number'); plt.ylabel('Minutes to Solve Both Parts')\n", + " plt.legend(loc='upper left')\n", + "\n", + "x = None\n", + "plot_times([\n", + " ('Me', 'd:', 4, 6, 20, 5, 12, 30, 33, 10, 21, 40, 13, 12, 30, 41, 13, 64, 54, 74, 50, 18, 40),\n", + " ('100th', 'v:', 6, 6, 23, 4, 5, 9, 25, 8, 12, 25, 12, 9, 22, 25, 10, 27, 16, 41, 18, 21, 45),\n", + " ('1st', '^:', 1, 1, 4, 1, 2, 3, 10, 3, 4, 6, 3, 2, 6, 5, 2, 5, 5, 10, 5, 7, 10)])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Advent of Code.ipynb b/pytudes/ipynb/Advent of Code.ipynb new file mode 100644 index 0000000..812fe73 --- /dev/null +++ b/pytudes/ipynb/Advent of Code.ipynb @@ -0,0 +1,3226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# December 2016: Advent of Code Solutions\n", + "\n", + "## Peter Norvig\n", + "\n", + "From Dec. 1 to Dec. 25, [I](http://norvig.com) will be solving the puzzles that appear each day at *[Advent of Code](http://adventofcode.com/)*. The two-part puzzles are released at midnight EST (9:00PM PST); points are awarded to the first 100 people to solve the day's puzzles. The code shown here basically represents what I did to solve the problem, but slightly cleaned up:\n", + "- On days when I start at 9:00PM and am competing against the clock, I take shortcuts. I use shorter names, because I'm not a fast typist. I run test cases in the Jupyter Notebook, but don't make them into `assert` statements. Even then, I'm not really competitive with the fastest solvers.\n", + "- On days when I didn't get a chance to start until after all the points are gone, what you see here is pretty much exactly what I did, or at least what I ended up with after correcting typos and other errors. \n", + "\n", + "To understand the problems completely, you will have to read the full description in the **\"[Day 1](http://adventofcode.com/2016/day/1):\"** link in each day's section header.\n", + "\n", + "# Day 0: Getting Ready\n", + "\n", + "On November 30th, I spent some time preparing: \n", + "\n", + "- I'll import my favorite modules and functions, so I don't have to do it each day.\n", + "\n", + "- From looking at [last year's](http://adventofcode.com/2015) puzzles, I knew that there would be a data file on many days, so I defined the function `Input` to open the file (and for those using this notebook on a remote machine, to fetch the file from the web). My data files are at [http://norvig.com/ipython/advent2016/](http://norvig.com/ipython/advent2016/).\n", + "\n", + "- From working on another puzzle site, [Project Euler](https://projecteuler.net/), I had built up a collection of utility functions, shown below:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Python 3.x\n", + "import re\n", + "import numpy as np\n", + "import math\n", + "import urllib.request\n", + "\n", + "from collections import Counter, defaultdict, namedtuple, deque\n", + "from functools import lru_cache\n", + "from itertools import permutations, combinations, chain, cycle, product, islice\n", + "from heapq import heappop, heappush\n", + "\n", + "def Input(day):\n", + " \"Open this day's input file.\"\n", + " filename = 'advent2016/input{}.txt'.format(day)\n", + " try:\n", + " return open(filename)\n", + " except FileNotFoundError:\n", + " return urllib.request.urlopen(\"http://norvig.com/ipython/\" + filename)\n", + "\n", + "def transpose(matrix): return zip(*matrix)\n", + "\n", + "def first(iterable): return next(iter(iterable))\n", + "\n", + "def nth(iterable, n, default=None):\n", + " \"Returns the nth item of iterable, or a default value\"\n", + " return next(islice(iterable, n, None), default)\n", + "\n", + "cat = ''.join\n", + "\n", + "Ø = frozenset() # Empty set\n", + "inf = float('inf')\n", + "BIG = 10 ** 999\n", + "\n", + "def grep(pattern, lines):\n", + " \"Print lines that match pattern.\"\n", + " for line in lines:\n", + " if re.search(pattern, line):\n", + " print(line)\n", + "\n", + "def groupby(iterable, key=lambda it: it):\n", + " \"Return a dic whose keys are key(it) and whose values are all the elements of iterable with that key.\"\n", + " dic = defaultdict(list)\n", + " for it in iterable:\n", + " dic[key(it)].append(it)\n", + " return dic\n", + "\n", + "def powerset(iterable):\n", + " \"Yield all subsets of items.\"\n", + " items = list(iterable)\n", + " for r in range(len(items)+1):\n", + " for c in combinations(items, r):\n", + " yield c\n", + "\n", + "# 2-D points implemented using (x, y) tuples\n", + "def X(point): return point[0]\n", + "def Y(point): return point[1]\n", + "\n", + "def neighbors4(point): \n", + " \"The four neighbors (without diagonals).\"\n", + " x, y = point\n", + " return ((x+1, y), (x-1, y), (x, y+1), (x, y-1))\n", + "\n", + "def neighbors8(point): \n", + " \"The eight neighbors (with diagonals).\"\n", + " x, y = point \n", + " return ((x+1, y), (x-1, y), (x, y+1), (x, y-1),\n", + " (x+1, y+1), (x-1, y-1), (x+1, y-1), (x-1, y+1))\n", + "\n", + "def cityblock_distance(p, q=(0, 0)): \n", + " \"City block distance between two points.\"\n", + " return abs(X(p) - X(q)) + abs(Y(p) - Y(q))\n", + "\n", + "def euclidean_distance(p, q=(0, 0)): \n", + " \"Euclidean (hypotenuse) distance between two points.\"\n", + " return math.hypot(X(p) - X(q), Y(p) - Y(q))\n", + "\n", + "def trace1(f):\n", + " \"Print a trace of the input and output of a function on one line.\"\n", + " def traced_f(*args):\n", + " result = f(*args)\n", + " print('{}({}) = {}'.format(f.__name__, ', '.join(map(str, args)), result))\n", + " return result\n", + " return traced_f\n", + "\n", + "def astar_search(start, h_func, moves_func):\n", + " \"Find a shortest sequence of states from start to a goal state (a state s with h_func(s) == 0).\"\n", + " frontier = [(h_func(start), start)] # A priority queue, ordered by path length, f = g + h\n", + " previous = {start: None} # start state has no previous state; other states will\n", + " path_cost = {start: 0} # The cost of the best path to a state.\n", + " while frontier:\n", + " (f, s) = heappop(frontier)\n", + " if h_func(s) == 0:\n", + " return Path(previous, s)\n", + " for s2 in moves_func(s):\n", + " new_cost = path_cost[s] + 1\n", + " if s2 not in path_cost or new_cost < path_cost[s2]:\n", + " heappush(frontier, (new_cost + h_func(s2), s2))\n", + " path_cost[s2] = new_cost\n", + " previous[s2] = s\n", + " return dict(fail=True, front=len(frontier), prev=len(previous))\n", + " \n", + "def Path(previous, s): \n", + " \"Return a list of states that lead to state s, according to the previous dict.\"\n", + " return ([] if (s is None) else Path(previous, previous[s]) + [s])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some tests/examples for these:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "assert tuple(transpose(((1, 2, 3), (4, 5, 6)))) == ((1, 4), (2, 5), (3, 6))\n", + "assert first('abc') == first(['a', 'b', 'c']) == 'a'\n", + "assert cat(['a', 'b', 'c']) == 'abc'\n", + "assert (groupby(['test', 'one', 'two', 'three', 'four'], key=len) \n", + " == {3: ['one', 'two'], 4: ['test', 'four'], 5: ['three']})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 1](http://adventofcode.com/2016/day/1): No Time for a Taxicab\n", + "\n", + "Given a sequence of moves, such as `\"R2, L3\"`, which means turn 90° to the right and go forward 2 blocks, then turn 90° left and go 3 blocks, how many blocks do we end up away from the start? I make the following choices:\n", + "* **Intersection Points** in the city grid will be represented as points on the complex plane. \n", + "* **Headings and turns** can be represented by unit vectors in the complex plane: if you are heading east (along the positive real axis), then a left turn means you head north, and a right turn means you head south, and [in general](https://betterexplained.com/articles/understanding-why-complex-multiplication-works/) a left or right turn is a multiplication of your current heading by the `North` or `South` unit vectors, respectively. \n", + "* **Moves** of the form `\"R53\"` will be parsed into a `(turn, distance)` pair, e.g. `(South, 53)`.\n", + "\n", + "To solve the puzzle with the function `how_far(moves)`, I initialize the starting location as the origin and the starting heading as North, and follow the list of moves, updating the heading and location on each step, before returning the distance from the final location to the origin." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "250.0" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Point = complex \n", + "N, S, E, W = 1j, -1j, 1, -1 # Unit vectors for headings\n", + "\n", + "def distance(point): \n", + " \"City block distance between point and the origin.\"\n", + " return abs(point.real) + abs(point.imag)\n", + "\n", + "def how_far(moves):\n", + " \"After following moves, how far away from the origin do we end up?\"\n", + " loc, heading = 0, N # Begin at origin, heading North\n", + " for (turn, dist) in parse(moves):\n", + " heading *= turn\n", + " loc += heading * dist\n", + " return distance(loc)\n", + "\n", + "def parse(text):\n", + " \"Return a list of (turn, distance) pairs from text of form 'R2, L42, ...'\"\n", + " turns = dict(L=N, R=S)\n", + " return [(turns[RL], int(d))\n", + " for (RL, d) in re.findall(r'(R|L)(\\d+)', text)]\n", + "\n", + "assert distance(Point(3, 4)) == 7 # City block distance; Euclidean distance would be 5\n", + "assert parse('R2, L42') == [(S, 2), (N, 42)]\n", + "assert how_far(\"R2, L3\") == 5\n", + "assert how_far(\"R2, R2, R2\") == 2\n", + "assert how_far(\"R5, L5, R5, R3\") == 12\n", + "\n", + "how_far(Input(1).read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two** of this puzzle, I have to find the first point that is visited twice. To support that, I keep track of the set of visited points. My first submission was wrong, because I didn't consider that the first point visited twice might be in the middle of a move, not the end, so I added the \"`for i`\" loop to iterate over the path of a move, one point at a time." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "151.0" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def visited_twice(text):\n", + " \"Following moves in text, find the first location we visit twice, and return the distance to it.\"\n", + " loc, heading = 0, N # Begin at origin, heading North\n", + " visited = {loc}\n", + " for (turn, dist) in parse(text):\n", + " heading *= turn\n", + " for i in range(dist):\n", + " loc += heading\n", + " if loc in visited:\n", + " return distance(loc)\n", + " visited.add(loc)\n", + "\n", + "assert visited_twice(\"R8, R4, R4, R8\") == 4\n", + "assert visited_twice(\"R8, R4, R4, L8\") == None\n", + "assert visited_twice(\"R8, R0, R1\") == 7\n", + "\n", + "visited_twice(Input(1).read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 2](http://adventofcode.com/2016/day/2): Bathroom Security\n", + "\n", + "Given instructions in the form of a sequence of Up/Down/Right/Left moves, such as `'ULL'`, output the keys on the bathroom lock keypad that the instructions correspond to. Start at the 5 key. Representation choices:\n", + "* **Keypad**: a keypad is an array of strings: `keypad[y][x]` is a key. The character `'.'` indicates a location that is `off` the keypad; by surrounding the keys with a border of `off` characters, I avoid having to write code that checks to see if we hit the edge.\n", + "* **Key**: A key is a character other than `'.'`.\n", + "* **Instructions**: A sequence of lines of `\"UDRL\"` characters, where each line leads to the output of one key." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'97289'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Keypad = str.split\n", + "\n", + "keypad = Keypad(\"\"\"\n", + ".....\n", + ".123.\n", + ".456.\n", + ".789.\n", + ".....\n", + "\"\"\")\n", + "\n", + "assert keypad[2][2] == '5'\n", + "\n", + "off = '.'\n", + "\n", + "def decode(instructions, x=2, y=2):\n", + " \"\"\"Follow instructions, keeping track of x, y position, and\n", + " yielding the key at the end of each line of instructions.\"\"\"\n", + " for line in instructions:\n", + " for C in line:\n", + " x, y = move(C, x, y)\n", + " yield keypad[y][x]\n", + "\n", + "def move(C, x, y):\n", + " \"Make the move corresponding to this character (L/R/U/D)\"\n", + " if C == 'L' and keypad[y][x-1] is not off: x -= 1\n", + " elif C == 'R' and keypad[y][x+1] is not off: x += 1\n", + " elif C == 'U' and keypad[y-1][x] is not off: y -= 1\n", + " elif C == 'D' and keypad[y+1][x] is not off: y += 1\n", + " return x, y\n", + "\n", + "assert move('U', 2, 2) == (2, 1)\n", + "assert move('U', 2, 1) == (2, 1)\n", + "assert cat(decode(\"ULL RRDDD LURDL UUUUD\".split())) == '1985'\n", + "\n", + "cat(decode(Input(2)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we have to deal with a different keypad. I won't need any new functions, but I will need to redefine the global variable `keypad`, and provide `decode` with the new `x` and `y` coordinates of the `5` key:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'9A7DC'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "keypad = Keypad(\"\"\"\n", + ".......\n", + "...1...\n", + "..234..\n", + ".56789.\n", + "..ABC..\n", + "...D...\n", + ".......\n", + "\"\"\")\n", + "\n", + "assert keypad[3][1] == '5'\n", + "\n", + "cat(decode(Input(2), x=1, y=3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 3](http://adventofcode.com/2016/day/3): Squares With Three Sides\n", + "\n", + "From a file of numbers, three to a line, count the number that represent valid triangles; that is, numbers that satisfy the [triangle inequality](https://en.wikipedia.org/wiki/Triangle_inequality)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "983" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def is_triangle(sides):\n", + " \"Do these side lengths form a valid triangle?\"\n", + " x, y, z = sorted(sides)\n", + " return z < x + y\n", + "\n", + "def parse_ints(text): \n", + " \"All the integers anywhere in text.\"\n", + " return [int(x) for x in re.findall(r'\\d+', text)]\n", + "\n", + "triangles = [parse_ints(line) for line in Input(3)]\n", + "\n", + "sum(map(is_triangle, triangles))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, the triangles are denoted not by three sides in the same line, but by three sides in the same column. For example, given the text:\n", + "\n", + " 101 301 501\n", + " 102 302 502\n", + " 103 303 503\n", + " 201 401 601\n", + " 202 402 602\n", + " 203 403 603\n", + " \n", + "The triangles are:\n", + "\n", + " [101, 102, 103]\n", + " [301, 302, 303]\n", + " [501, 502, 503]\n", + " [201, 202, 203]\n", + " [401, 402, 403]\n", + " [601, 602, 603]\n", + " \n", + "The task is still to count the number of valid triangles." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1836" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def invert(triangles):\n", + " \"Take each 3 lines and transpose them.\"\n", + " for i in range(0, len(triangles), 3):\n", + " yield from transpose(triangles[i:i+3])\n", + "\n", + "sum(map(is_triangle, invert(triangles)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 4](http://adventofcode.com/2016/day/4): Security Through Obscurity\n", + "\n", + "Given a list of room names like `\"aaaaa-bbb-z-y-x-123[abxyz]\"`, consisting of an encrypted name followed by a dash, a sector ID, and a checksum in square brackets, compute the sum of the sectors of the valid rooms. A room is valid if the checksum is the five most common characters, in order (ties listed in alphabetical order)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "185371" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def parse(line): \n", + " \"Return (name, sector, checksum).\"\n", + " return re.match(r\"(.+)-(\\d+)\\[([a-z]+)\\]\", line).groups()\n", + "\n", + "def sector(line):\n", + " \"Return the sector number if valid, or 0 if not.\"\n", + " name, sector, checksum = parse(line)\n", + " return int(sector) if valid(name, checksum) else 0\n", + "\n", + "def valid(name, checksum):\n", + " \"Determine if name is valid according to checksum.\"\n", + " counts = Counter(name.replace('-', '')) \n", + " # Note: counts.most_common(5) doesn't work because it breaks ties arbitrarily.\n", + " letters = sorted(counts, key=lambda L: (-counts[L], L))\n", + " return checksum == cat(letters[:5])\n", + "\n", + "assert parse('aaaaa-bbb-z-y-x-123[abxyz]') == ('aaaaa-bbb-z-y-x', '123', 'abxyz')\n", + "assert sector('aaaaa-bbb-z-y-x-123[abxyz]') == 123\n", + "assert valid('aaaaa-bbb-z-y-x', 'abxyz')\n", + "\n", + "sum(map(sector, Input(4)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initially I had a bug: I forgot the `name.replace('-', '')` to make sure that we don't count hyphens. \n", + "\n", + "In **part two**, we are asked *\"What is the sector ID of the room where North Pole objects are stored?\"* We are told that names are to be decrypted by a shift cipher, shifting each letter forward in the alphabet by the sector number." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "northpole-object-storage 984\n" + ] + } + ], + "source": [ + "def decrypt(line):\n", + " \"Decrypt the line (shift the name by sector; discard checksum).\"\n", + " name, sector, _ = parse(line)\n", + " return shift(name, int(sector)) + ' ' + sector\n", + "\n", + "def shift(text, N, alphabet='abcdefghijklmnopqrstuvwxyz'):\n", + " \"Shift cipher: letters in text rotate forward in alphabet by N places.\"\n", + " N = N % len(alphabet)\n", + " tr = str.maketrans(alphabet, alphabet[N:] + alphabet[:N])\n", + " return text.translate(tr)\n", + "\n", + "assert shift('hal', 1) == 'ibm'\n", + "assert shift('qzmt-zixmtkozy-ivhz', 343) == 'very-encrypted-name'\n", + "\n", + "grep(\"north\", map(decrypt, Input(4)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 5](http://adventofcode.com/2016/day/5): How About a Nice Game of Chess?\n", + "\n", + "This puzzle involves md5 hashes and byte encodings; it took me a while to look up how to do that. What I have to do, for integers starting at 0, is concatenate my door ID string with the integer, get the md5 hex hash, and if the first five digits of the hash are 0, collect the sixth digit; repeat until I have collected eight digits:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "515840 00000c6c3f533fe4f7b0cb6d851185a8 c\n", + "844745 000006a94bb1c9322cbb56dd8564e76e c6\n", + "2968550 000006c8c9090315b0fb38154a947c86 c66\n", + "4034943 00000970faef6424564944d5e8a59618 c669\n", + "5108969 000007b2e0e83dfeade14ebe09f9e6a7 c6697\n", + "5257971 00000bc5fdee6506b09262247ceb63f0 c6697b\n", + "5830668 0000051079ac6b44fc3a5266a1630d42 c6697b5\n", + "5833677 00000537192966c3ee924306195faede c6697b55\n" + ] + }, + { + "data": { + "text/plain": [ + "'c6697b55'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import hashlib\n", + "\n", + "door = \"ffykfhsq\"\n", + "\n", + "def find_password(door):\n", + " \"First 8 sixth digits of md5 hashes of door+i that begin with '00000'.\"\n", + " password = ''\n", + " for i in range(BIG):\n", + " x = hashlib.md5(bytes(door + str(i), 'utf-8')).hexdigest()\n", + " if x.startswith('00000'):\n", + " password += x[5]\n", + " print(i, x, password) # Just to see something happen\n", + " if len(password) == 8: \n", + " return password\n", + "\n", + "find_password(door)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, the sixth digit of the hash that starts with `'00000'` is to be treated as an index that tells where in the password to place the *seventh* digit of the hash. For example, if the sixth digit is `2` and the seventh digit is `a`, then place `a` as the second digit of the final password. Do nothing if the sixth digit is not less than 8, or if a digit has already been placed at that index location." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "844745 000006a94bb1c9322cbb56dd8564e76e ......a.\n", + "5108969 000007b2e0e83dfeade14ebe09f9e6a7 ......ab\n", + "5830668 0000051079ac6b44fc3a5266a1630d42 .....1ab\n", + "6497076 0000008239d1bbf480ea541e9da1e494 8....1ab\n", + "8962195 00000351ce68ffb449644d4bfa4cee5d 8..5.1ab\n", + "23867827 000001c3c28bcbacf0f543a33548ef24 8c.5.1ab\n", + "24090051 000004d57fc545f376c09f27383b2c88 8c.5d1ab\n", + "26383109 0000023d12c49f028699d4679ba91780 8c35d1ab\n", + "CPU times: user 30.4 s, sys: 48.7 ms, total: 30.4 s\n", + "Wall time: 30.4 s\n" + ] + }, + { + "data": { + "text/plain": [ + "'8c35d1ab'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def find_tougher_password(door):\n", + " \"For md5 hashes that begin with '00000', the seventh digit goes in the sixth-digit slot of the password.\"\n", + " password = [off] * 8\n", + " for i in range(BIG):\n", + " x = hashlib.md5(bytes(door + str(i), 'utf-8')).hexdigest()\n", + " if x.startswith('00000'):\n", + " index = int(x[5], 16)\n", + " if index < 8 and password[index] is off:\n", + " password[index] = x[6]\n", + " print(i, x, cat(password)) # Just to see something happen\n", + " if off not in password:\n", + " return cat(password)\n", + "\n", + "%time find_tougher_password(door)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 6](http://adventofcode.com/2016/day/6): Signals and Noise\n", + "\n", + "Given a file, where each line is a string of letters and every line has the same length, find the most common letter in each column. We can easily do this with the help of `Counter.most_common`. (Note I use `Input(6).read().split()` instead of just `Input(6)` so that I don't get the `'\\n'` at the end of each line.)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'tsreykjj'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counts = [Counter(col) for col in transpose(Input(6).read().split())]\n", + "cat(c.most_common(1)[0][0] for c in counts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just to make it clear, here's how we ask for the most common character (and its count) in the first column:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('t', 24)]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c = counts[0]\n", + "c.most_common(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here is how we pick out the `'t'` character:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'t'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.most_common(1)[0][0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we ask for the *least* common character in each column. Easy-peasy:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'hnfbujie'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(c.most_common()[-1][0] for c in counts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 7](http://adventofcode.com/2016/day/7): Internet Protocol Version 7\n", + "\n", + "Given input lines of the form `'abcd[1234]fghi[56789]zz[0]z'`, count the number of lines that are a *TLS*, meaning they have an *ABBA* outside of square brackets, but no *ABBA* inside brackets. An *ABBA* is a 4-character subsequence where the first two letters are the same as the last two, but not all four are the same.\n", + "\n", + "I assume brackets are in proper pairs, and are never nested. Then if I do a `re.split` on brackets, the even-indexed pieces of the split will be outside the brackets, and the odd-indexed will be inside. For example:\n", + "- Given the line `'abcd[1234]fghi[56789]zz'`\n", + "- Split on brackets to get `['abcd', '1234', 'fghi', '56789', 'zz']`\n", + "- Outsides of brackets are `'abcd, fghi, zz'` at indexes 0, 2, 4.\n", + "- Insides of brackets are `'1234, 56789'` at indexes 1, 3." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "110" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def abba(text): return any(a == d != b == c for (a, b, c, d) in subsequences(text, 4))\n", + "def subsequences(seq, n): return [seq[i:i+n] for i in range(len(seq) + 1 - n)]\n", + "def segment(line): return re.split(r'\\[|\\]', line)\n", + "def outsides(segments): return ', '.join(segments[0::2])\n", + "def insides(segments): return ', '.join(segments[1::2])\n", + "def tls(segments): return abba(outsides(segments)) and not abba(insides(segments))\n", + "\n", + "sum(tls(segment(line)) for line in Input(7))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are some tests:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "assert abba('abba') and not abba('aaaa') and not abba('abbc')\n", + "assert subsequences('abcdefg', 4) == ['abcd', 'bcde', 'cdef', 'defg']\n", + "assert segment('abcd[1234]fghi[56789]zz') == ['abcd', '1234', 'fghi', '56789', 'zz']\n", + "assert outsides(['abcd', '1234', 'fghi', '56789', 'zz']) == 'abcd, fghi, zz'\n", + "assert insides(['abcd', '1234', 'fghi', '56789', 'zz']) == '1234, 56789'\n", + "assert tls(['abba', '123']) \n", + "assert not tls(['bookkeeper', '123']) and not tls(['abba', 'xxyyx'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we are asked to count the number of *SSL* lines: an *SSL* is when there is an *ABA* outside brackets, and the corresponding *BAB* inside brackets. An *ABA* is a three-character sequence with first and third (but not all three) the same. The corresponding *BAB* has the first character of the *ABA* surrounded by two copies of the second character." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "242" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alphabet = 'abcdefghijklmnopqrstuvwxyz'\n", + "\n", + "def ssl(segments): \n", + " \"Is there an ABA outside brackets, and the corresponding BAB inside?\"\n", + " outs, ins = outsides(segments), insides(segments)\n", + " return any(a+b+a in outs and b+a+b in ins\n", + " for a in alphabet for b in alphabet if a != b)\n", + "\n", + "sum(ssl(segment(line)) for line in Input(7))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 8](http://adventofcode.com/2016/day/8): Two-Factor Authentication\n", + "\n", + "Given an array of pixels on a screen, follow commands that can:\n", + "- Turn on a sub-rectangle of pixels in the upper left corner: `rect 3x2`\n", + "- Rotate a row of pixels: `rotate row y=0 by 4`\n", + "- Rotate a column of pixels: `rotate column x=1 by 1`\n", + "\n", + "Then count the total number of `1` pixels in the screen.\n", + "\n", + "I will use `numpy` two-dimensional arrays, mostly because of the `screen[:, A]` notation for getting at a column." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "128" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def interpret(cmd, screen):\n", + " \"Interpret this command to mutate screen.\"\n", + " A, B = map(int, re.findall(r'(\\d+)', cmd)) # There should be 2 numbers on every command line\n", + " if cmd.startswith('rect'):\n", + " screen[:B, :A] = 1\n", + " elif cmd.startswith('rotate row'):\n", + " screen[A, :] = rotate(screen[A, :], B)\n", + " elif cmd.startswith('rotate col'):\n", + " screen[:, A] = rotate(screen[:, A], B)\n", + "\n", + "def rotate(items, n): return np.append(items[-n:], items[:-n])\n", + "\n", + "def Screen(): return np.zeros((6, 50), dtype=np.int)\n", + "\n", + "def run(commands, screen):\n", + " \"Do all the commands and return the final pixel array.\"\n", + " for cmd in Input(8):\n", + " interpret(cmd, screen) \n", + " return screen\n", + "\n", + "screen = run(Input(8), Screen())\n", + "np.sum(screen)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we are asked what message is on the screen. I won't try to do OCR; I'll just print the screen and look at the output:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "@@@@ @@ @@ @@@ @@ @@@ @ @ @ @ @@ @@ \n", + "@ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @ @ @ \n", + "@@@ @ @ @ @ @ @ @ @ @ @@@@ @ @ @ @ @ @ \n", + "@ @ @ @@@@ @@@ @ @@ @@@ @ @ @ @@@@ @ @ \n", + "@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n", + "@@@@ @@ @ @ @ @ @@@ @ @ @ @ @ @ @@ \n" + ] + } + ], + "source": [ + "for row in screen:\n", + " print(cat(' @'[pixel] for pixel in row))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "My answer is `EOARGPHYAO`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 9](http://adventofcode.com/2016/day/9): Explosives in Cyberspace\n", + "\n", + "In this puzzle we are asked to decompress text of the form `'A(2x5)BCD'`, where the `'(2x5)'` means to make 5 copies of the next 2 characters, yielding `'ABCBCBCBCBCD'`. We'll go through the input text, a character at a time, and if a `re` matcher detects a `'(CxR)'` pattern, process it; otherwise just collect the character. Note that the `C` characters that are to be repeated `R` times are taken literally; even if they contain an embedded `'(1x5)'`." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "138735" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matcher = re.compile(r'[(](\\d+)x(\\d+)[)]').match # e.g. matches \"(2x5)\" as ('2', '5')\n", + "\n", + "def decompress(s):\n", + " \"Decompress string s by interpreting '(2x5)' as making 5 copies of the next 2 characters.\"\n", + " s = re.sub(r'\\s', '', s) # \"whitespace is ignored\"\n", + " result = []\n", + " i = 0\n", + " while i < len(s):\n", + " m = matcher(s, i)\n", + " if m:\n", + " i = m.end() # Advance to end of '(CxR)' match\n", + " C, R = map(int, m.groups())\n", + " result.append(s[i:i+C] * R) # Collect the C characters, repeated R times\n", + " i += C # Advance past the C characters \n", + " else:\n", + " result.append(s[i]) # Collect 1 regular character\n", + " i += 1 # Advance past it\n", + " return cat(result)\n", + "\n", + "len(decompress(Input(9).read()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, the copied characters *are* recursively decompressed. So, given `'(8x2)(3x3)ABC'`, the `(8x2)` directive picks out the 8 characters `'(3x3)ABC'`, which would then be decompressed to get `'ABCABCABC'` and then the `'x2'` is applied to get `'ABCABCABCABCABCABC'`. However, for this part, we are not asked to actually build up the decompressed string, just to compute its length:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "11125026826" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def decompress_length(s):\n", + " \"\"\"Decompress string s by interpreting '(2x5)' as making 5 copies of the next 2 characters.\n", + " Recursively decompress these next 5 characters. Return the length of the decompressed string.\"\"\"\n", + " s = re.sub(r'\\s', '', s) # \"whitespace is ignored\"\n", + " length = 0\n", + " i = 0\n", + " while i < len(s):\n", + " m = matcher(s, i)\n", + " if m:\n", + " C, R = map(int, m.groups())\n", + " i = m.end(0) # Advance to end of '(CxR)'\n", + " length += R * decompress_length(s[i:i+C]) # Decompress C chars and add to length\n", + " i += C # Advance past the C characters \n", + " else:\n", + " length += 1 # Add 1 regular character to length\n", + " i += 1 # Advance past it\n", + " return length\n", + "\n", + "decompress_length(Input(9).read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are some tests:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert decompress('A(2x5)BCD') == 'ABCBCBCBCBCD'\n", + "assert decompress('ADVENT') == 'ADVENT'\n", + "assert decompress('(3x3)XYZ') == 'XYZXYZXYZ'\n", + "assert decompress('(5x4)(3x2)') == '(3x2)(3x2)(3x2)(3x2)'\n", + "assert decompress('X(8x2)(3x3)ABCY') == 'X(3x3)ABC(3x3)ABCY'\n", + " \n", + "assert decompress_length('(8x2)(3x3)ABC') == 18\n", + "assert decompress_length('(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN') == 445\n", + "assert decompress_length('(9x999)(2x999)xx') == 999 * 999 * 2 == 1996002" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 10](http://adventofcode.com/2016/day/10): Balance Bots\n", + "\n", + "In this puzzle, a fleet of robots exchange some chips from input bins, \n", + "passing them among themselves, and eventually putting them in output bins. We are given instructions like this:\n", + "\n", + " value 5 goes to bot 2\n", + " bot 2 gives low to bot 1 and high to bot 0\n", + " value 3 goes to bot 1\n", + " bot 1 gives low to output 1 and high to bot 0\n", + " bot 0 gives low to output 2 and high to output 0\n", + " value 2 goes to bot 2\n", + " \n", + "At first I thought I just had to interpret these instructions sequentially, but then I realized this is actually a *data flow* problem: *whenever* a bot acquires two chips, it passes the low number chip to one destination and the high number to another. So my representation choices are:\n", + "- Bots and bins are represented as strings: `'bot 1'` and `'output 2'`.\n", + "- Chips are represented by ints. (Not strings, because we want 9 to be less than 10).\n", + "- Keep track of which bot currently has which chip(s) with a dict: `has['bot 2'] = {5}`\n", + "- Keep track of what a bot does when it gets 2 chips with a dict: `gives['bot 1'] = ('output 1', 'bot 0')`\n", + "- Pull this information from instructions with `re.findall`. The order of instructions is not important.\n", + "- A function, `give`, moves a chip to a recipient, and if the recipient now has two chips, that triggers two more `give` calls." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "bot 113 has {17, 61}\n" + ] + } + ], + "source": [ + "def bots(instructions, goal={17, 61}):\n", + " \"Follow the data flow instructions, and if a bot gets the goal, print it.\"\n", + " def give(giver, chip, recip):\n", + " \"Pass the chip from giver to recipient.\"\n", + " has[giver].discard(chip)\n", + " has[recip].add(chip)\n", + " chips = has[recip]\n", + " if chips == goal:\n", + " print(recip, 'has', goal)\n", + " if len(chips) == 2:\n", + " give(recip, min(chips), gives[recip][0])\n", + " give(recip, max(chips), gives[recip][1])\n", + " \n", + " has = defaultdict(set) # who has what\n", + " gives = {giver: (dest1, dest2) # who will give what\n", + " for (giver, dest1, dest2) \n", + " in re.findall(r'(bot \\d+) gives low to (\\w+ \\d+) and high to (\\w+ \\d+)', instructions)}\n", + " for (chip, recip) in re.findall(r'value (\\d+) goes to (\\w+ \\d+)', instructions):\n", + " give('input bin', int(chip), recip)\n", + " return has\n", + "\n", + "has = bots(Input(10).read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we are asked for the product of three output bins:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "12803" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def out(i): return has['output ' + str(i)].pop()\n", + "\n", + "out(0) * out(1) * out(2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 11](http://adventofcode.com/2016/day/11): Radioisotope Thermoelectric Generators \n", + "\n", + "I *knew* my `astar_search` function would come in handy! To search for the shortest path to the goal, I need to provide an initial state of the world, a heuristic function (which estimates how many moves away from the goal a state is), and a function that says what states can be reached by moving the elevator up or down, and carrying some stuff. I will make these choices:\n", + "* The state of the world is represented by the `State` type, which says what floor the elevator is on, and for a tuple of floors, the set of objects that are on the floor. We use frozensets so that a state will be hashable.\n", + "* To figure out what moves can be made, consider both directions for the elevator (up or down); find all combinations of one or two items on each floor, and keep all of those moves, as long as they don't violate the constraint that we can't have a chip on the same floor as an RTG, unless the chip's own RTG is there.\n", + "* To calculate the heuristic, add up the number of floors away each item is from the top floor and divide by two (since a move might carry two items).\n", + "\n", + "Here is my input: \n", + "\n", + "* The first floor contains a thulium generator, a thulium-compatible microchip, a plutonium generator, and a strontium generator.\n", + "* The second floor contains a plutonium-compatible microchip and a strontium-compatible microchip.\n", + "* The third floor contains a promethium generator, a promethium-compatible microchip, a ruthenium generator, and a ruthenium-compatible microchip.\n", + "* The fourth floor contains nothing relevant." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "State = namedtuple('State', 'elevator, floors')\n", + "\n", + "def fs(*items): return frozenset(items)\n", + "\n", + "legal_floors = {0, 1, 2, 3}\n", + "\n", + "def combos(things):\n", + " \"All subsets of 1 or 2 things.\"\n", + " for s in chain(combinations(things, 1), combinations(things, 2)):\n", + " yield fs(*s)\n", + "\n", + "def moves(state):\n", + " \"All legal states that can be reached in one move from this state\"\n", + " L, floors = state\n", + " for L2 in {L + 1, L - 1} & legal_floors:\n", + " for stuff in combos(floors[L]):\n", + " newfloors = tuple((s | stuff if i == L2 else \n", + " s - stuff if i == state.elevator else \n", + " s)\n", + " for (i, s) in enumerate(state.floors))\n", + " if legal_floor(newfloors[L]) and legal_floor(newfloors[L2]):\n", + " yield State(L2, newfloors)\n", + "\n", + "def legal_floor(floor):\n", + " \"Floor is legal if no RTG, or every chip has its corresponding RTG.\"\n", + " rtgs = any(r.endswith('G') for r in floor)\n", + " chips = [c for c in floor if c.endswith('M')]\n", + " return not rtgs or all(generator_for(c) in floor for c in chips)\n", + "\n", + "def generator_for(chip): return chip[0] + 'G'\n", + "\n", + "def h_to_top(state):\n", + " \"An estimate of the number of moves needed to move everything to top.\"\n", + " total = sum(len(floor) * i for (i, floor) in enumerate(reversed(state.floors)))\n", + " return math.ceil(total / 2) # Can move two items in one move." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try it out on an easy sample problem:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[State(elevator=0, floors=(frozenset({'RG'}), frozenset(), frozenset({'RM'}), frozenset())),\n", + " State(elevator=1, floors=(frozenset(), frozenset({'RG'}), frozenset({'RM'}), frozenset())),\n", + " State(elevator=2, floors=(frozenset(), frozenset(), frozenset({'RG', 'RM'}), frozenset())),\n", + " State(elevator=3, floors=(frozenset(), frozenset(), frozenset(), frozenset({'RG', 'RM'})))]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "easy = State(0, (fs('RG'), Ø, fs('RM'), Ø))\n", + "\n", + "astar_search(easy, h_to_top, moves)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now to solve the real problem. The answer we need is the number of elevator moves, which is one less than the path length (because the path includes the initial state)." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 11.9 s, sys: 72.3 ms, total: 12 s\n", + "Wall time: 12 s\n" + ] + }, + { + "data": { + "text/plain": [ + "31" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "part1 = State(0, (fs('TG', 'TM', 'PG', 'SG'), fs('PM', 'SM'), fs('pM', 'pG', 'RM', 'RG'), Ø))\n", + "\n", + "%time path = astar_search(part1, h_to_top, moves)\n", + "len(path) - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we add four more items. Now, in part one there were 10 items, each of which could be on any of the 4 floors, so that's 410 ≈ 1 million states. Adding 4 more items yields ≈ 260 million states. We won't visit every state, but the run time could be around 100 times longer. I think I'll start this running, take the dog for a walk, and come back to see if it worked." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 14min 34s, sys: 11.4 s, total: 14min 46s\n", + "Wall time: 14min 52s\n" + ] + }, + { + "data": { + "text/plain": [ + "55" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "part2 = State(0, (fs('TG', 'TM', 'PG', 'SG', 'EG', 'EM', 'DG', 'DM'), \n", + " fs('PM', 'SM'), fs('pM', 'pG', 'RM', 'RG'), Ø))\n", + "\n", + "%time path = astar_search(part2, h_to_top, moves)\n", + "len(path) - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It worked. And it took about 60 times longer. If I wanted to make it more efficient, I would focus on *symmetry*: when there are two symmetric moves, we only need to consider one. For example, in terms of finding the shortest path, it is the same to move, say `{'TG', 'TM'}` or `{'EG', 'EM'}` or `{'DG', 'DM'}` when they are all on the ground floor." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 12](http://adventofcode.com/2016/day/12): Leonardo's Monorail\n", + "\n", + "This one looks pretty easy: an interpreter for an assembly language with 4 op codes and 4 registers. We start by parsing a line like `\"cpy 1 a\"` into a tuple, `('cpy', 1, 'a')`. Then to `interpret` the code, we set the program counter, `pc`, to 0, and interpret the instruction at `code[0]`, and continue until the `pc` is past the end of the code:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 318007, 'b': 196418, 'c': 0, 'd': 0}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def interpret(code, regs):\n", + " \"Execute instructions until pc goes off the end.\"\n", + " def val(x): return (regs[x] if x in regs else x)\n", + " pc = 0\n", + " while pc < len(code):\n", + " inst = code[pc]\n", + " op, x, y = inst[0], inst[1], inst[-1]\n", + " pc += 1\n", + " if op == 'cpy': regs[y] = val(x)\n", + " elif op == 'inc': regs[x] += 1\n", + " elif op == 'dec': regs[x] -= 1\n", + " elif op == 'jnz' and val(x): pc += y - 1\n", + " return regs\n", + "\n", + "def parse(line): \n", + " \"Split line into words, and convert to int where appropriate.\"\n", + " return tuple((x if x.isalpha() else int(x)) \n", + " for x in line.split())\n", + "\n", + "code = [parse(line) for line in Input(12)]\n", + "\n", + "interpret(code, dict(a=0, b=0, c=0, d=0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I had a bug initially: in the `jnz` instruction, I had `pc += y`, to do the relative jump, but I forgot the `-1` to offset the previous `pc += 1`.\n", + "\n", + "In **part two** all we have to do is initialize register `c` to 1, not 0:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 9227661, 'b': 5702887, 'c': 0, 'd': 0}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interpret(code, dict(a=0, b=0, c=1, d=0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 13](http://adventofcode.com/2016/day/13): A Maze of Twisty Little Cubicles \n", + "\n", + "This is a maze-solving puzzle, where the maze is infinite in the non-negative (x, y) quarter-plane. Each space in that infinite grid is open or closed according to this computation:\n", + "> Find `x*x + 3*x + 2*x*y + y + y*y`.\n", + "Add the office designer's favorite number (your puzzle input).\n", + "Find the binary representation of that sum; count the number of bits that are 1.\n", + "If the number of bits that are 1 is even, it's an open space (denoted `'.'`).\n", + "If the number of bits that are 1 is odd, it's a wall (denoted `'#'`).\n", + "\n", + "The problem is to find the length of the shortest path to the goal location, (31, 39). So I'll be using `astar_search` again." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "82" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "favorite = 1362\n", + "goal = (31, 39)\n", + "\n", + "def is_open(location):\n", + " \"Is this an open location?\"\n", + " x, y = location\n", + " num = x*x + 3*x + 2*x*y + y + y*y + favorite\n", + " return x >= 0 and y >= 0 and bin(num).count('1') % 2 == 0\n", + "\n", + "def open_neighbors(location): return filter(is_open, neighbors4(location))\n", + "\n", + "path = astar_search((1, 1), lambda p: cityblock_distance(p, goal), open_neighbors)\n", + "len(path) - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see a portion of the maze:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#..###.#...#..#....##.#...#....#....#..#.#.##...##.##.##.#####.#####.####.#.##..#..#.#.#.#\n", + "#.#..#.##.#######.#.#.####.##.###...##.#..#.###...#.#..#.##...#..###....##...##.#.##.#.#..\n", + "#..#.#.##.#....##...#..#.####.####...#..#..#..#.#...##......#.....######.#.#...##.##.#..##\n", + "##..##.##.#..#...###.#.....#.....##.######....#..###########.####..##....#...#......###..#\n", + "..#.##..########.#.#####...#..##.##.#.....##.###.#..#...##.###..#....####.#######.#.#.####\n", + "#............###.....#####.#####....#..##..#.###....#....#......#..#.##.#....##.###.###..#\n", + "###.##.####...#.##....#..#.#..#.##.####.##....####.###.#.##.##.###......###........#...#..\n", + "#.#..#.##.#.#.######..#.##..#.####..#.#######..###..##..#.##.#.##########.#####..#.#.#....\n", + ".###......#..#..#..####.###..#..#.#.##..#.......###...#....#....##...#......#####..#..##.#\n", + ".####..###.#.##.#.#...#..#.#.##.##......#..####..#.######.#####....#...##.......#.###..#.#\n", + "..######.###..###..##.#..###..##.#..##.####...#..##....##.#...#.###.######.######.#.##....\n", + "#..##..#.......###.#..###......#.#####..#.#...#...#..#....#...#...###....#.##..##.######..\n", + ".......##.##.#.....#....#.##.#.###..#.#.####..##.###########..##.#....##.....#..##..#..##.\n", + "#####.#.#.##...###.##...##.#..#..##.##...#######.....##..#######.#########.#.....##.#.#.#.\n", + "...##..##.#.###..#.###.#.##.#..#..##.#.....#..#####....#..##..##...#..##.#..##.#..###..##.\n", + ".#.###.#..#...#.##...#..#.#..#.......##..#.##..##.#.##.....#.....#..#...###..#......##.#..\n", + "##..#..#.######.#####.#..###..##.###.####...#.....#.#.##.#.##.#####...#.####..##.##.#..#.#\n", + "....##.#.##..#...##.#.##.####..#.###....#...#..###..#..#..#.#....#.##.#..#######.#..##.#..\n", + "##...#.......#......#.....#.###...########.#####.#..##..#..####..##.#.#...##..#..#...#..#.\n", + "###.#######.########.##.#.###.##...##..#.#.##..#.#########.##.###.##..###.....##.##.######\n", + ".##.#...###.##...#.##.#..#.....##....#.##......#.#..#........#..##.#......##.#.#.##.#...#.\n", + ".##.#.....#....#..#.##.#.####.#.#.##..#.#####.##.#..#..#####......###..##..#..##.#..#...##\n", + "...###.##.#.###.#.##.###...##..##.#.#......##.#..#.####.....##.##.#####.##..#.#..#####...#\n", + ".#..##.#..##..##...#.....#..##.#..#..##..#.##.#.##..#.#..##..#.#....#.#######.#.#....##.##\n", + "###....#...###.#...##.#####.#..#..##.#####..###.#.#.#####.###..#.##.##..#...###...##.##.##\n", + ".#.##.###.#..#.##.#.###..#..##.#####..........#.##...##.###.##.#.#....#.#.....######.#....\n", + ".####..##..#.#.##..#.....#...#.#..#####.##.##.##.#.....#.....#...#.##..###.##..#..#..#..##\n", + "...#.#...#..##..##...###.##.##..#..##.#.##.#...#.##..#.#.##.###..#.#.#..##.#.#..#.#.###...\n", + "#..##.##..#.###.#.####.#.##.###.#.....#....#.#.######..#.##.#.###..##.#....####..##.#####.\n", + "##..#######..#..#.....##.....#..######.##..#..#.....#.##.#..###.##..##.##.#..#.#..#..##.#.\n" + ] + } + ], + "source": [ + "for y in range(30):\n", + " print(cat(('.' if is_open((x, y)) else '#') for x in range(90)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we're asked how many locations we can reach in 50 moves or less. I'll grab the `breadth_first` search function from [aima-python](https://github.com/aimacode/aima-python/blob/master/search-4e.ipynb) and modify it to find all the states within N steps:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "138" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def count_locations_within(start, N, neighbors):\n", + " \"Find how many locations are within N steps from start.\"\n", + " frontier = deque([start]) # A queue of states\n", + " distance = {start: 0} # distance to start; also tracks all states seen\n", + " while frontier:\n", + " s = frontier.popleft()\n", + " if distance[s] < N:\n", + " for s2 in neighbors(s):\n", + " if s2 not in distance:\n", + " frontier.append(s2)\n", + " distance[s2] = distance[s] + 1\n", + " return len(distance)\n", + " \n", + "count_locations_within((1, 1), 50, open_neighbors)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# [Day 14](http://adventofcode.com/2016/day/14): One-Time Pad \n", + "\n", + "For this problem I again have to take the md5 hash of a string with increasing integers appended. The puzzle is to find the integer that yields the 64th key, where a hash is a key if:\n", + "- It contains three of the same character in a row, like 777. Only consider the first such triplet in a hash.\n", + "- One of the next 1000 hashes in the stream contains that same character five times in a row, like 77777.\n", + "\n", + "I'll use `lru_cache` to avoid repeating the hashing of the next 1000." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "25427" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "salt = 'yjdafjpo'\n", + "\n", + "@lru_cache(1001)\n", + "def hashval(i): return hashlib.md5(bytes(salt + str(i), 'utf-8')).hexdigest()\n", + "\n", + "def is_key(i):\n", + " \"A key has a triple like '777', and then '77777' in one of the next thousand hashval(i).\"\n", + " three = re.search(r'(.)\\1\\1', hashval(i))\n", + " if three:\n", + " five = three.group(1) * 5\n", + " return any(five in hashval(i+delta) for delta in range(1, 1001))\n", + " \n", + "def nth_key(N): return nth(filter(is_key, range(BIG)), N)\n", + "\n", + "nth_key(63)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we do *key stretching*, hashing an additional 2016 times. Eeverything else is the same:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 36.4 s, sys: 314 ms, total: 36.7 s\n", + "Wall time: 37 s\n" + ] + }, + { + "data": { + "text/plain": [ + "22045" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@lru_cache(1001)\n", + "def hashval(i, stretch=2016): \n", + " h = hashlib.md5(bytes(salt + str(i), 'utf-8')).hexdigest()\n", + " for i in range(stretch):\n", + " h = hashlib.md5(bytes(h, 'utf-8')).hexdigest()\n", + " return h\n", + "\n", + "%time nth_key(63)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This was my highest-scoring day, finishing #20 on part two." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 15](http://adventofcode.com/2016/day/15): Timing is Everything\n", + "\n", + "In this puzzle rotating discs with a slot in position 0 spin around. We are asked at what time will all the slots be lined up for a capsule to fall through the slots. The capsule takes one time unit to fall through each disc (not clear why it doesn't accelerate as it falls) and the discs spin one position per time unit." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "376777" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def parse(inputs): \n", + " \"Parse an input string into (disc#, positions, pos) triples.\"\n", + " return [tuple(map(int, triple))\n", + " for triple in re.findall(r'#(\\d+).* (\\d+) positions.* (\\d+)[.]', inputs)]\n", + " \n", + "discs = parse('''\n", + "Disc #1 has 13 positions; at time=0, it is at position 1.\n", + "Disc #2 has 19 positions; at time=0, it is at position 10.\n", + "Disc #3 has 3 positions; at time=0, it is at position 2.\n", + "Disc #4 has 7 positions; at time=0, it is at position 1.\n", + "Disc #5 has 5 positions; at time=0, it is at position 3.\n", + "Disc #6 has 17 positions; at time=0, it is at position 5.\n", + "''')\n", + "\n", + "def falls(t, discs):\n", + " \"If we drop the capsule at time t, does it fall through all slots?\"\n", + " return all((pos + t + d) % positions == 0 \n", + " for (d, positions, pos) in discs)\n", + "\n", + "first(t for t in range(BIG) if falls(t, discs))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "assert discs == [(1, 13, 1), (2, 19, 10), (3, 3, 2), (4, 7, 1), (5, 5, 3), (6, 17, 5)]\n", + "assert falls(5, [(1, 5, 4), (2, 2, 1)])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For **part two**, we add a 7th disc, with 11 positions, at position 0 at time 0. I coud go through all the possible times, just as in part one, but I see a way to get a 19-fold speedup: Disc #2 is the largest, with 19 positions, so we only need consider every 19 values of `t`. But what is the first one to consider? Disc @2 starts at position 10, so to get back to position 0, we have to release at `t=7`, because 10 + 2 + 7 = 19 = 0 mod 19. So we will iterate `t` over `range(7, BIG, 19)`:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3903937" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "discs.append((7, 11, 0))\n", + "\n", + "first(t for t in range(7, BIG, 19) if falls(t, discs))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 16](http://adventofcode.com/2016/day/16) Dragon Checksum\n", + "\n", + "Given a bit string of the form `'01...'`, expand it until it fills N bits, then report the checksum.\n", + "\n", + "The rules for expanding:\n", + "- Call the data you have at this point \"a\".\n", + "- Make a copy of \"a\"; call this copy \"b\".\n", + "- Reverse the order of the characters in \"b\".\n", + "- In \"b\", replace all instances of 0 with 1 and all 1s with 0.\n", + "- The resulting data is \"a\", then a single 0, then \"b\".\n", + "- If this gives N or more bits, take the first N; otherwise repeat the process.\n", + "\n", + "The rules for the checksum:\n", + "- Assume the string is 110010110100\n", + "- Consider each pair: 11, 00, 10, 11, 01, 00.\n", + "- These are same, same, different, same, different, same, producing 110101.\n", + "- The resulting string has length 6, which is even, so we repeat the process.\n", + "- The pairs are 11 (same), 01 (different), 01 (different).\n", + "- This produces the checksum 100, which has an odd length, so we stop." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'10010110010011110'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def expand(a, N):\n", + " \"Expand seed `a` until it has length N.\"\n", + " while len(a) < N:\n", + " b = flip(a[::-1])\n", + " a = a + '0' + b\n", + " return a[:N]\n", + "\n", + "def flip(text, table=str.maketrans('10', '01')): return text.translate(table)\n", + "\n", + "def checksum(a):\n", + " \"Compute the checksum of `a` by comparing pairs until len is odd.\"\n", + " while len(a) % 2 == 0:\n", + " a = cat(('1' if a[i] == a[i+1] else '0') \n", + " for i in range(0, len(a), 2))\n", + " return a\n", + " \n", + "seed = '10010000000110000'\n", + "\n", + "checksum(expand(seed, 272))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we take the same seed, but expand it to fill 35Mb of space:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 6.17 s, sys: 326 ms, total: 6.49 s\n", + "Wall time: 6.54 s\n" + ] + }, + { + "data": { + "text/plain": [ + "'01101011101100011'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time checksum(expand(seed, 35651584)) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 17](http://adventofcode.com/2016/day/17) Two Steps Forward\n", + "\n", + "In this puzzle, we move through a 4x4 grid/maze, starting at position (0, 0) and trying to reach (3, 3), but the door from one position to the next is open or not depending on the hash of the path to get there (and my passcode), so doors open and lock themselves as you move around. I'll represent a state as a tuple of `(position, path)` and use `astar_search` to find the shortest path to the goal:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[((0, 0), ''),\n", + " ((1, 0), 'R'),\n", + " ((1, 1), 'RD'),\n", + " ((1, 0), 'RDU'),\n", + " ((2, 0), 'RDUR'),\n", + " ((3, 0), 'RDURR'),\n", + " ((3, 1), 'RDURRD'),\n", + " ((3, 2), 'RDURRDD'),\n", + " ((2, 2), 'RDURRDDL'),\n", + " ((3, 2), 'RDURRDDLR'),\n", + " ((3, 3), 'RDURRDDLRD')]" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "passcode = 'awrkjxxr'\n", + "\n", + "openchars = 'bcdef'\n", + "\n", + "grid = set((x, y) for x in range(4) for y in range(4))\n", + "\n", + "start, goal = (0, 0), (3, 3)\n", + "\n", + "def to_goal(state): \n", + " \"City block distance between state's position and goal.\"\n", + " pos, path = state\n", + " return cityblock_distance(pos, goal)\n", + "\n", + "directions = [(0, 'U', (0, -1)), (1, 'D', (0, 1)), (2, 'L', (-1, 0)), (3, 'R', (1, 0))]\n", + "\n", + "def moves(state):\n", + " \"All states reachable from this state.\"\n", + " (x, y), path = state\n", + " hashx = hashlib.md5(bytes(passcode + path, 'utf-8')).hexdigest()\n", + " for (i, p, (dx, dy)) in directions:\n", + " pos2 = (x+dx, y+dy)\n", + " if hashx[i] in openchars and pos2 in grid:\n", + " yield (pos2, path+p)\n", + " \n", + "astar_search((start, ''), to_goal, moves)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we're asked for the longest path to the goal. We have to stop when we reach the goal, but we can make repeated visits to positions along the way, as long as the doors are open. I'll use a depth-first search, and keep track of the longest path length:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "526" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def longest_search(state, goal, moves):\n", + " \"Find the longest path to goal by depth-first search.\"\n", + " longest = 0\n", + " frontier = [state]\n", + " while frontier:\n", + " state = (pos, path) = frontier.pop()\n", + " if pos == goal:\n", + " longest = max(longest, len(path))\n", + " else:\n", + " frontier.extend(moves(state))\n", + " return longest\n", + " \n", + "longest_search((start, ''), goal, moves)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 18](http://adventofcode.com/2016/day/18) Like a Rogue\n", + "\n", + "Here we have a cellular automaton, where a cell is a \"trap\" iff the 3 tiles in the row above, (one to the left above, directly above, and one to the right above) are one of the set `{'^^.', '.^^', '^..', '..^'}`; in other words if the first of the three is different from the last of the three. Given an initial row, we're asked for the count of all the safe tiles in the first 40 rows:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1951" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "safe, trap = '.', '^' \n", + "initial = '.^^.^^^..^.^..^.^^.^^^^.^^.^^...^..^...^^^..^^...^..^^^^^^..^.^^^..^.^^^^.^^^.^...^^^.^^.^^^.^.^^.^.'\n", + "\n", + "def rows(n, row=initial):\n", + " \"The first n rows of tiles (given the initial row).\"\n", + " result = [row]\n", + " for i in range(n-1):\n", + " previous = safe + result[-1] + safe\n", + " result.append(cat((trap if previous[i-1] != previous[i+1] else safe)\n", + " for i in range(1, len(previous) - 1)))\n", + " return result\n", + "\n", + "cat(rows(40)).count(safe)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here I reproduce the simple example from the puzzle page:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['.^^.^.^^^^',\n", + " '^^^...^..^',\n", + " '^.^^.^.^^.',\n", + " '..^^...^^^',\n", + " '.^^^^.^^.^',\n", + " '^^..^.^^..',\n", + " '^^^^..^^^.',\n", + " '^..^^^^.^^',\n", + " '.^^^..^.^^',\n", + " '^^.^^^..^^']" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rows(10, '.^^.^.^^^^')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we just have to run longer (but only a few seconds):" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 7.92 s, sys: 90.6 ms, total: 8.01 s\n", + "Wall time: 8.08 s\n" + ] + }, + { + "data": { + "text/plain": [ + "20002936" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time cat(rows(400000)).count(safe)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 19](http://adventofcode.com/2016/day/19) An Elephant Named Joseph\n", + "\n", + "Elves numbered 1 to *N* sit in a circle. Each Elf brings a present. Then, starting with the first Elf, they take turns stealing all the presents from the Elf to their left. An Elf with no presents is removed from the circle and does not take turns. So, if *N* = 5, then:\n", + "\n", + " Elf 1 takes Elf 2's present.\n", + " Elf 2 has no presents and is skipped.\n", + " Elf 3 takes Elf 4's present.\n", + " Elf 4 has no presents and is also skipped.\n", + " Elf 5 takes Elf 1's two presents.\n", + " Neither Elf 1 nor Elf 2 have any presents, so both are skipped.\n", + " Elf 3 takes Elf 5's three presents, ending the game.\n", + " \n", + "Who ends up with all the presents for general case of *N*?\n", + "First, I note that I only need to keep track of the Elf number of the remaining elves,\n", + "I don't need to count how many presents each one has. I see two representation choices:\n", + "- Represent the circle of elves as a list of elf numbers, and everytime an Elf's presents are taken, delete the elf from the list. But this is O(*N*2), where *N* = 3 million, so this will be slow.\n", + "- Represent the elves by a range, and instead of deleting elf-by-elf, instead limit the range round-by-round.\n", + "If there is an even number of elves, then the elf in position 0 takes from position 1; position 2 takes from position 3, and so on, leaving only the even positions, which we denote `elves[0::2]`. If there is an odd number of elves, then it is the same, except that the last elf takes from the one in position 0, leaving `elves[2::2]`. Here's the code:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1842613" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def Elves(N=3018458): return range(1, N+1) \n", + "\n", + "def winner(elves): return (elves[0] if (len(elves) == 1) else winner(one_round(elves)))\n", + "\n", + "def one_round(elves): return (elves[0::2] if (len(elves) % 2 == 0) else elves[2::2])\n", + "\n", + "assert winner(Elves(5)) == 3\n", + "\n", + "winner(Elves())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a cool thing about representing the elves with a range: the total storage is O(1), not O(*N*).\n", + "We never need to make a list of 3 million elements.\n", + "Here we see a trace of the calls to `one_round`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "one_round(range(1, 3018459)) = range(1, 3018459, 2)\n", + "one_round(range(1, 3018459, 2)) = range(5, 3018459, 4)\n", + "one_round(range(5, 3018459, 4)) = range(5, 3018461, 8)\n", + "one_round(range(5, 3018461, 8)) = range(21, 3018461, 16)\n", + "one_round(range(21, 3018461, 16)) = range(53, 3018469, 32)\n", + "one_round(range(53, 3018469, 32)) = range(53, 3018485, 64)\n", + "one_round(range(53, 3018485, 64)) = range(181, 3018485, 128)\n", + "one_round(range(181, 3018485, 128)) = range(437, 3018549, 256)\n", + "one_round(range(437, 3018549, 256)) = range(437, 3018677, 512)\n", + "one_round(range(437, 3018677, 512)) = range(1461, 3018677, 1024)\n", + "one_round(range(1461, 3018677, 1024)) = range(3509, 3019189, 2048)\n", + "one_round(range(3509, 3019189, 2048)) = range(7605, 3020213, 4096)\n", + "one_round(range(7605, 3020213, 4096)) = range(7605, 3022261, 8192)\n", + "one_round(range(7605, 3022261, 8192)) = range(7605, 3022261, 16384)\n", + "one_round(range(7605, 3022261, 16384)) = range(7605, 3022261, 32768)\n", + "one_round(range(7605, 3022261, 32768)) = range(7605, 3022261, 65536)\n", + "one_round(range(7605, 3022261, 65536)) = range(7605, 3022261, 131072)\n", + "one_round(range(7605, 3022261, 131072)) = range(269749, 3022261, 262144)\n", + "one_round(range(269749, 3022261, 262144)) = range(794037, 3153333, 524288)\n", + "one_round(range(794037, 3153333, 524288)) = range(1842613, 3415477, 1048576)\n", + "one_round(range(1842613, 3415477, 1048576)) = range(1842613, 3939765, 2097152)\n" + ] + }, + { + "data": { + "text/plain": [ + "1842613" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "one_round = trace1(one_round)\n", + "winner(Elves())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two** the rules have changed, and each elf now takes from the elf *across* the circle. If there is an even number of elves, take from the elf directly across. Fo example, with 12 elves in a circle (like a clock face), Elf 1 takes from Elf 7. With an odd number of elves, directly across the circle falls between two elves, so choose the one that is earlier in the circle. For example, with 11 elves, Elf 2 takes from the Elf at position 7. Now who ends up with the presents?\n", + "\n", + "This is tougher. I can't think of a simple `range` expression to describe who gets eliminated in a round. But I can represent the circle as a list and write a loop to eliminate elves one at a time. Again, if I did that with a `del` statement for each elf, it would be O(*N*2). But if instead I do one round at a time, replacing each eliminated elf with `None` in the list, and then filtering out the `None` values, then each round is only O(*N*), and sine there will be log(*N*) rounds, the whole thing is only O(*N* log(*N*)). That should be reasonably fast.\n", + "\n", + "It is still tricky to know which elf to eliminate. If there are *N* elves, then the elf at position *i* should elminate the one at position *i* + *N* // 2. But we have to skip over the already-eliminated spaces; we can do that by keeping track of the number of eliminated elves in the variable `eliminated`. We also need to keep track of the current value of `N`, since it will change. And, since I don't want to deal with the headaches of wrapping around the circletconn, I will only deal with the first third of the elves: the first third all eliminate elves in the other two-thirds; if we went more than 1/3 of the way through, we would have to worry about wrapping around. (I had a bug here: at first I just iterated through `N // 3`. But when `N` is 2, that does no iteration at all, which is wrong; with two elves, the first should eliminate the other. It turns out it is safe to iterate through `ceil(N /3)` on each round.)\n", + "\n", + "I will change the `Elves` function to return a `list`, not a `range`. The function `winner` stays the same. The `one_round` function is where the work goes:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.26 s, sys: 74.7 ms, total: 1.33 s\n", + "Wall time: 1.34 s\n" + ] + }, + { + "data": { + "text/plain": [ + "1424135" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def Elves(N=3018458): return list(range(1, N+1))\n", + "\n", + "def one_round(elves):\n", + " \"The first third of elves eliminate ones across the circle from them; who is left?\"\n", + " N = len(elves)\n", + " eliminated = 0\n", + " for i in range(int(math.ceil(N / 3))):\n", + " across = i + eliminated + (N // 2) \n", + " elves[across] = None\n", + " N -= 1\n", + " eliminated += 1\n", + " return list(filter(None, elves[i+1:] + elves[:i+1]))\n", + "\n", + "assert winner(Elves(5)) == 2\n", + "\n", + "assert one_round(Elves(5)) == [4, 1, 2]\n", + "\n", + "%time winner(Elves())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I was worried that this solution might take over a minute to run, but it turns out to only take about a second." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 20](http://adventofcode.com/2016/day/20) Firewall Rules\n", + "\n", + "We are given a list of blocked IP addresses, in the form `\"2365712272-2390766206\"`, indicating the low and high numbers that are blocked by the firewall. I will parse the numbers into `(low, high)` pairs, and sort them by the low number first (and peek at the first 5 to see if I got it right): " + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[0, 97802],\n", + " [5682, 591077],\n", + " [591078, 868213],\n", + " [868214, 1216244],\n", + " [1216245, 1730562]]" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pairs = sorted(map(parse_ints, Input(20)))\n", + "\n", + "pairs[:5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are asked what is the lowest non-negative integer that is not blocked. I will generate all the unblocked numbers, and just ask for the first one. (Why do it that way? Because it feels like `unblocked` is the fundamental issue of the problem, and we already have a function to compute `first`; there's no need for a `first_unblocked` function that conflates two ideas.) To find unblocked numbers, start a counter, `i` at zero, and increment it past the high value of each range, after yielding any numbers from `i` to the low value of the range:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4793564" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def unblocked(pairs):\n", + " \"Find the lowest unblocked integer, given the sorted pairs of blocked numbers.\"\n", + " i = 0\n", + " for (low, high) in pairs:\n", + " yield from range(i, low)\n", + " i = max(i, high + 1)\n", + " \n", + "first(unblocked(pairs)) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two** we are asked how many numbers are unblocked:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "146" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(list(unblocked(pairs)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# [Day 21](http://adventofcode.com/2016/day/21) Scrambled Letters and Hash \n", + "\n", + "In this puzzle we are asked to take a password string, scramble it according to a list of instructions, and output the result, which will be a permutation of the original password. This is tedious because there are seven different instructions, but each one is pretty straightforward. I make the following choices:\n", + "- I'll transform `password` (a `str`) into `pw` (a `list`), because lists are mutable and easier to manipulate. At the end I'll turn it back into a `str`.\n", + "- I'll define functions `rot` and `swap` because they get used multiple times by different instructions.\n", + "- I use the variables `A, B` to denote the first two integers anywhere in a line. If there is only one integer (or none), then `B` (and `A`) get as a default value `0`. I accept ill-formed instructions, such as `\"move 1 to 4\"` instead of requiring `\"move position 1 to position 4\"`. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'gcedfahb'" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def scramble(password, instructions=list(Input(21)), verbose=False):\n", + " \"Scramble the password according to the instructions.\"\n", + " pw = list(password) \n", + " def rot(N): pw[:] = pw[-N:] + pw[:-N]\n", + " def swap(A, B): pw[A], pw[B] = pw[B], pw[A] \n", + " for line in instructions:\n", + " words = line.split()\n", + " A, B, = parse_ints(line + ' 0 0')[:2]\n", + " cmd = line.startswith\n", + " if cmd('swap position'): swap(A, B)\n", + " elif cmd('swap letter'): swap(pw.index(words[2]), pw.index(words[5]))\n", + " elif cmd('rotate right'): rot(A)\n", + " elif cmd('rotate left'): rot(-A)\n", + " elif cmd('reverse'): pw[A:B+1] = pw[A:B+1][::-1]\n", + " elif cmd('move'): pw[A:A+1], pw[B:B] = [], pw[A:A+1]\n", + " elif cmd('rotate based'):\n", + " i = pw.index(words[6])\n", + " rot((i + 1 + (i >= 4)) % len(pw))\n", + " if verbose: \n", + " print(line + ': ' + cat(pw))\n", + " return cat(pw)\n", + "\n", + "scramble('abcdefgh')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When I ran the first version of this code the answer I got was incorrect, and I couldn't see where I went wrong, so I implemented the test case from the problem description and inspected the results line by line." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "swap position 4 with position 0: ebcda\n", + "swap letter d with letter b: edcba\n", + "reverse positions 0 through 4: abcde\n", + "rotate left 1 step: bcdea\n", + "move position 1 to position 4: bdeac\n", + "move position 3 to position 0: abdec\n", + "rotate based on position of letter b: ecabd\n", + "rotate based on position of letter d: decab\n" + ] + }, + { + "data": { + "text/plain": [ + "'decab'" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test = '''swap position 4 with position 0\n", + "swap letter d with letter b\n", + "reverse positions 0 through 4\n", + "rotate left 1 step\n", + "move position 1 to position 4\n", + "move position 3 to position 0\n", + "rotate based on position of letter b\n", + "rotate based on position of letter d'''.splitlines()\n", + "\n", + "scramble('abcde', test, verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was enough to show me that I had two bugs (which are fixed above): \n", + "- For `\"reverse\"`, I thought `\"positions 0 through 4\"` meant `[0:4]`, when actually it means `[0:5]`.\n", + "- For `\"rotate based\"`, in the case where the rotation is longer than the password, I need to take the modulo of the password length.\n", + "\n", + "For **part two**, the task is to find the password that, when scrambled, yields `'fbgdceah'`. I think the puzzle designer was trying to tempt solvers into implementing an `unscramble` function, which would be another 20 or 30 lines of code. Fortunately, I was too lazy to go down that path. I realized there are only 40 thousand permutations of an 8-character password, so we can just brute force them all (which would be infeasible with a 20-character password):" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'hegbdcfa'}" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{cat(p) for p in permutations('fbgdceah') \n", + " if scramble(p) == 'fbgdceah'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# [Day 22](http://adventofcode.com/2016/day/22) Grid Computing\n", + "\n", + "We are given a description of files across a grid computing cluster, like this:\n", + "\n", + " root@ebhq-gridcenter# df -h\n", + " Filesystem Size Used Avail Use%\n", + " /dev/grid/node-x0-y0 92T 70T 22T 76%\n", + " /dev/grid/node-x0-y1 86T 65T 21T 75%\n", + "\n", + "For part one, we are asked how many pairs of nodes can viably make a transfer of data. The pair (A, B) is viable if\n", + "- Node A is not empty (its Used is not zero).\n", + "- Nodes A and B are not the same node.\n", + "- The data on node A (its Used) would fit on node B (its Avail).\n", + "\n", + "I'll represent a node as a `namedtuple` of six integers; the rest is easy:" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "903" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Node = namedtuple('Node', 'x, y, size, used, avail, pct')\n", + "\n", + "nodes = [Node(*parse_ints(line)) for line in Input(22) if line.startswith('/dev')]\n", + "\n", + "def viable(A, B): return A != B and 0 < A.used <= B.avail\n", + "\n", + "sum(viable(A, B) for A in nodes for B in nodes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That worked, but let's make sure the nodes look reasonable:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[Node(x=0, y=0, size=92, used=70, avail=22, pct=76),\n", + " Node(x=0, y=1, size=86, used=65, avail=21, pct=75),\n", + " Node(x=0, y=2, size=88, used=73, avail=15, pct=82),\n", + " Node(x=0, y=3, size=91, used=67, avail=24, pct=73),\n", + " Node(x=0, y=4, size=87, used=70, avail=17, pct=80)]" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nodes[:5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we are asked to move data from the node in the upper right (the one with maximum `x` value and `y=0`) to the upper left (x=0, y=0). At first I worried about all sorts of complications: could we split the data into two or more pieces, copying different pieces into different nodes, and then recombining them? I spent many minutes thinking about these complications. Eventually, after a more careful reading of the rules, I decided such moves were not allowed, and the answer had to just involve moving the empty square around. So to proceed, we need to find the initial position of the empty node, and the maximum x value, so we know where the data is: " + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(Node(x=35, y=21, size=91, used=0, avail=91, pct=0), 37)" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "empty = first(node for node in nodes if node.used == 0)\n", + "maxx = max(node.x for node in nodes)\n", + "\n", + "empty, maxx" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I will also define the `grid` as a dict of `{(x, y): node}` entries (which will enable me to find neighbors of a node):" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "grid = {(node.x, node.y): node \n", + " for node in nodes}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An `astar_search` seems appropriate. Each state of the search keeps track of the position of the data we are trying to get, and the position of the currently empty node. The heuristic is the city block distance of the data to the origin:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "215" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "State = namedtuple('State', 'datapos, emptypos')\n", + "\n", + "def distance(state): return cityblock_distance(state.datapos)\n", + "\n", + "def moves(state):\n", + " \"Try moving any neighbor we can into the empty position.\"\n", + " for pos in neighbors4(state.emptypos):\n", + " if pos in grid:\n", + " # Try to move contents of `node` at pos into `empty` at emptypos\n", + " node, empty = grid[pos], grid[state.emptypos]\n", + " if node.used <= empty.size:\n", + " newdatapos = (state.emptypos if pos == state.datapos else state.datapos)\n", + " yield State(newdatapos, pos)\n", + " \n", + "path = astar_search(State((maxx, 0), (empty.x, empty.y)), distance, moves)\n", + "len(path) - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# [Day 23](http://adventofcode.com/2016/day/23) Safe Cracking\n", + "\n", + "This day's puzzle is just like Day 12, except there is one more instruction, `tgl`. I made four mistakes in the process of coding this up:\n", + "- At first I didn't read the part that says register `'a'` should initially be 7.\n", + "- I wasn't sure exactly what constitutes an invalid instruction; it took me a few tries to get that right:\n", + "the only thing that is invalid is a `cpy` that does not copy into a register.\n", + "- I forgot to subtract one from the `pc` (again!) in the `tgl` instruction.\n", + "- I forgot that I had `parse` return instructions as immutable tuples; I had to change that to mutable lists." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def interpret(code, regs):\n", + " \"Execute instructions until pc goes off the end.\"\n", + " def val(x): return (regs[x] if x in regs else x)\n", + " pc = 0\n", + " while 0 <= pc < len(code):\n", + " inst = code[pc]\n", + " op, x, y = inst[0], inst[1], inst[-1]\n", + " pc += 1\n", + " if op == 'cpy' and y in regs: regs[y] = val(x)\n", + " elif op == 'inc': regs[x] += 1 \n", + " elif op == 'dec': regs[x] -= 1 \n", + " elif op == 'jnz' and val(x): pc += val(y) - 1 \n", + " elif op == 'tgl': toggle(code, pc - 1 + val(x))\n", + " return regs\n", + "\n", + "def toggle(code, i):\n", + " \"Toggle the instruction at location i.\"\n", + " if 0 <= i < len(code): \n", + " inst = code[i]\n", + " inst[0] = ('dec' if inst[0] == 'inc' else \n", + " 'inc' if len(inst) == 2 else\n", + " 'cpy' if inst[0] == 'jnz' else \n", + " 'jnz')\n", + "\n", + "def parse(line): \n", + " \"Split line into words, and convert to int where appropriate.\"\n", + " return [(x if x.isalpha() else int(x)) \n", + " for x in line.split()]" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 11340, 'b': 1, 'c': 0, 'd': 0}" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text = '''\n", + "cpy a b\n", + "dec b\n", + "cpy a d\n", + "cpy 0 a\n", + "cpy b c\n", + "inc a\n", + "dec c\n", + "jnz c -2\n", + "dec d\n", + "jnz d -5\n", + "dec b\n", + "cpy b c\n", + "cpy c d\n", + "dec d\n", + "inc c\n", + "jnz d -2\n", + "tgl c\n", + "cpy -16 c\n", + "jnz 1 c\n", + "cpy 84 c\n", + "jnz 75 d\n", + "inc a\n", + "inc d\n", + "jnz d -2\n", + "inc c\n", + "jnz c -5\n", + "'''.strip()\n", + "\n", + "code = [parse(line) for line in text.splitlines()]\n", + "\n", + "regs = dict(a=7, b=0, c=0, d=0)\n", + "\n", + "interpret(code, regs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two**, we are told to run the same computation, but with register `a` set to 12. We are also warned that this will take a long time, and we might consider implementing a multiply instruction, but I was too lazy to make sense of the assembly code, and just let my interpreter run to completion, even if it takes a while." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 25min 21s, sys: 5.37 s, total: 25min 27s\n", + "Wall time: 25min 31s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'a': 479007900, 'b': 1, 'c': 0, 'd': 0}" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "code = [parse(line) for line in text.splitlines()]\n", + "\n", + "regs = dict(a=12, b=0, c=0, d=0)\n", + "\n", + "%time interpret(code, regs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Well, it completed, and gave me the right answer. But I feel like the intent of *Advent of Code* is like *Project Euler*: all code should run in about a minute or less. So I don't think this counts as a \"real\" solution." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 24](http://adventofcode.com/2016/day/24) Air Duct Spelunking \n", + "\n", + "This is another maze-solving problem; it should be easy for my `astar_search`. First the maze:" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "maze = tuple(Input(24))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The tricky part is that we have to visit all the digits in the maze, starting at `0`, and not necessarily going in order. How many digits are there?" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'\\n', '#', '.', '0', '1', '2', '3', '4', '5', '6', '7'}" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(cat(maze))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OK, there are 8 digits. What is the start square (the square that currently holds a `'0'`)?" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(33, 11)" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "zero = first((x, y) for y, row in enumerate(maze) for x, c in enumerate(row) if c == '0')\n", + "zero" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I'm ready to go. The state of the search will include the x, y position, and also the digits visited so far, which I can represent as a sorted string (a `frozenset` would also work):" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "448" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def h(state):\n", + " \"Heuristic: the number of digits not yet visited.\"\n", + " _, visited = state\n", + " return 8 - len(visited) # Note: 8 == len('01234567')\n", + " \n", + "def moves(state):\n", + " \"Move to any neighboring square that is not a wall. Track the digits visited.\"\n", + " pos, visited = state\n", + " for x1, y1 in neighbors4(pos):\n", + " c = maze[y1][x1]\n", + " if c != '#':\n", + " visited1 = (visited if c in visited or c == '.' else cat(sorted(visited + c)))\n", + " yield (x1, y1), visited1\n", + "\n", + "path = astar_search((zero, '0'), h, moves)\n", + "len(path) - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In **part two** we need to get the robot back to the start square. I'll do that by creating a new heuristic function that still requires us to collect all the digits, and also measures the distance back to the start (`zero`) square." + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "672" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def h2(state):\n", + " \"Heuristic: the number of digits not yet visited, plus the distance back to start.\"\n", + " pos, visited = state\n", + " return 8 - len(visited) + cityblock_distance(pos, zero)\n", + "\n", + "path2 = astar_search((zero, '0'), h2, moves)\n", + "len(path2) - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# [Day 25](http://adventofcode.com/2016/day/25) Clock Signal\n", + "\n", + "This is another assembly language interpreter puzzle. This time there is one more instruction, `out`, which transmits a signal. We are asked to find the lowest positive integer value for register `a` that causes the program to output an infinite series of `0, 1, 0, 1, 0, 1, ...` signals. Dealing with infinity is difficult, so I'll approximate that by asking: what is the lowest value for register `a` that causes the program to output at least 100 elements in the `0, 1, 0, 1, 0, 1, ...` series, within the first million instructions executed?\n", + "\n", + "To do that, I'll change `interpret` to be a generator that yields signals, and change it to take an argument saying the number of steps to execute before halting:" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def interpret(code, regs, steps=BIG):\n", + " \"Execute instructions until pc goes off the end, or until we execute the given number of steps.\"\n", + " def val(x): return (regs[x] if x in regs else x)\n", + " pc = 0\n", + " for _ in range(steps):\n", + " if not (0 <= pc < len(code)):\n", + " return\n", + " inst = code[pc]\n", + " op, x, y = inst[0], inst[1], inst[-1]\n", + " pc += 1\n", + " if op == 'cpy' and y in regs: regs[y] = val(x)\n", + " elif op == 'inc': regs[x] += 1 \n", + " elif op == 'dec': regs[x] -= 1 \n", + " elif op == 'jnz' and val(x): pc += val(y) - 1 \n", + " elif op == 'tgl': toggle(code, pc - 1 + val(x))\n", + " elif op == 'out': yield val(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is my program, and the function `repeats`, which returns True if the code repeats with a given value of the register `a`. Then all we need to do is iterate through integer values for register `a` until we find one that repeats:" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "198" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text = '''\n", + "cpy a d\n", + "cpy 4 c\n", + "cpy 633 b\n", + "inc d\n", + "dec b\n", + "jnz b -2\n", + "dec c\n", + "jnz c -5\n", + "cpy d a\n", + "jnz 0 0\n", + "cpy a b\n", + "cpy 0 a\n", + "cpy 2 c\n", + "jnz b 2\n", + "jnz 1 6\n", + "dec b\n", + "dec c\n", + "jnz c -4\n", + "inc a\n", + "jnz 1 -7\n", + "cpy 2 b\n", + "jnz c 2\n", + "jnz 1 4\n", + "dec b\n", + "dec c\n", + "jnz 1 -4\n", + "jnz 0 0\n", + "out b\n", + "jnz a -19\n", + "jnz 1 -21\n", + "'''.strip()\n", + "\n", + "code = [parse(line) for line in text.splitlines()]\n", + "\n", + "def repeats(a, code, steps=10**6, minsignals=100):\n", + " \"Does this value for register a cause code to repeat `out` signals of 0, 1, 0, 1, ...?\"\n", + " signals = interpret(code, dict(a=a, b=0, c=0, d=0), steps)\n", + " expecteds = cycle((0, 1))\n", + " for (i, (signal, expected)) in enumerate(zip(signals, expecteds)):\n", + " if signal != expected:\n", + " return False\n", + " # We'll say \"yes\" if the code outputs at least a minimum number of 0, 1, ... signals, and nothing else.\n", + " return i >= minsignals\n", + " \n", + "first(a for a in range(1, BIG) if repeats(a, code))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's all folks! Thank you [Eric Wastl](http://was.tl/), that was fun!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/BASIC.ipynb b/pytudes/ipynb/BASIC.ipynb new file mode 100644 index 0000000..71f7b70 --- /dev/null +++ b/pytudes/ipynb/BASIC.ipynb @@ -0,0 +1,1957 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
Peter Norvig, Feb 2017
\n", + "\n", + "# BASIC Interpreter\n", + "\n", + "[Years ago](http://norvig.com/lispy.html), I showed how to write an Interpreter for a dialect of Lisp. Some readers appreciated it, and some asked about an interpreter for a language that isn't just a bunch of parentheses. In 2014 I saw a [celebration](http://time.com/69316/basic/) of the 50th anniversary of the 1964 [Dartmouth BASIC](http://web.archive.org/web/20120716185629/http://www.bitsavers.org/pdf/dartmouth/BASIC_Oct64.pdf) interpreter, and thought that I could show how to implement such an interpreter. I never quite finished in 2014, but in 2017 I rediscovered my unfinished file and completed it. For those of you unfamiliar with BASIC, here is a sample program:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "program = '''\n", + "10 REM POWER TABLE\n", + "11 DATA 8, 4\n", + "15 READ N0, P0\n", + "20 PRINT \"N\",\n", + "25 FOR P = 2 to P0\n", + "30 PRINT \"N ^\" P,\n", + "35 NEXT P\n", + "40 PRINT \"SUM\"\n", + "45 LET S = 0\n", + "50 FOR N = 2 TO N0\n", + "55 PRINT N,\n", + "60 FOR P = 2 TO P0\n", + "65 LET S = S + N ^ P\n", + "70 PRINT N ^ P,\n", + "75 NEXT P\n", + "80 PRINT S\n", + "85 NEXT N\n", + "99 END\n", + "'''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Of course I don't have to build everything from scratch in assembly language, and I don't have to worry about every byte of storage, like [Kemeny](http://www.dartmouth.edu/basicfifty/basic.html), [Gates](http://www.pagetable.com/?p=774), and [Woz](http://www.retrothing.com/2008/07/restoring-wozs.html) did, so my job is much easier. The interpreter consists of three phases: \n", + "* **Tokenization**: breaking a text into a list of tokens, for example: `\"10 READ N\"` becomes `['10', 'READ', 'N']`.\n", + "* **Parsing**: building an executable representation from the tokens, so this statement becomes: `Stmt(num=10, typ='READ', args=['N'])`.\n", + "* **Execution**: follow the flow of the program and do what each statement says; in this case an assignment: `variables['N'] = data.popleft()`.\n", + "\n", + "\n", + "\n", + "# Tokenization\n", + "\n", + "One way to turn a line of text into a list of tokens is with the `findall` method of a regular expression that defines all the legal tokens:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import re \n", + "\n", + "tokenize = re.compile(\n", + " r'''\\d* \\.? \\d+ (?: E -? \\d+)? | # number \n", + " SIN|COS|TAN|ATN|EXP|ABS|LOG|SQR|RND|INT|FN[A-Z]| # functions (including user-defined FNA-FNZ)\n", + " LET|READ|DATA|PRINT|GOTO|IF|FOR|NEXT|END|STOP | # keywords\n", + " DEF|GOSUB|RETURN|DIM|REM|TO|THEN|STEP | # more keywords\n", + " [A-Z]\\d? | # variable names (letter optionally followed by a digit)\n", + " \" .*? \" | # labels (strings in double quotes)\n", + " <>|>=|<= | # multi-character relational operators\n", + " \\S # any non-space single character ''', \n", + " re.VERBOSE).findall" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The only complicated part is the syntax for numbers: optional digits followed by an optional decimal point, some digits, and optionally a power of 10 marked by `\"E\"` and followed by an (optional) minus sign and some digits. \n", + "Example usage of `tokenize`:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['10', 'READ', 'N']" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tokenize('10 READ N')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['100', 'PRINT', '\"SIN(X)^2 = \"', ',', 'SIN', '(', 'X', ')', '^', '2']" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tokenize('100 PRINT \"SIN(X)^2 = \", SIN(X) ^ 2')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "That looks good. Note that my tokens are just strings; it will be the parser's job, not the tokenizer's, to recognize that `'2'` is a number and `'X'` is the name of a variable. (In some interpreters, the tokenizer makes distinctions like these.)\n", + "\n", + "There's one important complication: spaces don't matter in BASIC programs, so the following should all be equivalent:\n", + "\n", + " 10 GOTO 99\n", + " 10GOTO99\n", + " 10 GO TO 99\n", + " \n", + "The problem is that `tokenize` gets the last one wrong:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['10', 'G', 'O', 'TO', '99']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tokenize('10 GO TO 99')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "My first thought was to remove all white space from the input. That would work for this example, but it would change the token `\"HELLO WORLD\"` to `\"HELLOWORLD\"`, which is wrong. To remove spaces everywhere *except* between double quotes, I can tokenize the line and join the tokens back together. Then I can re-tokenize to get the final list of tokens; I do that in my new function below called `tokenizer`. \n", + "\n", + "Once I have a list of tokens, I access them through this interface:\n", + "* `peek()`: returns the next token in `tokens` (without changing `tokens`), or `None` if there are no more tokens.\n", + "* `pop()`: removes and returns the next token. \n", + "* `pop(`*string*`)`: removes and returns the next token if it is equal to the string; else return `None` and leave `tokens` unchanged.\n", + "* `pop(`*predicate*`)`: removes and returns the next token if *predicate*(*token*) is true; else return `None` and leave `tokens` unchanged." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tokens = [] # Global variable to hold a list of tokens\n", + "\n", + "def tokenizer(line):\n", + " \"Return a list of the tokens on this line, handling spaces properly, and upper-casing.\"\n", + " return tokenize(remove_spaces(line).upper())\n", + "\n", + "def peek(): \n", + " \"Return the first token in the global `tokens`, or None if we are at the end of the line.\"\n", + " return (tokens[0] if tokens else None)\n", + "\n", + "def pop(constraint=None):\n", + " \"\"\"Remove and return the first token in `tokens`, or return None if first token fails a constraint.\n", + " `constraint` can be None, a literal string (e.g. pop('=')), or a predicate (e.g. pop(is_varname)).\"\"\"\n", + " if constraint is None or (peek() == constraint) or (callable(constraint) and constraint(peek())):\n", + " return tokens.pop(0)\n", + " \n", + "def remove_spaces(line): \n", + " \"Remove white space from line, except space inside double quotes.\"\n", + " return ''.join(tokenize(line))\n", + "\n", + "def lines(text): \n", + " \"A list of the non-empty lines in a text.\"\n", + " return [line for line in text.splitlines() if line]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(Note: if I expected program lines to contain many tokens, I would use a `deque` instead of a `list` of tokens.) \n", + "\n", + "We can test `tokenizer` and the related functions:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ok'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_tokenizer():\n", + " global tokens\n", + " assert tokenizer('X-1') == ['X', '-', '1'] # Numbers don't have a leading minus sign, so this isn't ['X', '-1']\n", + " assert tokenizer('PRINT \"HELLO WORLD\"') == ['PRINT', '\"HELLO WORLD\"']\n", + " assert tokenizer('10 GOTO 99') == tokenizer('10GOTO99') == tokenizer('10 GO TO 99') == ['10', 'GOTO', '99']\n", + " assert (tokenizer('100 PRINT \"HELLO WORLD\", SIN(X) ^ 2') == \n", + " ['100', 'PRINT', '\"HELLO WORLD\"', ',', 'SIN', '(', 'X', ')', '^', '2'])\n", + " assert (tokenizer('100IFX1+123.4+E1-12.3E4 <> 1.2E-34*-12E34+1+\"HI\" THEN99') ==\n", + " ['100', 'IF', 'X1', '+', '123.4', '+', 'E1', '-', '12.3E4', '<>', \n", + " '1.2E-34', '*', '-', '12E34', '+', '1', '+', '\"HI\"', 'THEN', '99'])\n", + " assert remove_spaces('10 GO TO 99') == '10GOTO99'\n", + " assert remove_spaces('100 PRINT \"HELLO WORLD\", SIN(X) ^ 2') == '100PRINT\"HELLO WORLD\",SIN(X)^2'\n", + " assert lines('one line') == ['one line']\n", + " assert lines(program) == [\n", + " '10 REM POWER TABLE',\n", + " '11 DATA 8, 4',\n", + " '15 READ N0, P0',\n", + " '20 PRINT \"N\",',\n", + " '25 FOR P = 2 to P0',\n", + " '30 PRINT \"N ^\" P,',\n", + " '35 NEXT P',\n", + " '40 PRINT \"SUM\"',\n", + " '45 LET S = 0',\n", + " '50 FOR N = 2 TO N0',\n", + " '55 PRINT N,',\n", + " '60 FOR P = 2 TO P0',\n", + " '65 LET S = S + N ^ P',\n", + " '70 PRINT N ^ P,',\n", + " '75 NEXT P',\n", + " '80 PRINT S',\n", + " '85 NEXT N',\n", + " '99 END']\n", + " assert [tokenizer(line) for line in lines(program)] == [\n", + " ['10', 'REM', 'P', 'O', 'W', 'E', 'R', 'T', 'A', 'B', 'L', 'E'],\n", + " ['11', 'DATA', '8', ',', '4'],\n", + " ['15', 'READ', 'N0', ',', 'P0'],\n", + " ['20', 'PRINT', '\"N\"', ','],\n", + " ['25', 'FOR', 'P', '=', '2', 'TO', 'P0'],\n", + " ['30', 'PRINT', '\"N ^\"', 'P', ','],\n", + " ['35', 'NEXT', 'P'],\n", + " ['40', 'PRINT', '\"SUM\"'],\n", + " ['45', 'LET', 'S', '=', '0'],\n", + " ['50', 'FOR', 'N', '=', '2', 'TO', 'N0'],\n", + " ['55', 'PRINT', 'N', ','],\n", + " ['60', 'FOR', 'P', '=', '2', 'TO', 'P0'],\n", + " ['65', 'LET', 'S', '=', 'S', '+', 'N', '^', 'P'],\n", + " ['70', 'PRINT', 'N', '^', 'P', ','],\n", + " ['75', 'NEXT', 'P'],\n", + " ['80', 'PRINT', 'S'],\n", + " ['85', 'NEXT', 'N'],\n", + " ['99', 'END']]\n", + "\n", + " tokens = tokenizer('10 GO TO 99') \n", + " assert peek() == '10'\n", + " assert pop() == '10'\n", + " assert peek() == 'GOTO'\n", + " assert pop() == 'GOTO'\n", + " assert peek() == '99'\n", + " assert pop(str.isalpha) == None # '99' is not alphabetic\n", + " assert pop('98.6') == None # '99' is not '98.6'\n", + " assert peek() == '99'\n", + " assert pop(str.isnumeric) == '99' # '99' is numeric\n", + " assert peek() is None and not tokens \n", + " \n", + " return 'ok'\n", + " \n", + "test_tokenizer()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing: Grammar of Statements\n", + "\n", + "Parsing is the process of transforming the text of a program into an internal representation, which can then be executed.\n", + "For BASIC, the representation will be an ordered list of statements, and we'll need various data types to represent the parts of the statements.\n", + "I'll start by showing the grammar of BASIC statements, as seen on pages 56-57 of [the manual](http://web.archive.org/web/20120716185629/http://www.bitsavers.org/pdf/dartmouth/BASIC_Oct64.pdf) (see also pages 26-30 for a simpler introduction). A statement starts with a line number, and then can be one of the following 15 types of statements, each \n", + "type introduced by a distinct keyword:\n", + "\n", + "- **`LET`** `` **=** ``\n", + "- **`READ`** ``\n", + "- **`DATA`** ``\n", + "- **`PRINT`** ``\n", + "- **`GOTO`** ``\n", + "- **`IF`** ` ` **`THEN`** ``\n", + "- **`FOR`** `` **=** `` **`TO`** ` [`**`STEP`** `]`\n", + "- **`NEXT`** ``\n", + "- **`END`**\n", + "- **`STOP`**\n", + "- **`DEF`** ``**(**``**) = **``\n", + "- **`GOSUB`** ``\n", + "- **`RETURN`**\n", + "- **`DIM`** ``\n", + "- **`REM`** ``\n", + " \n", + "The notation `` means any variable and `` means zero or more variables, separated by commas. `[STEP ]` means that the literal string `\"STEP\"`, followed by an expression, is optional. \n", + "\n", + "Rather than use one of the many [language parsing frameworks](https://wiki.python.org/moin/LanguageParsing), I will show how to build a parser from scratch. First I'll translate the grammar above into Python. Not character-for-character (because it would take a lot of work to get Python to understand how to handle those characters), but almost word-for-word (because I can envision a straightforward way to get Python to handle the following format):" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def Grammar(): \n", + " return {\n", + " 'LET': [variable, '=', expression],\n", + " 'READ': [list_of(variable)],\n", + " 'DATA': [list_of(number)],\n", + " 'PRINT': [labels_and_expressions],\n", + " 'GOTO': [linenumber],\n", + " 'IF': [expression, relational, expression, 'THEN', linenumber],\n", + " 'FOR': [varname, '=', expression, 'TO', expression, step],\n", + " 'NEXT': [varname],\n", + " 'END': [],\n", + " 'STOP': [],\n", + " 'DEF': [funcname, '(', varname, ')', '=', expression],\n", + " 'GOSUB': [linenumber],\n", + " 'RETURN': [],\n", + " 'DIM': [list_of(variable)], \n", + " 'REM': [anycharacters]\n", + " }" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing Strategy\n", + "\n", + "The grammar of BASIC is designed so that at every point, the next token tells us unambiguously how to parse. For example, the first token after the line number defines the type of statement; also, in an expression we know that all three-letter names are functions while all 1-letter names are variables. So in writing the various grammatical category functions, a common pattern is to either `peek()` at the next token or try a `pop(`*constraint*`)`, and from that decide what to parse next, and never have to back up or undo a `pop()`. Here is my strategy for parsing statements:\n", + "\n", + "* The grammatical categories, like `variable` and `expression` (and also `statement`), will be defined as functions\n", + "(with no argument) that pop tokens from the global variable `tokens`, and return a data object. For example, calling `linenumber()` will pop a token, convert it to an `int`, and return that. \n", + "\n", + "* Consider parsing the statement `\"20 LET X = X + 1\"`. \n", + "\n", + "* First tokenize to get: `tokens = ['20', 'LET', 'X', '=', 'X', '+', '1']`.\n", + "\n", + "* Then call `statement()` (defined below).\n", + "\n", + " * `statement` first calls `linenumber()`, getting back the integer `20` (and removing `'20'` from `tokens`).\n", + "\n", + " * Then it calls `pop()` to get `'LET'` (and removing `'LET'` from `tokens`).\n", + " * Then it indexes into the grammar with `'LET'`, retrieving the grammar rule `[variable, '=', expression]`.\n", + "\n", + " * Then it processes the 3 constituents of the grammar rule:\n", + " * First, call `variable()`, which removes and returns `'X'`.\n", + " * Second, call `pop('=')`, which removes `'='` from `tokens`, and discard it.\n", + " * Third, call `expression()`, which returns a representation of `X + 1`; let's write that as `Opcall('X', '+', 1.0)`.\n", + "\n", + " * Finally, `statement` assembles the pieces and returns `Stmt(num=20, typ='LET', args=['X', Opcall('X', '+', 1.0)])`.\n", + "* If anything goes wrong, call `fail(\"`*error message*`\")`, which raises an error.\n", + "\n", + "Here is the definition of `statement`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def statement():\n", + " \"Parse a BASIC statement from `tokens`.\"\n", + " num = linenumber()\n", + " typ = pop(is_stmt_type) or fail('unknown statement type')\n", + " args = []\n", + " for c in grammar[typ]: # For each constituent of rule, call if callable or match if literal string\n", + " if callable(c):\n", + " args.append(c())\n", + " else:\n", + " pop(c) or fail('expected ' + repr(c))\n", + " return Stmt(num, typ, args)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some of the grammatical categories, like `expression`, are complex. But many of the categories are easy one-liners:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def linenumber(): return (int(pop()) if peek().isnumeric() else fail('missing line number'))\n", + "def number(): return (-1 if pop('-') else +1) * float(pop()) # Optional minus sign before number\n", + "def step(): return (expression() if pop('STEP') else 1) # 1 is the default step\n", + "def relational(): return pop(is_relational) or fail('expected a relational operator')\n", + "def varname(): return pop(is_varname) or fail('expected a variable name')\n", + "def funcname(): return pop(is_funcname) or fail('expected a function name')\n", + "def anycharacters(): tokens.clear() # The tokens in a REM statement don't matter, so just clear them" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are the predicates that distinguish different types of tokens:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def is_stmt_type(x): return isinstance(x, str) and x in grammar # LET, READ, ...\n", + "def is_funcname(x): return isinstance(x, str) and len(x) == 3 and x.isalpha() # SIN, COS, FNA, FNB, ...\n", + "def is_varname(x): return isinstance(x, str) and len(x) in (1, 2) and x[0].isalpha() # A, A1, A2, B, ...\n", + "def is_label(x): return isinstance(x, str) and x.startswith('\"') # \"HELLO WORLD\", ...\n", + "def is_relational(x): return isinstance(x, str) and x in ('<', '=', '>', '<=', '<>', '>=')\n", + "def is_number(x): return isinstance(x, str) and x and x[0] in '.0123456789' # '3', '.14', ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that `varname` means an unsubscripted variable name (a letter by itself, like `X`, or followed by a digit, like `X3`), and that `variable` is a `varname` optionally followed by index expressions in parentheses, like `A(I)` or `M(2*I, 3)`: " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def variable(): \n", + " \"Parse a possibly subscripted variable e.g. 'X3' or 'A(I)' or 'M(2*I, 3)'.\"\n", + " V = varname()\n", + " if pop('('):\n", + " indexes = list_of(expression)()\n", + " pop(')') or fail('expected \")\" to close subscript')\n", + " return Subscript(V, indexes) # E.g. 'A(I)' => Subscript('A', ['I'])\n", + " else: \n", + " return V # E.g. 'X3' " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`list_of` is tricky because it works at two different times. When I write `list_of(number)` in the grammar, this returns an object of class `list_of`. When this object is called (just as other grammatical categories like `variable` are called), the effect is that it will parse a list of `number`. That list can be empty (if there are no more tokens on the line), or can be a single number, or can be several numbers separated by comma tokens. I could have defined `list_of` as a function that returns a function, but I thought that it would be clearer to define it as a class, so I can clearly separate what happens at the two different times: first the `__init__` method determines what category to parse, and later the `__call__` method does the actual parsing." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class list_of:\n", + " \"list_of(category) is a callable that parses a comma-separated list of \"\n", + " def __init__(self, category): self.category = category\n", + " def __call__(self):\n", + " result = ([self.category()] if tokens else [])\n", + " while pop(','):\n", + " result.append(self.category())\n", + " return result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing: Top Level `parse`, and Handling Errors\n", + "\n", + "Most of the parsing action happens inside the function `statement()`, but at the very top level, `parse(program)` takes a program text (that is, a string), and parses each line by calling `parse_line`, sorting the resulting list of lines by line number. If we didn't have to handle errors, this would be simple:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def parse(program): return sorted(map(parse_line, lines(program)))\n", + "\n", + "def parse_line(line): global tokens; tokens = tokenizer(line); return statement()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To handle syntactic errors, I add to `parse_line` a `try/except` that catches exceptions raised by calls to `fail`. I acknowledge the interpreter isn't very thorough about handling all errors, and the error messages could be more helpful." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def parse_line(line):\n", + " \"Return a Stmt(linenumber, statement_type, arguments).\"\n", + " global tokens\n", + " tokens = tokenizer(line)\n", + " try:\n", + " stmt = statement()\n", + " if tokens: fail('extra tokens at end of line')\n", + " return stmt\n", + " except SyntaxError as err:\n", + " print(\"Error in line '{}' at '{}': {}\".format(line, ' '.join(tokens), err))\n", + " return Stmt(0, 'REM', []) # Have to return something: a dummy statement\n", + " \n", + "def fail(message): raise SyntaxError(message)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing: Building A Representation of the Program\n", + "\n", + "A program is represented by various data structures: a list of statements, where each statement contains various components: subscripted variable references, user-defined functions, function calls, operation calls, variable names, numbers, and labels. Here I define these data structures with `namedtuple`s:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from collections import namedtuple, defaultdict, deque\n", + "\n", + "Stmt = namedtuple('Stmt', 'num, typ, args') # Statement: '20 GOTO 99' => Stmt(20, 'GOTO', 99)\n", + "Subscript = namedtuple('Subscript', 'var, indexes') # Subscripted reference: 'A(I)' => Subscript('A', ['I'])\n", + "Funcall = namedtuple('Funcall', 'f, x') # Function call: 'SQR(X)' => Funcall('SQR', 'X')\n", + "Opcall = namedtuple('Opcall', 'x, op, y') # Infix operation: 'X + 1' => Opcall('X', '+', 1)\n", + "ForState = namedtuple('ForState', 'continu, end, step') # Data used to control a FOR loop variable\n", + "\n", + "class Function(namedtuple('_', 'parm, body')):\n", + " \"User-defined callable function; 'DEF FNC(X) = X ^ 3' => functions['FNC'] = Function('X', Opcall('X', '^', 3))\"\n", + " def __call__(self, value): \n", + " variables[self.parm] = value # Global assignment to the parameter\n", + " return evalu(self.body)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first four namedtuples should be self-explanatory. The next one, `ForState`, is used to represent the state of a `FOR` loop variable while the program is running, but does not appear in the static representation of the program.\n", + "`Function` is used to represent the definition of a user defined function. When the user writes `\"DEF FNC(X) = X ^ 3\"`, we create an object with `Function(parm='X', body=Opcall('X', '^', 3))`, and whenever the program calls, say, `FNC(2)` in an expression, the call returns 8, and also assigns 2 to the *global* variable `X` (whereas in modern languages, it would temporarily bind a new *local* variable named `X`). BASIC has no local variables. Note the technique of making `Function` be a subclass of a `namedtuple`; we are then free to add the `__call__` method to the subclass." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing: Grammar of `PRINT` Statements\n", + "\n", + "On page 26 of the manual, it appears that the grammar rule for `PRINT` should be `[list_of(expression)]`. But in section 3.1, **More about PRINT**, some complications are introduced:\n", + "\n", + "* Labels (strings enclosed in double quotes) are allowed, as well as expressions.\n", + "* The `\",\"` is not a separator. A line can end with `\",\"`.\n", + "* Optionally, `\";\"` can be used instead of `\",\"`.\n", + "* Optionally, the `\",\"` or `\";\"` can be omitted—we can have a label immediately followed by an expression.\n", + "\n", + "The effect of a comma is to advance the output to the next column that is a multiple of 15 (and to a new line if this goes past column 75). The effect of a semicolon is similar, but works in multiples of 3, not 15. (Note that column numbering starts at 0, not 1.) Normally, at the end of a `PRINT` statement we advance to a new line, but this is not done if the statement ends in `\",\"` or `\";\"`. Here are some examples:\n", + "\n", + "* `10 PRINT X, Y`\n", + "
Prints the value of `X` in column 0 and `Y` in column 15. Advances to new line.\n", + "\n", + "* `20 PRINT \"X =\", X`\n", + "
Prints the string `\"X =\"` in column 0 and the value of `X` in column 15. Advances to new line.\n", + "\n", + "* `30 PRINT \"X = \" X`\n", + "
Prints the string `\"X =\"` in column 0 and the value of `X` immediately after. Advances to new line.\n", + "\n", + "* `40 PRINT X; Y,`\n", + "
Prints the value of `X` in column 0, and the value of `Y` in the column that is the first available multiple of 3 after that.\n", + "For example, if `X` is `'0'`, then print `Y` in column 3, but if `X` is `'12345'`, then we've gone past column 3, so print `Y` in column 6.\n", + "Then, because the statement ends in a comma, advance to the next column that is a multiple of 15, but not to a new line.\n", + "\n", + "That explanation was long, but the implementation is short (at least for the parsing part; later we will see the execution part):" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def labels_and_expressions():\n", + " \"Parse a sequence of label / comma / semicolon / expression (for PRINT statement).\"\n", + " result = []\n", + " while tokens:\n", + " item = pop(is_label) or pop(',') or pop(';') or expression()\n", + " result.append(item)\n", + " return result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing: Grammar of Expressions\n", + "\n", + "Now for the single most complicated part of the grammar: the `expression`. The biggest complication is operator precedence: the string `\"A + B * X + C\"` should be parsed as if it were `\"A + (B * X) + C\"`, and not as `\"(A + B) * (X + C),\"` because multiplication binds more tightly than addition. There are [many schemes](https://en.wikipedia.org/wiki/Operator-precedence_parser) for parsing expressions, I'll use [an approach](https://groups.google.com/forum/#!topic/comp.compilers/ruJLlQTVJ8o) attributed to Keith Clarke.\n", + "\n", + "Like all our grammatical categories, calling `expression()` pops off some tokens and returns a data object. The first thing it does is parse one of five types of simple \"primary\" expressions: \n", + "a number like `1.23`; \n", + "a possibly-subscripted variable like `X` or `A(I)`;\n", + "a function call like `SIN(X)`;\n", + "a unary negation like `-X`;\n", + "or a parenthesied expression like `(X + 1)`. \n", + "\n", + "Next, `expression` looks for infix operators. To parse `'X + 1'` as an expression, first `primary()` would parse `'X'`, then it would pop off the `'+'` operator, then a recursive call to `expression()` would parse `1`, and the results can then be combined into an `Opcall('X', '+', 1)`. If there are multiple infix operators, they can all be handled, as in `'X+1+Y+2'`, which gets parsed as `Opcall(Opcall(Opcall('X', '+', 1), '+', 'Y'), '+', 2)`.\n", + "\n", + "When there are multiple infix operators of *different* precedence, as in `\"A + B * X + C\"`, the trick is to know which operators are parsed by the top-level call to `expression`, and which by recursive calls. When we first call `expression()`, the optional parameter `prec` gets the default value, 1, which is the precedence of addition and subtraction. When `expression` makes a recursive call, it passes the precedence of the current operator, and we only parse off operator/expression pairs at an equal or higher precedence. So, in parsing `\"A + B * X + C\"`, when we pop off the `'*'` operator (which has precedence 2), we then recursively call `expression(2)`, which parses off an expression containing operators of precedence 2 or higher, which means the recursive call will parse `X`, but it won't pop off the `'+'`, because that is at a lower precedence. So we correctly get the structure `\"(A + ((B * X) + C)\"`.\n", + "\n", + "The function `associativity` ensures that the operator `'^'` is right associative, meaning `10^2^3` = `(10^(2^3))`, whereas the other operators are left associative, so `10-2-3` = `((10-2)-3)`.\n", + "\n", + "Here is the implementation of `expression`:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def expression(prec=1): \n", + " \"Parse an expression: a primary and any [op expression]* pairs with precedence(op) >= prec.\"\n", + " exp = primary() # 'A' => 'A'\n", + " while precedence(peek()) >= prec:\n", + " op = pop()\n", + " rhs = expression(precedence(op) + associativity(op))\n", + " exp = Opcall(exp, op, rhs) # 'A + B' => Opcall('A', '+', 'B')\n", + " return exp\n", + "\n", + "def primary():\n", + " \"Parse a primary expression (no infix op except maybe within parens).\"\n", + " if is_number(peek()): # '1.23' => 1.23 \n", + " return number()\n", + " elif is_varname(peek()): # X or A(I) or M(I+1, J)\n", + " return variable()\n", + " elif is_funcname(peek()): # SIN(X) => Funcall('SIN', 'X')\n", + " return Funcall(pop(), primary())\n", + " elif pop('-'): # '-X' => Funcall('NEG', 'X')\n", + " return Funcall('NEG', primary())\n", + " elif pop('('): # '(X + 1)' => Opcall('X', '+', 1)\n", + " exp = expression()\n", + " pop(')') or fail('expected \")\" to end expression')\n", + " return exp\n", + " else:\n", + " return fail('unknown expression')\n", + "\n", + "def precedence(op): return (3 if op == '^' else 2 if op in ('*', '/') else 1 if op in ('+', '-') else 0)\n", + "\n", + "def associativity(op): return (0 if op == '^' else 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Parsing: The Complete Parser in Action\n", + "\n", + "I've now written all the grammatical categories, so I can now safely instantiate the global variable `grammar` by calling `Grammar()`, and parse a program:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[Stmt(num=10, typ='REM', args=[None]),\n", + " Stmt(num=11, typ='DATA', args=[[8.0, 4.0]]),\n", + " Stmt(num=15, typ='READ', args=[['N0', 'P0']]),\n", + " Stmt(num=20, typ='PRINT', args=[['\"N\"', ',']]),\n", + " Stmt(num=25, typ='FOR', args=['P', 2.0, 'P0', 1]),\n", + " Stmt(num=30, typ='PRINT', args=[['\"N ^\"', 'P', ',']]),\n", + " Stmt(num=35, typ='NEXT', args=['P']),\n", + " Stmt(num=40, typ='PRINT', args=[['\"SUM\"']]),\n", + " Stmt(num=45, typ='LET', args=['S', 0.0]),\n", + " Stmt(num=50, typ='FOR', args=['N', 2.0, 'N0', 1]),\n", + " Stmt(num=55, typ='PRINT', args=[['N', ',']]),\n", + " Stmt(num=60, typ='FOR', args=['P', 2.0, 'P0', 1]),\n", + " Stmt(num=65, typ='LET', args=['S', Opcall(x='S', op='+', y=Opcall(x='N', op='^', y='P'))]),\n", + " Stmt(num=70, typ='PRINT', args=[[Opcall(x='N', op='^', y='P'), ',']]),\n", + " Stmt(num=75, typ='NEXT', args=['P']),\n", + " Stmt(num=80, typ='PRINT', args=[['S']]),\n", + " Stmt(num=85, typ='NEXT', args=['N']),\n", + " Stmt(num=99, typ='END', args=[])]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grammar = Grammar()\n", + "\n", + "parse(program)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are some more tests:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ok'" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_parse(text, result, category=expression):\n", + " \"Test that text can be parsed as a category to yield the semantic result, with no tokens left over.\"\n", + " global tokens\n", + " tokens = tokenizer(text)\n", + " return category() == result and not tokens\n", + " \n", + "def test_parser():\n", + " assert is_funcname('SIN') and is_funcname('FNZ') # Function names are three letters\n", + " assert not is_funcname('X') and not is_funcname('')\n", + " assert is_varname('X') and is_varname('A2') # Variables names are one letter and an optional digit\n", + " assert not is_varname('FNZ') and not is_varname('A10') and not is_varname('')\n", + " assert is_relational('>') and is_relational('>=') and not is_relational('+')\n", + " \n", + " assert test_parse('A + B * X + C', Opcall(Opcall('A', '+', Opcall('B', '*', 'X')), '+', 'C'))\n", + " assert test_parse('A + B + X + C', Opcall(Opcall(Opcall('A', '+', 'B'), '+', 'X'), '+', 'C'))\n", + " assert test_parse('SIN(X)^2', Opcall(Funcall('SIN', 'X'), '^', 2))\n", + " assert test_parse('10 ^ 2 ^ 3', Opcall(10, '^', Opcall(2, '^', 3))) # right associative\n", + " assert test_parse('10 - 2 - 3', Opcall(Opcall(10, '-', 2), '-', 3)) # left associative\n", + " assert test_parse('A(I)+M(I, J)', Opcall(Subscript(var='A', indexes=['I']), '+', \n", + " Subscript(var='M', indexes=['I', 'J'])))\n", + " assert test_parse('X * -1', Opcall('X', '*', Funcall('NEG', 1.0)))\n", + " assert test_parse('X--Y--Z', Opcall(Opcall('X', '-', Funcall('NEG', 'Y')), '-', Funcall('NEG', 'Z')))\n", + " assert test_parse('((((X))))', 'X')\n", + " return 'ok'\n", + "\n", + "test_parser()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Execution\n", + "\n", + "Now that we can parse programs, we're ready to execute them. I'll first define `run` to `parse` and `execute` a program:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def run(program): execute(parse(program))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The function `execute(stmts)` first calls `preprocess(stmts)` to handle *declarations*: `DATA` and `DEF` statements that are processed one time only, before the program runs, regardless of their line numbers. (`DIM` statements are also declarations, but I decided that all lists/tables can have any number of elements, so I can ignore `DIM` declarations.)\n", + "`execute` keeps track of the state of the program, partially in three globals:\n", + "\n", + "* `variables`: A mapping of the values of all BASIC variables (both subscripted and unsubscripted).
For example, `{'P1': 3.14, ('M', (1, 1)): 42.0}` says that the value of `P1` is `3.14` and `M(1, 1)` is `42.0`.\n", + "* `functions`: A mapping of the values of all BASIC functions (both built-in and user-defined).
For example, `{'FNC': Function('X', Opcall('X', '^', 3)), 'SIN': math.sin}` \n", + "* `column`: The column that `PRINT` will print in next.\n", + "\n", + "And also with these local variables:\n", + "\n", + "* `data`: a queue of all the numbers in `DATA` statements.\n", + "* `pc`: program counter; the index into the list of statements.\n", + "* `ret`: the index where a `RETURN` statement will return to.\n", + "* `fors`: a map of `{varname: ForState(...)}` which gives the state of each `FOR` loop variable.\n", + "* `goto`: a mapping of `{linenumber: index}`, for example `{10: 0, 20: 1}` for a program with two line numbers, 10 and 20.\n", + "\n", + "\n", + "Running the program means executing the statement that the program counter (`pc`) is currently pointing at, repeatedly, until we hit an `END` or `STOP` statement (or a `READ` statement when there is no more data). \n", + "The variable `pc` is initialized to `0` (the index of the first statement in the program) and is then incremented by `1` each cycle to go to the following statement; but a branching statement (`GOTO`, `IF`, `GOSUB`, or `RETURN`) can change the `pc` to something other than the following statement. Note that branching statements refer to line numbers, but the `pc` refers to the *index* number within the list of statements. The variable `goto` maps from line numbers to index numbers. In BASIC there is no notion of a *stack*, neither for variables nor return addresses. If I do a `GOSUB` to a subroutine that itself does a `GOSUB`, then the original return address is lost, because BASIC has only one return address register (which we call `ret`).\n", + "\n", + "The main body of `execute` checks the statement type, and takes appropriate action. All the statement types are straightforward, except for `FOR` and `NEXT`, which are explained a bit later." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def execute(stmts): \n", + " \"Parse and execute the BASIC program.\"\n", + " global variables, functions, column\n", + " functions, data = preprocess(stmts) # {name: function,...}, deque[number,...]\n", + " variables = defaultdict(float) # mapping of {variable: value}, default 0.0\n", + " column = 0 # column to PRINT in next\n", + " pc = 0 # program counter\n", + " ret = 0 # index (pc) that a GOSUB returns to\n", + " fors = {} # runtime map of {varname: ForState(...)}\n", + " goto = {stmt.num: i # map of {linenumber: index}\n", + " for (i, stmt) in enumerate(stmts)}\n", + " while pc < len(stmts):\n", + " (_, typ, args) = stmts[pc] # Fetch and decode the instruction\n", + " pc += 1 # Increment the program counter\n", + " if typ in ('END', 'STOP') or (typ == 'READ' and not data): \n", + " return\n", + " elif typ == 'LET':\n", + " V, exp = args\n", + " let(V, evalu(exp))\n", + " elif typ == 'READ':\n", + " for V in args[0]:\n", + " let(V, data.popleft())\n", + " elif typ == 'PRINT':\n", + " basic_print(args[0])\n", + " elif typ == 'GOTO':\n", + " pc = goto[args[0]]\n", + " elif typ == 'IF':\n", + " lhs, relational, rhs, dest = args\n", + " if functions[relational](evalu(lhs), evalu(rhs)):\n", + " pc = goto[dest]\n", + " elif typ == 'FOR':\n", + " V, start, end, step = args\n", + " variables[V] = evalu(start)\n", + " fors[V] = ForState(pc, evalu(end), evalu(step))\n", + " elif typ == 'NEXT':\n", + " V = args[0]\n", + " continu, end, step = fors[V]\n", + " if ((step >= 0 and variables[V] + step <= end) or\n", + " (step < 0 and variables[V] + step >= end)):\n", + " variables[V] += step\n", + " pc = continu\n", + " elif typ == 'GOSUB':\n", + " ret = pc\n", + " pc = goto[args[0]]\n", + " elif typ == 'RETURN':\n", + " pc = ret" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are the functions referenced by `execute`:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import math\n", + "import random\n", + "import operator as op\n", + "\n", + "def preprocess(stmts):\n", + " \"\"\"Go through stmts and return two values extracted from the declarations: \n", + " functions: a mapping of {name: function}, for both built-in and user-defined functions,\n", + " data: a queue of all the numbers in DATA statements.\"\"\"\n", + " functions = { # A mapping of {name: function}; first the built-ins:\n", + " 'SIN': math.sin, 'COS': math.cos, 'TAN': math.tan, 'ATN': math.atan, \n", + " 'ABS': abs, 'EXP': math.exp, 'LOG': math.log, 'SQR': math.sqrt, 'INT': int,\n", + " '>': op.gt, '<': op.lt, '=': op.eq, '>=': op.ge, '<=': op.le, '<>': op.ne, \n", + " '^': pow, '+': op.add, '-': op.sub, '*': op.mul, '/': op.truediv, \n", + " 'RND': lambda _: random.random(), 'NEG': op.neg}\n", + " data = deque() # A queue of numbers that READ can read from\n", + " for (_, typ, args) in stmts:\n", + " if typ == 'DEF':\n", + " name, parm, body = args\n", + " functions[name] = Function(parm, body)\n", + " elif typ == 'DATA':\n", + " data.extend(args[0])\n", + " return functions, data\n", + "\n", + "def evalu(exp):\n", + " \"Evaluate an expression, returning a number.\"\n", + " if isinstance(exp, Opcall):\n", + " return functions[exp.op](evalu(exp.x), evalu(exp.y))\n", + " elif isinstance(exp, Funcall):\n", + " return functions[exp.f](evalu(exp.x))\n", + " elif isinstance(exp, Subscript):\n", + " return variables[exp.var, tuple(evalu(x) for x in exp.indexes)]\n", + " elif is_varname(exp):\n", + " return variables[exp]\n", + " else: # number constant\n", + " return exp\n", + " \n", + "def let(V, value):\n", + " \"Assign value to the variable name or Subscripted variable.\"\n", + " if isinstance(V, Subscript): # A subsscripted variable\n", + " variables[V.var, tuple(evalu(x) for x in V.indexes)] = value \n", + " else: # An unsubscripted variable\n", + " variables[V] = value" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Execution: `FOR/NEXT` Statements\n", + "\n", + "I have to admit I don't completely understand `FOR` loops. My questions include:\n", + "\n", + "* Are the `END` and `STEP` expressions evaluated once when we first enter the `FOR` loop, or each time through the loop?\n", + "* After executing `\"FOR V = 1 TO 10\"`, is the value of `V` equal to 10 or 11? (Answer: the manual says 10.)\n", + "* Does `\"FOR V = 0 TO -2\"` execute zero times? Or do all loops execute at least once, with the termination test done by the `NEXT`?\n", + "* What if control branches into the middle of a loop and hits the `NEXT` statement, without ever executing the corresponding `FOR` statement? \n", + "* What if control branches into the middle of a loop and hits the `NEXT` statement, without ever executing the corresponding `FOR` statement, but we have previously\n", + "executed a `FOR` statement of a *different* loop that happens to use the same variable name?\n", + "\n", + "I chose a solution that is easy to implement, and correctly runs all the examples in the manual, but I'm not certain that my solution is true to the original intent. Consider this program:\n", + "\n", + " 10 PRINT \"TABLE OF SQUARES\"\n", + " 20 LET N = 10\n", + " 30 FOR V = 1 to N STEP N/5\n", + " 40 PRINT V, V * V\n", + " 50 NEXT V\n", + " 60 END\n", + " \n", + " \n", + "* When control hits the `\"FOR V\"` statement in line 30, I assign:\n", + "
`variables['V'] = 1`\n", + "
` fors['V'] = ForState(continu=3, end=10, step=2)`\n", + "
where `3` is the index of line 40 (the line right after the `FOR` statement); `10` is the value of `N`; and `2` is the value of `N/5`.\n", + "* When control hits the `\"NEXT V\"` statement in line 50, I do the following:\n", + "
Examine `fors['V']` to check if `V` incremented by the step value, `2`, is within the bounds defined by the end, `10`. \n", + "
If it is, increment `V` and assign `pc` to be `3`, the `continu` value. \n", + "
If not, continue on to the following statement, `60`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Execution: Printing\n", + "\n", + "We showed how to parse a `PRINT` statement with `labels_and_expressions()`; now it is time to execute a `PRINT` statement, printing each of the labels and expressions, and keeping track of what column to print at next, using the global variable `column`." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def basic_print(items): \n", + " \"Print the items (',' / ';' / label / expression) in appropriate columns.\"\n", + " for item in items:\n", + " if item == ',': pad(15)\n", + " elif item == ';': pad(3)\n", + " elif is_label(item): print_string(item.replace('\"', ''))\n", + " else: print_string(\"{:g} \".format(evalu(item)))\n", + " if (not items) or items[-1] not in (',', ';'):\n", + " newline()\n", + " \n", + "def print_string(s): \n", + " \"Print a string, keeping track of column, and advancing to newline if at or beyond column 75.\"\n", + " global column\n", + " print(s, end='')\n", + " column += len(s)\n", + " if column >= 75: newline()\n", + " \n", + "def pad(width): \n", + " \"Pad out to the column that is the next multiple of width.\"\n", + " while column % width != 0: \n", + " print_string(' ')\n", + "\n", + "def newline(): global column; print(); column = 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Running the First Sample Program\n", + "\n", + "Let's re-examine, parse, and run our first sample program:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "10 REM POWER TABLE\n", + "11 DATA 8, 4\n", + "15 READ N0, P0\n", + "20 PRINT \"N\",\n", + "25 FOR P = 2 to P0\n", + "30 PRINT \"N ^\" P,\n", + "35 NEXT P\n", + "40 PRINT \"SUM\"\n", + "45 LET S = 0\n", + "50 FOR N = 2 TO N0\n", + "55 PRINT N,\n", + "60 FOR P = 2 TO P0\n", + "65 LET S = S + N ^ P\n", + "70 PRINT N ^ P,\n", + "75 NEXT P\n", + "80 PRINT S\n", + "85 NEXT N\n", + "99 END\n", + "\n" + ] + } + ], + "source": [ + "print(program)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[Stmt(num=10, typ='REM', args=[None]),\n", + " Stmt(num=11, typ='DATA', args=[[8.0, 4.0]]),\n", + " Stmt(num=15, typ='READ', args=[['N0', 'P0']]),\n", + " Stmt(num=20, typ='PRINT', args=[['\"N\"', ',']]),\n", + " Stmt(num=25, typ='FOR', args=['P', 2.0, 'P0', 1]),\n", + " Stmt(num=30, typ='PRINT', args=[['\"N ^\"', 'P', ',']]),\n", + " Stmt(num=35, typ='NEXT', args=['P']),\n", + " Stmt(num=40, typ='PRINT', args=[['\"SUM\"']]),\n", + " Stmt(num=45, typ='LET', args=['S', 0.0]),\n", + " Stmt(num=50, typ='FOR', args=['N', 2.0, 'N0', 1]),\n", + " Stmt(num=55, typ='PRINT', args=[['N', ',']]),\n", + " Stmt(num=60, typ='FOR', args=['P', 2.0, 'P0', 1]),\n", + " Stmt(num=65, typ='LET', args=['S', Opcall(x='S', op='+', y=Opcall(x='N', op='^', y='P'))]),\n", + " Stmt(num=70, typ='PRINT', args=[[Opcall(x='N', op='^', y='P'), ',']]),\n", + " Stmt(num=75, typ='NEXT', args=['P']),\n", + " Stmt(num=80, typ='PRINT', args=[['S']]),\n", + " Stmt(num=85, typ='NEXT', args=['N']),\n", + " Stmt(num=99, typ='END', args=[])]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "parse(program)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "N N ^2 N ^3 N ^4 SUM\n", + "2 4 8 16 28 \n", + "3 9 27 81 145 \n", + "4 16 64 256 481 \n", + "5 25 125 625 1256 \n", + "6 36 216 1296 2804 \n", + "7 49 343 2401 5597 \n", + "8 64 512 4096 10269 \n" + ] + } + ], + "source": [ + "run(program)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "# Running More Programs\n", + "\n", + "Rather than put together a suite of unit tests for `execute`, I'll run integration tests—additional whole programs. I've also added a few assertions." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4 -5.5 \n", + "0.666667 0.166667 \n", + "-3.66667 3.83333 \n" + ] + } + ], + "source": [ + "# Linear equation solver (page 3 and 19 of the manual)\n", + "\n", + "run('''\n", + "10 READ A1, A2, A3, A4\n", + "15 LET D = A1 * A4 - A3 * A2\n", + "20 IF D = 0 THEN 65\n", + "30 READ B1, B2\n", + "37 LET X1 = (B1*A4 - B2 * A2) / D\n", + "42 LET X2 = ( A1 * B2 - A3 * B1)/D\n", + "55 PRINT X1, X2\n", + "60 GOTO 30\n", + "65 PRINT \"NO UNIQUE SOLUTION\"\n", + "70 DATA 1, 2, 4\n", + "80 DATA 2, -7, 5\n", + "85 DATA 1, 3, 4, -7\n", + "90 END\n", + "''')\n", + "\n", + "assert variables['D'] != 0\n", + "assert variables['X1'] == -11/3" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X VALUE SINE RESOLUTION\n", + "1.6 0.999574 0.1 \n", + "1.57 1 0.01 \n", + "1.571 1 0.001 \n", + "1.5708 1 0.0001 \n" + ] + } + ], + "source": [ + "# Find max(sin(x)) for 0 <= x <= 3 (page 25)\n", + "\n", + "run('''\n", + "5 PRINT \"X VALUE\", \"SINE\", \"RESOLUTION\"\n", + "10 READ D\n", + "20 LET M = -1\n", + "30 FOR X = 0 TO 3 STEP D\n", + "40 IF SIN(X) <= M THEN 80\n", + "50 LET X0 = X\n", + "60 LET M = SIN(X)\n", + "80 NEXT X\n", + "85 PRINT X0, M, D\n", + "90 GO TO 10\n", + "95 DATA .1, .01, .001, .0001\n", + "99 END\n", + "''')\n", + "\n", + "assert abs(variables['X0'] - math.pi / 2) < 0.00001" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 2 3 4 5 \n", + "6 7 8 9 10 \n", + "11 12 " + ] + } + ], + "source": [ + "# Printing (page 32)\n", + "\n", + "run('''\n", + "10 FOR I = 1 TO 12\n", + "20 PRINT I,\n", + "30 NEXT I\n", + "40 END''')\n", + "\n", + "assert variables['I'] == 12" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "THIS PROGRAM COMPUTES AND PRINTS THE NTH POWERS\n", + "OF THE NUMBERS LESS THAN OR EQUAL TO N FOR VARIOUS\n", + "N FROM 1 TO 7\n", + "\n", + "N = 1 I^N:\n", + "1 \n", + "\n", + "N = 2 I^N:\n", + "1 4 \n", + "\n", + "N = 3 I^N:\n", + "1 8 27 \n", + "\n", + "N = 4 I^N:\n", + "1 16 81 256 \n", + "\n", + "N = 5 I^N:\n", + "1 32 243 1024 3125 \n", + "\n", + "\n", + "N = 6 I^N:\n", + "1 64 729 4096 15625 \n", + "46656 \n", + "\n", + "N = 7 I^N:\n", + "1 128 2187 16384 78125 \n", + "279936 823543 \n", + "\n" + ] + } + ], + "source": [ + "# Powers (page 33)\n", + "\n", + "run('''\n", + " 5 PRINT \"THIS PROGRAM COMPUTES AND PRINTS THE NTH POWERS\"\n", + " 6 PRINT \"OF THE NUMBERS LESS THAN OR EQUAL TO N FOR VARIOUS\"\n", + " 7 PRINT \"N FROM 1 TO 7\"\n", + " 8 PRINT\n", + "10 FOR N = 1 TO 7\n", + "15 PRINT \"N = \"; N; \"I^N:\"\n", + "20 FOR I = 1 TO N\n", + "30 PRINT I^N,\n", + "40 NEXT I\n", + "50 PRINT\n", + "60 PRINT\n", + "70 NEXT N\n", + "80 END''')\n", + "\n", + "assert variables['N'] ** variables['I'] == 7 ** 7" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1e+06 941192 884736 830584 778688 729000 681472 636056 592704 \n", + "551368 512000 474552 438976 405224 373248 343000 314432 287496 \n", + "262144 238328 216000 195112 175616 157464 140608 125000 110592 \n", + "97336 85184 74088 64000 54872 46656 39304 32768 27000 21952 17576 13824 10648 \n", + "8000 5832 4096 2744 1728 1000 512 216 64 8 0 " + ] + } + ], + "source": [ + "# Cubes (page 35; but with STEP -2 because I haven't tested negative step yet)\n", + "\n", + "run('''\n", + "10 FOR I = 100 TO 0 STEP -2\n", + "20 PRINT I*I*I;\n", + "30 NEXT I\n", + "40 END\n", + "''')\n", + "\n", + "assert variables['I'] == 0" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "TOTAL SALES FOR SALESMAN1 $180.5 \n", + "TOTAL SALES FOR SALESMAN2 $211.3 \n", + "TOTAL SALES FOR SALESMAN3 $131.65 \n", + "TOTAL SALES FOR SALESMAN4 $166.55 \n", + "TOTAL SALES FOR SALESMAN5 $169.4 \n" + ] + } + ], + "source": [ + "# Sales ledger (page 37; cleaned up a bit)\n", + "\n", + "run('''\n", + "10 FOR I = 1 TO 3\n", + "20 READ P(I)\n", + "30 NEXT I\n", + "40 FOR I = 1 TO 3\n", + "50 FOR J = 1 TO 5\n", + "60 READ S(I, J)\n", + "70 NEXT J\n", + "80 NEXT I\n", + "90 FOR J = 1 TO 5\n", + "100 LET S = 0\n", + "110 FOR I = 1 TO 3\n", + "120 LET S = S + P(I) * S(I, J)\n", + "130 NEXT I\n", + "140 PRINT \"TOTAL SALES FOR SALESMAN\"J, \"$\"S\n", + "150 NEXT J\n", + "190 DIM S(3, 5)\n", + "200 DATA 1.25, 4.30, 2.50\n", + "210 DATA 40, 20, 37, 29, 42\n", + "220 DATA 10, 16, 3, 21, 8\n", + "230 DATA 35, 47, 29, 16, 33\n", + "300 END\n", + "''')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can look at the variables that have been stored for this program:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "defaultdict(float,\n", + " {'J': 5.0,\n", + " ('S', (1.0, 1.0)): 40.0,\n", + " ('S', (2.0, 4.0)): 21.0,\n", + " ('P', (1.0,)): 1.25,\n", + " ('S', (3.0, 2.0)): 47.0,\n", + " ('S', (2.0, 2.0)): 16.0,\n", + " ('S', (3.0, 3.0)): 29.0,\n", + " ('S', (3.0, 5.0)): 33.0,\n", + " ('S', (1.0, 5.0)): 42.0,\n", + " ('S', (3.0, 4.0)): 16.0,\n", + " 'I': 3.0,\n", + " ('P', (3.0,)): 2.5,\n", + " ('S', (1.0, 4.0)): 29.0,\n", + " ('S', (2.0, 3.0)): 3.0,\n", + " ('S', (1.0, 3.0)): 37.0,\n", + " ('S', (2.0, 1.0)): 10.0,\n", + " ('S', (1.0, 2.0)): 20.0,\n", + " ('S', (2.0, 5.0)): 8.0,\n", + " ('S', (3.0, 1.0)): 35.0,\n", + " 'S': 169.4,\n", + " ('P', (2.0,)): 4.3})" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "variables" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6 3 2 6 9 0 0 3 3 6 9 2 7 9 1 2 1 4 4 1 2 7 3 7 8 \n", + "5 2 5 4 4 9 7 7 0 5 4 9 7 7 5 5 4 9 3 8 6 2 6 4 5 \n", + "8 7 6 0 3 4 1 4 2 2 8 1 1 9 2 4 0 1 0 2 1 3 4 0 2 \n", + "9 0 2 7 4 1 8 4 3 2 8 3 9 3 9 3 2 4 6 8 9 0 9 5 9 \n" + ] + } + ], + "source": [ + "# Random number generator (page 40)\n", + "\n", + "run('''\n", + "10 FOR I = 1 TO 100\n", + "20 PRINT INT(10 * RND(X));\n", + "30 NEXT I\n", + "40 END\n", + "''')" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "D SIN(D) COS(D) SIN(D)^2 + COS(D)^2\n", + "0 0 1 1 \n", + "15 0.258819 0.965926 1 \n", + "30 0.5 0.866025 1 \n", + "45 0.707107 0.707107 1 \n", + "60 0.866025 0.5 1 \n", + "75 0.965926 0.258819 1 \n", + "90 1 6.12323e-17 1 \n" + ] + } + ], + "source": [ + "# DEF example: table of SIN(X) and COS(X) in degrees (page 41, expanded some)\n", + "\n", + "run('''\n", + " 5 PRINT \"D\"; \"SIN(D)\", \"COS(D)\", \"SIN(D)^2 + COS(D)^2\"\n", + "20 LET P = 3.1415926535897932 / 180\n", + "30 FOR X = 0 TO 90 STEP 15\n", + "40 PRINT X; FNS(X), FNC(X), FNS(X)^2 + FNC(X)^2\n", + "50 NEXT X\n", + "97 DEF FNS(D) = SIN(D * P)\n", + "98 DEF FNC(D) = COS(D * P)\n", + "99 END\n", + "''')" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9 27 120 \n", + "25 125 780 \n", + "Z = 2615 \n" + ] + } + ], + "source": [ + "# GOSUB (page 43)\n", + "\n", + "run('''\n", + "100 LET X = 3\n", + "110 GOSUB 400\n", + "120 PRINT U, V, W\n", + "200 LET X = 5\n", + "210 GOSUB 400\n", + "215 PRINT U, V, W\n", + "220 LET Z = U + 2*V + 3*W\n", + "230 PRINT \"Z = \" Z\n", + "240 STOP\n", + "400 LET U = X*X\n", + "410 LET V = X*X*X\n", + "420 LET W = X*X*X*X + X*X*X + X*X + X\n", + "430 RETURN\n", + "440 END\n", + "''')" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "21 \n" + ] + } + ], + "source": [ + "# Sum of non-negative multiples of 0.1 less than or equal to 2, two ways (page 47)\n", + "\n", + "run('''\n", + " 5 LET S = 0\n", + "10 LET N = 0\n", + "20 LET S = S + N/10\n", + "30 IF N >= 20 THEN 60\n", + "40 LET N = N + 1\n", + "50 GOTO 20\n", + "60 PRINT S\n", + "70 END\n", + "''')" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "21 \n" + ] + } + ], + "source": [ + "run('''\n", + "20 FOR N = 1 TO 20\n", + "40 LET S = S + N/10\n", + "50 NEXT N\n", + "60 PRINT S\n", + "70 END\n", + "''')\n", + "\n", + "assert variables['S'] == sum(N/10 for N in range(1, 21))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Checking for Syntax Errors\n", + "\n", + "Here we show a collection of syntax errors, and the messages they generate:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Error in line '10 X = 1' at 'X = 1': unknown statement type\n", + "Error in line '20 GO TO JAIL' at 'J A I L': missing line number\n", + "Error in line '30 FOR I = 1 ' at '': expected 'TO'\n", + "Error in line '40 IF X > 0 & X < 10 GOTO 999' at '& X < 10 GOTO 999': expected 'THEN'\n", + "Error in line '50 LET Z = (Z + 1' at '': expected \")\" to end expression\n", + "Error in line '60 PRINT \"OH CANADA\", EH?' at '?': unknown expression\n", + "Error in line '70 LET Z = +3' at '+ 3': unknown expression\n", + "Error in line '80 LET X = Y ** 2' at '* 2': unknown expression\n", + "Error in line '90 LET A(I = 1' at '= 1': expected \")\" to close subscript\n", + "Error in line '100 IF A = 0 THEN 900 + 99' at '+ 99': extra tokens at end of line\n", + "Error in line '110 NEXT A(I)' at '( I )': extra tokens at end of line\n", + "Error in line '120 DEF F(X) = X ^ 2 + 1' at 'F ( X ) = X ^ 2 + 1': expected a function name\n", + "Error in line '130 IF X != 0 THEN 999' at '! = 0 THEN 999': expected a relational operator\n", + "Error in line '140 DEF FNS(X + 2*P1) = SIN(X)' at '+ 2 * P1 ) = SIN ( X )': expected ')'\n", + "Error in line '150 DEF FNY(M, B) = M * X + B' at ', B ) = M * X + B': expected ')'\n", + "Error in line '160 LET 3 = X' at '3 = X': expected a variable name\n", + "Error in line '170 LET SIN = 7 * DEADLY' at 'SIN = 7 * D E A D L Y': expected a variable name\n", + "Error in line '180 LET X = A-1(I)' at '( I )': extra tokens at end of line\n", + "Error in line 'STOP' at 'STOP': missing line number\n", + "Error in line '200 STOP IT, ALREADY' at 'I T , A L READ Y': extra tokens at end of line\n", + "PROGRAM STILL EXECUTES: 2 + 2 = 4 \n" + ] + } + ], + "source": [ + "run('''\n", + "10 X = 1\n", + "20 GO TO JAIL\n", + "30 FOR I = 1 \n", + "40 IF X > 0 & X < 10 GOTO 999\n", + "50 LET Z = (Z + 1\n", + "60 PRINT \"OH CANADA\", EH?\n", + "70 LET Z = +3\n", + "80 LET X = Y ** 2\n", + "90 LET A(I = 1\n", + "100 IF A = 0 THEN 900 + 99\n", + "110 NEXT A(I)\n", + "120 DEF F(X) = X ^ 2 + 1\n", + "130 IF X != 0 THEN 999\n", + "140 DEF FNS(X + 2*P1) = SIN(X)\n", + "150 DEF FNY(M, B) = M * X + B\n", + "160 LET 3 = X\n", + "170 LET SIN = 7 * DEADLY\n", + "180 LET X = A-1(I)\n", + "STOP\n", + "200 STOP IT, ALREADY\n", + "998 PRINT \"PROGRAM STILL EXECUTES: 2 + 2 = \" 2 + 2\n", + "999 END\n", + "''')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "# Final Program\n", + "\n", + "Now for a final, longer example, Conway's Game of [Life](https://en.wikipedia.org/wiki/Conway's_Game_of_Life),\n", + "which shows that BASIC is capable of handling a non-trivial problem—but I wouldn't want to rely on it for anything much bigger. This should give us some added confidence in the validity of the interpreter, but I would say the interpreter needs more work before I would trust it. I hope you found working through the interpreter informative, and maybe you have ideas for how to improve it, or to develop an interpreter for another language." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " GENERATION 0 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . O . . . . . . . \n", + ". . O . . O O . . . \n", + ". . O . . O O . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 1 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". O O O . O O . . . \n", + ". . . . . O O . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 2 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . O . . . . . . . \n", + ". . O . O O O . . . \n", + ". . O . O O O . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 3 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . O . O . . . . \n", + ". O O . O . O . . . \n", + ". . . . O . O . . . \n", + ". . . . . O . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 4 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . O O O O . . . . \n", + ". . O . O . O . . . \n", + ". . . O O . O . . . \n", + ". . . . . O . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 5 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . O O . . . . . \n", + ". . O . O O . . . . \n", + ". . O . . . O . . . \n", + ". . . O O . O . . . \n", + ". . . . O O . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 6 \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . O O O . . . . \n", + ". . O . O O . . . . \n", + ". . O . . . O . . . \n", + ". . . O O . O . . . \n", + ". . . O O O . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 7 \n", + ". . . . . . . . . . \n", + ". . . . O . . . . . \n", + ". . . O . O . . . . \n", + ". . O . . . O . . . \n", + ". . O . . . O . . . \n", + ". . O . . . O . . . \n", + ". . . O . O . . . . \n", + ". . . . O . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 8 \n", + ". . . . . . . . . . \n", + ". . . . O . . . . . \n", + ". . . O O O . . . . \n", + ". . O O . O O . . . \n", + ". O O O . O O O . . \n", + ". . O O . O O . . . \n", + ". . . O O O . . . . \n", + ". . . . O . . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 9 \n", + ". . . . . . . . . . \n", + ". . . O O O . . . . \n", + ". . O . . . O . . . \n", + ". O . . . . . O . . \n", + ". O . . . . . O . . \n", + ". O . . . . . O . . \n", + ". . O . . . O . . . \n", + ". . . O O O . . . . \n", + ". . . . . . . . . . \n", + ". . . . . . . . . . \n", + " GENERATION 10 \n", + ". . . . O . . . . . \n", + ". . . O O O . . . . \n", + ". . O O O O O . . . \n", + ". O O . . . O O . . \n", + "O O O . . . O O O . \n", + ". O O . . . O O . . \n", + ". . O O O O O . . . \n", + ". . . O O O . . . . \n", + ". . . . O . . . . . \n", + ". . . . . . . . . . \n" + ] + } + ], + "source": [ + "run('''\n", + "100 REM CONWAY'S GAME OF LIFE\n", + "102 REM G IS NUMBER OF GENERATIONS, M IS MATRIX SIZE (M X M)\n", + "104 REM A(X, Y) IS 1 IFF CELL AT (X, Y) IS LIVE\n", + "106 REM L(SELF_ALIVE, NEIGHBORS_ALIVE) IS 1 IFF CELL WITH THOSE COUNTS SHOULD LIVE ON\n", + "110 LET G = 10\n", + "120 LET M = 10\n", + "125 READ A(3,4), A(3,5), A(3,6), A(6,5), A(6,6), A(7,5), A(7,6)\n", + "130 DATA 1, 1, 1, 1, 1, 1, 1\n", + "140 READ L(0, 3), L(1, 3), L(1, 2)\n", + "145 DATA 1, 1, 1\n", + "\n", + "150 REM MAIN LOOP: PRINT, THEN REPEAT G TIMES: UPDATE / COPY / PRINT\n", + "155 LET I = 0\n", + "160 GOSUB 700\n", + "170 FOR I = 1 TO G\n", + "180 GOSUB 300\n", + "190 GOSUB 500\n", + "200 GOSUB 700\n", + "210 NEXT I\n", + "220 STOP\n", + "\n", + "300 REM SUBROUTINE: UPDATE B = NEXT_GENERATION(A)\n", + "310 FOR Y = 1 TO M\n", + "320 FOR X = 1 TO M\n", + "325 LET N = A(X-1,Y)+A(X+1,Y)+A(X,Y-1)+A(X,Y+1)+A(X-1,Y-1)+A(X+1,Y+1)+A(X-1,Y+1)+A(X+1,Y-1)\n", + "330 LET B(X, Y) = L(A(X, Y), N)\n", + "340 NEXT X\n", + "350 NEXT Y\n", + "360 RETURN\n", + "\n", + "500 REM SUBROUTINE: COPY A = B\n", + "510 FOR Y = 1 TO M\n", + "520 FOR X = 1 TO M\n", + "530 LET A(X, Y) = B(X, Y)\n", + "540 NEXT X\n", + "550 NEXT Y\n", + "560 RETURN\n", + "\n", + "700 REM SUBROUTINE: PRINT A\n", + "705 PRINT \" GENERATION \" I\n", + "710 FOR Y = 1 TO M\n", + "720 FOR X = 1 TO M\n", + "730 IF A(X, Y) = 0 THEN 750\n", + "740 PRINT \"O\";\n", + "750 IF A(X, Y) = 1 THEN 770\n", + "760 PRINT \".\";\n", + "770 NEXT X\n", + "780 PRINT\n", + "790 NEXT Y\n", + "795 RETURN\n", + "\n", + "999 END \n", + "''')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Beal.ipynb b/pytudes/ipynb/Beal.ipynb new file mode 100644 index 0000000..71cad1f --- /dev/null +++ b/pytudes/ipynb/Beal.ipynb @@ -0,0 +1,1070 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "
Peter Norvig 22 October 2015, revised 28 October 2015, 4 July 2017
\n", + "\n", + "# Beal's Conjecture Revisited\n", + "\n", + "In 1637, Pierre de Fermat wrote in the margin of a book that he had a proof of his famous \"[Last Theorem](https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem)\":\n", + "\n", + "> If $A^n + B^n = C^n$,\n", + ">
where $A, B, C, n$ are positive integers\n", + ">
then $n \\le 2$.\n", + "\n", + "Centuries passed before [Andrew Beal](https://en.wikipedia.org/wiki/Andrew_Beal), a businessman and amateur mathematician,\n", + "made his conjecture in 1993:\n", + "\n", + "> If $A^x + B^y = C^z$, \n", + ">
where $A, B, C, x, y, z$ are positive integers and $x, y, z$ are all greater than $2$, \n", + ">
then $A, B$ and $C$ must have a common prime factor.\n", + "\n", + "[Andrew Wiles](https://en.wikipedia.org/wiki/Andrew_Wiles) proved Fermat's theorem in 1995, but Beal's conjecture remains unproved, and Beal has offered [$1,000,000](http://www.ams.org/profession/prizes-awards/ams-supported/beal-prize) for a proof or disproof. I don't have the mathematical skills of Wiles, so I could never find a proof, but I can write a program to search for counterexamples. I first wrote [that program in 2000](http://norvig.com/beal2000.html), and [my name got associated](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=beal%20conjecture) with Beal's Conjecture, which means I get a lot of emails with purported proofs or counterexamples (many asking how they can collect their prize money). So far, all the emails have been wrong. This page catalogs some of the more common errors and updates my 2000 program." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# How to Not Win A Million Dollars\n", + "\n", + "\n", + "* A proof must show that there are no examples that satisfy the conditions. A common error is to show how a certain pattern generates an infinite collection of numbers that satisfy $A^x + B^y = C^z$ and then show that in all of these, $A, B, C$ have a common factor. But that's not good enough, unless you can also prove that no other pattern exists.\n", + "\n", + "

\n", + "\n", + "* It is valid to use proof by contradiction: assume the conjecture is true, and show that that leads to a contradiction. It is not valid to use proof by circular reasoning: assume the conjecture is true, put in some irrelevant steps, and show that it follows that the conjecture is true.\n", + "\n", + "\n", + "

\n", + "\n", + "* A valid counterexample needs to satisfy all four conditions—don't leave one out:\n", + "\n", + "> $A, B, C, x, y, z$ are positive integers
\n", + "$x, y, z > 2$
\n", + "$A^x + B^y = C^z$
\n", + "$A, B, C$ have no common prime factor.\n", + "\n", + "(If you think you might have a valid counterexample, before you share it with Andrew Beal or anyone else, you can check it with my [Online Beal Counterexample Checker](http://norvig.com/bealcheck.html).)\n", + "\n", + "

\n", + "\n", + "* One correspondent claimed that $27^4 + 162 ^ 3 = 9 ^ 7$ was a solution, because the first three conditions hold, and the common factor is 9, which isn't a prime. But of course, if $A, B, C$ have 9 as a common factor, then they also have 3, and 3 is prime. The phrase \"no common prime factor\" means the same thing as \"no common factor greater than 1.\"\n", + "\n", + "

\n", + "\n", + "* Another claimed that $2^3+2^3=2^4$ was a counterexample, because all the bases are 2, which is prime, and prime numbers have no prime factors. But that's not true; a prime number has itself as a factor.\n", + "\n", + "

\n", + "\n", + "* A creative person offered $1359072^4 - 940896^4 = 137998080^3$, which fails both because $3^3 2^5 11^2$ is a common factor, and because it has a subtraction rather than an addition (although, as Julius Jacobsen pointed out, that can be rectified by adding $940896^4$ to both sides).\n", + "\n", + "

\n", + "\n", + "* Mustafa Pehlivan came up with an example involving 76-million-digit numbers, which took some work to prove wrong (by using modulo arithmetic). \n", + "\n", + "

\n", + "\n", + "* Another Beal fan started by saying \"Let $C = 43$ and $z = 3$. Since $43 = 21 + 22$, we have $43^3 = (21^3 + 22^3).$\" But of course $(a + b)^3 \\ne (a^3 + b^3)$. This fallacy is called [the freshman's dream](https://en.wikipedia.org/wiki/Freshman%27s_dream) (although I remember having different dreams as a freshman).\n", + "\n", + "

\n", + "\n", + "* Multiple people proposed answers similar to this one:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import gcd #### In Python versions < 3.5, use \"from fractions import gcd\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A, B, C = 60000000000000000000, 70000000000000000000, 82376613842809255677\n", + "\n", + "x = y = z = 3.\n", + "\n", + "A ** x + B ** y == C ** z and gcd(gcd(A, B), C) == 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**WOW! The result is `True`!** Is this a real counterexample to Beal? And also a disproof of Fermat?\n", + "\n", + "Alas, it is not. Notice the decimal point in \"`3.`\", indicating a floating point number, with inexact, limited precision. Change the inexact \"`3.`\" to an exact \"`3`\" and the result changes to \"`False`\". Below we see that the two sides of the equation are the same for the first 18 digits, but differ starting with the 19th: " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(559000000000000000000000000000000000000000000000000000000000,\n", + " 559000000000000000063037470301555182935702892172500189973733)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(A ** 3 + B ** 3,\n", + " C ** 3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "They say \"close\" only counts in horseshoes and hand grenades, and if you threw two horseshoes at a stake on the planet [Kapteyn-b](https://en.wikipedia.org/wiki/Kapteyn_b) (a possibly habitable and thus possibly horseshoe-playing exoplanet 12.8 light years from Earth) and the two paths differed in the 19th digit, the horseshoes would end up [less than an inch](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=12.8%20light%20years%20*%201e-19%20in%20inches) apart. That's really, really close, but close doesn't count in number theory.\n", + "\n", + "\n", + "# *The Simpsons* and Fermat\n", + "\n", + "In two different [episodes of *The Simpsons*](http://www.npr.org/sections/krulwich/2014/05/08/310818693/did-homer-simpson-actually-solve-fermat-s-last-theorem-take-a-look), close counterexamples to Fermat's Last Theorem are shown: \n", + "$1782^{12} + 1841^{12} = 1922^{12}$ and $3987^{12} + 4365^{12} = 4472^{12}$. These were designed by *Simpsons* writer David X. Cohen to be correct up to the precision found in most handheld calculators. Cohen found the equations with a program that must have been something like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from itertools import combinations\n", + "\n", + "def simpsons(bases, powers):\n", + " \"\"\"Find the integers (A, B, C, n) that come closest to solving \n", + " Fermat's equation, A ** n + B ** n == C ** n. \n", + " Let A, B range over all pairs of bases and n over all powers.\"\"\"\n", + " equations = ((A, B, iroot(A ** n + B ** n, n), n)\n", + " for A, B in combinations(bases, 2)\n", + " for n in powers)\n", + " return min(equations, key=relative_error)\n", + "\n", + "def iroot(i, n): \n", + " \"The integer closest to the nth root of i.\"\n", + " return int(round(i ** (1./n)))\n", + "\n", + "def relative_error(equation):\n", + " \"Error between LHS and RHS of equation, relative to RHS.\" \n", + " (A, B, C, n) = equation\n", + " LHS = A ** n + B ** n\n", + " RHS = C ** n\n", + " return abs(LHS - RHS) / RHS" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1782, 1841, 1922, 12)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simpsons(range(1000, 2000), [11, 12, 13])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(3987, 4365, 4472, 12)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simpsons(range(3000, 5000), [12])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Back to Beal\n", + "\n", + "In October 2015 I looked back at my original [program from 2000](http://norvig.com/beal2000.html).\n", + "I ported it from Python 1.5 to 3.5 (by putting parens around the argument to `print` and adding `long = int`). The program runs 250 times faster today than it did in 2000, a tribute to both computer hardware engineers and the developers of the Python interpreter.\n", + "\n", + "I found that I was a bit confused about the definition of [the problem in 2000](https://web.archive.org/web/19991127081319/http://bealconjecture.com/). I thought then that, *by definition*, $A$ and $B$ could not have a common factor, but actually, the definition of the conjecture only rules out examples where all three of $A, B, C$ share a common factor. Mark Tiefenbruck (and later Edward P. Berlin and Shen Lixing) wrote to point out that my thought was actually correct, not by definition, but by derivation: if $A$ and $B$ have a commmon prime factor $p$, then the sum of $A^x + B^y$ must also have that factor $p$, and since $A^x + B^y = C^z$, then $C^z$ and hence $C$ must have the factor $p$. So I was wrong twice, and in this case two wrongs did make a right.\n", + "\n", + "Mark Tiefenbruck also suggested an optimization: only consider exponents that are odd primes, or 4. The idea is that a number like 512 can be expressed as either $2^9$ or $8^3$, and my program doesn't need to consider both. In general, any time we have a composite exponent, such as $b^{qp}$, where $p$ is prime, we should ignore $b^{(qp)}$, and instead consider only $(b^q)^p$. There's one complication to this scheme: 2 is a prime, but 2 is not a valid exponent for a Beal counterexample. So we will allow 4 as an exponent, as well as all odd primes up to `max_x`.\n", + "\n", + "Here is the complete, updated, refactored, optimized program:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import gcd, log\n", + "from itertools import combinations, product\n", + "\n", + "def beal(max_A, max_x):\n", + " \"\"\"See if any A ** x + B ** y equals some C ** z, with gcd(A, B) == 1.\n", + " Consider any 1 <= A,B <= max_A and x,y <= max_x, with x,y prime or 4.\"\"\"\n", + " Apowers = make_Apowers(max_A, max_x)\n", + " Czroots = make_Czroots(Apowers)\n", + " for (A, B) in combinations(Apowers, 2):\n", + " if gcd(A, B) == 1:\n", + " for (Ax, By) in product(Apowers[A], Apowers[B]): \n", + " Cz = Ax + By\n", + " if Cz in Czroots:\n", + " C = Czroots[Cz]\n", + " x, y, z = exponent(Ax, A), exponent(By, B), exponent(Cz, C)\n", + " print('{} ** {} + {} ** {} == {} ** {} == {}'\n", + " .format(A, x, B, y, C, z, C ** z))\n", + "\n", + "def make_Apowers(max_A, max_x): \n", + " \"A dict of {A: [A**3, A**4, ...], ...}.\"\n", + " exponents = exponents_upto(max_x)\n", + " return {A: [A ** x for x in (exponents if (A != 1) else [3])]\n", + " for A in range(1, max_A+1)}\n", + "\n", + "def make_Czroots(Apowers): return {Cz: C for C in Apowers for Cz in Apowers[C]} \n", + " \n", + "def exponents_upto(max_x):\n", + " \"Return all odd primes up to max_x, as well as 4.\"\n", + " exponents = [3, 4] if max_x >= 4 else [3] if max_x == 3 else []\n", + " for x in range(5, max_x, 2):\n", + " if not any(x % p == 0 for p in exponents):\n", + " exponents.append(x)\n", + " return exponents\n", + "\n", + "def exponent(Cz, C): \n", + " \"\"\"Recover z such that C ** z == Cz (or equivalently z = log Cz base C).\n", + " For exponent(1, 1), arbitrarily choose to return 3.\"\"\"\n", + " return 3 if (Cz == C == 1) else int(round(log(Cz, C)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "It takes less than a second to verify that there are no counterexamples for combinations up to $100^{100}$, a computation that took Andrew Beal thousands of hours on his 1990s-era computers:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 256 ms, sys: 1.44 ms, total: 257 ms\n", + "Wall time: 256 ms\n" + ] + } + ], + "source": [ + "%time beal(100, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The execution time goes up roughly with the square of `max_A`, so the following should take about 100 times longer:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 29.1 s, sys: 25.2 ms, total: 29.2 s\n", + "Wall time: 29.2 s\n" + ] + } + ], + "source": [ + "%time beal(1000, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# How `beal` Works\n", + "\n", + "The function `beal` first does some precomputation, creating two data structures:\n", + "* `Apowers`: a dict of the form `{A: [A**3, A**4, ...]}` giving the\n", + "nonredundant powers (prime and 4th powers) of each base, `A`, from 3 to `max_x`.\n", + "* `Czroots`: a dict of `{C**z : C}` pairs, giving the zth root of each power in `Apowers`.\n", + "\n", + "Here is a very small example Apowers table:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{1: [1],\n", + " 2: [8, 16, 32, 128],\n", + " 3: [27, 81, 243, 2187],\n", + " 4: [64, 256, 1024, 16384],\n", + " 5: [125, 625, 3125, 78125],\n", + " 6: [216, 1296, 7776, 279936]}" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Apowers = make_Apowers(6, 10)\n", + "Apowers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Then we enumerate all combinations of two bases, `A` and `B`, from `Apowers`. Consider the combination where `A` is `3` and `B` is `6`. Of course `gcd(3, 6) == 3`, so the program would not consider them further, but imagine if they did not share a common factor. Then we would look at all possible `Ax + By` sums, for `Ax` in `[27, 81, 243, 2187]` and `By` in `[216, 1296, 7776, 279936].` One of these would be `27 + 216`, which sums to `243`. We look up `243` in `Czroots`:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{1: 1,\n", + " 8: 2,\n", + " 16: 2,\n", + " 27: 3,\n", + " 32: 2,\n", + " 64: 4,\n", + " 81: 3,\n", + " 125: 5,\n", + " 128: 2,\n", + " 216: 6,\n", + " 243: 3,\n", + " 256: 4,\n", + " 625: 5,\n", + " 1024: 4,\n", + " 1296: 6,\n", + " 2187: 3,\n", + " 3125: 5,\n", + " 7776: 6,\n", + " 16384: 4,\n", + " 78125: 5,\n", + " 279936: 6}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Czroots = make_Czroots(Apowers)\n", + "Czroots" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Czroots[243]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We see that `243` is in `Czroots`, with value `3`, so this would be a counterexample (except for the common factor). The program uses the `exponent` function to recover the values of `x, y, z`, and prints the results.\n", + "\n", + "# Is the Program Correct?\n", + "\n", + "Can we gain confidence in the program? It is difficult to test `beal`, because the expected output is nothing, for all known inputs.\n", + "One thing we can do is verify that `beal` finds cases like `3 ** 3 + 6 ** 3 == 3 ** 5 == 243` that would be a counterexample except for the common factor `3`. We can test this by temporarily replacing the `gcd` function with a mock function that always reports no common factors:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 ** 3 + 6 ** 3 == 3 ** 5 == 243\n", + "7 ** 7 + 49 ** 3 == 98 ** 3 == 941192\n", + "8 ** 4 + 16 ** 3 == 2 ** 13 == 8192\n", + "8 ** 5 + 32 ** 3 == 16 ** 4 == 65536\n", + "9 ** 3 + 18 ** 3 == 9 ** 4 == 6561\n", + "16 ** 5 + 32 ** 4 == 8 ** 7 == 2097152\n", + "17 ** 4 + 34 ** 4 == 17 ** 5 == 1419857\n", + "19 ** 4 + 38 ** 3 == 57 ** 3 == 185193\n", + "27 ** 3 + 54 ** 3 == 3 ** 11 == 177147\n", + "28 ** 3 + 84 ** 3 == 28 ** 4 == 614656\n", + "34 ** 5 + 51 ** 4 == 85 ** 4 == 52200625\n" + ] + } + ], + "source": [ + "def gcd(a, b): return 1\n", + "\n", + "beal(100, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's make sure all those expressions are true:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{True}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{3 ** 3 + 6 ** 3 == 3 ** 5 == 243,\n", + " 7 ** 7 + 49 ** 3 == 98 ** 3 == 941192,\n", + " 8 ** 4 + 16 ** 3 == 2 ** 13 == 8192,\n", + " 8 ** 5 + 32 ** 3 == 16 ** 4 == 65536,\n", + " 9 ** 3 + 18 ** 3 == 9 ** 4 == 6561,\n", + " 16 ** 5 + 32 ** 4 == 8 ** 7 == 2097152,\n", + " 17 ** 4 + 34 ** 4 == 17 ** 5 == 1419857,\n", + " 19 ** 4 + 38 ** 3 == 57 ** 3 == 185193,\n", + " 27 ** 3 + 54 ** 3 == 3 ** 11 == 177147,\n", + " 28 ** 3 + 84 ** 3 == 28 ** 4 == 614656,\n", + " 34 ** 5 + 51 ** 4 == 85 ** 4 == 52200625}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I get nervous having an incorrect version of `gcd` around; let's change it back, quick!" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import gcd\n", + "\n", + "beal(100, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can also provide some test cases for the subfunctions of `beal`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'tests pass'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " assert make_Apowers(6, 10) == {\n", + " 1: [1],\n", + " 2: [8, 16, 32, 128],\n", + " 3: [27, 81, 243, 2187],\n", + " 4: [64, 256, 1024, 16384],\n", + " 5: [125, 625, 3125, 78125],\n", + " 6: [216, 1296, 7776, 279936]}\n", + " \n", + " assert make_Czroots(make_Apowers(5, 8)) == {\n", + " 1: 1, 8: 2, 16: 2, 27: 3, 32: 2, 64: 4, 81: 3,\n", + " 125: 5, 128: 2, 243: 3, 256: 4, 625: 5, 1024: 4,\n", + " 2187: 3, 3125: 5, 16384: 4, 78125: 5}\n", + " Czroots = make_Czroots(make_Apowers(100, 100))\n", + " assert 3 ** 3 + 6 ** 3 in Czroots\n", + " assert 99 ** 97 in Czroots\n", + " assert 101 ** 100 not in Czroots\n", + " assert Czroots[99 ** 97] == 99\n", + " \n", + " assert exponent(10 ** 5, 10) == 5\n", + " assert exponent(7 ** 3, 7) == 3\n", + " assert exponent(1234 ** 999, 1234) == 999\n", + " assert exponent(12345 ** 6789, 12345) == 6789\n", + " assert exponent(3 ** 10000, 3) == 10000\n", + " assert exponent(1, 1) == 3\n", + " \n", + " assert exponents_upto(2) == []\n", + " assert exponents_upto(3) == [3]\n", + " assert exponents_upto(4) == [3, 4]\n", + " assert exponents_upto(40) == [3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]\n", + " assert exponents_upto(100) == [\n", + " 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, \n", + " 67, 71, 73, 79, 83, 89, 97]\n", + " \n", + " assert gcd(3, 6) == 3\n", + " assert gcd(3, 7) == 1\n", + " assert gcd(861591083269373931, 94815872265407) == 97\n", + " assert gcd(2*3*5*(7**10)*(11**12), 3*(7**5)*(11**13)*17) == 3*(7**5)*(11**12)\n", + " \n", + " return 'tests pass'\n", + " \n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The program is mostly straightforward, but relies on the correctness of these arguments: \n", + "\n", + "* Are we justified in taking `combinations` without replacements from the `Apowers` table? In other words, are we sure there are no solutions of the form $A^x + A^x = C^z$? Yes, we can be sure, because then $2\\;A^x = C^z$, and all the factors of $A$ would also be factors of $C$.\n", + "\n", + "

\n", + "* Are we justified in having a single value for each key in the `Czroots` table? Consider that $81 = 3^4 = 9^2$. We put `{81: 3}` in the table and discard `{81: 9}`, because any number that has 9 as a factor will always have 3 as a factor as well, so 3 is all we need to know. But what if a number could be formed with two bases where neither was a multiple of the other? For example, what if $2^7 = 5^3 = s$; then wouldn't we have to have both 2 and 5 as values for $s$ in the table? Fortunately, that can never happen, because of the [fundamental theorem of arithmetic](https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic).\n", + "\n", + "

\n", + "* Could there be a rounding error involving the `exponent` function that was not caught by the tests? Possibly; but `exponent` is not used to find counterexamples, only to print them, so any such error wouldn't cause us to miss a counterexample.\n", + "\n", + "

\n", + "* Are we justified in only considering exponents that are odd primes, or the number 4? In one sense, yes, because when we consider the two terms $A^{(qp)}$ and $(A^q)^p$, we find they are always equal, and always have the same prime factors (the factors of $A$), so for the purposes of the Beal problem, they are equivalent, and we only need consider one of them. In another sense, there is a difference. With this optimization, when we run `beal(6, 10)`, we are no longer testing $512$ as a value of $A$ or $B$, even though $512 = 2^9$ and both $2$ and $9$ are within range, because the program chooses to express $512$ as $8^3$, and $8$ is not in the specified range. So the program is still correctly searching for counterexamples, but the space that it searches for given `max_A` and `max_x` is different with this optimization.\n", + "\n", + "

\n", + "* Are we really sure that when $A$ and $B$ have a common factor greater than 1, then\n", + "$C$ also shares that common factor? Yes, because if $p$ is a factor of both $A$ and $B$, then it is a factor of $A^x + B^y$, and since we know this is equal to $C^z$, then $p$ must also be a factor of $C^z$, and thus a factor of $C$.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "# Faster Arithmetic (mod *p*)\n", + "\n", + "Arithmetic is slow with integers that have thousands of digits. If we want to explore much further, we'll have to make the program more efficient. An obvious improvement would be to do all the arithmetic modulo some number $m$. Then we know:\n", + "\n", + "$$\\mbox{if} ~~ \n", + "A^x + B^y = C^z\n", + "~~ \\mbox{then} ~~\n", + "(A^x (\\mbox{mod} ~ m) + B^y (\\mbox{mod} ~ m)) (\\mbox{mod} ~ m) = C^z \\;(\\mbox{mod} ~ m)$$\n", + "\n", + "\n", + "So we can do efficient tests modulo $m$, and then do the full arithmetic only for combinations that work modulo $m$. Unfortunately there will be collisions (two numbers that are distinct, but are equal mod $m$), so the tables will have to have lists of values. Here is a simple, unoptimized implementation:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import gcd\n", + "from itertools import combinations, product\n", + "from collections import defaultdict\n", + " \n", + "def beal_modm(max_A, max_x, m=2**31-1):\n", + " \"\"\"See if any A ** x + B ** y equals some C ** z (mod p), with gcd(A, B) == 1.\n", + " If so, verify that the equation works without the (mod m).\n", + " Consider any 1 <= A,B <= max_A and x,y <= max_x, with x,y prime or 4.\"\"\"\n", + " assert m >= max_A\n", + " Apowers = make_Apowers_modm(max_A, max_x, m)\n", + " Czroots = make_Czroots_modm(Apowers)\n", + " for (A, B) in combinations(Apowers, 2):\n", + " if gcd(A, B) == 1:\n", + " for (Axm, x), (Bym, y) in product(Apowers[A], Apowers[B]): \n", + " Czm = (Axm + Bym) % m\n", + " if Czm in Czroots:\n", + " lhs = A ** x + B ** y\n", + " for (C, z) in Czroots[Czm]:\n", + " if lhs == C ** z:\n", + " print('{} ** {} + {} ** {} == {} ** {} == {}'\n", + " .format(A, x, B, y, C, z, C ** z)) \n", + " \n", + "\n", + "def make_Apowers_modm(max_A, max_x, m): \n", + " \"A dict of {A: [(A**3 (mod m), 3), (A**4 (mod m), 4), ...]}.\"\n", + " exponents = exponents_upto(max_x)\n", + " return {A: [(pow(A, x, m), x) for x in (exponents if (A != 1) else [3])]\n", + " for A in range(1, max_A+1)}\n", + "\n", + "def make_Czroots_modm(Apowers): \n", + " \"A dict of {C**z (mod m): [(C, z),...]}\"\n", + " Czroots = defaultdict(list)\n", + " for A in Apowers:\n", + " for (Axm, x) in Apowers[A]:\n", + " Czroots[Axm].append((A, x))\n", + " return Czroots " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here we see that each entry in the `Apowers` table is a list of `(A**x (mod p), x)` pairs.\n", + "For example, $6^7 = 279,936$, so in our (mod 1000) table we have the pair `(936, 7)` under `6`." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{1: [(1, 3)],\n", + " 2: [(8, 3), (16, 4), (32, 5), (128, 7)],\n", + " 3: [(27, 3), (81, 4), (243, 5), (187, 7)],\n", + " 4: [(64, 3), (256, 4), (24, 5), (384, 7)],\n", + " 5: [(125, 3), (625, 4), (125, 5), (125, 7)],\n", + " 6: [(216, 3), (296, 4), (776, 5), (936, 7)]}" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Apowers = make_Apowers_modm(6, 10, 1000)\n", + "Apowers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And each item in the `Czroots` table is of the form `{C**z (mod m): [(C, z), ...]}`.\n", + "For example, `936: [(6, 7)]`." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "defaultdict(list,\n", + " {1: [(1, 3)],\n", + " 8: [(2, 3)],\n", + " 16: [(2, 4)],\n", + " 24: [(4, 5)],\n", + " 27: [(3, 3)],\n", + " 32: [(2, 5)],\n", + " 64: [(4, 3)],\n", + " 81: [(3, 4)],\n", + " 125: [(5, 3), (5, 5), (5, 7)],\n", + " 128: [(2, 7)],\n", + " 187: [(3, 7)],\n", + " 216: [(6, 3)],\n", + " 243: [(3, 5)],\n", + " 256: [(4, 4)],\n", + " 296: [(6, 4)],\n", + " 384: [(4, 7)],\n", + " 625: [(5, 4)],\n", + " 776: [(6, 5)],\n", + " 936: [(6, 7)]})" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "make_Czroots_modm(Apowers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's run the program:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 35.5 s, sys: 44.1 ms, total: 35.5 s\n", + "Wall time: 35.5 s\n" + ] + } + ], + "source": [ + "%time beal_modm(1000, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We don't see a speedup here, but the idea is that as we start dealing with much larger integers, this version should be faster. I could improve this version by caching certain computations, managing the memory layout better, moving some computations out of loops, considering using multiple different numbers as the modulus (as in a Bloom filter), finding a way to parallelize the program, and re-coding in a faster compiled language (such as C++ or Go or Julia). Then I could invest thousands (or millions) of CPU hours searching for counterexamples. \n", + "\n", + "But [Witold Jarnicki](https://plus.sandbox.google.com/+WitoldJarnicki/posts) and [David Konerding](http://www.konerding.com/~dek/) already did that: they wrote a C++ program that, in parallel across thousands of machines, searched for $A, B$ up to 200,000 and $x, y$ up to 5,000, but found no counterexamples. So I don't think it is worthwhile to continue on that path.\n", + "\n", + "# Conclusion\n", + "\n", + "This was fun, but I can't recommend anyone spend a serious amount of computer time looking for counterexamples to the Beal Conjecture—the money you would have to spend in computer time would be more than the expected value of your prize winnings. I suggest you work on a proof rather than a counterexample, or work on some other interesting problem instead!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Bike Speed versus Grade.ipynb b/pytudes/ipynb/Bike Speed versus Grade.ipynb new file mode 100644 index 0000000..5791e61 --- /dev/null +++ b/pytudes/ipynb/Bike Speed versus Grade.ipynb @@ -0,0 +1,184 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Bike Speed versus Grade\n", + "\n", + "Like most people, I bike slower when I'm going up a steep hill than on a flat road. But how much slower?\n", + "To answer that, I downloaded data on my past rides \n", + "from [Strava](https://www.strava.com/athletes/575579) and manipulated the `data` to create two lists: \n", + "\n", + "- `X`: the *grade* of each ride, in feet of ascent per mile. \n", + "- `Y`: the *speed* of each (corresponding) ride, in miles per hour.\n", + "\n", + "I omit rides shorter than 30 miles, because on some short rides I was sprinting at an unsustainable speed, and on others I was slowed by city traffic. Here is the code to collect and plot the X:Y data:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nLiKSQv8frjJL86AyaU0AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import csv\n", + "\n", + "def hours(sec): return float(sec) / 60 / 60\n", + "def feet(meters): return float(meters) * 100 / 2.54 / 12\n", + "def miles(meters): return feet(meters) / 5280\n", + "\n", + "# Read data file with three fields: distance (m), climb (m), elapsed time (sec)\n", + "X, Y = [], []\n", + "for (dist, climb, time) in csv.reader(open('dist-climb-time.csv')):\n", + " if miles(dist) > 30:\n", + " X.append(feet(climb) / miles(dist))\n", + " Y.append(miles(dist) / hours(time))\n", + "\n", + "plt.plot(X, Y, 'o');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As expected, the speeds get slower as the grade gets steeper. The data has a lot of variance, and I can say that it \n", + "looks more like a curve than a straight line, so I'll fit a cubic (degree two) polynomial to the data,\n", + "and make the plot prettier:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzgAAAIcCAYAAAA6xgsWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XtgU1W6NvAnTe2FClpa2lLaBhQKXgbGcdTx8zoKM+KI\nRxG0hUodaFGwIlULKJQClTsKQgHl4ghSQfGgM+qo53gbUUaPjgg4jlBEE1oKpRcupk1D03x/lISm\n2Ul30p19y/P7S9Mka+29krDfvdb7LsOJEyecICIiIiIi0oEIpTtAREREREQkFQY4RERERESkGwxw\niIiIiIhINxjgEBERERGRbjDAISIiIiIi3WCAQ0REREREusEAh4iIiIiIdEPxAGfXrl3Izs7GpZde\nivj4eGzdutXj71arFUVFRbjsssvQu3dvXHXVVVizZo1CvSUiIiIiIjWLVLoDVqsVl112GbKzszFp\n0iSvvz/11FP49NNPsW7dOmRkZGDXrl2YMmUKEhMTce+99yrQYyIiIiIiUivFZ3CGDRuGWbNm4c47\n74TBYPD6+1dffYX77rsP1113HdLT03Hffffht7/9Lb7++msFektERERERGqmeIDTmd/97nd47733\nUFVVBQD48ssv8d1332HYsGEK94yIiIiIiNRG8SVqnVm8eDGmTp2Kyy+/HJGRkTAYDFiyZAkDHCIi\nIiIi8qL6AOf555/HV199hVdffRVpaWnYtWsXZs2ahYyMDNxyyy1Kd4+IiIiIiFRE1QGOzWZDaWkp\nNm/ejD/84Q8AgEsvvRR79+7FqlWrGOAQEREREZEHVefgnDlzBmfOnEFEhGc3jUYjWltbFeoVERER\nERGpleIBjtVqxb59+7B37160traisrIS+/btQ2VlJbp3747rrrsOc+bMwWeffQaz2Yzy8nJs27YN\nI0aMULrrsNlsumtLzmOqqKiQrS09jpXcbelxvDhWXafXcyhXWxwrbbXF8dJGOwDHSmttSU3xAGf3\n7t248cYbcfPNN8Nms2HhwoW46aabsHDhQgDAX/7yF/zmN7/Bgw8+iGuvvRYrV67ErFmzkJeXp3DP\niYiIiIhIbRTPwbn++uvR0NDg8++9evVCWVmZjD0iIiIiIiKtUnwGh4iIiIiISCoMcIiIiIiISDcY\n4BARERERkW4wwCEiIiIiIt1ggENERERERLrBAIeIiIiIiHSDAQ4REREREekGAxwiIiIiItINBjhE\n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\ns+rVq5fsdhpkylJpuTp//rx27dqlMWPGaOPGjVq+fLkOHTqknj17Ov1DArlyn2v9bBX74IMPtGPH\nDjVs2LDEazeTL1O0qD344INq3ry5ZsyY4TgWExOjRx99VMnJyR5cGS6Xl5en4OBgvf322+rYsaMk\nKSoqSk899ZQSEhIkSQUFBQoPD9ekSZMUGxvryeVWSqdPn1b79u31yiuvKC0tTbfddpumTp0qiVwZ\nyYsvvqht27Y5PR/sSuTLOHr16qV69erp1VdfdRwbOnSocnJytGLFCknkywgaN26sjIwM9enTx3Hs\nWnk5c+aMwsLCNHfuXPXo0UOSdPjwYTVv3lzvvfeeHnjgAY9ci9m5ytWV9uzZo1atWmnr1q1q1qwZ\nufKgq+Xr4MGD6ty5s1avXq0ePXpo8ODBGjFihCTddL4q/A7Ov//9b3333Xdq37690/EOHTroq6++\n8syi4NLZs2dVVFSkOnXqSJIOHDigY8eOOX2T+vr6qnXr1uTOQ0aNGqVu3brp/vvvdzpOrozlo48+\nUkxMjOLi4hQeHq42bdpo4cKFjtfJl7Hce++92rRpk+ORBz/++KM2bdrk+Ice8mVM15OXnTt36uLF\ni07nNGrUSJGRkeTOw86cOSOLxeL4neO7774jVwZis9kUHx+vxMREhYeHl3j9ZvPlU6ar9YCTJ0/K\nZrPJarU6Ha9fv76++OILD60KrowdO1bR0dG65557JEnZ2dmyWCxObTXSpdwdPXrUE0us1JYuXaoD\nBw5o8eLFJV4jV8ZSnKdhw4YpISHB0ZphsVg0aNAg8mUwo0aN0rlz59SyZUt5e3vLZrPpmWee0cCB\nAyXx82VU15OX48ePy9vbW3Xr1i1xTnZ2ttvWCmf//ve/9dxzz6lz585q0KCBpEv5JFfGMXnyZAUE\nBGjAgAEuX7/ZfFX4AgcVw7PPPqvt27frk08+kcVi8fRycIWffvpJKSkp+vTTT+XlVeE3dk2vqKhI\nMTExjhbc5s2ba9++fVq0aJEGDRrk4dXhSu+9955WrFihJUuWKDIyUrt27VJSUpJCQkLUr18/Ty8P\nMJXinYGzZ8/qnXfe8fRy4MKmTZu0fPlybd68udxiVPjfZOrVqydvb+8S1dzx48dL7OrAM8aNG6f3\n339fa9euVXBwsOO41WqV3W7X8ePHnc4nd+63fft2nTp1Si1btlRAQIACAgK0ZcsWLVq0SPXr11fd\nunXJlYEEBgYqIiLC6VhERIRjYhA/W8YyYcIEjRw5Uo8++qiaNWumxx9/XMOHD3fcN0q+jOl68mK1\nWmWz2XTq1KmrngP3sdlsiouL0+7du7VmzRpHe5pEroxky5YtOnbsmCIiIhy/c/zyyy+aMGGCY8DR\nzearwhc4VapUUYsWLfT55587Hd+wYYNatWrlmUXBISkpyVHchIaGOr12yy23KDAwUBs2bHAcKygo\n0LZt28idm3Xp0kVbt27V5s2bHf/dddddeuyxx7R582aFhYWRKwNp1aqV436OYnv37lWTJk0k8bNl\nNOfPny+xM+rl5eWY7kS+jOl68tKiRQv5+Pg4nXP48GHHDe5wn4sXL2rAgAHavXu31q1bp4CAAKfX\nyZVxxMfHa8uWLU6/czRo0EDDhw/XBx98IOnm82WKFrXhw4dryJAhuuuuu9SqVSstXrxYx44du2pf\nH9xj9OjRevfdd7Vs2TLVrl3bscvm5+cnPz8/SZcmCU2fPl1hYWEKDQ3VtGnTVLNmTcfEDLhH7dq1\nVbt2badjNWrUUJ06dRQZGSmJXBnJsGHD1LFjR7300kvq3r27MjMztWDBAr3wwguOc8iXcXTq1Ekz\nZ85UcHCwoqKilJmZqVdffVVPPPGE4xzy5Rl5eXnav3+/7Ha7ioqKdOjQIe3atUv+/v5q3LjxNfNS\nu3ZtPfnkk5owYYICAgJUp04dPffcc2revLnatWvn4aszl9Jy1aBBA/Xv31+ZmZlavny57Ha743eO\n2rVry9fXl1y52bV+turVq+d0vo+Pj6xWq+Mfw282X6YYEy1JS5Ys0csvv6xjx46pWbNmmjJlChW5\nh/n7+7u83yYpKUlJSUmOP6enp+v1119Xbm6uYmJiNG3aNEVFRblzqXCha9euatasmWNMtESujGT9\n+vWaOHGi9u3bp8aNG2vw4MGKj493Ood8GUNeXp5SU1O1bt06nThxQoGBgerRo4fGjBmjqlWrOs4j\nX+63efNmde3atcTfVX369NGcOXMkXTsvxTe0r1y5UgUFBWrXrp2mTZvm8rke+P1Ky1VSUpKio6Nd\n/s4xZ84cx3hicuU+1/Ozdbno6GjFx8c7xkRLN5cv0xQ4AAAAAFDh78EBAAAAgGIUOAAAAABMgwIH\nAAAAgGlQ4AAAAAAwDQocAAAAAKZBgQMAAADANChwAAAAAJgGBQ4A4Ko2b94sf39/bdmypUzf9/z5\n84qMjNRbb73ldPyf//ynOnfurMaNG6tu3br6/vvvyzSup0yZMkX+/v5Ox/77v/9bXbt2/V3v16FD\nB73wwgtlsDIAMB8KHAAwoJMnT+rFF1/UfffdpyZNmigoKEgtWrTQkCFDtGnTJreuxdXTwW/W3Llz\nVaVKFfXu3dtxzG63a+DAgcrOzlZqaqrmz5+vJk2alHns/Px8paWlXbNou+2225SRkVEmMS0Wi7y8\nvEoc+70SEhK0cOFCHT9+/GaXBgCmQ4EDAAazc+dOtWrVSnPnzlV0dLReeOEFTZs2TT179tT333+v\nRx55RP/4xz88vczf7eLFi5o3b56efPJJ+fj4OI4fOXJE+/fv11NPPaXY2Fj17NlTf/jDH8o8fn5+\nvtLT07V58+arnpOZmamjR4+qU6dOZRJzzJgxOnLkSJm8lyR16dJFtWrV0sKFC8vsPQHALHyufQoA\nwF1Onz6tvn37ysfHR5s3b1ZoaKjT6+PHj9e6devk5+dX6vucP39eNWrUKM+l/m4ff/yxTp48qUcf\nfdTpeHZ2tiSpVq1a5Rrfbrdf85zPPvtMQUFBat68eZnE9PLyUtWqVcvkvaRLuz8PP/ywli9frmef\nfbbM3hcAzIAdHAAwkCVLlujo0aNKS0srUdwU69Kli1q1auX4c/H9Hbt379bgwYPVtGlTtW7dWpL0\nyy+/aPTo0WrZsqUaNmyokJAQ9erVS//6179KvO+vv/6qJ554Qo0aNVJ4eLieffZZFRYWuiwIduzY\noZ49eyo4OFgNGjRQ586dr7t17qOPPlJQUJAiIyMdx4YNG6YHHnhAFotFw4YNk7+/v9P9Kfv27dOA\nAQN06623KigoSG3bttUHH3xQ4r3PnDmjZ599VnfccYesVqtatGihjIwMFRUVSZIOHjyosLAwWSwW\npaWlyd/fX/7+/ho+fLjT+6xfv14PPfSQ48/NmzdXz549tXnzZj3wwANq0KCBWrdurY0bN0qS1q1b\np/vuu09BQUFq166dvvvuO6f3c3UPztXMnz9frVu3VlBQkMLDw/XXv/5Vp06dKnHeAw88oMOHD5eI\nBQCVHTs4AGAgn376qapXr64uXbpc99cU38sRFxenkJAQJScnq7CwUNKlQmTbtm165JFH1LhxYx09\nelSvv/66unTpoi+//FJWq1WSVFBQoIcffli//vqrhgwZosDAQP3973/Xxo0bS9wrsnnzZj322GO6\n8847lZSUpCpVquidd95R9+7dtXr1at13332lrnf79u1q0aKF07G4uDjdeuutSk1N1cCBA3Xvvfc6\n1rZnzx517NhRQUFBGjVqlPz8/LRu3ToNGDBACxYsUM+ePR3X0KVLFx06dEhxcXEKDg7Wt99+q7S0\nNB06dEgvv/yyAgICNGPGDCUkJKhr166OIqpp06aOtZw6dUrffvutRo0a5fQZ//zzz4qPj1dsbKx6\n9+6tWbNmqW/fvpoxY4YmTpyo+Ph4WSwWTZs2TQMHDtSOHTscn53FYrmue24SEhK0bNkyPfHEE3rq\nqad06NAhzZ8/Xzt27NCGDRucdoFatGghu92uL7/8ssTnCQCVGQUOABjInj17FBYWJm9vb6fj586d\ncxQtklStWrUSbWqRkZF6/fXXnY516tRJjzzyiNOxXr16qWXLlnrzzTf1zDPPSJJee+017d+/X6+9\n9prj/AEDBqhNmzYl1vj000+rdevWWrVqleNYXFyc2rRpo5SUFH3yySdXvT6bzaaff/5ZHTt2dDr+\nxz/+UT4+PkpNTdWf/vQnR9EiSWPHjlXDhg31+eefO37B/8tf/qLu3btr4sSJjnPnzJmjffv2aePG\njY7dr/79+ys4OFipqakaOXKkQkND9fDDDyshIUG33367U5xin332mapUqaL27ds7Hd+/f78+/vhj\ntWzZUpIUERGh7t27669//au2b9/uGIhQu3ZtJSQkaOPGjWrXrt1VP4srffXVV3r99dc1f/58Pf74\n447jDz74oDp16qQVK1aof//+juMNGjRQ1apVtWfPnuuOAQCVAS1qAGAgZ8+edXl/zd/+9jeFhoY6\n/hszZozT6xaLRQMHDizxddWqVXP87/z8fOXk5KhmzZoKCwtzam36n//5H1mtVqdiqFq1anryySed\n3m/Xrl3au3evevTooVOnTjn+O336tNq3b69vvvlGBQUFV72+nJwc2e121alT59ofhqTc3Fx98cUX\nevTRR3Xu3DmnmB06dNCvv/6qffv2SZJWr16tVq1ayd/f3+m8du3ayW63lzpU4HLr169X69atS9zD\nFBYW5ihuJCkmJkaS1KZNG6dpbzExMbLb7crKyrqueMXef/991apVSx06dHBaf1hYmKxWq8sWwDp1\n6ujkyZM3FAcAzI4dHAAwkJo1a+rcuXMljicmJjr+9f7y0cqXu7zNqtiFCxeUmpqqv//97zp69Kjj\nuMViUb169Rx//uWXX1x+fVhYmNOfi4uJESNGuFyDxWLRqVOn1LBhQ5evF7ueG/2lS7smdrtdaWlp\nmjJlist4x48fV2hoqPbt26cffvjB5b1Lxeddi81m0z/+8Q+NGzeuxGuNGzd2+nPt2rUlqcS1Fh/P\nzc29ZrzL7d+/X2fPnlV4eHiJ1662frvdXi5jvAGgIqPAAQADiYyM1Pfffy+bzebUphYVFaWoqChJ\nKtG+Vqx69eoljiUmJurtt9/WU089pXvuuUd/+MMfZLFYNG7cOMeN9zei+GtefPFF3XnnnS7PCQgI\nuOrX161bVxaL5bp/+S+ON2zYMKeb/i/XrFkzx7lt27bV008/7bKAuuWWW64Z78svv9SZM2f05z//\nucRrV/vcr3b8eou4YkVFRapXr56WLFni8mtd7XqdPn3aqVAFAFDgAIChdOrUSV9//bU++OADde/e\n/abf74MPPlCfPn2UmprqdDw3N9fpF+MmTZrohx9+KPH1P/30k9Ofi3d5/Pz8buj+kmJeXl4KDQ29\n7vat4qLEx8fnmvGaNm2qc+fOqW3btqWeV9qOx/r16xUaGupyN6u8NW3aVJ9//rn++Mc/XteI7yNH\njqiwsFARERFuWB0AVBzcgwMABjJw4EAFBgZq/Pjx2rt3702/n7e3d4mdmpUrV5Z46ORDDz2k7Oxs\np9HL+fn5evPNN53Oa9GihW699VbNmTPHZSvd9dwP0rJly+sebRwQEKA2bdpo6dKlLh+UeXm8bt26\naceOHVq/fn2J8y4f0lC80+VqF+mzzz5zuXvjDt26dZPNZtPUqVNLvFZUVFRivd99950sFovTfUEA\nAHZwAMBQ6tSpo2XLlqlXr15q06aNunfvrpiYGFWpUkWHDx/W2rVrdf78eaeb2kvTuXNnvfPOO6pZ\ns6Zuu+027dq1S6tWrSqxQxEbG6uFCxdqyJAh2rlzpxo0aKB3333XaUiBdGn345VXXlHPnj3VqlUr\n9e3bV40aNdKRI0e0ZcsWSdKaNWtKXdN//dd/6e2339aePXucnoVzNdOnT1enTp103333KTY2Vk2b\nNtXx48f1zTff6P/+7//07bffSpJGjhypTz75RH379lXv3r3VokUL5efn61//+pfWrl2rLVu2qEmT\nJvL19VWzZs20atUqhYaGqm7dugoJCZHVatXu3buVlpZ2XZ9tWWvdurUGDRqkWbNm6fvvv1eHDh1U\nrVo17du3T2vWrNH48ePVp08fx/n/+7//q4YNG+quu+7yyHoBwKgocADAYO6++259+eWXmjNnjj75\n5BOtWbNGNptNQUFBatmypdLT012Ob3YlPT1dVatW1erVq7Vs2TLdddddWrVqlZKTk51atapXr641\na9ZozJgxWrRokapXr67HH39cDz74oHr06OH0nq1bt9b69euVkZGhJUuW6OzZs7Jarbr77rudxhhf\nTceOHRUQEKD3339fY8eOdXrNVftYWFiYNmzYoPT0dL3zzjs6efKkAgICdMcdd+i5555znOfr66sP\nP/xQ06dP1+rVq/Xuu++qZs2aCg0NVWJiogIDAx3nzp49W0lJSUpOTtaFCxfUp08f3X333apVq5bj\nIalXrsvV2m7k+NXOu1xGRoZatGih1157TampqfL29lbjxo3Vo0cPp9Y7u92utWvXlphyBwCQLLm5\nuTd2FyQAADdpxowZWrx4sTIzM696k7679erVS9WqVdMbb7zh6aVc05o1azR06FDt3LnT8UBUAMAl\n3IMDAHC7IUOG6OLFi1q+fLmnl+Jw//33X3X8tdHMnDlTgwcPprgBABfYwQEAAABgGuzgAAAAADAN\nChwAAAAApkGBAwAAAMA0KHAAAAAAmAYFDgAAAADToMABAAAAYBoUOAAAAABMgwIHAAAAgGn8P3ea\nzHDl3n7pAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def poly(X, Y, n):\n", + " \"Best-fit degree-n polynomial for X, Y data.\"\n", + " C = np.polyfit(X, Y, n)[::-1] # Array of coefficients, reversed\n", + " return lambda x: sum(C[i] * x ** i for i in range(n + 1)) \n", + "\n", + "F = poly(X, Y, 2) # defines y = F(x); x in ft/mile, y in mph\n", + "\n", + "def show(X, Y, F=F): \n", + " plt.rcParams[\"figure.figsize\"] = (12, 8)\n", + " plt.style.use('fivethirtyeight')\n", + " plt.plot(X, Y, 'o')\n", + " X1 = list(range(int(max(X))))\n", + " plt.plot(X1, [F(x) for x in X1], 'o')\n", + " plt.ylabel('Speed (mph)')\n", + " plt.xlabel('Grade (feet/mile)')\n", + " plt.minorticks_on()\n", + " plt.grid(True, which='major')\n", + " plt.grid(True, which='minor', alpha=0.2)\n", + " \n", + "show(X, Y) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, I average about 14 mph when the road is fairly flat, with a lot of variability from 12 to 16 mph, depending more on my level of effort than on the grade of the road. But from 60 ft/mile and up, speed falls off quickly at 1 mph for every 20 ft/mile, and by 140 ft/mile, I'm down around 8 mph. Note that 140 ft/mile is only 2.7% grade, but if you figure a typical route is 1/3 up, 1/3 down, and 1/3 flatish, then that's 8% grade on the up part.\n", + "\n", + "I can use the polynomial `F` to estimate the duration of a route:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def duration(dist, climb, F=F):\n", + " \"Given a distance in miles and total climb in feet, return estimated time in minutes.\"\n", + " return dist / F(climb / dist) * 60" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For example, to get to Pescadero from La Honda, I could take the flatter [coast route](https://www.google.com/maps/dir/La+Honda,+California/Pescadero,+California/@37.2905834,-122.3896683,12z/data=!4m19!4m18!1m10!1m1!1s0x808faed4dc6265bd:0x51a109d3306a7219!2m2!1d-122.274227!2d37.3190255!3m4!1m2!1d-122.4039496!2d37.3116594!3s0x808f062b7d7585e7:0x942480c22f110b74!1m5!1m1!1s0x808f00b4b613c4c1:0x43c609077878b77!2m2!1d-122.3830152!2d37.2551636!3e1), or the shorter [creek route](https://www.google.com/maps/dir/La+Honda,+California/Pescadero,+California/@37.2905834,-122.3896683,12z/data=!4m19!4m18!1m10!1m1!1s0x808faed4dc6265bd:0x51a109d3306a7219!2m2!1d-122.274227!2d37.3190255!3m4!1m2!1d-122.3658887!2d37.2538867!3s0x808f00acf265bd43:0xb7e2a0c9ee355c3a!1m5!1m1!1s0x808f00b4b613c4c1:0x43c609077878b77!2m2!1d-122.3830152!2d37.2551636!3e1):" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6.7314081227852185" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "coast = duration(15.7, 344)\n", + "creek = duration(13.5, 735)\n", + "\n", + "coast - creek" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This says the coast route takes 6.7 minutes longer. Good to know, but other factors are probably more important in making the choice." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Cheryl-and-Eve.ipynb b/pytudes/ipynb/Cheryl-and-Eve.ipynb new file mode 100644 index 0000000..29864bd --- /dev/null +++ b/pytudes/ipynb/Cheryl-and-Eve.ipynb @@ -0,0 +1,1202 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# When Cheryl Met Eve: A Birthday Story" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Peter Norvig, May 2015\n", + "\n", + "The \"Cheryl's Birthday\" logic puzzle [made the rounds](https://www.google.com/webhp?#q=cheryl%27s+birthday),\n", + "and I wrote [code](Cheryl.ipynb) that solves it. There I said that one reason for solving the problem with code rather than pencil and paper is that you can do more with code. [Gabe Gaster](http://www.gabegaster.com/) proved me right when he [tweeted](https://twitter.com/gabegaster/status/593976413314777089/photo/1) that he had extended my code to generate a new list of dates that satisfies the constraints of the puzzle:\n", + "\n", + " January 15, January 4,\n", + " July 13, July 24, July 30,\n", + " March 13, March 24,\n", + " May 11, May 17, May 30\n", + "\n", + "In this notebook, I verify Gabe's result, and find some other variations on the puzzle.\n", + "\n", + "First, let's recap [the puzzle](https://en.wikipedia.org/wiki/Cheryl%27s_Birthday):\n", + "\n", + "> Albert and Bernard just became friends with Cheryl, and they want to know when her birthday is. Cheryl gives them a list of 10 possible dates:\n", + "\n", + "> May 15 16 19\n", + "> June 17 18\t\n", + "> July 14 16\t\t\t\n", + "> August 14 15 17\t\t\n", + "\n", + "> Cheryl then tells Albert and Bernard separately the month and the day of her birthday respectively.\n", + "\n", + ">**Albert**: I don't know when Cheryl's birthday is, but I know that Bernard does not know too.\n", + "\n", + ">**Bernard**: At first I don't know when Cheryl's birthday is, but I know now.\n", + "\n", + ">**Albert**: Then I also know when Cheryl's birthday is.\n", + "\n", + ">So when is Cheryl's birthday?\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Code for Original Cheryl's Birthday Puzzle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a slight modification of my [previous code](Cheryl.ipynb), and I'll give a slight modification of the explanation. The puzzle concerns these concepts:\n", + "\n", + "- **Possible dates** that might be Cheryl's birthday.\n", + "- **Knowing** which dates are still possible; knowing for sure when only one is possible.\n", + "- **Telling** Albert and Bernard specific facts about the birthday.\n", + "- **Statements** about knowledge.\n", + "- **Hearing** the statements about knowledge.\n", + "\n", + "I implement them as follows:\n", + "- `DATES` is a set of all possible dates (each date is a string); we also consider subsets of `DATES`.\n", + "- `know(possible_dates)` is a function that returns `True` when there is only one possible date.\n", + "- `tell(part)` is a function that returns the set of possible dates after Cheryl tells a part (month or day).\n", + "- *`statement`*`(date)` returns true for dates that satisfy the statement.\n", + "- `hear(possible_dates, statement,...)` returns a subset of possible_dates that are still possible after hearing the statements.\n", + "\n", + "For example, `albert1` is Albert's first statement, which says in part that he knows that Bernard\n", + "does not yet know Cheryl's birthday. So `albert1('May 19')` should be `False`, because if May 19 were Cheryl's birthday, then she would have told Bernard `'19'`, he would know that `'May 19'` is the only possibility.\n", + "\n", + "`tell('17')` returns `{'June 17', 'August 17'}`, the set of possible dates after Bernard is told `'17'`. \n", + "\n", + " `know(tell('17'))` is `False` because if Bernard was told `'17'` he would not know Cheryl's birthday for sure; there would be two possibilities. But `know(tell('19'))` is `True` because there would be only one possibility.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Albert and Bernard just became friends with Cheryl, and they want to know when her birthday is. \n", + "# Cheryl gives them a set of 10 possible dates:\n", + "\n", + "cheryl_dates = DATES = {\n", + " 'May 15', 'May 16', 'May 19',\n", + " 'June 17', 'June 18',\n", + " 'July 14', 'July 16',\n", + " 'August 14', 'August 15', 'August 17'}\n", + "\n", + "def month(date): return date.split()[0]\n", + "\n", + "def day(date): return date.split()[1]\n", + "\n", + "# Cheryl then tells Albert and Bernard separately \n", + "# the month and the day of the birthday respectively.\n", + "\n", + "def tell(part):\n", + " \"Cheryl tells a part of her birthdate; return a subset of DATES that match the part.\"\n", + " return {date for date in DATES if part in date}\n", + "\n", + "def know(possible_dates):\n", + " \"A person knows the birthdate if they know there is exactly one possible date.\"\n", + " return len(possible_dates) == 1\n", + "\n", + "def hear(possible_dates, *statements):\n", + " \"Return the subset of possible dates that are consistent with all the statements.\"\n", + " return {date for date in possible_dates\n", + " if all(stmt(date) for stmt in statements)}\n", + "\n", + "# Albert and Bernard make three statements:\n", + "\n", + "def albert1(date):\n", + " \"Albert: I don't know when Cheryl's birthday is, but I know that Bernard does not know too.\"\n", + " after_being_told = tell(month(date))\n", + " return (not know(after_being_told) \n", + " and all(not know(tell(day(d)))\n", + " for d in after_being_told))\n", + "\n", + "def bernard1(date):\n", + " \"Bernard: At first I don't know when Cheryl's birthday is, but I know now.\"\n", + " at_first = tell(day(date))\n", + " return (not know(at_first)\n", + " and know(hear(at_first, albert1)))\n", + "\n", + "def albert2(date):\n", + " \"Albert: Then I also know when Cheryl's birthday is.\"\n", + " return know(hear(tell(month(date)), bernard1))\n", + " \n", + "# So when is Cheryl's birthday?\n", + "\n", + "def cheryls_birthday(dates):\n", + " \"Return a list of the possible dates after hearing the three statements.\"\n", + " return hear(using(dates), albert1, bernard1, albert2)\n", + "\n", + "def using(dates):\n", + " \"Make dates be the value of the global variable DATES.\"\n", + " global DATES # This is necessary because `tell` looks at `DATES`\n", + " DATES = dates\n", + " return dates\n", + "\n", + "# Some tests\n", + "\n", + "assert month('May 19') == 'May'\n", + "assert day('May 19') == '19'\n", + "assert albert1('May 19') == False\n", + "assert albert1('July 14') == True\n", + "assert know(tell('17')) == False\n", + "assert know(tell('19')) == True" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 16'}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cheryls_birthday(cheryl_dates)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'August 14', 'August 15', 'August 17', 'July 14', 'July 16'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(DATES, albert1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'August 15', 'August 17', 'July 16'}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(DATES, albert1, bernard1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 16'}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(DATES, albert1, bernard1, albert2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Verifying Gabe's Version" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Gabe tweeted these ten dates:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "gabe_dates = [\n", + " 'January 15', 'January 4',\n", + " 'July 13', 'July 24', 'July 30',\n", + " 'March 13', 'March 24',\n", + " 'May 11', 'May 17', 'May 30']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can verify that they do indeed make the puzzle work, giving a single known birthdate:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 30'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cheryls_birthday(gabe_dates)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Creating Our Own Versions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If Gabe can do it, we can do it! Our strategy will be to repeatedly pick a random sample of dates, and check if they solve the puzzle. We'll limit ourselves to a subset of dates (not all 366) to make it more likely that a random selection will have multiple dates with the same month and day (otherwise Albert and Bernard would know right away):" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "some_dates = {mo + ' ' + d1 + d2\n", + " for mo in ('March', 'April', 'May', 'June', 'July')\n", + " for d1 in '12'\n", + " for d2 in '56789'}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need to cycle through random samples of these possible dates until we hit one that works. I anticipate wanting to solve other puzzles besides the original `cheryls_birthday`, so I'll make the `puzzle` be a parameter of the function `pick_dates`. Note that `pick_dates` returns two things: the one date that is the solution (the birthday), and the `k` (default 10) dates that form the puzzle." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "\n", + "def pick_dates(puzzle=cheryls_birthday, k=10):\n", + " \"Pick a set of dates for which the puzzle has a unique solution.\"\n", + " while True:\n", + " dates = set(random.sample(some_dates, k))\n", + " solutions = puzzle(dates)\n", + " if know(solutions):\n", + " return solutions.pop(), dates" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('June 27',\n", + " {'April 19',\n", + " 'April 28',\n", + " 'June 19',\n", + " 'June 27',\n", + " 'June 28',\n", + " 'March 15',\n", + " 'March 28',\n", + " 'May 16',\n", + " 'May 19',\n", + " 'May 27'})" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pick_dates()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Great! We can make a new puzzle, just like Gabe. But how often do we get a unique solution to the puzzle (that is, the puzzle returns a set of size 1)? How often do we get a solution where Albert and Bernard know, but we the puzzle solver doesn't (that is, a set of size greater than 1)? How often is there no solution (size 0)? Let's make a Counter of the number of times each length-of-solution occurs:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import Counter\n", + "\n", + "def counter(puzzle=cheryls_birthday, N=10000, k=10):\n", + " \"Try N random samples and count how often each possible length-of-solution appears.\"\n", + " return Counter(len(puzzle(set(random.sample(some_dates, k))))\n", + " for _ in range(N))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({0: 8700, 1: 614, 2: 684, 3: 2})" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counter(cheryls_birthday)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This says that about 6% of the time we get a unique solution (a set of `len` 1). With similar frequency we get an ambiguous solution (with 2 or more possible birth dates). And most of the time, the sample of dates leads to no solution.\n", + "\n", + "What happens if Cheryl changes the number of possible dates?" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({0: 9972, 1: 11, 2: 17})" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counter(cheryls_birthday, k=6)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({0: 7532, 1: 1394, 2: 1030, 3: 44})" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counter(cheryls_birthday, k=12)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is really hard (but not impossible) to find a set of 6 dates that work for the puzzle, and much easier to find a solution with 12 dates." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A New Puzzle: All About Eve" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's see if we can create a more complicated puzzle. We'll introduce a new character, Eve, give her a statement, and alter the rest of the puzzle slightly:\n", + "\n", + "> *Albert and Bernard just became friends with Cheryl, and they want to know when her birthday is. Cheryl wrote down a list of 10 possible dates for all to see.*\n", + " \n", + "> *Cheryl then writes down the month and shows it just to Albert, and also writes down the day and shows it just to Bernard.*\n", + "\n", + "> **Albert**: *I don't know when Cheryl's birthday is, but I know that Bernard does not know either.*\n", + "\n", + "> **Bernard**: *At first I didn't know when Cheryl's birthday is, but I know now.*\n", + " \n", + "> **Albert**: *Then I also know when Cheryl's birthday is.*\n", + "\n", + "> **Eve**: *Hi, my name is Eve and I'm an evesdropper. It's what I do! I peeked and saw the first letter of the month and the first digit of the day. When I peeked, I didn't know Cheryl's birthday, but after listening to Albert and Bernard I do. And it's a good thing I peeked, because otherwise I couldn't have\n", + "figured it out.*\n", + " \n", + "> *So when is Cheryl's birthday?*\n", + "\n", + "We can easily code this up:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "def cheryls_birthday_with_eve(dates):\n", + " \"Return a set of the dates for which Albert, Bernard, and Eve's statements are true.\"\n", + " return hear(using(dates), albert1, bernard1, albert2, eve1)\n", + "\n", + "def eve1(date):\n", + " \"\"\"Eve: I peeked and saw the first letter of the month and the first digit of the day. \n", + " When I peeked, I didn't know Cheryl's birthday, but after listening to Albert and Bernard \n", + " I do. And it's a good thing I peeked, because otherwise I couldn't have figured it out.\"\"\"\n", + " at_first = tell(first(day(date))) & tell(first(month(date)))\n", + " otherwise = tell('')\n", + " return (not know(at_first) and\n", + " know(hear(at_first, albert1, bernard1, albert2)) and\n", + " not know(hear(otherwise, albert1, bernard1, albert2)))\n", + "\n", + "def first(seq): return seq[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Note*: I admit I \"cheated\" a bit here. Remember that the function `tell` tests for `(part in date)`. For that to work for Eve, we have to make sure that the first letter is distinct from any other character in the date (it is—because only the first letter is uppercase) and that the first digit is distinct from any other character (it is—because in `some_dates` I carefully made sure that the first digit is always 1 or 2, and the second digit is never 1 or 2). Also note that `tell('')` denotes the hypothetical situation where Cheryl \"told\" Eve nothing.\n", + "\n", + "I have no idea if it is possible to find a set of dates that works for this puzzle. But I can try:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('July 17',\n", + " {'April 18',\n", + " 'April 25',\n", + " 'April 29',\n", + " 'July 17',\n", + " 'July 18',\n", + " 'June 18',\n", + " 'June 29',\n", + " 'March 27',\n", + " 'May 17',\n", + " 'May 28'})" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pick_dates(puzzle=cheryls_birthday_with_eve)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy. How often is a random sample of dates a solution to this puzzle?" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({0: 9492, 1: 258, 2: 250})" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counter(cheryls_birthday_with_eve)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "About half as often as for the original puzzle." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# An Even More Complex Puzzle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's make the puzzle even more complicated by making Albert wait one more time before he finally knows:\n", + "\n", + "> *Albert and Bernard just became friends with Cheryl, and they want to know when her birtxhday is. Cheryl wrote down a list of 10 possible dates for all to see.*\n", + " \n", + "> *Cheryl then writes down the month and shows it just to Albert, and also writes down the day and shows it just to Bernard.*\n", + " \n", + "> **Albert**: *I don't know when Cheryl's birthday is, but I know that Bernard does not know either.*\n", + " \n", + "> **Bernard**: *At first I didn't know when Cheryl's birthday is, but I know now.*\n", + " \n", + "> **Albert**: *I still don't know.*\n", + "\n", + "> **Eve**: *Hi, my name is Eve and I'm an evesdropper. It's what I do! I peeked and saw the first letter of the month and the first digit of the day. When I peeked, I didn't know Cheryl's birthday, but after listening to Albert and Bernard I do. And it's a good thing I peeked, because otherwise I couldn't have figured it out.*\n", + "\n", + "> **Albert**: *OK, now I know.*\n", + " \n", + "> *So when is Cheryl's birthday?*\n", + "\n", + "Let's be careful in coding this up; Albert's second statement is different; he has a new third statement; and Eve's statement uses the same words, but it now implicitly refers to a different statement by Albert. We'll use the names `albert2c`, `eve1c`, and `albert3c` (`c` for \"complex\") to represent the new statements:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "def cheryls_birthday_complex(dates):\n", + " \"Return a set of the dates for which Albert, Bernard, and Eve's statements are true.\"\n", + " return hear(using(dates), albert1, bernard1, albert2c, eve1c, albert3c)\n", + "\n", + "def albert2c(date):\n", + " \"Albert: I still don't know.\"\n", + " return not know(hear(tell(month(date)), bernard1))\n", + "\n", + "def eve1c(date):\n", + " \"\"\"Eve: I peeked and saw the first letter of the month and the first digit of the day. \n", + " When I peeked, I didn't know Cheryl's birthday, but after listening to Albert and Bernard \n", + " I do. And it's a good thing I peeked, because otherwise I couldn't have figured it out.\"\"\"\n", + " at_first = tell(first(day(date))) & tell(first(month(date)))\n", + " otherwise = tell('')\n", + " return (not know(at_first)\n", + " and know(hear(at_first, albert1, bernard1, albert2c)) and\n", + " not know(hear(otherwise, albert1, bernard1, albert2c)))\n", + "\n", + "def albert3c(date):\n", + " \"Albert: OK, now I know.\"\n", + " return know(hear(tell(month(date)), eve1c))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again, I don't know if it is possible to find dates that works with this story, but I can try:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('July 29',\n", + " {'April 29',\n", + " 'July 15',\n", + " 'July 18',\n", + " 'July 29',\n", + " 'June 25',\n", + " 'March 15',\n", + " 'March 19',\n", + " 'March 25',\n", + " 'May 18',\n", + " 'May 27'})" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pick_dates(puzzle=cheryls_birthday_complex)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It worked! Were we just lucky, or are there many sets of dates that work?" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({0: 9047, 1: 951, 2: 2})" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "counter(cheryls_birthday_complex)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Interesting. It was actually easier to find dates that work for this story than for either of the other stories." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Analyzing a Solution to the Complex Puzzle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we will go through a solution step-by-step. We'll use a set of dates selected in a previous run:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "DATES = {\n", + " 'April 28',\n", + " 'July 27',\n", + " 'June 19',\n", + " 'June 16',\n", + " 'July 15',\n", + " 'April 15',\n", + " 'June 29',\n", + " 'July 16',\n", + " 'May 24',\n", + " 'May 27'}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's find the solution:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 27'}" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cheryls_birthday_complex(DATES)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the first step is that Albert was told \"July\":" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 15', 'July 16', 'July 27'}" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tell('July')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And no matter which of these three dates is the actual birthday, Albert knows that Bernard would not know the birthday, because each of the days (15, 16, 27) appears twice in the list of possible dates." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all(not know(tell(day(d)))\n", + " for d in tell('July'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, Bernard is told the day:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 27', 'May 27'}" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tell('27')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are two dates with a 27, so Bernard did not know then. But only one of these dates is still consistent after hearing Albert's statement:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 27'}" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(tell('27'), albert1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So after Albert's statement, Bernard knows. Poor Albert still doesn't know (after being told `'July'` and hearing Bernard's statement):" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 15', 'July 16', 'July 27'}" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(tell('July'), bernard1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then along comes Eve. She evesdrops the \"J\" and the \"2\":" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 27', 'June 29'}" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tell('J') & tell('2')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Two dates, so Eve doesn't know yet. But only one of the dates works after hearing the three statements made by Albert and Bernard:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 27'}" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(tell('J') & tell('2'), albert1, bernard1, albert2c)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But Eve wouldn't have known if she had been told nothing:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 15', 'July 16', 'July 27'}" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(tell(''), albert1, bernard1, albert2c)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What about Albert? After hearing Eve's statement he finally knows:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'July 27'}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(tell('July'), eve1c)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Three Children\n", + "\n", + "Here's another puzzle:\n", + "\n", + "> *A parent has the following conversation with a friend:*\n", + "\n", + "> **Parent:** the product of my three childrens' ages is 36.\n", + "\n", + "> **Friend**: I don't know their ages.\n", + "\n", + "> **Parent**: The sum of their ages is the same as the number of people in this room.\n", + "\n", + "> **Friend**: I still don't know their ages.\n", + "\n", + "> **Parent**: The oldest one likes bananas.\n", + "\n", + "> **Friend**: Now I know their ages.\n", + "\n", + "Let's follow the same methodology to solve this puzzle. Except this time, we're not dealing with sets of possible dates, we're dealing with set of possible *states* of the world. We'll define a state as a tuple of 4 numbers: the ages of the three children (in increasing order), and the number of people in the room. (We'll limit the children's ages to be below 30 and the number of people in the room to be below 90.)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(2, 2, 9, 13)}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "N = 30\n", + "states = {(a, b, c, n) \n", + " for a in range(1, N)\n", + " for b in range(a, N)\n", + " for c in range(b, N) if a * b * c == 36\n", + " for n in range(2, 90)}\n", + "\n", + "def ages(state): return state[:-1]\n", + "def room(state): return state[-1]\n", + "\n", + "def parent1(state): \n", + " \"The product of my three childrens' ages is 36.\"\n", + " a, b, c = ages(state)\n", + " return a * b * c == 36\n", + "\n", + "def friend1(state): \n", + " \"I don't know their ages.\"\n", + " return not know({ages(s) for s in hear(states, parent1)})\n", + "\n", + "def parent2(state):\n", + " \"The sum of their ages is the same as the number of people in this room.\"\n", + " return sum(ages(state)) == room(state)\n", + "\n", + "def friend2(state, possibilities=hear(states, parent1, friend1, parent2)): \n", + " \"I still don't know their ages.\"\n", + " # Given there are room(state) people in the room, I still don't know the ages.\n", + " return not know({ages(s) for s in possibilities if room(s) == room(state)})\n", + "\n", + "def parent3(state):\n", + " \"The oldest one likes bananas.\"\n", + " # I.e., there is an oldest one (and not twins of the same age)\n", + " a, b, c = ages(state)\n", + " return c > b\n", + "\n", + "def friend3(state, possibilities=hear(states, parent1, friend1, parent2, friend2, parent3)): \n", + " \"Now I know their ages.\"\n", + " return know({ages(s) for s in possibilities})\n", + "\n", + "def child_age_puzzle(states):\n", + " return hear(states, parent1, friend1, parent2, friend2, parent3, friend3)\n", + "\n", + "child_age_puzzle(states)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The tricky part of this puzzle comes after the `parent2` statement:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 2, 18, 21),\n", + " (1, 3, 12, 16),\n", + " (1, 4, 9, 14),\n", + " (1, 6, 6, 13),\n", + " (2, 2, 9, 13),\n", + " (2, 3, 6, 11),\n", + " (3, 3, 4, 10)}" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hear(states, parent1, friend1, parent2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that out of these 7 possibilities, if the number of people in the room (the last number in each tuple) \n", + "were anything other than 13, then the friend (who can observe the number of people in the room) would know the ages. Since the `friend2` statement professes continued ignorance, it must be that the number of people in the room is 13. Then the `parent3` statement makes it clear that there can't be 6-year-old twins as the oldest children; it must be 2-year-old twins with an oldest age 9." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# What Next?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you like, there are many other directions you could take this:\n", + "\n", + "- Could you create a puzzle that goes one or two rounds more before everyone knows?\n", + "- Could you add new characters: Faith, and then George, and maybe even a new Hope?\n", + "- Would it be more interesting with a different number of possible dates (not 10)?\n", + "- Should we include the year or the day of the week, as well as the month and day?\n", + "- Perhaps a puzzle that starts with [Richard Smullyan](http://en.wikipedia.org/wiki/Raymond_Smullyan) announcing that one of the characters is a liar.\n", + "- Or you could make a puzzle harder than [the hardest logic puzzle ever](https://en.wikipedia.org/wiki/The_Hardest_Logic_Puzzle_Ever).\n", + "- Try the \"black and white hats\" [Riddler Express](https://fivethirtyeight.com/features/can-you-solve-these-colorful-puzzles/) stumper.\n", + "- It's up to you ..." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Cheryl.ipynb b/pytudes/ipynb/Cheryl.ipynb new file mode 100644 index 0000000..f4af940 --- /dev/null +++ b/pytudes/ipynb/Cheryl.ipynb @@ -0,0 +1,504 @@ +{ + "metadata": { + "name": "", + "signature": "sha256:b9e2e6c3f7e82432833f1416dd0552c13753f683e1888682faf2910ef7d9f8ff" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When is Cheryl's Birthday?\n", + "===\n", + "\n", + "Peter Norvig, April 2015\n", + "\n", + "This logic puzzle has been [making the rounds](https://www.google.com/webhp?#q=cheryl%27s+birthday):\n", + "\n", + "\n", + "1. Albert and Bernard just became friends with Cheryl, and they want to know when her birthday is. Cheryl gave them a list of 10 possible dates:\n", + "

\n",
+      "       May 15     May 16     May 19\n",
+      "      June 17    June 18\n",
+      "      July 14    July 16\n",
+      "    August 14  August 15  August 17\n",
+      "
\n", + " \n", + "2. Cheryl then tells Albert and Bernard separately the month and the day of the birthday respectively.\n", + " \n", + "3. **Albert**: I don't know when Cheryl's birthday is, but I know that Bernard does not know too.\n", + " \n", + "4. **Bernard**: At first I don't know when Cheryl's birthday is, but I know now.\n", + " \n", + "5. **Albert**: Then I also know when Cheryl's birthday is.\n", + " \n", + "6. So when is Cheryl's birthday?\n", + "\n", + "Problem-Solving Tools\n", + "---\n", + "\n", + "Cheryl's puzzle was designed to be solved with a pencil, the greatest problem-solving tool in the history of mathematics (although some prefer a pen, chalk, marker, or a [stick for drawing in the sand](http://www.hellenicaworld.com/Greece/Science/en/Archimedes.html)). But I will show how to solve it with another tool: **computer code**. I choose this tool for four reasons: \n", + "- It is a more direct way to find the solution. All I have to do is faithfully describe the problem with code that says: *\"for each of the 10 possible dates, tell Albert the month and Bernard the day and check if statements 3 through 5 are true.\"* The intended [pencil and paper solution](https://scontent-iad.xx.fbcdn.net/hphotos-xpa1/v/t1.0-9/s720x720/11111802_983395601695416_3208022346737572922_n.jpg?oh=15fcb7edc4689dd9c71385b613446465&oe=55DD4488) requires not just understanding the *problem*, but also creatively discovering the steps of the *solution*—a harder task.\n", + "- With tested, debugged code, you're less likely to make a mistake that leads you to a [wrong answer](http://www.theguardian.com/science/alexs-adventures-in-numberland/2015/apr/15/why-the-cheryl-birthday-problem-turned-into-the-maths-version-of-thatdress).\n", + "- You'll learn how to solve problems that are similar, but can't be solved with pencil and paper because they have millions of possibilities rather than just 10.\n", + "- Solving puzzles is fun; programming is fun; solving puzzles with programs is double fun.\n", + "\n", + "We will translate each of the 6 statements in the puzzle into Python code:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. Cheryl gave them a list of 10 possible dates:\n", + "---\n" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "DATES = ['May 15', 'May 16', 'May 19',\n", + " 'June 17', 'June 18',\n", + " 'July 14', 'July 16',\n", + " 'August 14', 'August 15', 'August 17']" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll also define accessor functions for the month and day of a date:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def Month(date): return date.split()[0]\n", + "\n", + "def Day(date): return date.split()[1]" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 2 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "Month('May 15')" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 3, + "text": [ + "'May'" + ] + } + ], + "prompt_number": 3 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "Day('May 15')" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 4, + "text": [ + "'15'" + ] + } + ], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Cheryl then tells Albert and Bernard separately the month and the day of the birthday respectively.\n", + "---\n", + "\n", + "We can define the idea of **telling**, and while we're at it, the idea of **knowing** a birthdate:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def tell(part, possible_dates=DATES):\n", + " \"Cheryl tells a part of her birthdate to someone; return a new list of possible dates that match the part.\"\n", + " return [date for date in possible_dates if part in date]\n", + "\n", + "def know(possible_dates):\n", + " \"A person knows the birthdate if they have exactly one possible date.\"\n", + " return len(possible_dates) == 1" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 5 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that we use a *list of dates* to represent someone's knowledge of the possible birthdates, and that someone *knows* the birthdate when they get down to only one possibility. For example: If Cheryl tells Albert that her birthday is in May, he would have a list of three possible birthdates:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "tell('May')" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 6, + "text": [ + "['May 15', 'May 16', 'May 19']" + ] + } + ], + "prompt_number": 6 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And if she tells Bernard that her birthday is on the 15th, he would end up with two possibilities:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "tell('15')" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 7, + "text": [ + "['May 15', 'August 15']" + ] + } + ], + "prompt_number": 7 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With two possibilities, Bernard does not know the birthdate:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "know(tell('15'))" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 8, + "text": [ + "False" + ] + } + ], + "prompt_number": 8 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Overall Strategy\n", + "---\n", + "\n", + "When Cheryl tells Albert `'May'` then *he* knows there are three possibilities, but *we* (the puzzle solvers) don't, because we don't know what Cheryl said. So what can we do? We will consider *all* of the possible dates, one at a time. For example, first consider `'May 15'`. Cheryl tells Albert `'May'` and Bernard `'15'`, giving them the lists of possible birthdates shown above. We can then check whether statements 3 through 5 are true in this scenario. If they are, then `'May 15'` is a solution to the puzzle. Repeat the process for each of the possible dates. If all goes well, there should be exactly one solution. \n", + "\n", + "Here is the main function, `cheryls_birthday`:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def cheryls_birthday(possible_dates=DATES):\n", + " \"Return a list of the possible dates for which statements 3 to 5 are true.\"\n", + " return filter(statements3to5, possible_dates)\n", + "\n", + "def statements3to5(date): return statement3(date) and statement4(date) and statement5(date)\n", + "\n", + "## TO DO: define statement3, statement4, statement5" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 9 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " (*Python note:* `filter(predicate, items)` returns a list of all items for which `predicate(item)` is true.)\n", + " \n", + " 3. Albert: I don't know when Cheryl's birthday is, but I know that Bernard does not know too.\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The function `statement3` takes as input a possible birthdate and returns true if Albert's statement is true for that birthdate. How do we go from Albert's English statement to a Python function? Let's paraphrase in a form that is closer to Python code:\n", + "\n", + "> **Albert**: After Cheryl told me the month of her birthdate, I didn't know her birthday. I don't know which day Cheryl told Bernard, but I know that for all of the possible dates, if Bernard is told that day, he wouldn't know the birthdate.\n", + "\n", + "That I can translate directly into code:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def statement3(date):\n", + " \"Albert: I don't know when Cheryl's birthday is, but I know that Bernard does not know too.\"\n", + " possible_dates = tell(Month(date))\n", + " return (not know(possible_dates) \n", + " and all(not know(tell(Day(d)))\n", + " for d in possible_dates))" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 10 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can try the function on a date:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "statement3('May 15')" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 11, + "text": [ + "False" + ] + } + ], + "prompt_number": 11 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In fact, we can see all the dates that satisfy statement 3:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "filter(statement3, DATES)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 12, + "text": [ + "['July 14', 'July 16', 'August 14', 'August 15', 'August 17']" + ] + } + ], + "prompt_number": 12 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4. Bernard: At first I don't know when Cheryl's birthday is, but I know now.\n", + "---\n", + "\n", + "Again, a paraphrase:\n", + "\n", + "> **Bernard:** At first Cheryl told me the day, and I didn't know. Then I considered just the dates for which Albert's statement 3 is true, and now I know." + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def statement4(date):\n", + " \"Bernard: At first I don't know when Cheryl's birthday is, but I know now.\"\n", + " at_first = tell(Day(date))\n", + " return (not know(at_first)\n", + " and know(filter(statement3, at_first)))" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 13 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see which dates satisfy both statement 3 and statement 4:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "filter(statement4, filter(statement3, DATES))" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 14, + "text": [ + "['July 16', 'August 15', 'August 17']" + ] + } + ], + "prompt_number": 14 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait a minute—I thought that Bernard **knew**?! Why are there three possible dates remaining? Bernard does indeed know the birthdate,\n", + "because he knows something we don't know: the day. We won't know the birthdate until after statement 5.\n", + "\n", + "5. Albert: Then I also know when Cheryl's birthday is.\n", + "---\n", + "\n", + "Albert is saying that after hearing the month and Bernard's statement 4, he now knows Cheryl's birthday:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def statement5(date):\n", + " \"Albert: Then I also know when Cheryl's birthday is.\"\n", + " return know(filter(statement4, tell(Month(date))))" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 15 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "6. So when is Cheryl's birthday?\n", + "---\n", + "\n", + "Let's see:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "cheryls_birthday()" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 16, + "text": [ + "['July 16']" + ] + } + ], + "prompt_number": 16 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Success!** We have deduced that Cheryl's birthday is **July 16**. It is now `True` that we know Cheryl's birthday:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "know(cheryls_birthday())" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 17, + "text": [ + "True" + ] + } + ], + "prompt_number": 17 + } + ], + "metadata": {} + } + ] +} diff --git a/pytudes/ipynb/Coin Flip.ipynb b/pytudes/ipynb/Coin Flip.ipynb new file mode 100644 index 0000000..ff1c312 --- /dev/null +++ b/pytudes/ipynb/Coin Flip.ipynb @@ -0,0 +1,1191 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Devil and the Coin Flip Game\n", + "\n", + ">You're playing a game with the devil, with your soul at stake. You're sitting at a circular table which has 4 coins, arranged in a diamond, at the 12, 3, 6, and 9 o'clock positions. You are blindfolded, and can never see the coins or the table.\n", + "\n", + ">Your goal is to get all 4 coins showing heads, by telling the devil the position(s) of some coins to flip. We call this a \"move\" on your part. The devil must faithfully perform the requested flips, but may first sneakily rotate the table any number of quarter-turns, so that the coins are in different positions. You keep making moves, and the devil keeps rotating and flipping, until all 4 coins show heads.\n", + "\n", + "> Example: You tell the devil tthe 12 o'clock and 6 o'clock positions. The devil could leave the table unrotated (or could rotate it a half-turn), and then flip the two coins that you specified. Or the devil could rotate the table a quarter turn in either direction, and then flip the coins that are now in the 12 o'clock and 6 o'clock positions (which were formerly at 3 o'clock and 9 o'clock). You won't know which of these actions the devil took.\n", + "\n", + "> What is a shortest sequence of moves that is *guaranteed* to win, no matter what the initial state of the coins, and no matter what rotations the devil applies?\n", + "\n", + "# Analysis\n", + "\n", + "The player, being blindfolded, does not know the true state of the coins. So the player should represent what is known: the *set of possible states* of the coins. We call this a *belief state*. At the start of the game, each of the four coins could be either heads or tails, so that's 24 = 16 possibilities in the belief state. \n", + "\n", + "A move updates the belief state as follows: for every coin sequence in the current belief state, rotate it in every possible way, and then flip the coins specified by the position(s) in the move. Collect all these results together to form the new belief state. Solving the game means coming up with a sequence of moves that ends in a belief state consisting of just `{'HHHH'}`. It must be a shortest possible sequence, so a breadth-first search seems right. The search space will be tiny, so compute time will be trivial; the only issue is specifying the domain correctly. To increase the chance of getting it correct, I won't try to do anything fancy, such as noticing that some coin sequences are rotational variants of other sequences.\n", + "\n", + "\n", + "# Implementation Choices\n", + "\n", + "Here are the main concepts, and my implementation choices:\n", + "\n", + "- `Coins`: A *coin sequence* is represented as a `str` of four characters, such as `'HTTT'`. \n", + "- `Belief`: A *belief state* is represented as a `frozenset` of `Coins` (frozen so that it can be hashed in a `set`).\n", + "- `Move`: A *move* is a set of positions to flip. A position will be an integer index into the coin sequence, so a move is a set of these such as `{0, 2}`, which we can interpret as \"flip the 12 o'clock and 6 o'clock positions.\" \n", + "- `all_coins`: Set of all possible coin sequences: `{'HHHH', 'HHHT', ...}`.\n", + "- `rotations`: The function `rotations(coins)` returns the set of all 4 rotations of the coin sequence.\n", + "- `update`: The function `update(belief, move)` returns an updated belief state, representing all the possible coin sequences that could result from any devil rotation followed by the specified flip(s). (But don't flip `'HHHH'`, because the game would have already ended.)\n", + "- `flip`: The function `flip(coins, move)` flips the specified positions within the coin sequence." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from collections import deque, Counter\n", + "from itertools import product, combinations\n", + "import random\n", + "\n", + "Coins = ''.join # A coin sequence, such as 'HHHT'.\n", + "Belief = frozenset # A belief state is a set of possible coin sequences.\n", + "all_coins = Belief(map(Coins, product('HT', repeat=4)))\n", + "\n", + "def rotations(coins) -> [Coins]: \n", + " \"A list of all possible rotations of a coin sequence.\"\n", + " return [coins[r:] + coins[:r] for r in range(4)]\n", + "\n", + "def update(belief, move) -> Belief:\n", + " \"Update belief: consider all possible rotations, then flip.\"\n", + " return Belief((c if c == 'HHHH' else flip(c, move))\n", + " for coins in belief\n", + " for c in rotations(coins))\n", + "\n", + "def flip(coins, move) -> Coins:\n", + " \"Flip the coins in the positions specified by the move.\"\n", + " coins = list(coins) # Need a mutable sequence\n", + " for i in move:\n", + " coins[i] = ('H' if coins[i] == 'T' else 'T')\n", + " return Coins(coins)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try out these functions:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'THTT'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flip('HHHT', {0, 2})" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['HHHT', 'HHTH', 'HTHH', 'THHH']" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rotations('HHHT')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "frozenset({'HHHH',\n", + " 'HHHT',\n", + " 'HHTH',\n", + " 'HHTT',\n", + " 'HTHH',\n", + " 'HTHT',\n", + " 'HTTH',\n", + " 'HTTT',\n", + " 'THHH',\n", + " 'THHT',\n", + " 'THTH',\n", + " 'THTT',\n", + " 'TTHH',\n", + " 'TTHT',\n", + " 'TTTH',\n", + " 'TTTT'})" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_coins" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see there are 16 coin sequences in the `all_coins` belief state. Now if we update this belief state by flipping all 4 positions, we should get a new belief state where we have eliminated the possibility of 4 tails, leaving 15 possible coin sequences:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "frozenset({'HHHH',\n", + " 'HHHT',\n", + " 'HHTH',\n", + " 'HHTT',\n", + " 'HTHH',\n", + " 'HTHT',\n", + " 'HTTH',\n", + " 'HTTT',\n", + " 'THHH',\n", + " 'THHT',\n", + " 'THTH',\n", + " 'THTT',\n", + " 'TTHH',\n", + " 'TTHT',\n", + " 'TTTH'})" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "update(all_coins, {0, 1, 2, 3})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Everything looks good so far. One more thing: we need to find all subsets of the 4 positions; these are the possible moves:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def powerset(sequence): \n", + " \"All subsets of a sequence.\"\n", + " return [set(c) \n", + " for r in range(len(sequence) + 1)\n", + " for c in combinations(sequence, r)]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[set(),\n", + " {0},\n", + " {1},\n", + " {2},\n", + " {3},\n", + " {0, 1},\n", + " {0, 2},\n", + " {0, 3},\n", + " {1, 2},\n", + " {1, 3},\n", + " {2, 3},\n", + " {0, 1, 2},\n", + " {0, 1, 3},\n", + " {0, 2, 3},\n", + " {1, 2, 3},\n", + " {0, 1, 2, 3}]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "powerset(range(4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Search for a Solution\n", + "\n", + "The function `search` does a breadth-first search starting\n", + "from a `belief` state consisting of `all_coins`, and applying a sequences of moves, trying to\n", + "find a sequence that leads to the goal belief state in which the only possibility is 4 heads: `{'HHHH'}`.\n", + "As is typical for search algorithms, we build a search tree, keeping a queue of tree `nodes` to consider, where each \n", + "node consists of a path (a sequence of moves) and a resulting belief state. We also keep track, in `explored`, of\n", + "the states we have already explored, so that we don't have to revisit them." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def search():\n", + " \"Breadth-first search from all_coins to all heads.\"\n", + " explored = set()\n", + " queue = deque([Node([], all_coins)])\n", + " while queue:\n", + " (path, belief) = queue.popleft()\n", + " if belief == {'HHHH'}:\n", + " return path\n", + " for move in powerset(range(4)):\n", + " belief2 = update(belief, move)\n", + " if belief2 not in explored:\n", + " explored.add(belief2)\n", + " queue.append(Node(path + [move], belief2))\n", + " \n", + "def Node(path, belief) -> tuple: return (path, belief)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3}]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "search()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's a 15-move sequence that is guaranteed to lead to a win. You can stop reading here if all you want is the answer to the puzzle. Or you can continue on ...\n", + "\n", + "# Verifying the Solution\n", + "\n", + "Can I verify that the solution is correct? Exploring with paper and pencil, it does appear to work. A colleague did the puzzle and got the same answer. And here's further validation: The function `random_devil` takes an initial coin sequence and a sequence of moves, and plays those moves with a devil that chooses rotations randomly, returning the number of moves it takes until the player wins:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def random_devil(coins, moves) -> int or None:\n", + " \"\"\"A random devil responds to moves starting from coins; \n", + " return the number of moves until win, or None.\"\"\"\n", + " if coins == 'HHHH': return 0\n", + " for (i, move) in enumerate(moves, 1):\n", + " coins = flip(random.choice(list(rotations(coins))), move)\n", + " if coins == 'HHHH': \n", + " return i" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I will let the `random_devil` play 1000 times from each possible starting coin sequence:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({0: 1000,\n", + " 1: 1000,\n", + " 2: 986,\n", + " 3: 1014,\n", + " 4: 1052,\n", + " 5: 1004,\n", + " 6: 976,\n", + " 7: 968,\n", + " 8: 964,\n", + " 9: 1014,\n", + " 10: 985,\n", + " 11: 1003,\n", + " 12: 1056,\n", + " 13: 983,\n", + " 14: 1021,\n", + " 15: 974})" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "moves = search()\n", + "\n", + "Counter(random_devil(coins, moves) \n", + " for coins in all_coins\n", + " for _ in range(1000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This says that the player won all 16,000 times. (If the player had ever lost, there would have been an entry for `None` in the Counter.)\n", + "The remarkable thing, which I can't explain, is that there are very nearly exactly 1,000 results for each of the move counts from 0 to 15. Can you explain that?\n", + "\n", + "# Canonical Coin Sequences and Moves\n", + "\n", + "Consider the four coin sequences `{'HHHT', 'HHTH', 'HTHH', 'THHH'}`. In a sense, these are all the same: they all denote the same sequence of coins with the table rotated to different degrees. Since the devil is free to rotate the table any amount at any time, we could be justified in treating all four of these as equivalent, and collapsing them into one representative member (we could arbitrarily choose the one that comes first in alphabetical order, `'HHHT'`). I will write a definition for `Belief` that returns a `frozenset`, just like before, but makes it a set of canonical coin sequences.\n", + "\n", + "Similarly, the four moves `[{3}, {2}, {1}, {0}]` are equivalent, in that they all say \"flip one of the coins, but since you're going to rotate the table first, it doesn't matter which one I specify.\" I will write a function `canonical_moves` that lists all the canonical rotationally invariant moves corresponding to a belief state." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def Belief(coin_collection): \n", + " \"A set of all the coin sequences in this collection, canonicalized.\"\n", + " return frozenset(min(rotations(c)) for c in coin_collection)\n", + "\n", + "def canonical_moves(coin_collection):\n", + " \"All rotationally invariant moves for a sequence of N coins.\"\n", + " return [set(i for (i, coin) in enumerate(coins) if coin == 'H' and 'H')\n", + " for coins in sorted(coin_collection) if 'H' in coins]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "frozenset({'HHHH', 'HHHT', 'HHTT', 'HTHT', 'HTTT', 'TTTT'})" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Belief(all_coins)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{0, 1, 2, 3}, {0, 1, 2}, {0, 1}, {0, 2}, {0}]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "canonical_moves(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The starting belief set is down from 16 sequences to 6. Call these 4 heads, 3 heads, 2 adjacent heads, 2 opposite heads, 1 head, and no heads, respectively. Similarly, there are only 5 distinct moves, which we can call flip 4, flip 3, flip 2 adjacent, flip 2 opposite, and flip 1.\n", + "\n", + "I have to confess to a form of cheating here: I threw in the `sorted` in `canonical_moves` even though it was not necessary. By including it, I made sure that `{0, 1, 2, 3}` is the first of the possible moves, which makes `search` faster, because half the time `{0, 1, 2, 3}` is the right move to make.\n", + "\n", + "# Visualizing the Solution\n", + "\n", + "How does the solution work? One answer is \"it takes care of all possibilities.\" But it would be nice to gain more insight. I'll print a table showing the belief state after each move, using the newly-defined canonicalized `Belief` form, and lining them up neatly in columns." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def show(moves, belief=all_coins):\n", + " \"For each move, print the move number, move, and belief state.\"\n", + " show_line(0, 'start', belief)\n", + " for (i, move) in enumerate(moves, 1):\n", + " belief = update(belief, move)\n", + " show_line(i, move, belief)\n", + "\n", + "def show_line(i, move, belief, order=sorted(Belief(all_coins))):\n", + " \"Print the move number, move, and belief state.\"\n", + " ordered_belief = [(coins if coins in belief else ' ')\n", + " for coins in order]\n", + " print('{:2} | {:5} | {} | {}'\n", + " .format(i, join(move), join(ordered_belief, ' '), i))\n", + " \n", + "def join(items, sep='') -> str: return sep.join(map(str, items))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0 | start | HHHH HHHT HHTT HTHT HTTT TTTT | 0\n", + " 1 | 0123 | HHHH HHHT HHTT HTHT HTTT | 1\n", + " 2 | 02 | HHHH HHHT HHTT HTTT TTTT | 2\n", + " 3 | 0123 | HHHH HHHT HHTT HTTT | 3\n", + " 4 | 01 | HHHH HHHT HTHT HTTT TTTT | 4\n", + " 5 | 0123 | HHHH HHHT HTHT HTTT | 5\n", + " 6 | 02 | HHHH HHHT HTTT TTTT | 6\n", + " 7 | 0123 | HHHH HHHT HTTT | 7\n", + " 8 | 0 | HHHH HHTT HTHT TTTT | 8\n", + " 9 | 0123 | HHHH HHTT HTHT | 9\n", + "10 | 02 | HHHH HHTT TTTT | 10\n", + "11 | 0123 | HHHH HHTT | 11\n", + "12 | 01 | HHHH HTHT TTTT | 12\n", + "13 | 0123 | HHHH HTHT | 13\n", + "14 | 02 | HHHH TTTT | 14\n", + "15 | 0123 | HHHH | 15\n" + ] + } + ], + "source": [ + "show(search())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that every odd-numbered move flips all four coins to eliminate the possibility of `TTTT`, flipping it to `HHHH`. We can also see that moves 2, 4, and 6 flip two coins and have the effect of eventually eliminating the two \"two heads\" sequences from the belief state, and then move 8 flips a single coin, thus eliminating the \"three heads\" and \"one heads\" sequences, and bringing back the \"two heads\" possibilities. Repeating moves 2, 4, and 6 in moves 10, 12, and 14 then re-eliminates the \"two heads\", and move 15 gets the belief state down to `{'HHHH'}`.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Different Numbers of Coins\n", + "\n", + "What if there are 3 coins on the table arranged in a triangle? Or 6 coins in a hexagon? To answer that, I'll generalize the two functions that have a \"4\" in them, `search`, and `rotations`. I'll also generalize `update`, which had `'HHHH'` in it. And I'll introduce the function `canonical_coins` to return a belief state of all canonical coin sequences of length `N`." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def search(N=4):\n", + " \"Breadth-first search from all_coins to all heads.\"\n", + " start = canonical_coins(N)\n", + " all_moves = canonical_moves(start)\n", + " goal = {'H' * N}\n", + " explored = set()\n", + " queue = deque([Node([], start)])\n", + " while queue:\n", + " (path, belief) = queue.popleft()\n", + " if belief == goal:\n", + " return path\n", + " for move in all_moves:\n", + " belief2 = update(belief, move)\n", + " if belief2 not in explored:\n", + " explored.add(belief2)\n", + " queue.append(Node(path + [move], belief2))\n", + "\n", + "def rotations(coins) -> [Coins]: \n", + " \"A list of all possible rotations of a coin sequence.\"\n", + " return [coins[r:] + coins[:r] for r in range(len(coins))]\n", + " \n", + "def update(belief, move) -> Belief:\n", + " \"Update belief: consider all possible rotations, then flip.\"\n", + " return Belief((flip(c, move) if 'T' in c else c)\n", + " for coins in belief\n", + " for c in rotations(coins))\n", + "\n", + "def canonical_coins(N) -> Belief: return Belief(map(Coins, product('HT', repeat=N)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First verify that we didn't break `search`:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3}]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "search(4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now test the new definitions:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['HHHHHT', 'HHHHTH', 'HHHTHH', 'HHTHHH', 'HTHHHH', 'THHHHH']" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rotations('HHHHHT')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "frozenset({'HHHH', 'HHHT', 'HHTT', 'HTHT', 'HTTT', 'TTTT'})" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "canonical_coins(4)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "frozenset({'HHHHH',\n", + " 'HHHHT',\n", + " 'HHHTT',\n", + " 'HHTHT',\n", + " 'HHTTT',\n", + " 'HTHTT',\n", + " 'HTTTT',\n", + " 'TTTTT'})" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "canonical_coins(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{0, 1, 2, 3, 4}, {0, 1, 2, 3}, {0, 1, 2}, {0, 1, 3}, {0, 1}, {0, 2}, {0}]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "canonical_moves(_)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{1: 2, 2: 3, 3: 4, 4: 6, 5: 8, 6: 14, 7: 20, 8: 36, 9: 60, 10: 108}" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{N: len(canonical_coins(N))\n", + " for N in range(1, 11)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the one hand this is encouraging; there are only 108 canonical coin sequences of length 10, far less than the 1024 non-canonical squences. On the other hand, it is discouraging; since we are searching over the belief states, that would be 2108 ≌ 1032 belief states, which is infeasible. However, we should be able to easily handle up to N=7, because 220 is only a million.\n", + "\n", + "# Solutions for 1 to 7 Coins" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{1: [{0}],\n", + " 2: [{0, 1}, {0}, {0, 1}],\n", + " 3: None,\n", + " 4: [{0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3},\n", + " {0, 1},\n", + " {0, 1, 2, 3},\n", + " {0, 2},\n", + " {0, 1, 2, 3}],\n", + " 5: None,\n", + " 6: None,\n", + " 7: None}" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{N: search(N) for N in range(1, 8)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Too bad; there are no solutions for N = 3, 5, 6, or 7. \n", + "\n", + "There are solutions for N = 1, 2, 4; of lengths 1, 3, 15. That suggests the conjecture: for every *N* that is a power of 2, there will be a solution of length 2*N* - 1. \n", + "\n", + "# Solution for 8 Coins\n", + "\n", + "Even though there are 236 = 68 billion belief states fo N = 8, I hope we can find a solution early in the search process. Let's try:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1min 47s, sys: 731 ms, total: 1min 48s\n", + "Wall time: 1min 50s\n" + ] + }, + { + "data": { + "text/plain": [ + "255" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time solution8 = search(8)\n", + "len(solution8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Eureka! That's evidence in favor of my conjecture, and it took less time than I thought it would. It is still not proof, and I'll need a more efficient/clever approach to test even for N=16. Can you come up with that approach? Can you prove the conjecture for all powers of 2? Here's the solution for N = 8 to help you discover a pattern:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 3},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 2, 4, 5, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 1, 4, 5},\n", + " {0, 1, 2, 3, 4, 5, 6, 7},\n", + " {0, 2, 4, 6},\n", + " {0, 1, 2, 3, 4, 5, 6, 7}]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solution8" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Convex Hull.ipynb b/pytudes/ipynb/Convex Hull.ipynb new file mode 100644 index 0000000..de6c550 --- /dev/null +++ b/pytudes/ipynb/Convex Hull.ipynb @@ -0,0 +1,2039 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The Convex Hull Problem" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Pound a bunch of nails into a board, then stretch a rubber band around them and let the rubber band snap taut, like this:\n", + "\n", + "\n", + "\n", + "The rubber band has traced out the *convex hull* of the set of nails. It turns out this is an important problem with applications in computer graphics, robot motion planning, geographical information systems, ethology, and other areas.\n", + "More formally, we say that:\n", + "\n", + "*Given a finite set, **P**, of points in a plane, the convex hull of **P** is a polygon, **H**, such that:*\n", + "\n", + "- *Every point in **P** lies either on or inside of **H**.*\n", + "- *Every vertex of **H** is a point in **P**.*\n", + "- **H** *is convex: a line segment joining any two vertexes of **H** either is an edge of **H** or lies inside **H**.*\n", + "\n", + "\n", + "In this notebook we develop an algorithm to find the convex hull (and show examples of how to use `matplotlib` plotting). The first thing to do is decide how we will represent the objects of interest:\n", + "\n", + "- **Point**: We'll define a class such that `Point(3, 4)` is a point where `p.x` is 3 and `p.y` is 4.\n", + "- **Set of Points**: We'll use a Python set: `{Point(0,0), Point(3,4), ...}`\n", + "- **Polygon**: We'll represent a polygon as an ordered list of vertex points.\n", + "\n", + "First, get the necessary imports done:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from __future__ import division, print_function\n", + "\n", + "%matplotlib inline \n", + "import matplotlib.pyplot as plt\n", + "import collections\n", + "import random\n", + "import math" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Points and Sets of Points\n", + "\n", + "I'll define the class `Point` as a named tuple of `x` and `y` coordinates, and `Points(n)` as a function that creates a set of *n* random points. \n", + "\n", + "There are two complications to the function `Points(n)`:\n", + "1. A second optional argument is used to set the random seed. This way, the same call to `Points` will return the same result each time. That makes it easier to reproduce tests. If you want different sets of points, just pass in different values for the seed.\n", + "2. Since `matplotlib` plots on a 3×2 rectangle by default, the points will be uniformly sampled from a 3×2 box (with a small border of 0.05 on each edge to prevent the points from bumping up against the edge of the box)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "Point = collections.namedtuple('Point', 'x, y')\n", + "\n", + "def Points(n, seed=42):\n", + " \"Generate n random points within a 3 x 2 box.\"\n", + " random.seed((n, seed))\n", + " b = 0.05 # border\n", + " return {Point(random.uniform(b, 3-b), random.uniform(b, 2-b)) \n", + " for _ in range(n)}" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{Point(x=0.15172583449638682, y=1.6108693392839208),\n", + " Point(x=0.968326330695687, y=1.3139550880088586),\n", + " Point(x=1.3508070075242857, y=0.22290610532132638)}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Points(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Visualizing Points and Line Segments\n", + "\n", + "\n", + "Now let's see how to visualize points; I'll define a function `plot_points`. We will want to be able to see:\n", + "- The **points** themselves. \n", + "- Optionally, **line segments** between points. An optional `style` parameter allows you to specify whether you want lines or not, and what color they should be. This parameter uses the standard [style format](http://matplotlib.org/1.3.1/api/pyplot_api.html#matplotlib.pyplot.plot) defined by matplotlib; for example, `'r.'` means red colored dots with no lines, `'bs-'` means blue colored squares with lines between them, and `'go:'` means green colored circles with dotted lines between them. The lines go from point to point in order; if you want the lines to close\n", + "back from the last point to the first (to form a complete polygon), specify `closed=True`. (For that to work,\n", + "the collection of points must be a list; with `closed=False` the collection can be any collection.)\n", + "- Optionally, **labels** on the points that let us distinguish one from another. You get\n", + "labels (integers from 0 to *n*) if you specify `labels=True`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def plot_points(points, style='r.', labels=False, closed=False): \n", + " \"\"\"Plot a collection of points. Optionally change the line style, label points with numbers, \n", + " and/or form a closed polygon by closing the line from the last point to the first.\"\"\"\n", + " if labels:\n", + " for (i, (x, y)) in enumerate(points):\n", + " plt.text(x, y, ' '+str(i))\n", + " if closed:\n", + " points = points + [points[0]]\n", + " plt.plot([p.x for p in points], [p.y for p in points], style, linewidth=2.5)\n", + " plt.axis('scaled'); plt.axis('off')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here's an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_points(Points(200))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Convexity\n", + "\n", + "\n", + "We want to make a *convex* hull, so we better have some way of determining whether a polygon is *convex*. Let's examine one that is:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\niAWdyUSNAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "octagon = [Point(-10, 0), Point(-7, -7), Point(0, -10), Point(+7, -7), \n", + " Point(+10, 0), Point(+7, +7), Point(0, +10), Point(-7, 7)]\n", + "plot_points(octagon, 'bs-', labels=True, closed=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "If you start at point 0 at the left and proceed in order counterclockwise around the octagon, following edges from point to point, you can see that at every vertex you are making a **left** turn.\n", + "\n", + "Now let's consider a non-convex polygon:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPMAAAEDCAYAAADgEzKSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEfFJREFUeJzt3X2QXfVdx/H3d5cEEkJCIGvCUwdBUxnagdbWdhSHQzow\naFumtQ9CayEWgWKT6AjWon+4U/uQSh1mksbayMNWaQE7pdiiVZThjNNBbEUbMZQujE0MlMCWmoSF\nPOfrH/dscnOze5/2nHvO+f0+rxkm2b33Zn9t8t7zvfe7O2vujojU31DZBxCRfChmkUAoZpFAKGaR\nQChmkUAoZpFAKGYplJl9ysx+YGabzWxV2ecJ2XFlH0DCZWYrgTPc/bXZ20vKPVHYTF80IkUxs38D\nrnL3/yn7LDHQmC1FOhe40sy+a2Z/Z2Y/U/aBQqaYpUjHA6+6+5uB24E7Sz5P0DRmS2HM7EngV9x9\na/b2Dnc/ueRjBUtXZinSA8AKADNLgB+UeprA6coshTGzRcCXgdcALwMfcfcnyj1VuLSako7S1BYB\nvwmsAs4dG4OVK4+9X/b+/wDWAfe5+07gHQM7aOQUs8woTe3ngNXANcCJU+935yAwPMPD3giMAZ9L\nU/si8IUk8ecKPqqgmKVFmtoQ8Ks0Ir6s5eangfXbtvF+4KLWx+7axRbgBGAZsAT4I+AP0tTup3G1\nfjRJ9LyuKHrOLMCxo3TLzd8C1gP/mCR+6PzzbePICMtb/4yJCcY3bGAV8B5gDfDWlrscHsGTxPfk\n/b8hdoo5cjON0sAkcBfw+STx8T7/7F/I/uxfB+Y03fRjQCN4zhRzhLoZpYEvJYnvyunjLQOuB26k\nMYJPOQBoBM+JYo5IL6N0QR9/LhrBC6OYI5Cmdh6NgHMfpWdxJo3gOVPMgRr0KN2vNiP4QeBraATv\nmmIOTNmjdL80gs+eYg5EFUfpfqWpvZnGRHElGsG7pphrrC6jdL80gvdGMddQXUfpfmkE745irpE2\no/TLNL4eujajdL80gs9MMVdc6KN0vzSCH0sxV1Rso3S/uhjB1wP3xjCCK+aK0Sjdv9hHcMVcARql\n8xXrCK6YS6RRulixjeCKuQQapQcvhhFcMQ+IRulqCHkEV8wF0yhdTSGO4Iq5IBql6yOUEVwx56hp\nlF4DXNpys0bpiqv7CK6Yc5CmdjKNUfqjTD9KrwMe0ihdDx1G8P+k8fdZuRFcMc9Ch1H6LmCDRul6\nq9MIrpi7YGb/AiwADPippUvZeu+9TKJROhpNI/hHgNOabsp9BDezu4CLgZ2AAyvd/b86Pk4xd2dq\nlL7lFv5kxQpOvPTojDVKR2IQI3gW8zfc/es9PU4xt9c8Sr/yCidedRXcdx/Mm6dROnZFjeBZzA+6\n+9d6epxiPtZMr0o/9BCkKZOf/jR/iEZpyeQ9gmcx/yKwG3gY+Li77+/4uJhjbv0xK8PDHHfSSSxb\nvJiRa65hYcvdv/Xe97Jkxw7WHjjg9w/4qFIDnUbwtWvZtXcvQ+4c9VRsYoLxzZv9+qm3zWypu79g\nZnOAvwSecfdPdvr4Uf/guJERlo+OcnHr+8fGDv/28Ch9ySW8BDwFPDio80m9JInvA+4B7plmBH/D\nsmXT/yjc0dGj33b3F7Jf92dX6Zu6+fhDfZ88YAcOsJvGZ9czk8R/J3tO/D4az2P2lXs6qYMk8e8m\niV9N4wfN/zHwfLePNbNl2a8GvAv4724eF/WVeSbPPst3ksTXt7z7/cDaMs4j9ZUkvh34RJra2slJ\nngHO6uJhXzazJTRWod+j8Vy8o6hjPv74o77Qoy13X1HkWSR4F86fz+nd3NHd39bPB4h6zF64kDPK\nPoOEL/u5Wg8NDTFc5MeJ9sqcprZ40SJGxsZgzx5e2r79yPOSiQm0N5ZcTIUMLJo7F267jfGdO49+\n/pzXv7doV1NpajcDt2ZvXpYk/k9lnkfC0xxy9q4bksQ3FvXxohyz09SGaXyHE8D3gX8u8TgSoEGH\nDJHGDLwDODv7/eer+v2pUk9lhAzxxrwm+3UX8FdlHkTCUlbIEGHMaWqvA6bWTHckiU+WeR4JR5kh\nQ4Qx0/gOKGh8n+iGMg8i4Sg7ZIjs1ew0tcXAc8A84MEk8XeWfCQJQBVChviuzNfSCBka35YmMitV\nCRkiilnrKMlblUKGiGJG6yjJUdVChrhi1jpKclHFkCGSmLWOkrxUNWSIJGa0jpIcVDlkiGA1pXWU\n5KHqIUMcV2ato2RW6hAyBB6z1lEyW3UJGQKPmaPXUeu1jpJe1ClkCD/mqXXUTuCvyzyI1EvdQoaA\nY25ZR92pdZR0q44hQ8Axo3WU9KGuIUOgqymto6QfdQ4Zwr0yax0lPal7yBBgzFpHSa9CCBkCjBmt\no6QHoYQMYcasdZR0JaSQIbCYtY6SboUWMgQWM1pHSRdCDBkCWk1pHSXdCDVkCOvKrHWUtBVyyBBI\nzFpHSSehhwyBxIzWUdJGDCFDODFrHSXTiiVkCCBmraNkJjGFDAHEjNZRMo3YQoaar6a0jpLpxBgy\n1P/KrHWUHCXWkKHGMWsdJa1iDhlqHDNaR0mT2EOGesesdZQACnlKLWPWOkqmKOQjahkzWkcJCrlV\n7VZTLeuobyaJX1HykaQECvlYdbwyN6+j1pd5ECmHQp5erWLWOkoU8sxqFTNaR0VNIbdXt5i1joqU\nQu6sNjFrHRUvhdyd2sSM1lFRUsjdq8VqSuuoOCnk3tTlyqx1VGQUcu8qH7PWUfFRyP2pfMxoHRUV\nhdy/OsSsdVQkFPLsVDpmraPioZBnr9Ixo3VUFBRyPiq7mtI6Kg4KOT9VvjJrHRU4hZyvSsasdVT4\nFHL+KhkzWkcFTSEXo6oxax0VKIVcnMrFrHVUuBRysSoXM1pHBUkhF69Sqymto8KkkAejaldmraMC\no5AHpzIxax0VHoU8WJWJGa2jgqKQB69KMWsdFQiFXI5KxDzTOsrMzjazx8xs3MzuMbPjyjuldGO6\nkC+5hNeZ2cslHisKlYiZmddRnwX+zN2XAztovEAmFTVDyI8DJ9P4u5UClb6aareOMrMJYKm7HzKz\ntwKj7n55SUeVNmYI+XYaL2ReBTzt7gvLOl8MqnBlnnYdZWanAv/n7oeydz0LnD7gs0kX2jxHXgU8\n4O4vAFbW+WJR+nPQz3yGz5qBO4e2bWPdk09yXtlnkvbOP982joywHGDePE4aGeGCoSGG586FD3yg\nEbKZnQa8D7i43NPGo/SYb7nl8HQwNDrKaVPvd/eXzOxkMxvKrs5n0hjHpWQjIywfHT020ttuY7zp\nVes3AOcCz5iZAfPNbDx7/UMKUIUxu51HaHx2B7gG+NsSzyId7NzJ81O/d/e/d/fT3f0cd/9p4FWF\nXKyqx/xx4PfMbBw4Bbij5PNI//RqdsFKH7PbcfcfAm8p+xzSnTlzOGGm2/RKdvGqfmWWGlm2jAvS\n1M4u+RjRKn3PfOmltnd4mLkAzz3HM0884T9b6oGko+ZXswGWLOGcBQs4K3s1ewtwSZL4ltIOGKnS\nY05TeyPwePbm2iTxW8o8j/QuTc2APwVuzt61BQU9cKXHDJCm9m3gl4CXgLOSxHeXfCTpkYIuX1We\nM6/Lfj2Vxpf+Sc1k37L6MeBz2bvOBh7Rc+jBqUrMX+fIF4SsyT7LS80o6HJVIuYk8f3AF7I3LwAu\nKvE4MgsKujyViDmzEdib/X5NuztKtSnoclQm5iTxCeCe7M13p6m9pszzyOwo6MGrTMyZqW+BHAZu\nLPMgMnsKerAqsZpqpjVVeLS2GoyqXZlBa6rg6Ao9GFWMWWuqACno4lUuZq2pwqWgi1W5mDNaUwVK\nQRenkjFrTRU2BV2MSsac0ZoqYAo6f5VbTTXTmip8Wlvlp8pXZtCaKni6Quen6jFrTRUBBZ2PSsc8\nzZrql0s8jhRIQc9epWPONK+pVpd5ECmWgp6dysesNVVcFHT/Kh9zRmuqiCjo/lR6NdVMa6r4aG3V\nm7pcmUFrqujoCt2bOsWsNVWEFHT3ahOz1lTxUtDdqU3MGa2pIqWgO6tVzFpTxU1Bt1ermDNaU0VM\nQc+sNqupZlpTidZWx6rjlRm0poqertDHqmvMWlOJgm5Ry5i1ppIpCvqIWsac0ZpKAAU9pbYxa00l\nzRR0jWPOaE0lh8UedC1XU82a1lQ/Ac7UmkpiXVvV/coMR9ZUp6A1lRDvFTqEmLWmkmPEGHTtY9aa\nSmYSW9C1jzmjNZVMK6agg4hZayppJ5agg4g5ozWVzCiGoGu/mmqmNZV0EvLaKqQrM2hNJR2EfIUO\nLWatqaSjUIMOKmatqaRbIQYdVMwZramkK6EFHVzMWlNJL0IKOriYM1pTSddCCTqo1VQzramkV3Vf\nW4V6ZQatqaRHdb9Chxyz1lTSszoHHWzMWlNJv+oadLAxZ5rXVGvKPIjUSx2DDjrmljXVu7Smkl7U\nLeigY85oTSV9q1PQwa6mmmlNJbNVh7VVDFdm0JpKZqkOV+hYYtaaSmat6kFHEbPWVJKXKgcdRcwZ\nrakkF1UNOpqYtaaSPFUx6GhizmhNJbmpWtBRrKaaaU0leavK2iq2KzNoTSU5q8oVOsaYtaaS3FUh\n6Ohi7mdNZWYfNbOnzeygmZ1S6AGltvIK2sxuN7PvZf/9jZnN7+Zx0cWc6XVN9W3gbcDWwk4kQcgp\n6N919wvd/UJgG7CqmwdFGXOvayp33+Tu/wtoJJeOZhu0u08CmJkB84CuXqWOMuaM1lRSmNkGbWZ3\nAs8Dr+XIv9X2j4ltNdXsQx+y7cPDLD10iAPbtvGv7hwCmJhgfPNmv771/mb2Q+Dn3f0nAz+s1FLz\n2uorX4Hdu9mzfTub9u9nz9R92vx7Mxoh/7u7j3X6WMfleO7a2bGDl266iaU0/n84/ELY6OiMD4n3\nM5/0JUnc09Q+BrBvHzdfey0nAG9pvs9M/97c3c3sPuD3gbFOHyvmMZvJSX7c40MMPW+WHk2N3JOT\nh1eibZnZudmvBlwBPNXN46KO2X36K+3ixZyVpkdWUGa22sy2AWcAm8xs46DOKPWXpnYW8Kn581na\n6b5ZwF8ys03AJmAZ8IluPk7UY/ZMFi3iHODZNLW7gfXuvp4uX4QQgcPPlS+isfp8NzA81MWl0xsv\nYl3Uz8dUzDObB1wHXJemltL4MtBvJIkfLPVUUmlpavNofJnwauDC5tv27WMXsLCojx11zBMTjE/3\n4oMZk8BB4J00niMn2X9b09T+HLg9SfSKthyRjdI3AtcDpzbdtI/G1zSs37SJG0ZHWd762IkJxvM4\nQ9SrqU7S1M4Bfhv4LWBR0027gbuB9UniT5RxNinfdKN0080/ovFlwxuTxF8cxHkUcxfS1BYAv0Hj\nL+281pvRCB6VdqM08CiNfw/3Z98HMDCKuQfZZ+IVNKKeGsGnbAU0ggesm1E6SfzxMs4GirlvGsHj\nULVRuh3FPEsawcNU1VG6HcWcky5G8A3AHRrBq63qo3Q7irkAGsHrpWmUXg38GhUepdtRzAXSCF5t\n2Sh9JY2/n1qM0u0o5gHQCF4tdR6l21HMA6YRvByhjNLtKOaSaAQfjNBG6XYUc8k0ghcj1FG6HcVc\nIRrBZyeGUbodxVxBHUbwR2h8b7VG8ExMo3Q7irnCNIK3F+Mo3Y5irgmN4A2xj9LtKOaaiXUE1yjd\nmWKuqVhGcI3S3VPMAQhtBNco3R/FHJC6j+BpaifQ+LZDjdJ9UMwBqtsI3jRKXwcsabpJo3QPFHPg\nqjqCa5TOn2KORBcj+Drgm3mO4GZ2N/AmGlfY7wA3PPIIc9AoXQjFHJlBjuBmdrm7/wPAggX2wOWX\nc/yqVbwJjdKFUMwRK3oEbx6lv/pV3vPyywx9+MOHb9YonTPFLLmP4K2vSh88CDfeCKtXw+tfr1G6\nKIpZDpvtCD7Tq9K33sqhV17hqdFRrtYoXRzFLNNqN4Jv2MDWXbuY3LuXVwDmzWPRwoWcsXAhSz74\nwaM+AfxodJTvP/YYe/fs8bcP8PhRUszS1nQj+NgYrFx57H2b3v8osO6yyzh5/36uBla4+95BnDdm\nUf8USOksSXwS+Is0tS9yZAS/Yrr7vvoqLwBvnxql9++3/cAW4DEzc+B+d//kQA4eIcUsXUkSd+Bh\n4OHRUUuBi1vv8+KLPNX8nNjd5wzuhKIxWyQQQ2UfQETyoZhFAqGYRQKhmEUCoZhFAqGYRQKhmEUC\noZhFAqGYRQKhmEUCoZhFAqGYRQKhmEUCoZhFAqGYRQKhmEUCoZhFAqGYRQKhmEUC8f8ApjhkA+SI\nJwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pacman = octagon[:4] + [Point(0, 0)] + octagon[5:]\n", + "plot_points(pacman, 'ys-', labels=True, closed=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The `pacman` polygon is non-convex; you can see that a line from point 3 to point 5 passes *outside* the polygon. You can also see that as you move counterclockwise from 3 to 4 to 5 you turn **right** at 4. That leads to the idea: **a polygon is convex if there are no right turns** as we go around the polygon counterclockwise. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Turn Directions\n", + "\n", + "\n", + "Now how do we determine if a turn from point A to B to C is a left turn at B or a right turn (or straight)? Consider this diagram:\n", + "\n", + "\n", + "\n", + "It is a left turn at B if angle β is bigger than angle α; in other words, if β's opposite-over-adjacent ratio is bigger than α's: \n", + "\n", + " (C.y - B.y) / (C.x - B.x) > (B.y - A.y) / (B.x - A.x)\n", + " \n", + "But if we did that computation, we'd need special cases for when each denominator is zero. So multiply each side by the denominators:\n", + "\n", + " (B.x - A.x) * (C.y - B.y) > (B.y - A.y) * (C.x - B.x) \n", + " \n", + "(*Note:* This step should make you very nervous! In general, multiplying both sides of an inequality by a negative number reverses the inequality, and here the denominators might be negative. In this case it works out; basically because we are doing two multiplications so that negatives cancel out, but [the math proof](https://en.wikipedia.org/wiki/Cross_product) is tricky, involving some concepts in vector algebra, so I won't duplicate it here; instead I will provide good test coverage below.)\n", + " \n", + "That leads to the function definition: " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def turn(A, B, C):\n", + " \"Is the turn from A->B->C a 'right', 'left', or 'straight' turn?\"\n", + " diff = (B.x - A.x) * (C.y - B.y) - (B.y - A.y) * (C.x - B.x) \n", + " return ('right' if diff < 0 else\n", + " 'left' if diff > 0 else\n", + " 'straight')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Sketch of Convex Hull Algorithm\n", + "\n", + "\n", + "Now we have the first part of a strategy to find the convex hull:\n", + "\n", + "> *Travel a path along the points in some order. (It is not yet clear exactly what order.) Any point along the way that does not mark a left-hand turn is not part of the hull.*\n", + "\n", + "What's a good order? Let's see what happens if we start at the leftmost point and work our way to the rightmost. We can achieve that ordering by calling the built-in function `sorted` on the points (since points are tuples, `sorted` sorts them lexicographically: first by their first component, `x`, and if there are ties, next by their `y` component). We start with 11 random points, and I will define a function to help plot the partial hull as we go:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def plot_partial_hull(points, hull_indexes=()):\n", + " \"Plot the points, labeled, with a blue line for the points named by indexes.\"\n", + " plot_points(points, labels=True)\n", + " plot_points([points[i] for i in hull_indexes], 'bs-')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "Here are the points without any hull:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\nZuQlqbH/AxfLr4h5SHPkAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now I will start building up the hull by following the points in order from point 0 to 1 to 2 to 3:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAADsCAYAAACR39Z5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGtxJREFUeJzt3Xm4nVV99vHvLQlgShAIFGSSQUGGIqCo0QI1oGJVUEhC\nGISoCGrxLYoD1oli1WJfaXGoCChBJoEI4oi+2KJxiL4ySsAGFCUioMgUQAiEX/9Ya2efk5xhn7OH\n9exn35/r4jrPes4+e/8g4c7KetagiMDMzOrpaaULMDOz7nHIm5nVmEPezKzGHPJmZjXmkDczqzGH\nvJlZjTnkxyBpG0mLJS2VdJGkKaVrMjObCIf82E4FPhUROwAPAG8uXI+Z2YTIi6FGJ+lPwKYR8ZSk\nFwMnR8QBpesyM2uVe/KjkDQDuD8insq3fg9sXrAkM7MJc8ibmdWYQ34UEfFnYANJjf9GWwJ3FizJ\nzGzCHPJj+29gTr4+GriiYC1mZhM2kCEvHbZIItb8Z+7Vq730JOBdkpYCGwFf7HmxZmZtGNB53ytX\ntvKqiLgdeFGXizEz65qB7MmbmQ0Kh/wwU9cuXYGZWScN6HDNsqUwN1/P2Aw23TFdb7udxNQInihW\nmplZB3nFKyBxFnBMbp4ewQkl6zEz6xSHPCCxLvBjYM98a14EFxcsycysIzwmD0TwGDAbuD/f+qLE\nzgVLMmuLpE9LWl66DivPIZ9FcDtwJBDAXwFflZhetiqziZP0fGAD0u9lG3AO+SEi+Dbw0dx8LqlH\nr4IlmU1I3obj34D3lK7FqsEhv6ZTgO/m6zngh7DWV44HvhYR94A7KOYHryOSmAFcC2wNrAReFsGi\nslWZjU3SM4FLgH3zGQjLI8JDjgPOPfkRRPBn0oPYFcBawMUSm5WtymxcewDbA7dJuh2YlvddsgHm\nnvwYJI4DzsjNHwL7RfBkwZKsyySdD7yA9Af8z4HjIqKlvY56QpoO7ArcRMSYs2fckzdwT348ZwLn\n5ut9gE8UrMV64/yIeG5E7AZMo7lIrrwU8IuAHwCLcnss7sGZQ34sEQTwduDGfOvdEgcXLMm6LCKu\nHNL8OemwmKrYFdgZmArsBOwy1osjYv1eFGXV5pAfRwSPAocAD+ZbCyR2LFiS9YCkKcAbgCvHe20P\n3QTcTBpKugVYUrYc6wcek2+RxIE0T4ZaArwogkcKlmRdJOlM4OGIeFfpWoZJQzS7AEvGG5M3A4f8\nhEh8HHh/bl4EHJGHdKzipJlnwlY7rPmdZUsjfnrs8Nfqw8DuEeGhOet7A7rV8KR9CHghsB9wGPAT\n4LNFK7IWbbUDXLLvmvfnDmtJOgZ4JTCrJ2WZdZnH5CcggpXA4cCd+dZpEjMLlmSd93ngr4HFkq6V\n9MHSBZm1wz35CYrgjxKzSfPmpwKXSuwZwR8Ll2YdEBFTS9dg1knuyU9CBIuBxgO5LYCLJNYqWJKZ\n2Ygc8pP3OeDCfD2L5u6VZmaV4eGaSYogJI4Fnkea0vZ+icURfL1waTaiZUvhHc+CGds07z10V7pv\nVl+eQtkmiR2AXwDTSQumXhDBbWWrspFIfJLh+6w/BGwWwV8KlWTWdR6uaVMES4H5ufkM0olS08pV\nZGP4q9Xa6wOvK1GIWa845DsggsuA/5ubuwGf94lSldQI+buB+/L1/DKlmPWGQ75z3k+aVglwFHDs\nGK+1Mhohfz9pxTLA/hJbFKrHakTSfpKukXSdpB9K2q50TeCQ75i8z/yhwF351qcl9ipYkq2pEfKP\nAAvy9dNIG5GZtes/gcMiYg9SJ6ISC+kc8h0Uwd2kdfIrgbWBhRIbl63Khhga8teQdnQEONrDa9YB\nT5Gey5G//qFgLas45Dssgh/RnMGxNXCBF0pVxnr56yN5Y7kFuf1c0p5EZu14C/AdSXcARwL/Wrge\nwCHfLf8BXJqvXwF8uGAt1jS0Jw9wPqn3BXB078uxmnkncEBEbA2cA/x74XoAh3xX5F7im4Ff5Vsf\nlvj7giVZMizkI7gL+F6+N09i3SJVWX+QpiPNHOnYRUkbA8+LiF/kW5dANTYvdMh3SQTLgYMZ0muU\n2LZgSbZmTx6aQzYbAq/taTXWP8Y/X/d+YH1Jz87tV5BO7yrOId9FEdxC6tFDCpGF7i0WNVLIX0Hz\naEcP2dhoxjxfNyJWksbkL5N0HXAEw1dXF+OQ77IILgZOz809gc8ULGdgSUwhzXgCeLhxP4LHgK/k\n5gESm/W6NusL456vGxFXRMRuEbFHRMyKiN/2uMYROeR74z3Aj/P1MRJvKlnMgBq6pcHqZ/Oem7+u\nReqBmQ2XztPdG9gX2Lufztd1yPdABE+QFko1Dhb5T4k9CpY0iMYK+cVAYzfK+Z4zbyOKWE7E4n4K\neHDI90wEd5KC/ilgHdJGZhuWrWqgjBryeTZUoze/K/gPYKsPh3wPRXA1aY8bgG2B8yT/GvTIekOu\nV+/JA5wHNPbdnt/1amzgSfoHSbdKWilpo9W+9+n8vesl7d7O5zhgeu/fgMvz9auBfypYyyAZa7iG\nCJYB38/Nw6VVD2nNuuVHwH7A74belPQqYPuIeA5wHHBGOx/ikO+xPDTwRuDWfOsUiVcULGlQjBny\nWWPIZgZ48Zp1V0TcEBF3wBrPgA4Cvpxf8zPgGZI2neznOOQLiOBB4BDgL6Rf4Aslti5bVe21EvKX\nA42HavO7Wo3Z6LYAlg1p35nvTYpDvpAIfklaPAGp57hQYp2CJdXduCEfwSM09xx6tcQmXa/KrMsc\n8gVFcAFpD2qAvajIhkY11UpPHprbHEwBDu9aNVZ/Y+x1s5rVD9q+E9hqSHvLfG9SHPLlvQv4Wb5+\nm+QDLLpkaMg/POqr0sOw3+Rrb3NgkzP+XjfDXs3wcfmvk06XQ9KLgQci4p7JluKQLyyCx4E5wL35\n1hckditYUl211JNfbc78Hv61sEkac68bAEnvkLSMNN5+g6QzASLi28Dtkm4DvgC8vZ1CFLH63xSs\nBIn9SdveCrgN2CuCB8pWVR8SpwLvBR6PGHuTOIltgNtz87QITuxyeVY3zZ78TqS9boptheCefEVE\ncBXwodx8NrDAy+s7aqQdKEcUwW9Jf80GOEJiareKspqq0F43Dvlq+QTwjXx9EKnnaZ2x6ui/Fl+/\nIH/dFHhlx6ux+qvIXjcO+QqJ4CnSw77Gg7+PS8wqWFKdtNyTz74KPJqv/QDW+pZDvmIiuJ+0UOox\n0q/PV6TJL4SwVSYU8vlkr4W5eaDERmO93qyqHPIVFMH1wNtycxPgUu+l0raJ9uShOctmbWBeZ8sx\n6w2HfEVFsAA4KzdnkjY2s8mbTMhfDdyRr+d3shizXnHIV9v/Aa5pXEscVrKYPtcI+bEWQg2Tn5F8\nOTf3kti541WZdZlDvsLy+aOzgfvyrbOlNRdVWEsm05OH5pAN+AGs9SGHfMXlOdtHkPa3mEY6UWr9\nokX1p0mFfAS30Tyf90iJtTpalVmXOeT7QARXAqfk5o7AF71QasIm25OHZm9+c2D/zpRj1hsO+f5x\nCnBlvp4NvLNgLX1FYgqs2sZ5MiF/CWlKK/gBrPUZh3yfyA8Bj6R5VNgnJfYpWFI/aXWb4RHlQ14a\nRza+TmKDjlRl1gMO+T4SwZ9JvfgVwFrAxRLPLFtVX2gr5LMF+eu6wNy2qjHrIYd8n4ngF8DxubkZ\nKei9gdbYOhHy36d5cINn2VjfcMj3p7Np9iz3Jm1sZqNrO+QjWAmcl5svkdih7arMesAh34fywRZv\nB27It06UmF2wpKrrRE8ehs+ZP6qN9zHrGYd8n4rgL6SNzB7Mt86R2LFgSVXW6tF/Y4rgVzSPajxK\n8v8/Vn3+TdrHIvg1acYNpP3SL5NW7ZtuTZ3qyUOzN78V8LI238us6xzyfS6CbwIfy82dgbO8UGoN\nnQz5i0mzm8APYK0POOTr4SPAVfl6Hs3ZN5Z0LOQjuA+4IjcPkZjezvuZdZtDvgbyzI/Dgd/nW6dJ\nvKRgSVUzdAir3Z48NIdspoEfeFu1OeRrIoI/kQLnCWAK6aCRvy5bVWV0crgG4LvAPfl6fgfez6xr\nHPI1EsHPgBNyc3PS0YFTCpZUFY2QXxHBk+2+WX6P83NzH4nt2n1Ps25xyNfP54EL8vXLgI8WrKUq\n2tmBcjSeM299wSFfM3mh1HHATfnWSRIHFSypCjoe8hH8Erg2Nz1n3irLvzFrKIJHSAulHsq3vizx\n7IIlldaNnjw0t5bYFvjbDr+3WUc45GsqgqU0HwquTzpRalq5ioqa8PmuLbqI9KAb/ADWKsohX2MR\nXA58Mjd3A84Y0IVSXenJR3Av8K3cnCMNm8VjVgkO+fr7AHB1vn4Dabx+0HRruAaaQzbrAQd34f3N\n2uKQr7k83W8ecFe+dbrECwuWVEJjMVQ3Qv47wL352tscWOU45AdABPcAc4AngbWBhRIbl62qp7rW\nk49gBc0pq7Mktu70Z5i1wyE/ICL4MfDu3NwKuFBirYIl9VI3h2ugOWdepCExs8pwyA+WT5N2UQR4\nOWljs0HQ7ZC/HrgxXx89oA+3raIc8gMkL5Q6Brgl3/qQxKsLltR1+W8r6+RmV0I+/3dt9OafA8zs\nxueYTYZDfsBE8DBpFkhjzvj5EtsWLKnbOr052WguAFbmaz+AtcpwyA+gfIzdm3JzA9JCqacXLKmb\nehLy+eH2d3JzXo3/e1qfccgPqAguBf49N/cAPluwnG7qyPmuLWoM2awPA79fkFWEQ36wvQ/4Ub5+\nk8SbSxbTJb0argH4BnB/vp7f5c8ya4lDfoBF8ARwKM0DMD4n8fyCJXVDp0+FGlUEj5P2swF4ucQW\n3fw8s1Y45AdcBH8gBf1K0iyUhRIbla2qo3rZk4fmNgdPA47sweeZjckhb0TwA+Ck3NwGOK9G+6P3\nOuR/QXOKqufMW3F1+R/Z2vcp4LJ8/fekjc3qoKchn+fML8jNnYC9uv2ZZmNxyBuwKpzeCCzNt/5Z\n4pUFS+qUXvfkIZ3/+lS+9px5K8ohb6tE8BDpRKlHSfuwXCjxrLJVta3nIZ+fc3wvNw+TVq24Nes5\nh7wNE8FNwFtycyPg0j4PqRI9eWjOmd8QeG0PP9dsGIe8rSGCC2kujtoLOL1gOe1qhPyKPGW0V64A\nHszXHrKxYhzyNpoTgcX5+jipb4Oq2ztQjiiCv9Dc8fNVEpv28vPNGhzyNqJ8GMYcmqcenSHxvIIl\nTVaRkM8aQzZrAUcU+Hwzh7yNLoLfk44OfApYl7SR2QZlq5qwbh79N56fArfm6/meM28lOORtTBF8\nH/hgbm4PnNtnC6WK9eRX22f+b4Dde12DWT/9z2rlnErafAvgQOC9BWuZqJLDNQDnAZGv+/W5Ri1I\n+qGkayVdJ+lOSZeN/1P9zyFv44rgKeAo4Nf51sck9itY0kQUDfkI7gD+KzePkFi7RB0GEbFPROwZ\nEXuQhtIc8mYNETxAWij1GOn3zUUSW5atqiWle/LQHLLZGHhVwToMkLQ+MAv4WulaesEhby2L4Abg\nrbm5CWmhVNV7plUI+ctoHlgyv2AdlhwEXBUR3T5EphIc8jYhEZwLfCE3X0za2KzKiod8BI8Al+bm\nayQ2KVWLAXAYzX3/a88hb5NxAmlLXYDjJQ4vWcw4GiFfute2IH+dQgoZK0DSDNIq7m+VrqVXHPI2\nYRE8BswG7su3zpLYtWBJI5JYizS/H8oO10A6ZvH2fO1ZNt0gTUeaiTR9jFfNAb4ZESt6VVZpDnmb\nlAh+BxxOmh44jbRQav2yVa2h1OZka8gzlBoPYPeU+JuS9dROCvZFwA+ARWME/VwGaKgGHPLWhgi+\nC5ycmzsA51RsVWdlQj778pBr9+Y7a1dgZ2Aq6bCWXUZ6UUTMiojvjfS9unLIW7v+BfhOvj4YeFfB\nWlZXqZCP4HZSTxPgSIkpJeupmZuAm4EVpOMXl5Qtpzoc8taWPAxxJPDbfOtUiX3KVTRMpUI+awzZ\nbAq1OHmrGiKWA3sD+wJ757bhkLcOiOA+0oPYx0k7Ll4isXnZqoBqhvxC0slb4CGbzopYTsRiB/xw\nDnnriAiuAY7PzU2BiyWmFiwJKhjyESwHvpqbB0lsVLIeqz+HvHVMBGcDX8rNvyVtbFZS5UI+awzZ\nrA0cWrIQqz+HvHXa8cB1+fqdEnMK1lLVkP9vYFm+nl+wDhsADnnrqHzs3WzggXzrSxI7FSpnaMiX\nXvG6Sn5Y3ZhO+UKJ55asx+rNIW8dF8FvgDfk5nqkhVLrjfEj3VLVnjw0h2zAD2Ctixzy1hURfJM0\nhx7S4pSzCyyUGvoHS6VCPoJbgZ/k5lF5CwazjnPIWzedDPy/fH0o8I4ef36jJ/9EBE/0+LNbsSB/\n3Rz65hAW6zMOeeuaCFaS9rdpPGT8lMRLe1hC8W2Gx3EJ6RAW8APYjpP0MUn/I2mJpOPH/4l6cshb\nV0VwL+lB7BOkbXYvkdi0Rx9f6ZCP4EGapxO9XuIZJeupE0nzgS0iYseI2AX4SuGSinHIW9dF8HPg\nH3Nzc+ArPdq3pdIhny3IX9cl7ZBonfE24JRGIyLuLVhLUQ5565UzgPPy9d8BH+vBZ/ZDyF8F/CFf\ne5ZN52wPzJP0/yV9S9KzSxdUikPeeiKCIJ0P+8t8670Sr+/yx1Y+5PNzi8Yffi+VeE7JempkHeDR\niNgLhq3EHjgOeeuZCB4FDgEeyrcWdDnUKh/y2dA580cVq6JelgGXA0TE5cBuZcspxyFvPZXnhzeC\nbH3gMmnYoqVOqsr5rmOK4Bbg57l5lOT/L8c1/lF/XwNmpZfq74D/6VVpVePfTNZzEVxBc/OyXYEz\nurRQqrEYquo9eWj25rcmPbOw0bR21N+pwCGSbiQ9/zmmhxVWikPeSvkgaaMuSIeOvLULn9EvwzWQ\npvg1Dpf2A9ixjXvUX0Q8GBGviYjdIuKlEfHL1V8zKBzyVkQETwKH0ZxZcrrEizr8MX0T8vngla/n\n5myJ0YYhzEf9TYhD3oqJ4B5gDvAkqVe2UGKTTrx33gtm3dysfMhnjSGbaaQH1DYSH/U3IQ55KyqC\nnwAn5uaWwIUd2qxr2pDrfgn57wL35Ov5BeuoPh/11zKHvFXBZ2guO98f+OcOvGeVtxkeUd5E7YLc\n3Fdi25L1WD045K24vFDqLaRxVoAPSLymzbftu5DPPGfeOsohb5UQwcOkcejGnPbzJLZr4y37MuQj\nuJHm8YlHFdiD32rGIW+VEcGvgDfm5gakE6WePsm3q+TRfy1akL9uRzoQ3WzSHPJWKREsBE7Lzd2B\nz02yN9uXPfnsItKMI/ADWGuTQ96q6CTSikZIPfvJrFas7NF/44ngT8A3c3NOF7d9sAHgkLfKybNM\nDgXuzrc+K/GCCb5NP/fkofkAdjp0fbdOqzGHvFVSBHeRgn4lsDZpodSMCbxFv4f8t4E/52tvc2CT\n5pC3yorgh8D7cvNZwPkT2KGxr0M+ghU058zvJ7FVyXqsfznkrepOAxbm6wOAD7X4c30d8lljyEbA\nG0oWYv3LIW+VlhdKvZnmfuAfkTighR9thPyTuVfcj66jeZLW0Z4zb5PhkLfKi+Ah0kKpR0m92gsk\nthnnx/pmB8rR5D/gGr35HYAXFyzH+pRD3vpCBEtoTqXciPQgdt0xfqTvQz67gPTwGVp4ACvpbEnX\n538ukTRtvJ+xenPIW9+I4CLSZmYAzwdOH+PlfXH033giuBu4MjfntbAC+ISI2D0idiedc3p8Vwu0\nynPIW795N/DTfH2sNOqK0H46+m88C/LXZwAHjvXCiHgYQJKApwPR1crSZ50j6TeSrpN0raSBPTS7\nihzy1lfyQ9S5wJ/yrc9L7D7CS+syXAPwDeD+fD1/vBdL+hJwF7Ajzb/5dNuJEbFHROwZETf26DOt\nBQ556zsR/B6YBzxFOv3pqxIbrvay2oR8BI/T3G//FRKbj/36eBPwTNLRePO6XF6Ds6Si/AtjfSmC\n/wI+kJvbAeeutlBqzJCX9A+SbpW0UtJGXSy1Q17/TDgZOPlpcPwiae7V6Z+ZZ4706ogI4GLg4B4V\n+PH8sPdTkqb26DOtBVNKF2DWhlNJ0woPAl5L2tjs4/l74/Xkf0QaBrm6i/V10NQNU8gD6Q+1vNf+\n3GGvkrR9RPw6j8kfCPyqB8WdFBH35HA/i7RK+V968LnWAvfkrW/leeRHA7flWx+V2D9fjxnyEXFD\nRNwB9VlglIP9XEk3ADcAmwGndOCNpyPNRJo+0rcj4p789QngHOCFbX+mdYx78tbXInhQ4hBgMWk2\nyUUSe1KjMflW5SGazh4ykoJ9EbAzcDPS3qsfni1ps4i4O/8h8zrgpo7WYG1xT976Xj4y77jc3Bi4\nFFbNJx+YkO+SXUkBPxXYCdhlhNdcMORvDzPwUE2luCdvtRDBeRIvgX99Kzz2ouZ37j1S+uO+sGxp\nxE+PHelHe1Zkf7qJdMD6TqTZOktWf0FE7Nfroqx1DnmrkxPgwSPgE0PHjvNDyrmj/Yzoi3H5ZUtH\n/ndYtrSrHxuxHGlvUg9+yepDNVZ9DnmrjQgel5YtoYWNvCS9A3gvsClwg6RvR8RIPf1KGOVvIb36\n8OWkZx7WhxzyVjMrHm/lVRHxGXq3GtSsGD94NTOrMYe8mVmNebjGaqbQA0qzilJaP2FmZnXk4Roz\nsxpzyJuZ1ZhD3sysxhzyZmY15pA3M6sxh7yZWY055M3Maswhb2ZWYw55M7Mac8ibmdWYQ97MrMYc\n8mZmNeaQNzOrMYe8mVmNOeTNzGrMIW9mVmMOeTOzGnPIm5nVmEPezKzGHPJmZjXmkDczqzGHvJlZ\njTnkzcxqzCFvZlZjDnkzsxpzyJuZ1ZhD3sysxhzyZmYdIGmWpGsk3SjpHEmVyNdKFGFm1s8kCVgA\nzI2I3YDfAfNL1tTgkDcza98M4PGI+HVuXwUcUrCeVRzyZmZtioh7gSmS9sy3ZgNbFixpFYe8mVln\nzAP+Q9Ji4CFgZeF6AJhSugAzszqIiJ8B+wBIejmwQ9mKEvfkzcxaIU1Hmok0feRva5P8dR3gfcAZ\nvSxvNA55M7PxpGBfBPwAWDRK0L9H0s3A9cAVEXF1DysclSKidA1mZtUmzSQF/FRgBbAvEYvLFtUa\n9+TNzMZ3E3AzKeBvAZaULad17smbmbUiDdHsAiwhYnnpclrlkDczqzEP15iZ1ZhD3sysxhzyZmY1\n5pA3M6sxh7yZWY055M3Maswhb2ZWYw55M7Mac8ibmdWYQ97MrMYc8mZmNeaQNzOrMYe8mVmNOeTN\nzGrMIW9mVmMOeTOzGnPIm5nVmEPezKzGHPJmZjXmkDczqzGHvJlZjTnkzcxqzCFvZlZj/wtsmrBu\nuo+17wAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 2, 3])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We see that we made a valid left turn at point 1, but a right turn at 2. So we remove point 2 from the hull:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\nXu3xhMF/x4mDviKbudc9Rxh5zZqCn0ezLeO1RMxdtegjYtPMvKv8kNkfuGZMM2hULHn1vEx+HcHh\nwNeBDYGzItgrkwfH8n3K5iXTGFpxb8zoP4y8B1gM3AVLZpbfs9N2oin4icAOwEyaH6iP9c2I2JDm\n/x6uAo7oaEINyJJXK2TyjQieBR89Ah54Jtx3a8QdN614xVo/oEzYf3IET2bg0l4+jTLau2z/DtwJ\n3DXI44+ZLF3+TRG/P586JX8NcC1NwV9Hc1nmSjLz+Z0OpaGz5NUmR8N9r4ETpgJPLI/iiE0jeB+r\nzXk/6Ulw8h2jfN+HefSMe7XHqseXZI7kBqVFN676IeuK4+Mo836aq3RmAgvXNCev7uYllGqViNde\nDKfPXv0rHyyP5b4AfJymgzemuXfopFW/6c8MfsZ9F3DPUC/dlDrNM3m1zINLB3nBEuAueHt5DDhd\n4rXe6nmWvPrELQuAfTJZUjuJ1Eneiqw+sfQBC179yDN5tUylDyilLuUHr5LUYk7XSFKLWfKS1GKW\nvCS1mCUvSS1myUtSi1nyktRilrwktZglL0ktZslLUotZ8pLUYpa8JLWYJS9JLWbJS1KLWfKS1GKW\nvCS1mCUvSS1myUtSi1nyktRilrwktZglL0ktZslLUotZ8pLUYpa8JLWYJS9JLWbJS1KLWfKS1GKW\nvCS1mCUvSWMgIp4XEZdHxK8j4pSI6Ip+7YoQktTLIiKAU4GDMnNn4HfAITUzLWfJS9LozQCWZuYt\nZfxz4BUV8zzKkpekUcrMPwETImJWOXQAsEXFSI+y5CVpbBwMfDYi5gN/BZZVzgPAhNoBJKkNMnMB\nsBdAROwLbFs3UcMzeUkaioipRMwhYuqavxwblV8nAe8FTuxkvLWx5CVpME2xzwMuAOatpeiPjYhr\ngauA72fm+R1MuFaRmbUzSFJ3i5hDU/ATgQeBvcmcXzfU0HgmL0mDuwa4lqbgrwMW1o0zdJ7JS9JQ\nNFM0M4GFZN5fO85QWfKS1GJO10hSi1nyktRilrwktZglL0ktZslLUotZ8pLUYpa8JLWYJS9JLWbJ\nS1KLWfKS1GKWvCS1mCUvSS1myUtSi1nyktRilrwktZglL0ktZslLUotZ8pLUYpa8JLWYJS9JLWbJ\nS1KLWfKS1GKWvCS12P8DNZrqgpzBy5EAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 3])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We move on to points 4 and 5:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 3, 4, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Point 4 is a right turn, so we remove it:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 3, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "But now we see point 3 is also a right turn. The addition of one new point (5) can remove multiple points (4 and 3) from the hull. We remove 3 and move on to 6, 7, and 8:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\nOeTNzCrs/wEQ9RRP5yV8CAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 5, 6, 7, 8])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Point 7 is a right turn so we remove 7 and move on to 9:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAADsCAYAAACR39Z5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGdBJREFUeJzt3XmYXFWdxvHvSxJAQiAGZBEyyjJhFUgAIQ4QFlEQFSUB\nQUVAkEVwRFBkZlwYRBkcFVFHAVFZRZBVFjcUJGBAgiyyaNgNqCwKCQHJxm/+OKe6O0mn00tVnapb\n7+d58nDPraq+v5D0m9vnnkURgZmZVdNypQswM7PGccibmVWYQ97MrMIc8mZmFeaQNzOrMIe8mVmF\nOeT7IOmNkm6TNEPSxZKGl67JzGwgHPJ9Ow34akSMA14ADi1cj5nZgMiToZZO0rPAmhHxqqTtgZMi\nYo/SdZmZ9Zfv5JdC0mrA8xHxaj71JPD6giWZmQ2YQ97MrMIc8ksREX8HRkuq/T9aF3iqYElmZgPm\nkO/bjcC++fgg4OqCtZiZDVhHhrx0wFSJWPLXfjct9tYTgeMkzQDGAN9rerFmZkPQoeO+Fy7sz7si\n4jFguwYXY2bWMB15J29m1ikc8osYsXzpCszM6qlDu2tmzoD98vFqa8GaG6Xj9daXGBHB/GKlmZnV\nkWe8AhLfBQ7LzTMiOLZkPWZm9eKQByRWBG4FJuRT+0dwScGSzMzqwn3yQASvAFOA5/Op70lsWrAk\nsyGR9A1JL5auw8pzyGcRPAZ8EAhgJHC5xKiyVZkNnKStgdGkv8vW4RzyPURwPfCF3NyYdEevgiWZ\nDUhehuN/gU+VrsVag0N+SScDP8/H+4IfwlpbOQa4KiKeBt+gmB+89kpiNeD3wL8AC4FdIphatiqz\nvklaG7gUmJT3QHgxItzl2OF8J9+LCP5OehA7DxgGXCKxVtmqzJZpPLAB8LCkx4CV8rpL1sF8J98H\niSOAM3PzZmC3CBYULMkaTNKFwDakf+B/BxwREf1a66gppFHA5sB9RPQ5esZ38ga+k1+Ws4Hz8vFO\nwKkFa7HmuDAiNo6ILYCV6J4kV14K+KnAb4Cpud0X38GZQ74vEQTwUeDefOqTEvsULMkaLCJ+1qP5\nO9JmMa1ic2BTYASwCbBZX2+OiFWaUZS1Nof8MkTwMjAZmJVPnSuxUcGSrAkkDQcOBH62rPc20X3A\nA6SupAeB+8uWY+3AffL9JPFuuneGuh/YLoKXCpZkDSTpbGBORBxXupZFpC6azYD7l9UnbwYO+QGR\n+BLwH7n5Q+CDuUvHKkTS54CtIsJdc9b23F0zMJ8FfpWP3w8cXbAWGwxpFNLEpT20lHQY8HbggOYW\nZtYYvpMfIIk1SBOl1gHmA5MimFa2KuuX7tEpm5L6tndcvMtD0nzgcWAOaXTKFRFxSpMrNasbh/wg\nSGxPGjc/AngKmBDBM2WrsmWSJpKGH44gPbycRMRtZYsyayx31wxCBLcBtQdy6wAXSwwrWJL1j0en\nWMfxnfwg5dUpLyT1zQOcGsF/FizJ+sOjU6zDOOSHQGIkcDvdk1L2juAnBUsyM1uEQ36IJMYB04FR\npAlT20TwcNmqzMwS98kPUQQzgINzc1XSjlIrlavIzKybQ74OIrgC+EpubgF82ztKmVkrcMjXz3+Q\nhlUCHAQcXrAWM2sySbtJulPSXZJulrR+6ZrAffJ1lTcW+T2wNmmY3g4R3FG2KjNrBkl/At4VETMk\nHQVsGxEfLl2X7+TrKIK/AfuRtgxcHrhMYvWyVZlZk7xKei5H/u9fCtbSxXfyDSDxCeBrufkL4B0R\ntM7uQmZWd5J2AK4CXgZmA9tHxJyyVTnkGyI/dL0E2DefOjmCzxcsycwGSZp4Nowdt+QrM2dETDu8\n+326HDg1IqZLOh7YOCI+0rxKeze8dAFVFEFIHAq8CdgY+JzE7RFcX7g0MxuwsePg0klLnt+v60jS\n6sCWETE9n7oU+GkzqlsW98k3SAQvAvtA18YiF0qsV7AkM2uc54FVJG2Y228jrY9UnEO+gSJ4EDg0\nN19LehC7YsGSzKwBImIh8BHgCkl3AR8APlW2qsQh32ARXAKckZsTgG8WLMfMGiQiro6ILSJifETs\nGhGPl64JHPLN8ing1nx8mETxsbNm1l/LtfUy4n7w2gQRzJd4H2mi1BqkZQ/uiuCuwqWZ2TKNmAsn\n9Wg/cRe8NBtmzihV0UB4CGUTSexM2iN2OeAxYOsIni9alJn1SeJHwPt6nHpLO2356e6aJorgJtIa\nNwDrARdI/jMwa1V5oMRejfnaOlrSQ5IWShqz2GvfyK/dLWmroVzHAdN8/wtcmY/3Au8mZdbCdgdW\nbtDXvgXYDXii50lJewIbRMS/AkcAZw7lIg75JosggEOAh/KpkyV2L1iSmS3d5EZ94Yi4JyL+DEss\nS743cH5+z+3AqpLWHOx1HPIFRDCL9Jfnn6Q/4Isl/qVsVWbWk8QI4N25OauJl14HmNmj/VQ+NygO\n+UIi+ANp8gTAasCPJVYoWJKZLWpn0iRGgGsK1jEkDvmCIrgI+HZuvhk4vWA5ZraoffJ/5wPXDvjT\n0iikiUijlvHOxYc4PgWM7dFeN58bFId8eccBt+fjoyQOLFmMmYHEMOC9ufkr4IUBfoFRwFTgN8DU\nZQS9WLRf/ifAh9KX0fbACxHx9ICu34NDvrAI5pKWJH4unzpLYouCJZkZTARqDzuvGMTnNwc2BUYA\nmwCbLf4GSR+TNJPU336PpLMBIuJ64DFJDwNnAR8dxPW7r+PJUK1B4q2kDUYEPAxsGzHAuwczqwuJ\n04FjSbs9rQ2MB36WX172ZKjuO/lNSKtR7kjEiw0ruA++k28REdwAfDY3NwTOzZuPmFkT5e+7Wn/8\n1AieGfAXSYG+IzCJggEPDvlWcyrdT/H3Bk4oWItZp9oauoY0Xz7orxLxIhG3lQx4cMi3lAheBQ4C\nHs2nviSxS8GSzDrRPj2Or1zqu9qEQ77F5AXLJgOvkP58fiQNfiKEmfVf7qqpzXK9PYInS9ZTDw75\nFhTB3cBRubkGaaLU8gVLMusUmwG1TbsHM6qm5TjkW1QE5wLfzc2JpIXNzKyxenbVOOSt4f4duLN2\nLHFAyWLMOkCtq+beCB4uWkmdOORbWASvAFOAf+RT50hLTqows6GT2BC6JiIOflRNi3HIt7gIHift\n/B7ASsDlEqsULcqsmnp21TjkrXki+Blwcm5uBHzPE6XM6q4W8jOAB0oWUk8O+fZxMt3TqqcAnyhY\ni1mlSKwLbJebl+fNfSrBId8m8kSpD9K9VdiXJXYsWJJZlby3x3ElRtXUOOTbSAR/J93FzwOGAZdK\nrF22KrNKqI2q+TPdI9oqwSHfZiKYDhyTm2sBl+RtysxsECTWgK6fiq+oUlcNOOTb1TnAufl4R9LC\nZmY2OHvTnYWVGVVT45BvQ/lO46PAPfnU8RJTCpZk1s5qo2qehmWsE9+GHPJtKoJ/kvoRa7vI/0Bi\no4IlmbUdidHAbrl5ZQQLS9bTCA75NhbBI6QRNwArA1dIrFywJLN2807oeqZVqVE1NQ75NhfBtcAX\nc3NT4GxPlDLrt9qomueBmwrW0TAO+Wr4PHBDPj6A7tE3ZrYUEiOBPXLzJxHML1lPozjkKyD3I74f\nujY4+JrExIIlmbWDPYEV83HlRtXUOOQrIoJnSROl5gPDSRuNrFG2KrOWVhtVMwf4ZclCGskhXyER\n3A4cm5vrkLYOHF6wJLOWJLEC6aErwHV5We9KcshXz3eAi/LxLsAXCtZi1qreCozKx5UcVVPjkK+Y\nPFHqCOC+fOpEib0LlmTWimqjauYC15cspNEc8hUUwUukv8Sz86nz8643Zh0vd2HWbnx+HsGckvU0\nmkO+oiKYARycm6uQdpRaqVxFZi1jEjAmH1d2VE2NQ77CIrgS+HJubgGc6YlSZl1dNQuAa0oW0gwO\n+er7L7pn8h1I6q8360gSy9G9QcivI3i+ZD3N4JCvuAgWAPsDf82nzpB4c8GSzEqaSNqHASo+qqbG\nId8BInga2Jf04+nywGUSq5etyqyI2gSoAK4qWUizOOQ7RAS3Ap/MzbHARRLDCpZk1lT5eVStP/6W\nfPNTeQ75zvIN4JJ8/DbSwmZmnWI88IZ8XPlRNTUO+Q6SJ0odBjyYT31WYq+CJZk10+Qex1cWq6LJ\nHPIdJk/82Ae6JoBcKLFewZLMmqXWH39HBH8uWkkTOeQ7UAR/BD6cm6NJE6VeU7Aks4aS2BTYODc7\npqsGHPIdK4IfA6fn5njgmwXLMWu0fXocd8TQyRqHfGf7NHBLPj5U4tCSxZg1UK0//g8RPFS0kiZz\nyHewvN3Z+6BrKNn/SUwoWJJZ3UmsD2yVmx11Fw8O+Y4XwV9IQb8QWIHUPz+m70+ZtZWeXTUd1R8P\nDnkDIvgNcGJuvhG4IK/xYVYFtZB/mO59FjqGv5Gt5qt0/yj7DtLCZmZtTWId6NrU/vI8V6SjOOQN\n6JoodQgwI5/6b4m3FyzJrB7e0+O44/rjwSFvPUQwmzQK4WVAwA+lrmngZu2oNqrmSeCOkoWU4pC3\nRURwH/CR3BwD/DjvbG/WVvJKq5Ny84pO7KoBh7z1IoIfAt/KzW2Brxcsx2yw9qY74zpuVE2NQ96W\n5njgtnx8pMSHShZjNgi1UTXPALeWLKQkh7z1KoJ5pI1GnsunzpLYsmBJZv0msSqwe25eFcHCkvWU\n5JC3pYrgSdLWga8CK5ImSo0uW5VZv+wFjMjHHTmqpsYhb32K4FfAZ3JzA+A8T5SyNlAbVfMCcGPJ\nQkrzN6v1x2nANfn43cAJBWsx65PESGDP3Lwmdz0i6WZJv5d0l6SnJHXEHb5D3pYpgleBDwGP5FNf\nlNitYElmfXk7dO2P0DWqJiJ2iogJETEemEaHdOM45K1fIniB9CPwK6S/NxdLrFu2KrNe1bpqXgJ+\nsfiLklYBdgWuamZRpTjkrd8iuAc4MjdfR5ootXzBkswWkSfuvTM3r4/gn728bW/ghoiY08trleOQ\ntwGJ4DzgrNzcHvhKwXLMFrcbsEo+Xlp3zAHAxc0ppzyHvA3GscD0fPwxiQNKFmPWQ20C1DzgusVf\nlLQaaRb3Eq9VlUPeBiyCV4ApwD/yqXMkNitYkhlTtePo4cyfkpu/iODFXt62L3BtRMxrYmlFOeRt\nUCJ4Ang/EMBKwBVS14/JZs0ljZrFqtMXMGJVgNV4bml36vvRQV014JC3IYjg58BJuTkO+L6EylVk\nHWzzn7LnegDDWMDFHPBob2+KiF0jYokRN1XmkLehOgX4aT6eDBxXsBbrUI+w/v2XMWUhwHbcPmd3\nbphWuqZW4ZC3IckTpT4IPJ5PnSaxU7mKrBNtyCObPcOaIwAeZJPPENFbf3xHcsjbkEXwD9KD2LnA\nMOBSibXLVmUdpjaqJp5nzCVFK2kxDnmriwjuBI7JzTVJQT+ij4+Y1UV+DlSb5XprBH8rWU+rcchb\n3URwDvD93NwB+J+C5Vjn2BJYLx93xHo0A+GQt3o7BrgrHx8nsW/JYqwjTO5x7JBfjEPe6iqvFTKF\ntI43pGGVGxcsyaqv1h9/Z56/YT045K3uIngUODA3VyZNlFq5YElWUfkGYtPcbNZm3W01F8Qhbw0R\nwbWkMfQAmwDf9UQpa4B9ehy7q6YXDnlrpJOAX+bj/YGPlSvFKqrWH39/BH8qWkmLcshbw0SwkLS+\nzcx86qsS/1awJKsQiTcCE3Jzibt4SV+U9CdJ90s6ZvHXO8Xw0gVYtUXwnMQU4BZgBGn8/IQIni5c\nmrW/nl01i/THSzoYWCciNsrt1ZtYV0vxnbw1XAS/Az6em68HfiT5BsOGrBbyjwL3LvbaUcDJtUZE\nPDfEa8UQP1+MQ96a5Uzggny8M90PZc0GLC+b8ZbcvDxiiRDeANhf0h2SrpO0YXMrbB0OeWuK/E14\nJPCHfOrTEu8pWJK1t/fSPZSxt1E1KwAvR8S2sMhM7I6jiLb9KcTakMS/krYOXAWYDWwTwUNlq7J2\nIU08G8aOg/W2hNeMhgXzYMY0mDkjYtrh3e/TA8CeEfFEbr8QEaMHf13eBvw8N/8tgt8O6TfSRO4X\ntaaK4CGJDwFXkYL+comJEbxUuDRrC2PHwaWTepxYHpiUNnxaxFXArsAPJO0MnTu80t011nQRXA2c\nlptvAs70RCnrn2HD+vnG04DJku4Fvggc1riaWpvv5K2UzwBvBnYhbTryW+A7RSuylpY2o9lgm/68\nNyJmAe9scEltwXfyVkQEC4ADgL/kU2dIbFewJGtREitKfAW4CYavWLqeduOQt2LyhKh9gQWkiVKX\nSbyubFXWSiTGkx7UHw8I4tXCJbUdd9dYURH8VuJ44AxgXeCHEnvkJRGsQ+XJcp8mrX9Uy6k7YPpj\nsN+aS35i5oymFddmHPLWCr4JTCQtYvZW0jf2Z0sWZOVIjAPOh67uuwXAF4AvRVy3oFhhbcrdNVZc\nnij1EeCBfOozkh+adRoJSRwN3E13wD8ITIzg5PwcxwbIIW8tIYI5pGVj5+RTF0isX7AkayKJdUmT\njb4FvCafPh3YOoLpxQqrAIe8tYwI/ggckpujSROlXtPHR6zN5bv395OWu9g9n/4zsGsEx+XtJG0I\nHPLWUiK4DPhabm5FurOzCpJYDbgEuIj0jzrAucAWEdxYqq6qcchbKzoRmJqPPyx17mzFqpLYC7iP\nNIQW4FngvREcEsGscpVVj0PeWk4E84H3AX/Lp74lsXXBkqxOJFaWOAu4Flgrn74a2DyCq8pVVl0O\neWtJEfyVFPQLScvGXi4xpmxVNhQSOwD3ALXVIl8EDibdwT9Tqq6qc8hby4rgZtKEGIA3ABdK/jvb\nbiRWkDgNuBm6RkzdCLwpgvN62fDD6sjfMNbqvgZclo/3JC1sZm1CYkvgDuAE0iYfc4FPAG+N4ImS\ntXUKh7y1tHyXdyjd64GfJLFHwZKsHySGSZxICvg35dN3AhMi+HoEXoOmSRzy1vIimE2aKPUy6W7w\nIok3lK3KlkZiQ1LXzKmkhecWAv9Nmrn6QF+ftfpzyFtbiOB+ujd+GENasdLLzi5G0jmS7s6/LpW0\nUvOujSSOJD1crW2y/SdSuJ+UR01ZkznkrW1EcDFpMTOAbYCvFyynVR0bEVtFxFbATOCYZlxU4vXA\n9aSNX2r/sHyD1D1zRzNqsN455K3dfBKYlo+PkDioZDGtJiLmAEgSaQ2Yho9ckTa/Ed44E8bvAROA\nO58mPVj9eAQvN/r61jeHvLWVCOaRdm1+Np86U2KrgiW1HEnfB/4KbET3Tz4NuA5jJC6GbXeG05eD\nu4Dfnw9bbxzBrxp1XRsYh7y1nQieJK09/yqwImmi1Oi+P9U5IuLDwNqkZXr3b8Q18gin+7q//tzZ\nwOQIDorghUZc0wbHIW9tKYJfA/+Vm+sD5w9kopSkoyU9JGmhpMrNpI2IIC3+tU89v67ESInvAD8l\n/UMCPDsTDnwW9DlJX5U0op7XtKHxzlDWzk4Dtgf2Bt5Fmh17aj8/ewtwDXBTQyprFGkUsDlwHxEv\nLvmyNoiIR3Kf/LuBPw7+UhPPhrHjus+MXAVevwmMWjGtIccc4OPw6+si5j+dw/27pD+HUwZ7Xasv\nh7y1rQgiP3idDmwInCLxu/70B0fEPdD1gLI9pICfCmwKPIC0Y8+gz7+X85TeJ9JQxqMGf8Gx4+DS\nSUuePwnSOPiDI3iM/Gw1IuZL+gFp021rEQ55a2sRzJKYDNxGGk3yI4nxud++ajYnBfwIYBNgM9Lv\nG+jqotkB0ph10lDGlSXWBFYGRub/Lu3XYq9vMKH3Mp59BNilNmtV0loR8bf8j8x7SH311iIc8tb2\nIrhX4gjS5s+rAz+WmJRH4rQ8ieXpRwCPYtaYA7ng+UCrP8MaL13Du06clyaE9RbSI0l380OwwlLO\nP/vkYssSXCRp9Xy9u4Ejh3ZdqyeHvFVCBBdIvAX+50h4ZXuY9aj01MPd75g5I2La4b19tL/XyA92\nV2KZd8ADfr1fDypfZBW+zdG15mtJzyLqZc5iv16ClzfN1+lTROxWxzqszhzyViXHwqwPwKmjgHXy\nr+yQURK7skT4vva1MP3zEsNZdkCPbOLvZWnmsWQg9xLQA3r9n70tGCY9fhPQS5+8tROHvFVGBHOl\nmfeTRtws5g0ToOcD2W8CXyZl3E7/Du8Azq5rOQw8fJf1npeau/7LzBlp3llv561dOOStYubN7d/7\nPpZ/AWmN80bcHbf1ZhhL6d6yNuOQtw7x5B9Iqd7b3fGCkpWZNZJD3jrE7H9E8JvSVZg1m0PeKsb9\nyGY9OeStUtyPbLYoL1BmZlZhDnkzswpzyJuZVZhD3syswhzyZmYV5pA3M6swh7yZWYU55M3MKswh\nb2ZWYQ55M7MKc8ibmVWYQ97MrMIc8mZmFeaQNzOrMIe8mVmFOeTNzCrMIW9mVmEOeTOzCnPIm5lV\nmEPezKzCHPJmZhXmkDczqzCHvJlZhTnkzcwqzCFvZlZhDnkzswpzyJuZVZhD3sysDiTtKulOSfdK\n+oGklsjXlijCzKydSRJwLrBfRGwBPAEcXLKmGoe8mdnQrQbMjYhHcvsGYHLBero45M3MhigingOG\nS5qQT00B1i1YUheHvJlZfewPfF3SbcBsYGHhegAYXroAM7NWJk08GzbbrvvG/IlvSS/NhpkzIqYd\nXntfRNwO7JQ+o92BcQXKXYJD3sysT2PHwTlb9DgxPv1nv0XeJel1EfGspBWATwOnNKvCvri7xsys\nPj4l6QHgbuDqiLipcD2A7+TNzOoiIk4ATihdx+J8J29mVmEOeTOzCnN3jZlZn2bOWPwha/f51qeI\nKF2DmZk1iLtrzMwqzCFvZlZhDnkzswpzyJuZVZhD3syswhzyZmYV5pA3M6swh7yZWYU55M3MKswh\nb2ZWYQ55M7MKc8ibmVWYQ97MrMIc8mZmFeaQNzOrMIe8mVmFOeTNzCrMIW9mVmEOeTOzCnPIm5lV\nmEPezKzCHPJmZhX2/wkatt8dvyIjAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 5, 6, 8, 9])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Point 8 is a right turn, so we remove 8. But then 6 and 5 are also right turns, so they too are removed. We proceed on to 10:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAADsCAYAAACR39Z5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGxBJREFUeJzt3Xe4XVWd//H3R0iooQWkF6lSBulNetDBUdShREAQBAEL\n4yA2HB3lhyiDFctvRESKokgVZyyMEzpKUFoEFANICQgRKSGhJSTf+WOtk3Nvcsu5955z1j7nfF7P\nc5/ste++d38heT533bX3WksRgZmZdafXlC7AzMxaxyFvZtbFHPJmZl3MIW9m1sUc8mZmXcwhb2bW\nxRzyQ5C0gaSpkqZLuljSkqVrMjMbCYf80M4EvhoRmwLPAccWrsfMbETkyVCDk/QUsHpELJC0C3Bq\nROxfui4zs0a5Jz8ISROBZyNiQT71GLBWwZLMzEbMIW9m1sUc8oOIiKeBlSTV/h+tAzxesCQzsxFz\nyA/tOuCQfHwU8LOCtZiZjVhPhrx02E0SsfjH5OsXufQU4GRJ04FVgO+3vVgzszHo0fe+589v5KqI\neAjYucXFmJm1TE/25M3MeoVDvp9x40tXYGbWTD06XDNjOkzOxxPXgNU3S8ev21BiXATzipVmZtZE\nnvEKSHwPeF9ufiOCk0rWY2bWLA55QGJp4DfAdvnUoRFcUrAkM7Om8Jg8EMHLwMHAs/nU9yW2KFiS\n2ZhI+qak2aXrsPIc8lkEDwFHAAEsB1whMaFsVWYjJ2l7YCXSv2XrcQ75PiL4JfD53Hw9qUevgiWZ\njUhehuPLwMdL12LV4JBf3GnA/+TjQ8APYa2jnAhcFREzwR0U84PXAUlMBO4A1gPmA/tEcFPZqsyG\nJmlN4FJgr7wHwuyI8JBjj3NPfgARPE16EDsXWAK4RGKNslWZDWtbYCPgAUkPAcvmdZesh7knPwSJ\nE4Czc/NGYFIErxYsyVpM0kXADqQf8L8DToiIhtY6agtpArAVcA8RQ7494568gXvywzkHuDAf7wmc\nUbAWa4+LIuL1EbE1sCz1SXLlpYC/CbgBuCm3h+IenDnkhxJBAB8E/pBPfUziwIIlWYtFxNV9mr8j\nbRZTFVsBWwDjgM2BLYe6OCJWaEdRVm0O+WFE8CJwEDArn7pAYrOCJVkbSFoSOBK4erhr2+ge4I+k\noaQ/AfeWLcc6gcfkGyTxduo7Q90L7BzBCwVLshaSdA4wJyJOLl1LP2mIZkvg3uHG5M3AIT8iEl8E\nPpWbFwPvzkM61kUkfRbYJiI8NGcdz8M1I/PvwDX5+DDgQwVrsdGQJiDtOthDS0nvA/6R9Pdr1vHc\nkx8hideSJkqtDcwD9orglrJVWUPqb6dsQRrb3mPRIQ9J84CHgTmkt1OujIjT21ypWdM45EdBYhfS\ne/PjgMeB7SL4W9mqbFjSrqTXD8eRHl7uRcTUskWZtZaHa0YhgqlA7YHc2sDFEksULMka47dTrOe4\nJz9KeXXKi4DD86kzIvi3giVZI/x2ivUYh/wYSCwH3Ep9Uso7Ixa+ZmlmVpxDfowkNgVuAyaQJkzt\nEMEDZasyM0s8Jj9GEUwHjs7NFUk7Si1briIzszqHfBNEcCXwldzcGviOd5QysypwyDfPp0ivVQK8\nBzi+YC1m1maSJkm6XdKdkm6UtGHpmsBj8k2VNxa5A1iT9Jre7hH8vmxVZtYOkv4MHBAR0yV9ANgx\nIo4pXZd78k0UwZPAZNKWgeOByyVWLVuVmbXJAtJzOfKffy1Yy0LuybeAxEeAr+Xmr4F/iqA6uwuZ\nWdNJ2h24CngReB7YJSLmlK3KPflWOQu4LB+/GfhswVrMrD0+AuwfEesB5wNfL1wP4J58y0hMIO0s\n9Pp86q0R/LJgSWY2FkPsrytpVWBqRGyc2+sCv4qIrdpfaH/uybdIBLOBA2HhxiIXSbyuYElmNlrD\n76/7LLCCpI1z+82k9ZGKc8i3UAR/Ao7NzZVJD2KXLliSmY3OkPvrRsR84DjgSkl3Au8GPt7uIgfi\n4Zo2kDgL+NfcPDeC40rWY2YjVO/Jb07qoS+2F0FVOeTbQGIccB3wxnzq2AjOK1iSmY1Uh65g6pBv\nE4m1SROlXgu8AuwawZ1lqzKzbucx+TaJ4HHgXaQJE0uRFjJbuWxVZtbtHPJtFMH1pDVuAF5HeuPG\nfwdmPUjShyTdL2m+pFUW+dw38+fukrTNWO7jgGm/LwM/zcf/BN5NyqxH3QxMAh7pe1LSW4CNImIT\n4ATg7LHcxCHfZhEE8F7g/nzqNIk3FyzJzAqIiGkR8Sgstiz5O4Af5GtuBVaUtPpo7+OQLyCCWcBB\nwEukv+AfS6xXtiozq4i1gRl92o/nc6Oy5JjLsVGJ4G6J40ibgU8kTZTaI4JXCpdmZmMg7XoOrLvp\n4p+ZMT3ilrbvM+GQLyiCH0nsBnwQ2JG0oNEHy1ZlZmOz7qZw6V6Ln5882Bcs+h7748C6fdrr5HOj\n4uGa8k4Gbs3HH5A4smQxZtZ2ov+4/H+RdpdD0i7AcxExc7Tf3CFfWB6eOQT4ez71XYmtC5ZkZm0g\n6V8kzSCNt0+TdA5ARPwSeEjSA8B3GeNv9x6uqYAIZkgcRtpgZBnSRKkdI3iucGlm1iIR8S3gW4N8\n7sRm3cc9+YqIYArw77m5MXCBJ0qZ2Vi5J18tZwA7AweQ3pX9OHBm0YrMbIRmTIfP7AxLLg2zZ8KM\n++rn288LlFVMXs/mNmBD0jo3b4rg2rJVmdlISMwGlgfOiuAjJWvxcEDFRPAsaaLUy6S/n5/kFSzN\nrAPkjYGWz82/D3VtOzjkKyiCu4AP5OZqwGUS4wuWZGaNW7XP8VPFqsgc8hUVwQXA93JzV9LCZmZW\nfX1D3j15G9KHgdtrx/k1SzOrNoe8NSaCl4GDgWfyqXOl/hsIm1nlrNbn2CFvQ4vgYdLO7wEsC1wp\nsULRosxsKB6Tt5GJ4GrgtNzcFDhPWmwNajOrhlrIB/BsyULAId9JTgOuzscHQdl3b81sULXhmmcj\neLVoJTjkO0YEC4AjqG8V9iWJPQuWZGYDq/Xki4/Hg0O+o0TwNOlB7FxgCeASiTXLVmVmi6iFfPHx\neHDId5wIbgNqK9StQQr6cQVLMrP+3JO3MTsXuCAf70Fa2MzMqqE2Ju+Qt9GJIEgbCUzLpz4qcXDB\nkswMyG+9uSdvYxfBS6S3bGblU+dLvL5gSWYGK1Bfwt1j8jY2ETxIeuMG0qp3V0gLV78zs/ar1JIG\n4JDveBH8HPhCbm4BfM8TpcyKqdSSBuCQ7xafA6bk40Opv31jZu1VqSUNwCHfFSKYDxwOPJZPfU1i\nt4IlmfUqD9dYa0TwFGmi1DzSg5/LJF5btiqznuOQt9aJ4FbgpNxci7R1oDdrN2uf2pj8PGB2yUJq\nHPLd5zvAj/LxPsDpBWsx6zULlzTI81mKc8h3mfwP6wTgnnzqkxLvLFiSWS+p1EQocMh3pQheIE2U\nej6fulBik4IlmfUKh7y1RwTTgaNzcwXSRKlly1Vk1hMqtW4NOOS7WgQ/Bb6Um/8AnO2JUmYtVall\nhsEh3ws+DVyfj48kjdebWZPlN9lWzk335K098vZjhwJP5FPfkNipYElm3Wpin2OHvLVPBDOBQ4BX\ngfHA5VK/SRtmNnaVmwgFDvmeEcFvgI/l5rrAjyWWKFiSWbep3Lo14JDvNd8ELsnHbwJOLVeKWddx\nT97KyhOl3gf8KZ/6jMRbC5Zk1k0qt8wwOOR7TgRzgAOBOfnURRIbFizJrFu4J2/VEMF9wDG5uRLp\nQewyBUsy6wa1kJ8dwStFK+nDId+jIrgM+Hpubgt8u2A5Zt2gcksagEO+130SuDkfHyNxbMlizDpc\n5ZY0AId8T4tgHvAuYGY+9f8lti9Yklknq9ySBuCQ73kR/JUU9POBpUjj86uUrcqsI3m4xqopghuA\nU3JzA9IbN/63YTYyDnmrtK8CV+bjtwCfKViLWUfJy3jXlvJ2yFv15IlS7wWm51OnSvxjwZLMOkkl\nlzQAh7z1EcHzpB2lXgREWt9m/bJVmXWESk6EAoe8LSKCe4DjcnMV0oPYpQqWZNYJHPLWOSL4MfXJ\nUTsA3yhYjlknqOS6NeCQt8F9FJiaj0+QOKpkMWYV5zF56ywRzCVtNFLrlZwt8YaCJZlVWS3kFwDP\nlSxkUQ55G1QEj5G2DlwALA1cIbFS2arMKqk2XPNMBPOLVrIIh7wNKYJrqL8zvxHwA0+UMltMJSdC\ngUPeGnMm8N/5+ADSwmZmHUXSjZLukHSnpMclXTn8VzWskuvWgEPeGhDBAuA9wIP51OkSkwqWZDZi\nEbFnRGwXEdsCt1Cf4d0M7slbZ4vgOdJEqZdJ/24ullinbFVmIydpBWBf4KomfttKLjMMDnkbgQim\nAe/PzdWAyyTGFyzJbDTeAUyJiDnDXtmA/IxqYm465K2zRXAh8N3c3IW0sJlZJzkMuLiJ329FYIl8\n7DF56wonAbfl4xMl3l2yGLNGSZoI7Aj8oonftrJLGoBD3kYhgpeBg4Fn8qlzJLYqWJIZSBOQdkWa\nMMRVhwA/j4i5TbxzZZc0AIe8jVIEjwCHA0FaR/sKiRXKVmU9KwX7TcANwE1DBP1kmjtUAxVe0gAc\n8jYGEfwPcGpubgqcL6FyFVkP2wrYAhgHbA5sOdBFEbFvRPy6yff2cI11tdOBX+XjA0kLm5m12z3A\nH4G5wJ+Ae9t4b4e8da88UeoI4OF86j8k9ipXkfWkiNnAHsBewB653S61MflXgBfaeN+GOORtzCJ4\nhvQg9hXSq2SXSKxVtirrORGziZja5oCHPksa5G00K8Uhb00Rwe3Aibm5OinoxxUsyaxdKrukATjk\nrYkiOBc4Lzd3Jy1sZtbtHPLWU04E7szHH5GYXLIYszao7Lo14JC3JovgJdL4fG13nO9LbF6wJLNW\nq+wyw+CQtxaI4C/Akbm5PGmi1PIFSzJrifzcacXcdE/eekcEPye9Qw9pcsq5nihlXajS78iDQ95a\n61Tgf/Pxu4APlyvFrCUc8ta78obGhwMz8qmvSLyxYEnWQyR9QdKfJd0r6cThv2JUKr1uDcCSpQuw\n7hbB3yUOBm4mrStyqcR2EcwsXJp1MUlHA2tHxGa5verQXzFq7smbRfA74F9zcy3gJ5I7GNZSHwBO\nqzUiolUBXOllhsEhb+1zNvDDfLw38IVypVgP2Ag4VNLvJf1C0sYtuk/fnvzTLbrHmDjkrS3ymh7v\nB+7Opz4h8c8FS7LuthTwYkTsCP1mYjdbLeRnRdDMjUiaxiFvbRPBi8BBwPP51IUSmxYsybrXDOCn\nABHxU2DrFt2n0ksagEPe2iyC+4H35OYE0kSp5QqWZJ1o+K3+rgL2TZdqb+DPLaqk0ksagEPeCojg\nZ9QXL9sKONsTpaxhjW31dyZwkKQ/kJ7/vK9F1bgnbzaIzwDX5eMjSG9DmDVi2K3+ImJWRLwtIraO\niDdGxN2LXtMklV63BhzyVkgErwKHAX/Np86S2LlgSdY5Sm71t1D+7dM9ebPB5AlRhwCvknpll0v9\n3js2W1zZrf76Wg5YOh875M0GEsFvqW/+vQ7wY4klCpZknaDcVn99VX5JA3DIWzV8C/hJPt4P+H8F\nazFrVOWXNACHvFVAnih1HGmcFeDTEgcULMmsEQ55s0ZFMIc0UWpOPvVDiQ0LlmQ2nMqvWwMOeauQ\nCO4D3pubK5ImSi1TsCSzoXhM3mykIrgc+FpubgP8pydKWUXVQn4+MKtkIUNxyFsVnUKa0QhwNK2b\nrWg2FrXhmqcjWFC0kiE45K1yIphH2i7wyXzq2xI7FCzJbCCVnwgFDnmrqAieIAX9fGA8aaLUxLJV\nmfVT+SUNwCFvFRbBjcAnc3N94CJPlLIKcU/erAm+Blyej/cnLWxmVgWVX2YYHPJWcXmi1LHU1wP/\nnMT+BUsyI/9GuUpuOuTNxiKC50kTpV4EBPxIYoOiRVmvW4l6fnpM3mysIriX+quUq5AexC49xJf0\nJEnnSrorf1wqadnSNXWpjljSABzy1kEiuJi0mBnA9sA3CpZTVSdFxDYRsQ1pn9MTSxfUpTpiSQNw\nyFvn+RhwSz4+XuLogrVUTkTMAZAkYBkgWn1PSedL+oukOyXdIalVm2ZXiXvyZq0QwVxgMvVx0O9I\nbFOwpMqRdB7wBLAZ9d98Wu2jEbFtRGwXEX9o0z1L6oh1a8Ahbx0ogseAQ4EFpJ15rpBYuWxV1RER\nxwBrkrbGO7RNt+21LHFP3qyVIrgW+HRubgj8QGr837OkD0m6X9J8SasM/xWdJSICuAQ4sE23/GJ+\n2PtVSePadM+SamPyL0XwYtFKhuGQt052JvCzfPw20sJmjboZmAQ80uyiWkqagLQr0oSBP62N8p8C\n3g7c14aqTomIzYAdgYnUZyl3s45Y0gAc8tbB8kSpo4AH8qnPS+zX2NfGtIh4FDpoGeMU7DcBNwA3\nLRr0OdgvlDQNmAasAZzWlPsO8YMlImbmP+cB5wM7jfme1dcRSxqAQ946XASzSBOlXiL9e75YYt2y\nVbXMVsAWwDhgc2DLvp+MZPeIeENEbB0RR9bethm1YX6wpEu0Rv5TwDuBe8Z0z87QEUsagEPeukAE\nfwBOyM1VgcsklipYUqvcQ9oHdy7poeq9bbjnkD9Ysh/1+e1hInB6G+oqrWN68kuWLsCsGSL4ocRu\n8B/vh5d3hll/kR6/v37FjOkRtxw/0Je2rcixipiNtAcpaO8lYnYb7lr7wbI5g/xgiYhJbaijajpm\nTN4hb93kJJj1bjhjArBW/sgmD/Y1opPG5VOwT23r/dr/g6XS8m+JtWGryvfkPVxjXSOCV2DGIEMY\nyy7f9xVLSf8iaQawNjBN0jntqbIDRcwmYqoDfqGOeUce3JO3rjP3lYHPb7A98DeJ64ApEL8Evp3f\n0DEbCYe8WUVNBA7OHwAPS1wDTAGujeBvxSqzTtIxSxqAh2usZ8ycTpoB2rfntQFpQ5KLgZkS0yS+\nKvEWieULFGmdwT15s3JmTB/4IeuM6REcn8fltybNdt0P2BOorbm+df44GZgnMZXUy58C/D6CeS0v\n3zpBxywzDKC0xIVZb8pvSuxCPfR3ggE3C59NmhBUC/0/ejy/N0mcCnwuN8dX/Ye/Q96sD4kVgL1I\ngb8faSLQQJ6EheP510Qwoz0VWmkS3wY+BDwbQeUXt3PImw1BYi1gX+qhv/Ygl06n3su/PoJn21Oh\ntZvET4B3AfdHsGnpeobjkDdrkIRIG3HUhnb2AVYc4NIFwO3UQ/+3EbzcrjqttfIbWfsCt0SwW+l6\nhuOQNxsliSWB7aj38t8IjB/g0pdJSxvXQv+uCOa3q05rLolppAf0/x3B20vXMxyHvFmTSCxLCvpa\n6G/LwEsmPAO1SVlMAR70Q9zOIfE4acmM8yI4tnQ9w3HIm7WIxETSkE4t9Dca5NJHqQf+tRHMbE+F\nNlJ5yO5l0m9sX4qo/gYpDnmzNpHYgPp4/iT6v2/d193UQ//GCMa2Jrw1TX77alZufiKCL5espxEO\nebMC8qSsraj38veiPimrr1eh36Ss31X9vexuJrEh8GBuHhPB+SXraYRD3qwCJMYDO1MP/Z0ZeFLW\nHOqTsq4B7vF4fvtI7ATcmpsHRPDzkvU0wiFvVkF5WGBP6qE/0I5MADPpPynr0fZU2Jsk3goLg33X\niDau7T9KDnmzDiCxJv0nZa0zyKX3Ux/auc6TsppL4ijggtzcJGLhJvKV5ZA36zD5DY9NqAf+PsBK\nA1wa1CdlXQP8JoKX2lVnN5L4KPCV3FwpbyRfaQ55sw4nsQSLT8oaaCPzV6hPyroGuMOTskZG4gzg\nFNID8fGd8DzEIW/WZSSWof+krO0YeFLWc8C11EP//k4IrZIkziXtQfBkBGuWrqcRDnmzLiexCvVJ\nWZNIQz0DmUE98K+J4Mn2VNg5JK4C3kF6q+kfStfTCIe8WY+RWJ/+k7JeO8il91AP/Rsi6PmNvCVu\nJv2WdF0E+5aupxEOebMelh/iLjopa7kBLn2V9H54LfRvjWBuu+qsCon7SCuRXhYx4BZkleOQN7OF\n8qSsnaj38ndh4G1CXyBNyqq9o39PBAvaVWcpEk8DqwDfieCDpetphEPezAYlMYH6pKxJMOg49N/I\nY/nAlAgeaU+F7ZOXlp5Leoj9+Qg+W7ikhjjkzaxhEmvQf1LWuoNc+gD1oZ3rIni6PRW2jsRqpB9m\nAB+O4Fsl62mUQ97MRiWP529MvZe/L7DyAJcGcAf1oZ2bO3FSlsTmwB9z8/AILi5ZT6Mc8mbWFHlS\n1rbUQ38PBp+U9RvqoX97J0zKktiT9BwC4M0R/G/JehrlkDezlsiTsnajHvo7MPikrOuoh/70Kk7K\nkjgQuCI3t4vgzpL1NMohb2ZtkSdl7U39Hf1NB7n0MfpPynqiLQUOQ+J44Lu5uW4Ej5Wsp1EOeTMr\nQmI9UuDXQn/1QS69l3ov/4YInm9Phf1J/BvwhdxctlOeKzjkzay4/BB3S+pDO3sDyw9w6XzSpKxa\n6E9t16Qsia8DJwEvRAxYWyU55M2sciTGkSZl1Xr5uzLwpKwX6T8p6+5WTcqS+CFwBPBIBBu04h6t\n4JA3s8qTWJ40KasW+lsPculT1FfWnBLBw02s4VfA/sBtEey4+Oe1L/BlYBxpHf9jI6L4LGCHvJl1\nHInVSe/lTwLeBKw3yKUPUu/lXxfB38dwz9uA7YGrI3hL/89JwCPAPhHxoKRTgUcj4rzR3q9ZHPJm\n1tHyeP5G1Hv5+5LWl1lUAHdR3x7x5gheHMF9HgbWBy6K4Mj+n9OqwC0RsUlu7w58KiLeOuL/oCZz\nyJtZV8mTsrahHvp7AEsPcOlc4LfUQ//2CF4d4vvOIa3Q+fUITl7883oIOCgi7pB0FqlX/4ax/veM\nlUPezLqaxNKkSVm10N8BeM0Al84Crqce+n+uTcrKE7tqvf5PR/DFxe+jnUlj8uOBXwNvi4jtmvof\nMwoOeTPrKRIr039S1maDXPpXYAoctS68ZkVYPwf2zOnw9BMwY3rELccPfA+9ifTg9dBm1z9SDnkz\n62kS61AP/P2ANfpfcWr+WNTkGyIu3bv+fbRaRDwlaSngF8DpEXF9K2oeiYHeOzUz6xl5eYILgQvz\nQ9wtqIf+3sCEBr/VxyW9jbQ+z39WIeDBIW9mtlAeg783f3wzTcp65FbS6prDfG18AvhEi0scsYEe\nPpiZGRDBPHihyFo5zeKQNzPrYh6uMTMb0ozpMHmQ89Xnt2vMzLqYh2vMzLqYQ97MrIs55M3MuphD\n3sysiznkzcy6mEPezKyLOeTNzLqYQ97MrIs55M3MuphD3sysiznkzcy6mEPezKyLOeTNzLqYQ97M\nrIs55M3MuphD3sysiznkzcy6mEPezKyLOeTNzLqYQ97MrIs55M3MuphD3sysi/0fjdvaLAGIuH0A\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 9, 10])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now what do we do? We got all the way to the end of our set of 11 points, but we only got half the hull (the lower half). Well, if looking at all the points in left-to-right order gives us the lower half of the hull, maybe looking at all the points in right-to-left order will give us the upper half. Let's try. " + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [10, 9, 8])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Point 9 is a right turn; remove it and move on:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\nQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [10, 8, 7, 6, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Adding 5 reveals 6, and then 7, to be right turns; remove them and move on to 4:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [10, 8, 5, 4])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Remove 5 and continue on to 3 and then 2:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [10, 8, 4, 3, 2])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now 3 is a right turn; remove it and continue on to 1 and finally 0:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAADsCAYAAACR39Z5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGaZJREFUeJzt3Xm4XVV9xvHvC4SpBoEwKkoYBBmkEIgSFbEgVEGlhSQC\ngqCISIuK4oBVHy2WKvqIRRxAUUBBhACKtVQtVTBYgiAQJAxhCgZkEJmCgSQkv/6x1p3ne88565y9\n38/znCd77XuGX8jlvfuutddaigjMzKyaVitdgJmZNY9D3syswhzyZmYV5pA3M6swh7yZWYU55M3M\nKswhPwxJUyXNk7RQ0kWS1ihdk5nZWDjkh3ca8JWI2A54CjimcD1mZmMiT4YamqQ/A5tGxCpJewKf\ni4g3l67LzGy0fCU/BElTgCcjYlU+9SDwkoIlmZmNmUPezKzCHPJDiIi/AOtL6vpvtAXwUMGSzMzG\nzCE/vF8Ds/LxUcAVBWsxMxuzWoa8dNhciRj4mH11v6eeDHxE0kJgQ+C7LS/WzGwCanrf98qVo3lW\nRNwPvKbJxZiZNU0tr+TNzOrCId/HpDVLV2Bm1kg17a5ZvBBm5+Mpm8Gm26fjrbaWmBTBimKlmZk1\nkGe8AhLfAd6bm2dEcGLJeszMGsUhD0isDfwWmJZPHRrBxQVLMjNrCPfJAxE8D8wEnsynviuxY8GS\nzCZE0tckLSldh5XnkM8iuB84Agjgb4DLJCaXrcps7CTtDqxP+l62mnPI9xLBlcDnc/OVpCt6FSzJ\nbEzyMhxfBj5WuhZrDw75gU4BfpGPZ4EHYa2jnAD8JCIeBV+gmAdeByUxBbgJeDmwEvi7COaWrcps\neJI2By4B9s57ICyJCHc51pxDfggS04FrgTWBh4FpETxStiqrK2nGt+Fl2w38yuKFEde9Lz1HBwDn\nAM+TruJfDtybdzazmqrpZKiRRXCDxAeBs4DNgYsl9o3ghcKlWRNJugDYA1gO/A44LiJGtdZR82pi\nNdh6Z7hwxsCvzu4+iogr6bWxTb6Sd8DXnPvkh/dt4Px8/AbgCwVrsda4ICJeGRG7AOvSM0muaSRW\nk9hcYobEYRKflDhb4hcSdwFL4RWDBDzA1F0kTpE4IHcz9uZf081X8sOJICT+CdgN2AX4qMR1EVxe\nuDRrkoj4ea/m70ibxUxIvkNrU2BqfmzV63gqsCWw1vjefd0NgM/0+qx7gHnA9RD7SKwZwfJxlm4V\n4JAfQQRLJQ4BbgReDJwnsSCCuwqXZk0kaQ3gSOCDIz93QIj3f2wJrD3GEv4CLOp5PHYQsO3Ap61Y\nSvqNo8u2+XFEbi+T+D3dwc88YHGEr/LrwiE/ChHcI/Eu0s5Qk0kTpV4TwV8Ll2bN803gmoj4bQ7x\nTRgY3l1X5OMJ8SfoE+IsAu7Pfz4QQZ/ZqtLjezBoyN99A/APwHRgT9L+B3tCd9fNWsBr86PLw1J3\n4F8P3BjBs2Os3zqE764ZA4l/Bz6ZmxcB7/QVUWcY7u4UuO44+oT4IcfAQ9vCvLt6zjUkxLseD0Tw\nTKPq77q7pue5CNiGnsB/DanLcaiLulXAH6BP8N8Zwaqx1GjtySE/BhKrkyZK7ZtPfSCCrxcsyUYp\nbe14yd4Dv/KppXCqgHVS+xzgXOBXjNBN/iTDh/jTE6+6cfIifLuRQr8r+Lcc5iVPk8YkuoM/gseb\nXac1nkN+jCQ2IU2UeimwAtg7guvKVmUjGTrkP5cfXSaRLtzXXQkrlsM+i+Drv6CnK2URbRji4yGx\nOSnsu674p5PWbRrKvfTt25/vQd325z75MYrgMYmZwG9IiTBHYloEjxUuzcblr48DF9Ad4CsWkUL8\nqYJFtUQEDwM/yQ8k1gB2pG/f/g70LI+wTX68M7eXSdxE3+D/o7sw24uv5MdJ4gTgzNz8FbB/BEUn\nzdjQhr6Sn31NxCVvbHU9nULixQwc1N1omJc8Qt++/Rs8qFuWr+TH7xvADOBwYB/S6pX/UrQiswbL\n3VJX5UfXoO7WDBzUnZRfshlwUH4ArJK4jZ7gn4cHdVvKV/ITIPE3pG/enfKpgyL4acGSbAjp7pQ9\n9oMpU9OZ269Jfw68O8XGptegblfw78nwg7rPMHBQ98/NrrOuHPITJLEdaaLUZNIdCXtEcE/Zqmww\nEl8irbO+LGLMt0TaGEhsRt9B3Vcz/KDuffTt27/Fg7qN4ZBvAImDgcty81ZgRgRLC5Zkg5D4BvBP\nwBMRA9Z5sSbKtx/3H9TdkaHXvF8G3ExPF8/1pAFxB9YYOeQbROLLwEdz8/vA0f6GbC8S5wFHkab1\nv7xwObUnsR49g7pd4b/xMC95lL59+zf2nxlsAznkGyTffva/pNUqAd4fwdkFS7J+JOaQNmy/M4Id\nStdjfeVB3a3o27ffe1C3v1XAAvoG/x2lBnUl7Qt8ibS67xLg6Ii4r0QtvTnkGyj3Q95EWn9+OfD6\nCG4oW5V1kbgSeAvpCnB66XpsZHlQd1f6Bv/UYV6yhIGDui2ZwyLpLuBtEbFQ0vHA9Ih4Tys+ezi+\nhbKBInhEYjZwNWlHqUsldvd08LbRNfDnheU6RATP03OVfgaAxKb0vYXz1cCL8ksmk5Yd6Vp6BIn7\n6du3f0sEy5pQ7irSSrXkP//UhM8YM1/JN4HEh4HTc/OXwAGeKFVeXnJ3GnBlBAeWrscaIw/q7kDf\nvv2dGHpQdzkDB3UXTXQMTdLrSbOHl5JuE90zIopPBHPIN0HuW7wYmJVPnRLBZwuWZIDEncD2wJyI\nXvvmWeXkQd096Bv8mwzzksfo27d/Q9eg7mhXAJV0GfCFiLhR0knAKyPi2Mb8jcbPId8kEpNJfYOv\nzKcOjODKgiXVnsRi0k5P50Xw7tL1WOvkC6+p9L2FczdSt+pggu5B3eP3gm8NEvI9S2JI2giYFxHb\n5vbLgP+OiJ0b+hcZB/fJN0kES/L98zeQ+oIvyP3z9xcurc7cJ19TuSvm/vy4CEBiLdKgbu/g3yq/\nRMDO6bHpaD7iSWA9SdtGxD3A/sAdjfw7jJdDvokiuEPiGOBHwAakgdjX5cEkaz2HvHXLg6/X5wfQ\nvZR4/0HdySO/V6yUdCxwuaSVpNAvfmcNOOSbLoKLJWYAHyIN+p0JFO+nq5s8j6HrV3OHvA0q3275\nn/mRB3Xvn0fq3+9Hq/V9bVxB2iK0raw28lOsAT4G/DYfv1dqj5/wNdN73RSHvI1KuivuuSG+X7bc\nOd/H39Z8Jd8CEayQeAdpotQmwDclbo7g5sKl1YlD3sZp8UK6b8bSajD1VbDO+rDhBsBlEgc36b77\nhvDdNS0k8UbS0gerkQaAdo/gyaJF1YTEK4CFuXlkBBeUrMc6V15i/Ep6ljD5KTCrXVfNdHdNC0Vw\nNfDJ3NwK+IHkf4MWeVGvY1/J27hF8FfgQHq6YN8OXCQNucbOoCT9s6S7Ja2UtGG/r30tf+0WSbtO\npF4HTOt9GfhxPj4Q7ybVKu6usYbJWxoeQJo4BXAw6TbpsXSBX0tafuGB3iclvQXYJiJeARwHnDWR\nWh3yLZbv1303cHc+dYrE/gVLqguHvDVUBM8AbyZtGgSp4/78vMzCKF4f8yPijwxcfuEg0nLlRMT1\nwIsljepm/cE45AvI+2YeAjxH+gf+oeT1zZvMIW8Nl/9f3h+6b6I4HPjuBLthXwos7tV+KJ8bF99d\nU0gEf5A4FrgAmEKaKLVXO4/SdziHvDVFBE9K7Af8GngVfPEoeGx/6cGFfZ9ZZj9hh3xBEVwo8VrS\nlnTTga/mY2s8h7w1TQR/kXgT8Gt4fkc4fXPSvhK9DLkmXv9bHB8CXtarvUU+Ny7urinvI/RMqz5e\n4siSxVSYQ96aKs+W3RdWPDfGl4q+/fI/Bd4FIGlP4KmIeHS8dTnkC8vdM7Oge2ORsyV2KVhSVTnk\nrekieAQW3TKa50r6gKTFpP72+ZK+nd4jrgTul3QPcDYT/O3e3TVtIILFEoeRNhhZhzSLbnoETxUu\nrUq6Qn5ZBC8UrcQqbsWoJkVFxJmktawG+9oJjarGV/JtIoKrgM/k5rbAeXkNbGsMr0BpteQr+fby\nBdLypm8j3Sv7ceC0ohVVR9eMV4e8NVnvtW76n289r13TZiQ2IE2u2Jq0MfB+EfyqbFWdT2IOMBO4\nM4IdStdj1irurmkzecGyQ4DnSf8+P5LGPxHCurm7xmrJId+GIrgFOD43NwbmSEPuRWmj45C3WnLI\nt6kIzgO+k5szSAub2fg55K2WHPLt7YPA77uO822WNj4Oeaslh3wbyxt+zwSeyKfOkdipYEmdzCFv\nteSQb3MRLALeSVrfYl3SRKn1ihbVmRzyVksO+Q4Qwc+BU3Jze9JSpp4oNTZdIf9s0SrMWswh3zlO\nAX6ej2cCHy5YS0fJu/WslZu+krdacch3iAhWAUfQs1XYl6TujYRteF6czGrLId9BIvgL6Sp+ObA6\ncLHUf81qG4RD3mrLId9hIrgR6FqhbjNS0I9pl/gacshbbTnkO9M5wHn5eC/SwmY2NIe81ZZDvgNF\nEKSNBObnUydJzCxYUrtzyFttOeQ7VATPkRYyezqfOldi+4IltTOHvNWWQ76DRXAv6Y4bSOulXy51\nr5tuPRzyVlsO+Q4Xwc+AU3NzR+A7nig1QO+Q92QoqxWHfDV8FrgqHx9Kz903lvhK3mrLIV8BEawE\nDgcezKdOl3htwZLaTe8uLIe81YpDviIi+DNpotQK0t69cyQ2KVtV2/CVvNWWQ75CIrgeODE3X0La\nOtCbtfeE/PIIXihaiVmLOeSr51vAhfn474DPF6ylXXiZYasth3zF5IlSxwG35VMnSxxUsKR24JC3\n2nLIV1AEfyVNlHomn/q+xLYFSyrNIW+15ZCvqAgWAkfn5nqkHaXWLVdRUQ55qy2HfIVF8GPgS7m5\nC3BWTSdKOeStthzy1fcp4Op8fCSpv75uvPWf1ZZDvuLyLYOHAg/nU2dIvLpgSSV0TYbylbzVjkO+\nBiJ4FJgFvACsCVwqsVHZqlrK3TVWWw75mojgt8BHc/NlwA8lVi9YUis55K22HPL18jXg4ny8H2lh\nszpwyFttOeRrJE+Uei9wRz71GYkDC5bUdPm3lbVy0yFvteOQr5kIngUOpudOkwsktipYUrN5cTKr\nNYd8DUVwJ/Ce3FyfNFFqnYIlNZND3mrNIV9TEcwBvpqbuwFfL1hOMznkrdYc8vX2CeDafPweiWNK\nFtMk3vrPas0hX2MRrADeATyaT31DYveCJTWDd4WyWnPI11wEfyIF/UrSXSiXSmxYtqqGcneN1ZpD\n3ojgGuDk3JwK/ECqzPeGQ95qrSr/I9vEfQW4PB8fQFrYrAoc8lZrDnkDuidKvRtYmE/9q8TfFyyp\nURzyVmsOeesWwTOkHaWWAiKtb7Nl2aomzCFvteaQtz4iuA04Njc3BOZI3csCdCKHvNWaQ94GiOCH\n9EyOmg6cUbCcieoK+RX5llGzWnHI21BOAubl4+MkjipZzAR4BUqrNYe8DSqC5aSNRh7Pp86S+NuC\nJY2Xt/6zWnPI25AieJC0deAqYG3SQmbrl61qzLz1n9WaQ96GFcH/Ap/OzW2A8ztsopS7a6zWOul/\nVivnNOA/8/HbgY8XrGWsHPIGgKTfSLpJ0s2SHpJ0+civ6nwOeRtRBKuAdwH35lOnSuxbsKSxcMgb\nABHxhoiYFhG7AdfRM8O70hzyNioRPEWaKPU86fvmIoktylY1Kg5560PSesA+wE9K19IKDnkbtQjm\nA+/PzY1JE6XWLFjSaDjkrb+DgKsiohZ3XDnkbUwiOB84Ozf3JC1s1s4c8tbfYcBFpYtoFYe8jceJ\nwI35+ASJw0sWMwKHvHWTNIU0i/u/StfSKg55G7MIngdmAk/kU9+R2LlgSYOSWJ10fz94MlT1SZOR\nZiBNHuZZs4CfRcTyVpVVmkPexiWCB4DDgQDWJU2UWq9sVQN4cbK6SME+F7gGmDtM0M+mRl014JC3\nCYjgF8DncnM74FwJlatoAId8fewM7AhMAnYAdhrsSRGxT0T8spWFleaQt4n6N+C/8/HBwEcK1tKf\nQ74+bgNuB5YDdwALypbTPhzyNiF5otQRwKJ86jSJN5SrqA+HfF1ELAH2AvYG9sptwyFvDRDBE6SB\n2GXA6sAlEi8pWxXgkK+XiCVEzHPA9+WQt4aI4PfACbm5KXCxxKSCJYFD3swhb40TwTnA93Lz9aSF\nzUpyyFvtOeSt0U4Abs7HH5aYVbAWh7zVnkPeGiqC50j980/lU9+T2KFQOQ55qz2HvDVcBPcBR+bm\ni0gTpV40zEuapXfIe8ar1ZJD3poigp+R7qGHNDnlnAITpXr/YPGVvNWSQ96a6XPA/+TjdwAfaPHn\nd13Jr4hgRYs/26wtOOStaSJYSVrfZnE+9RWJ17WwBK9AWWOSTpV0l6QFkk4Y+RXVtEbpAqzaInhc\nYiZwLWldkUskpkXwaAs+3iFfU5KOBl4aEdvn9kZlKyrHV/LWdBH8DvhQbr4E+JHUkgsMh3x9HQ+c\n0tWIiMcL1lKUQ95a5SzgB/n4jcCpLfhMh3x9bQMcKukGSf8ladvSBZXikLeWiCBI+8P+IZ/6uMQ/\nNvljHfL1tRawNCKmQ5+Z2LXjkLeWiWApcAjwTD51nsQrmviRDvn6Wgz8GCAifgzsUracchzy1lIR\n3A28KzfXAy6X+kxaaqSu9/VEqKoZeau/nwD7pKfqjcBdrSqt3TjkreUiuIKexct2Bs5q0kSprslQ\nvpKvktFt9XcacIikW0njP+9tYYVtxSFvpXwa+HU+PoLUX99o7q6pphG3+ouIpyPirRGxS0S8LiL+\n0P85deGQtyIieAE4DPhTPnWGxGsa/DEO+WryVn9j4JC3YvKEqFnAC6SrskslNm7Ee0usDqydmw75\nKvFWf2PikLeiIvg/4KTc3AL4YQ7oiVq317FDvmq81d+oOeStHZwJ/Cgfvwn41wa8p9eSN8Mhb20g\nT5Q6ltTPCvApibdO8G0d8mY45K1NRPAsaaJU1z3tP5DYegJv6ZA3wyFvbSSCO4F35+b6pB2l1hnn\n2znkzXDIW5uJ4FLg9NzcFfjGOCdKees/Mxzy1p5OJs1ohHRlP57Zit76zwyHvLWhvFXfO4BH8qmv\nS+wxxrdxd40ZDnlrUxE8TAr6lcCapIlSU8bwFg55Mxzy1sYi+A3widzcErhAGvX3rEPeDIe8tb/T\ngUvz8ZuBz4zydQ55Mxzy1ubyRKlj6FkP/LMSbx7FS7tC/oUIljelOLMO4JC3thfBM6SJUksBARdK\nTB3hZV6B0gyHvHWICBbQcyvlhqSB2LWHeUktQ17SOZJuyY9LJK078qusyhzy1jEiuIi0mBnA7sAZ\nwzy9rlv/nRgRu0bErqR9Tk8oXZCV5ZC3TvNR4Lp8/D6Jo4d4Xi23/ouIZwEkCVgHiGZ/pqRzJd0n\n6WZJN0mq7abZ7cghbx0lD6LOBv6cT31LYtdBnlrL7hoASd8DHga2p+c3n2Y7KSJ2i4hpEXFriz7T\nRsEhbx0nggeBQ4FVpN2fLpPYoN/TahvyEfEeYHPS1niHtuhjnSVtyv8w1pEi+BXwqdzcGji/30Sp\nYUNe0j9LulvSSkkbNrHUIiIigIuBg1v0kf+eB3u/ImlSiz7TRsEhb53sNOCKfPw20sJmXUa6kr8W\n2Bd4oDmlNYk0GWkG0uTBv6xt8p8C3g7c2YKqTo6I7YHpwBR6ZilbG3DIW8fKE6WOAu7Jpz4v8aZ8\nPGzIR8T8iPgjjGsZ4zJSsM8FrgHm9g/6HOznS5oPzAc2A05pyOcO84MlIh7Nf64AzgVePeHPtIZZ\no3QBZhMRwdMShwDzSHeTXCQxjWr2ye8M7AhMAnYAdiL9vYHuLprXN/QTe36w7AjcjrRX/82zJW0W\nEY/kHzL/ANzW0BpsQnwlbx0vgluB43JzI2AOdO8oVaWQv420D+5y0qDqghZ85mA/WPq7sNdvD1OA\nf2tBXTZKSj/8zTqfxLfgi++H53udffw+eGwxLF4Ycd37Br5G9wF7RMQTrat0AtKV9U7Agv5X1E38\nvLmkgL8DGHAlb+3N3TVWJSfC0++EL/TuO946PWYP9RrRSf3yKWDnjfi8Rn6etBet/MFiDeXuGquM\nCJbB4lF1YUj6gKTFwEuB+ZK+3dzqOljEEiLmOeA7k6/krWKWLxvNsyLiTFo3G9SsGF/Jm5lVmEPe\nzKzC3F1jFbN44eCDrIsXtrwUszbgWyjNzCrM3TVmZhXmkDczqzCHvJlZhTnkzcwqzCFvZlZhDnkz\nswpzyJuZVZhD3syswhzyZmYV5pA3M6swh7yZWYU55M3MKswhb2ZWYQ55M7MKc8ibmVWYQ97MrMIc\n8mZmFeaQNzOrMIe8mVmFOeTNzCrMIW9mVmEOeTOzCnPIm5lVmEPezKzCHPJmZhXmkDczqzCHvJlZ\nhTnkzcwaQNI+kn4v6VZJ50pqi3xtiyLMzDqZJAHnAbMjYhfgAeDokjV1ccibmU3cFGBZRNyb21cB\nhxSsp5tD3sxsgiLicWANSdPyqZnAFgVL6uaQNzNrjEOB/5A0D3gGWFm4HgDWKF2AmVkVRMT1wBsA\nJO0HbFe2osRX8mZmoyFNRpqBNHnwL2vj/OdawCeAs1pZ3lAc8mZmI0nBPhe4Bpg7RNB/TNLtwC3A\nFRFxdQsrHJIionQNZmbtTZpBCvhJwHJgbyLmlS1qdHwlb2Y2stuA20kBfwewoGw5o+creTOz0Uhd\nNDsBC4hYUrqc0XLIm5lVmLtrzMwqzCFvZlZhDnkzswpzyJuZVZhD3syswhzyZmYV5pA3M6swh7yZ\nWYU55M3MKswhb2ZWYQ55M7MKc8ibmVWYQ97MrMIc8mZmFeaQNzOrMIe8mVmFOeTNzCrMIW9mVmEO\neTOzCnPIm5lVmEPezKzCHPJmZhXmkDczq7D/ByG+MGv0JK0MAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [10, 8, 4, 2, 1 ,0])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Adding 0 makes, 1, and then 2 be right turns, so they are removed:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [10, 8, 4, 0])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's bring back the lower hull and concatenate it with the upper hull:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_partial_hull(sorted(Points(11)), [0, 1, 9, 10] + [10, 8, 4, 0])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "That's all there is to the basic idea of the algorithm, but there are a few edge cases to worry about: \n", + "\n", + "* **Degenerate polygons**: What happens when there are only 1 or 2 (or zero) points? Such a set of points should be considered convex because there is no way to draw a line segment that goes outside the points.\n", + "\n", + "* **Colinear points:** if three or more points are colinear, we should keep only the two \"outside\" ones. The rationale for not keeping them all is that we want the convex hull to be the minimal possible set of points. We need to keep the outside ones because they mark true corners in the hull. We can achieve this by rejecting a point when it is a \"straight\" turn as well as when it is a \"right\" turn.\n", + "\n", + "* **First and last points:** An astute reader might have noticed that our algorithm only rejects the middle point, point B, in the A->B->C turn. That means that the first and last point in sorted order will never be a candidate for rejection, and thus will always end up on the hull. Is that correct? Yes it is. The first point is the leftmost point, the one with lowest `x` value (and if there are ties, it is the lowest-leftmost point). That is an extreme corner, so it should always be on the hull. A similar argument holds for the last point in sorted order.\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Implementation of Convex Hull Algorithm" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def convex_hull(points):\n", + " \"Find the convex hull of a set of points.\"\n", + " if len(points) <= 3:\n", + " return points\n", + " # Find the two half-hulls and append them, but don't repeat first and last points\n", + " upper = half_hull(sorted(points))\n", + " lower = half_hull(reversed(sorted(points)))\n", + " return upper + lower[1:-1]\n", + "\n", + "def half_hull(sorted_points):\n", + " \"Return the half-hull from following points in sorted order.\"\n", + " # Add each point C in order; remove previous point B if A->B-C is not a left turn.\n", + " hull = []\n", + " for C in sorted_points:\n", + " # if A->B->C is not a left turn ...\n", + " while len(hull) >= 2 and turn(hull[-2], hull[-1], C) != 'left':\n", + " hull.pop() # ... then remove B from hull.\n", + " hull.append(C)\n", + " return hull" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can try it out on our 11 random points, but it is not easy to tell at a glance whether the answer is correct:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[Point(x=0.3253748207631174, y=1.7900592822602743),\n", + " Point(x=1.3968712854329428, y=0.4086086096198411),\n", + " Point(x=2.7310024878562857, y=0.05565070635109892),\n", + " Point(x=2.835445111495586, y=1.375183795456248),\n", + " Point(x=2.7309330192147097, y=1.4818235191572668),\n", + " Point(x=1.8813296288048804, y=1.666404092312656)]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "convex_hull(Points(11))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "# Visualization of Results\n", + "\n", + "To visualize the results of the algorithm, I'll define a function to call `convex_hull` and plot the results: " + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def plot_convex_hull(points):\n", + " \"Find the convex hull of these points, and show a plot.\"\n", + " hull = convex_hull(points)\n", + " plot_points(points)\n", + " plot_points(hull, 'bs-', closed=True)\n", + " print(len(hull), 'of', len(points), 'points on hull')" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6 of 11 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\nCnkRkQr7f1PEM2SRRT6YAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_convex_hull(Points(11))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the octagon and pacman shapes:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 of 8 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\nTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_convex_hull(octagon)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7 of 8 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_convex_hull(pacman)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "How about 100 random points?" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "15 of 100 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_convex_hull(Points(100))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Will 10,000 points be slow? " + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 48.3 ms per loop\n" + ] + } + ], + "source": [ + "P10K = Points(10000)\n", + "\n", + "%timeit convex_hull(P10K)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "No problem! Still well under a second! Here's what it looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "27 of 10000 points on hull\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAEACAYAAABWLgY0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvXu4ndddHvg7sh1f5TjX5tAwbajKlF4QzLQg0TYGiekU\nJJpAJKa0DjDY7lDL7hDZ0LHpNKEzSVqSAAEmQAiXQAIPlEIYWmD6lD5poaV0OlOPqkrOkXSkWLYT\n3+PEOufsvY/2O39836v1rnf91paTGOIezn6e75HO3t+3vnX5rd/l/V3WEoDY/mx/tj/bn+3P1vzs\n+Fx3YPuz/dn+bH+2P79/n20mv/3Z/mx/tj9b+LPN5Lc/25/tz/ZnC3+2mfz2Z/uz/dn+bOHPNpPf\n/mx/tj/bny382Wby25/tz/Zn+7OFP9tMfvuz/dn+bH+28GebyW9/tj/bn+3PFv5sM/ntz/Zn+7P9\n2cKfbSa//dn+bH+2P1v4s83ktz/bn+3P9mcLf7aZ/PZn+7P92f5s4c82k9/+bH+2P9ufLfy58nPd\ngefyWVra+96Iz//C9pfzK8Dv/q2t/v7tzx/cZ3ut//B8/rCs9X8RTH5YiF+8uf3+Gz+z5paWdkbE\nn42I4wF86g/8/Vvp82nP5Qv9/Z/BWn82ffhcz9/v82dpKZYud88T8bIbboxP/tlPxo3HXx5PPstH\nP5PXfXq3f2729R+0cPkvhMn3Pl+4Z2kpHoyyuEtLMV+6KmZXzeKqTcQOLMV8x1Uxu3IWV10c/156\naTz+sitj88pZXLX59NL8acQOaBtx6T/zHVfExSsi/uvr8/f/qb+4tBRP1d8hroiLV16MKy5ehuae\nK0HKfYgr4uIVQ9sh/19aqn/rNn3Zd47zddUsrpoN84LYEfMd89gxt8eXIhDXxNo1/H1jCRvtPZ/u\nGIdxsk159xJ/WwosIZYQEfGi2HgR/54uYVruu9z7tB195Is6e+KLbl5awqwdEuLKmF56ZnMJC+Zf\nz25YimHNZldwVPMlzPl9093uOD7dD+I5ztEf2Ofl8eTn6M1/uvP9F+5dWorViNgYr8lz+P9GRExe\nHJ/AF8exl56IP332yXj5M/l9X/ilEe//8+17f3+EywuKyecS7uprIzb+XP7ElVdHxOfrN4gdMY2r\nF/79ZLz8UgMR8YpefxA7YjN2RMQVnTt2XBkRL7FRxMXft2mt267f8/y8V+brKrY7745/KTbiWv6x\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_convex_hull(P10K)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "How about a non-random set? Here is a set of coordinates of 80 US cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9 of 80 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\ngg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "P = Point\n", + "\n", + "USA = {\n", + " P(-621, 289), P(-614, 297), P(-613, 319), P(-613, 342), P(-612, 263), \n", + " P(-612, 332), P(-603, 247), P(-599, 277), P(-592, 238), P(-591, 323), \n", + " P(-586, 229), P(-581, 289), P(-581, 305), P(-576, 253), P(-568, 260), \n", + " P(-563, 322), P(-560, 234), P(-560, 285), P(-559, 292), P(-558, 246),\n", + " P(-557, 259), P(-555, 225), P(-549, 271), P(-543, 321), P(-535, 313), \n", + " P(-530, 249), P(-524, 278), P(-524, 288), P(-515, 308), P(-505, 206), \n", + " P(-504, 327), P(-492, 207), P(-488, 194), P(-488, 248), P(-487, 264), \n", + " P(-484, 305), P(-484, 328), P(-482, 297), P(-480, 289), P(-477, 210), \n", + " P(-470, 319), P(-468, 291), P(-462, 247), P(-461, 328), P(-452, 271), \n", + " P(-450, 210), P(-450, 226), P(-450, 245), P(-441, 311), P(-440, 301), \n", + " P(-438, 233), P(-438, 293), P(-431, 278), P(-425, 266), P(-423, 273),\n", + " P(-422, 213), P(-422, 236), P(-420, 251), P(-415, 297), P(-413, 196), \n", + " P(-409, 214), P(-409, 290), P(-401, 181), P(-401, 253), P(-400, 230), \n", + " P(-400, 282), P(-394, 251), P(-394, 301), P(-387, 263), P(-385, 272), \n", + " P(-371, 285), P(-370, 285), P(-369, 299), P(-363, 309), P(-357, 292), \n", + " P(-355, 297), P(-352, 306), P(-344, 314), P(-340, 328), P(-608, 270)\n", + " }\n", + "\n", + "plot_convex_hull(USA)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "A decidedly non-random set of points:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4 of 100 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\npNcdqg1h46UAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "grid = {Point(x+0.5, y+0.5) \n", + " for x in range(10) for y in range(10)}\n", + "\n", + "plot_convex_hull(grid)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "A variant with some noise thrown in:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "13 of 100 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\nhBT8P7A959r75ABgAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def noisy(points, d=0.3, seed=42): \n", + " \"Add some uniform noise to each of the points.\"\n", + " random.seed(seed)\n", + " def noise(): return random.uniform(-d, +d)\n", + " return {Point(x + noise(), y + noise())\n", + " for (x, y) in points}\n", + "\n", + "plot_convex_hull(noisy(grid))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Circles and donuts:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "28 of 790 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "square = {Point(random.uniform(-1, 1), random.uniform(-1, 1)) for _ in range(1000)}\n", + "circle = {p for p in square if p.x ** 2 + p.y ** 2 < 1}\n", + "plot_convex_hull(circle)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "28 of 628 points on hull\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAREAAAEACAYAAACUHkKwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXmcXkWV97/V3SEbnRAwQEMCCIEAiYICkcgSTEBgQFGR\niDojoywzLsMMjvs4L6gfHBxHZVwYX9xGfd2QcR/BDRKQxQQwhCzQCZCQsAohJCGd9HbeP+re3P3e\nuttzn+7U7/OpTzrPc5+qU1Wnzj116pxTSkSwsLCwKIqOpgmwsLAY2bBCxMLCohSsELGwsCgFK0Qs\nLCxKwQoRCwuLUrBCxMLCohSsELGwsCgFK0QsLCxKwQoRCwuLUrBCxMLCohSsELGwsCiFrqYJsGgW\nSnEQsAA4Xf971X5wVcyTVxH/eRJEOhnaPkzHZqHjBWCLU/x/bzH4fCssvAVumBdtY+FikRtOy0GU\nRQ2wQmQ3g1JMAV6DFhqnA4eb/XKgD73QJwETTFoaomsiMBE4sBCxu3DkUPzncqxSCxcFP9vQK3LX\nZeXas8gDK0RGOZRiHHASntA4DlAxj74A3ALPzCZWsKxZIsJpTp1dQDdaoLhlsvv3HP70sjP43Xu2\nsWfHZvYa/g1n3vYUPYOh5ycBe5r1oqMz/vNZk+GqkIay0KxKi8pghcgog1J0Aq/A26KcDIyLebQf\n+CPwe6fcJ8KQUn++HhY+EX18Q6/7lwiDwPNOiSHixG7gFOAoYDXwekS2OgR2A7OBFQrZjhYkuwRQ\nfNl8MTDNbAS6xpg9Z1EVrBAZ4VAKBczAExrzgSkxjwpwH57QuEOEvshDaVsBnwDYJRTiPhfZilKn\nALOAlT4B0gMsBg4BVgnqFEReQGtBKc0+cRrGQmTGq5TiauBzImwy+41FGVgh0sZQau71MP2I6Deb\nNsDvf423RTkooYq1aIHxB+BWEZ4rQUw3cDtwNPAgSl0BLHG+dT9fhVKn7BIkcHfo94vxtkpHAbNQ\naiVxgimADb3RbYocC8dNjj7b0Ql8DHifUlwLfEGEzbn7a2EOEbGlTQtcsAhEouXKmM9EQJ4B+T7I\nxSCHVEoPzBXodxoaFhgQWCawwPf5ToETDX4vAr0CPU4d/c6/3eXH5sMvhD7bDPKvIJOans/RWqwm\n0tYYs0f69/IiqMV42sYKEYZrImYFsAqtcXQ55Sj0NmkVnv1jZcbvjwLWA/PQ25qjgTG4molfe0lF\nnHbifs5PgU8Cx6PtLZ8ErlCKzwJfFiFB47EohKalmC3RAnIgyJfg/wzHvW17eGf/Yk4Z6GPs/Xne\n3qULdAvMF1juaB3LnM+6BU7MpCX8nP7/skBd1Y2hAnkdyH3+sVMMPQvyIZCJTc/zaCmNE2CLbzKQ\n6SBfAdmZtm05ldOGM7cPdRZToVG2Lv3d3DLtgKgeHr9wJqv7QuP4NMj7QSY0Pe8jvVi39zaAUkxX\niutA1gLvAZxtzPbYI9QddGxHH9GmbR+KEtONUnMdQ2g8tOH0bhINoTmQVJdnyF0M3J5KT2r1yBMc\n+JeVzBr7Y97M0d5w7Qt8DnhYKS53/GksCkBpaW3RCkRPW/YYC1MPgn33h4/uEuinsnjrU+z/xl7+\n9i1xpzPjWPdIH0uvxxMgGacbxgT6T2BWAadUIiiK0TIXLUDGoAXmPEQM7SW76nCPnvcBfgGoQTrl\nrfzg6hu54AJgpvfwp16EJ5+A557UmooL6wGbiaZVod2pZJ22nMWvh+9mjhhvUzybQr7TDW+b0BPY\nLgRPUMpvlcpsR8raS3Tfep3+LBdY4fu7G6QT5O0gveknXhcsappv2r3Y05k2wBSe46fMWzuP2/rQ\nb8f0bYr3hp1A3tONoLYxiD5lWeU4h/lPUMptlcJaja4fh+516JOZZO0pyWHNvG2/T8pM4Gxgu1uX\no2p8Tyl+BLwdBr5KvGevRRaalmK7U4FLV8S97eYxT5w37vxMg2VQ+1geOSnJoiPqr+G2faKv/vxG\n07DWEdVq5vvo7hPtZ7K8yhOZlD72ZrUDFyyO10T+YT3I+KZ5p52LNay2CErxeug5Ou470b4Wq4Gl\nZBssZ+NpHzOBf0L7XJjaL1xtox/oI2yg9Rs6TYysunNxRlB/O6vRQX8u3ePQGtBs4AQDms3g0qs1\nHbftNWh7ytbAM9E+JRgH9z4IWK4UCyqjc5TBCpEWQCn+CrgRVFz0LA+w1zK0uj3b4BQivDhNBI8H\n/dwpaMFzGEkCyPR0RH9+IeFtVbCdU9Au8qvQW6jqEaT3JvR4zgOOQ+TJXH2KYgbwe6X4tlK8pGrS\nRzrs6UzNOFitP28D028QOvaATw/BI6tgSyAwzDlteSWmpyKa+fPbCvLA5HQkal/pRAu2IP2eDWcd\nWsh8ETgCeBA4kyz7SHX0Jj6THKc0eQ/42svReVEAngPeD3xX75wsGt9PjeZyCI+cM5a+YRDpol8O\nYOPC2GerPhUpWvx2DZPTkSjdF0eeiztB8uwuhWNnEmhf7j+BSXgm94kPyEEgvwjZS34PcnjTPNYO\npXECRmsBObWDwT4Q6WRAfsz5A4nCoUb378wSPO5NWuzx9HgLd0BgrUBPzDPJArKs8IwKPZeWZIOt\n57q/IM84O27054M84RMkO0A+BrJH0/zWZGmcgNFYQE4C2QYiHQzKD3iLG/GadeoSXLAVuH2nlqCW\n4PpUSOqCji7cFaKjeodjF2+agCwjPKMajmk0cTHfGm9uJ4NcB+KPa1oB8uqm+a4xfm+agNFWQF4F\nssVhruGpPH1x6ts8qZRk9pi6osIoqgn0pi7o+IU7IN5q6o9dvNnxMUXGJ+kIOV0gVbR1BHm1Izzc\n7g87wmVy0zzY6tI4AaOpgByHzl/hMtVFheuryk6SJoyimkBP6oKOX7jLUzWReHrKa1dxWoyJQKpw\n6wiyh7Od2eETJk842x7VND+2qtjTmYqgFMcCt+ClJrxUhK+XqNA9+XC9R4vFsWSdWuQ56YmjScP1\n9ViaWkfVsTlFT6kqPt06Sd1x7IMc+bVN7HO89+mH18PjT0L/zuDTozAWp2kpNhoKyMtAnvW9jd5d\nSd1mhs30t3qeN695fcVsN+1yClXd3OwySA+h+r/Me9Yrhp7b3WJxGidgpBeQo9FpCV1GubwlbZue\nRnjP5nGnzxvMZ/a7Jk+hqh/7WIP0TZx5Jsi3dychYj1WS0ApZqLTEk51PvqACF9sUfNz0A5c2e7j\nZvk//O70bjCfCcx/F/ZiNd1KmLrftw7+Ph+MdqLrB1afxW/uFOEi2HB/g/S1FFaIFIRSzEDbQPZ3\nPvqoCJ9rkKSyCLvTp0fwxsepZP/ONKGRJzh6qCA5UWkEBVl4rP4KeC9wttevrbtNhnmbCqAAlOKl\naAFygPPRlSJck3gvi/5R8nf5GnfrWYVm5iPR7uNLC9cJ+ULvowbSs9Fv5Grc8IP1r0O7xQfTHVQ1\nnvnp0QZhXWahk07fROjKjC6GO+sJEmpDNL2fGmnFcYF+1LfP/ZRIZJ+cdJRazucjWk/6kWzRkmUo\nrTt5UZb/SvZY++sqdqQcdKrL43U7X2DBW5nx3KmcNjyH+dvg/c9oG8mVAu+4tWkernxNNE3ASCog\n00Ae9gmQa3b5A9Tp3l11PeltZAu8JANpkQWbHFuT7L+SNA7xQja5L8lOeEn1ZHnduvldBkT7zYjA\nzt9y+mtBnLSLshlkWtO8XOm6aJqAkVJAetiVSk8E5PMBh6Js9+5gcFi5BVff6UaWoAoebcZd/5D3\ndCdNIKR5ucYJsXBdlyT2JV2bidJk5nXrd70f9teNvr7C5Z2bR5MzWuMEjIQCsh/Iah8TfCmWCZIY\nzYsxGXT+zRe9Go1XqX4LE2wr661rtvCS+mDaXjadYX+VHoHtDg3bBWZIVKMx2aKUocmvlcz3/xbk\nv308dGnTfF3Z+miagHYvIFNDMRJfzf0W0W8oV70dFnhf6oIL/ra6GJr4upMWdpww9MfKmC+8rD6Y\n+7FkOcKlaRBhwZ28RTGlKZnO2N+B7AWy0eGjrVR91WlDpXEC2rmA7ANyv0+AfB2kI3ddUSFyTuiN\nlRyWXpcdJGlhpwuW9DiZZOFTRch/tiCNagILfP3Kt0Wpj6fO9PHTLYX4qc1K4wS0awGZAnKvb8K/\nXVCAdDvMHLiywCluAFt+I6Z52/Fv7+RFZbJd6ReYn5OOMtc/xJ2AJPUrflzL01BZWgZHm3X56n1N\n83rp/jRNQDsWdM6IJb6J/j5IZ+66gosyskc2fkPH7/+zjmFNthDhKNjq7QRpfcg/jv4TEP+2JDgO\nRYy15vNYeksJ0u1zE3gRZEbTPF+qP00T0G7FmeA7fQLkxyBdheozMzaWMeClaTDZAiq8qLLoKbcI\n0zQHk6C/BeJlJAv7kMRtyao7xaphSwlymstje7Hp/vs4dsTmIWmcgHYqIBNBbvMJkJ+CjClcpwkz\nF1mY5gKimlOP/H0OO3sVd8KLPuM3iCZnY/O2NbnSIGb0odKj9fG8eJ3La1dy5eNV1dvq0jgB7VJA\nJjiGLleA/JIiuTPjGdBsUXq/jaro0edMsnjFaRqV7Osz6PLbIpLtGWbC0OTEJf+JUJ4+5J1Hw7Ka\nmacdzkMCImPpk0/zkQubXgdFSuMEtEMBGQfyW58AuQlkbO668jKuf1EHf7s9s468TF3xvj6hjTRj\nbZI9w0RTS9ti9Yh2KuvJpKVoH+riPej+HQt6OxgUEOlk4J7CW+cGS+MENF1AxjpCwxUgv6PotYl5\nGDC6qP17fSnFxHEaRysu605a8J7AiyZT9gvDJE0pSWCabZWyj9Hj66x065I4dtB9JKu+65v2f2l6\nTeQtjRPQaOd1jkz/fSK3gkwoyRxmDBhd1OeIF2i2PbYOMyNkj1RpbEwXFkmL191qmAmZrDrNxzDO\ncJ19jB7f53r8R2L66WjCKx0e7Ac5pum1kWsdNU1AYx1HxoD8xCdAbgfZM2HSs+0IQXtGNgMmq/m9\not214450TYyQvZKkyVS1BTI/dUoTMuUd0swM163bnpiNaSw9IMeDDDpTt6yQPa6h0jgBjXQa6QK5\nwSdA7vo4n0x7c5p6ShYx4s0X+IdMRs9vhBTRF0qlq/FpQjI7WjZ+q2B+euS3By1w6ip3mtSik5XC\nJYUekE/5ePKTTa8T4/XUNAEt7zDSCfI932QtfT//cWChN67HGEWNeGFjanEDo36mR7wAtB0Cq1IF\nW5bwy95+xG8Vso2hYSc8f4Tz/Fha849nrScrpUoCPc72epnDl4MgxzdOq0FpnICWdhbpIBhJeR/I\nlEQhYPoWK/K207+5NNRu9C5bA+bzfe/vR78kBcvFPx88fjVpM9vD1eR32XSalnbbuhTj0WMcu4g4\ndpJxTdOUVUb1vTPRm96nzYRJ+8M44CMPAK8R4bnUO168O0rWk3Z7fbH7W44GBoHOSLv5O9uNTt78\nBWAm8JDzzczEuoP9dp8/EtM7YYrejRPfbjKdptD5WB8GxgN9wGGIPFmorgahFB8HPuX8999F+HCT\n9GSiaSlWr1S/YFHwxNQtH30RZN/A8+lvzmp9LKJvzHQNJLu++Bid7D75DcFmd9nG11PEFd7z76hq\nu9GUJmJqfDfmW+kCWerw6xDI3Jb0oyi9TRNQa+cShcjb7szJJHX4WJQ39nnMm08A6N8F76ypywCZ\n94i4fFtmd/FU0Y8ifTEUOOj7jNzrOXtLuR7UXHbTKyMG+nP+IN91Clkoev+KH96WYDF6C/NggL70\nu1qid9ZURZO/zSCN/useit5xY4IOQOFeh5I2DknfmfcjX1/S6gm1KcIq4F+dbw8HPm3W/QbQtBSr\nsyRrIgVuIfOr3BWrr4VKvFHUpS/e4cz7bThJknlukPTxyYqbuaSQ1mPuq5OU/Mks+C941JzUj4HA\neOXpi3mC6W7Nv9IJcoePd+c1vaZi11nTBNTaOS5bVZkQSWM+899VI3jS/Cr0d36Hs2gCIU/t95Ik\nlaMlfksVXGDBeCBTO0ie8Y4KkffGLlr9bJwQXiahTO2+fiRndcvfl/CcJW6XQQ4H2e5M5yOxDpEN\nl8YJqK1jyAT4xDZ918fH+yfzpmVdnH+71k5OvL5w3eU8K4vZAKKOWWEjao/v+7DDWb5UhvnpCvt7\nxAm15Kzr2X02t/dkJ2pOc8FPzNTuPJ+cXzb//CV5I8dqMyCX+16C/9X02oqstaYJqK1jyFW+gb+4\nsrqL+YSYC56wxhIVQOFFNT/0fY8kvVFN2ss3FslbquQxyw6GMxFOpuOcfULl36L6aQxnoSvqCxTd\nHiU/m5TguQMd1+Xy8xlNr68AfU0TUEun9C11rgp4H0VSG2YzR5EYFFOntax8HElvUP/Ccb1JTbxg\ny2hIpvYA82A4U+FkQk+8UE5y889y5jOfd48WM2GeUdf/5dI3KYa2gYhiaCNI22RCa5yAWjqF/MCV\n2oex5rWJTFOkFH1zmzBgdj6OqD0hbSFnL4ryR9f5FpZpGEHx4+b4sQlrafXlVInv63CIBnP+8fXh\nK7zb9WSVsfR9pzbac5bGCai8Q8jJ7kDvwY4bK2Wasm9u8/rj7ArVvCFN2qur5Ndcytps4k6H6s2p\nEt9Xv+0qH//4+jAM8lpuFt+25txa58uwNE5ApZ3Re0f3moe+b3HRGypmmvo9IqtYPGXaK2MjSW8j\n2bBYb9/8QqtHqhKaJi+U6NiWMcrvFNi+nuk792TLkMPjT4Ls3RI+SSmNNl55Z5B3+aT0Jyp/07by\nzV3HYjbvX3Xel3Vrb2Z9CgvJ+lzsowIzzkiej388mnsETtyHv/y9j8+/19LxjCmNNl5pR5BJIE85\nA7vx3/jwfpInSVD6BIYZod43afR0Il/G8uJ2m7ynSNnCITvSN84lvrzwzGNQLV5/3CXt4VOlytMS\ngCh0InFXkLypNl40oafJxivtCPIZd1Cn8vS7Knn7mausVav/YaPcQGz7yYuwWN/z2SzKGUnj6KxK\na2mFQdUTIv74I/+YVJfiIJ7fe0A2OTz/DMjUKuvPRUtTDVc8oDNAdjoDekc/XdXYLsqkASxTgvX6\njwf91y3Et13WbmP6pixrJI0/iapr3qo1qCbTHzammvq3FHoRgbzVp43cSN6L5isqLW+wlk4gP/MN\n5gm5GDxtIrPqSY+p6BGddKgntY1kenoE3if6Dl8/UyY5neVLpFRFKaOax9FZFe1VG1Tz8IZ/TEzG\np8SLyNnW3Ojj/be2Yr1F6Gii0Uo7gJzuG8RvhSYnr2NQUqBWmsdjNKYi6n7dk4tZonvruOsjw05n\n+WM5mi7xGko1p0VVGVSL8kZ2nXN9/5puCyPjADLV2c6Is705oNXz2DwjlSFeJ29Z4QzgVpCeQnXl\nVaP1hC5wyrkS3vtqDUR85eJcbRRxOmuD+ai81LFdzCuUqs8l0yPBCOtsLSljHEDe6GO3X7V6W9M8\no5QhHnmvb/A+UpKx8uzv/drHCgnvfTVj9DmE9UlQEzFtI0lVdrWSfJ6PI7GUiTlKH9c8zl7VbQ91\nXf4Ia/8LopRnMcj/862Fd7ZynppnlKKEI3uDPOcM2sOUTWjrTWT64tTfDfgYoV/CsR26rhUCg86/\n+VXqZFXfXQTZV22O9GK6gE2FQ7ms/FX7logjUCoRZCBTQJ5wqn4BZHqr5ql5RilKOPJFn+R9o8Ek\nZL+1TZgxyQ6SzCzVHe9FmbDa+tuxmBknyx03t7Yvbvu9Er4/uOQ4gPyVjzV+26ptTfNMUoRoZBbe\nbWF/iB0sT3CY+wjkY8b5knRHSl3MGqy3T+rIJToSS/6tYnN2pJrbB/mGT5D8fSv61DwD5B8k5UhZ\nQWfCflnCRLmCwzViSeZbu/r9b1bQnKl2FPa8nC96m2SFiOl4j5aSwTfv5z8OHEuf67m9DeTQumlq\nflDyEoy8zidpr0sY6LBG0RsrGOImpA5mjBcEJnv4ehzKbCk+d63+vQk/hL7/LacP+NbIIpCOOseo\n+UnKQ6y+ZnCNMzjPg7wkYbDDfhrFLsiuosS1U/Z6zqb39rtLKcsjVfNYtgf1ru/fzVfEJ0j+sc5x\nan6i8hCLfMA3MJenTFz4ekqzC7KrfGtkt5Pn1MHveel3ex/96nuTpXwIQdU+Jlke1LuOkLcyUQ5l\nrbtWtoMcUdc4NT9RpoQi+4FscQZlFciYlEF2j0BNHHjCrtF1xcEku0dn//7E2uizJW68/YK6rLt8\ntRpjtq3NdWbbeRNnroHhYWfN3EnVaUKd0vykmRKKfM2nhZyZMIBhyW9+QXaddoYqtAZrB6m/xG89\ny8YHLZCkU7x6+3GiQDfIF3zr5kN1tNfWF3p7F3JP2BMOOU5/un0T3P4/InddFvODYhdMl/1tK9Du\n9I0GKDUXfTvdGKAfmIfI3Tl+342+EW+F84l7abvZBek1QCnGA8vgmiO0V8Cj98CO7d4TG3pj11IO\ndJWksWZMPwJumBf6cG9YeETs4yJbUeoU9FWGK3NNWpnftg7/DAiwtE3pGxnwL/bgOLrXpbqC2vy6\nVE/Iu0Ljn4ler2kukCqCCH1KcRHsuAs+oYATgk8sLN3G6LuLV2QrIncXWmRlfpsFpXpQ6lKU6inw\nW5dBbwI+XzVpuxXS7sMteh+xruNCgkJDqPL+ZhMaEu4cFuFueH5DXU2PLiFiekFz6+nqAR4Grgce\nRakZOWuo8wLs3Q3pY5n3ReIJpa8Ag3hCYyllL0g3RfqF4w6eerSu5kePENEL9T7gNuAOwxvdW4Vz\ngfHO32OBW3LS4arZrXmrjW5UPZZ+odQJvAdXaNSp2SbTkPCSqc/42eZCZPxEo8f0grwNmIG288zG\n2/u1w1v8V8BO3//3y0VHUTXbIgo9dmcD7wXOThzLOO01XqP1C6X1wK8bmJ9GXzJtblgdsxOucv5+\nZKlnVd7QG3pwNnBIQiXFjWVVQeRJlJoN3IIWIPnp0IzZcsPcqIMWADfhGkCVigrlsJFUG9yJfOZq\nG0qdjdZ0DwFuiq0zP41xht94GB0KbOiFt4+Fw0/U///LWvjL4zFrKT8aP5tPKSA/dM63n0kNa46G\n568InMsXOeuvx3vVepk2XUz8bfImka7Sh8csPqYQXzrBq24Onm9WNabNT2p6hx93OvwTw8FPDs+v\nciJtGbnFxIs07pm035m5o6clusrOueo5rmVfiJ5SQG511tQ9VY1p85Oa3NlDfZ52V6QOfJ7v0pkr\naSIvMWKANhg3W4zn2iQLe1IS6Wj2u6Q6DSNvfd9Hc656zwxI8AqR3BoPyH86a6oPpKuK8Wx+QpM7\ne5FPiBxvPDFFtIj0iUxOQ5gvpD8qaKwAGhklPp7G9KpR48hbCQZoJt3hO1xSE7nYt66OqmJ8mp+g\n5M5+3eno1ojErHp/mjyR6Zceme2vk3KC2C3TSCjReYq/7yf790lbnV0Bc4l8EKzDvUKkEL+AHO8T\nIm+pYoyan6Tkzj7kdPQ3uSamSORkeqRt1l43a3+dtMe1AXUjoUTnKfm+n3T+ytrqpOdcDQaLljGu\nTkBnBBSQq6sYo+YnKb6j+/mk5cdzTUzWd8UmOivNYdb3+QWULe1Rko2sVWd/N9WaS2uwIA86a+tX\nVYxRW0bxKsX5wI3Of08TYXHCg/nO05uCpjN6hp/0uUV7oa55KhKZXTbSGFCKH6Ej7zaIcFABygNo\nV49V17lnAFgS+0R7uLObxeUkuT+3zi3aogyqnieXZzTyeiKX9k7tZsuDzp/TlWJK3t+H0e5CZKkI\nfQnPNO/O3i6CzKJeVBnAqeu4AzfGC8gloMqEQOh+LLiey97hfnQoD7/K+PcJaDu3d6XeejvMfKX+\n3/PTlXpyUULilObd2eMFmXVNH02Ic4Evp5HMQfONwovxuiWmzeRtepEQCK8fs+ZyV6f78f48dQYc\ndnOuukJoOyECPzjZ95/pusQkTmmPJELlBdlIsevsvvC/KGYRXvTRbGbl5tLTVDRPKXVSRXzh9qNr\nOhtkMpt5gb24j1fuU7bidt3OmCFur5pH9SyrppaNrrXboZGAFcCD6CRDncC1CWkm7nBK1lwuceoc\ncP5dGvre1VTC0ehl+XWXLaUDWdHF4HKAHYw/ukBdAbShJlICeVTPqtRUU9UyXuOw26F2Q3ietMZ7\nBXAzer3MxJsn//wdid6idJE2l7q+k8irQZflV5/mPp4TLtvB1WfCZECOU2r1Iv1QsXyrbShErgr9\nfxxT2DkJpboNBi15UUYXcesWcDIDtINdx8JF8jwtQc9NeJ788/eQ89nMwDNxL4/0F4+rqRyJzk+y\n2vm8PL9qQbJyPD3H7uALBzifdqA1aQrnW23cmSfqCCPBcqWcymnDRo412Y5d4asAikdeVuVUZNMD\ntE9Jv9CsJ9MZMRrz4qaoCN6ZnB3V67rCm/OrWf+6BZadymnD0XUmAhcsKjJuzU9cmKBQxyZxnlzK\nS71JjR+Y8D234ejLtPDq/JGXBSevFAPYUn+JzlO5C8N0nI0bdTss2mU+KiCiv0vj1/lOvUWEyFyB\n/nnMixEgUliItL1h9Wi29F3Po/GONXGGyXjHoHgHnWQnomp9UGx6w5GB8DzpTGVV+iKNR/Pq4Rl1\npjmUfR6dma2IIX4FsEq0kbgytL0Q2QMZh94bxuXDNFvs+RdxdBKrOMmx3qntj+A8lfUODZ/E7CCY\nxnN9bJ3J/Fru5ebU+wB7Lcv1uwy0oWE1CIUo4GCnPBn62twwaXKKEjzz93xQNKp0OLIYCSjrixQ+\nidFw+XU9Ou4lvs54fi1viBfZ2qfmLHspbzv6UY4YC9DJ2nuH6N9WNN9q2wXgKXWVABzPEpnIdnUE\nj3E9j64Bjosd8KzgKFNnrugNZp6giAY9nQ30ZdZpMTJRtQNZtO7iDpJVBAMqNfezfOD2D/HZToDb\nOfmMk+WPvy9UF7SvYXU9092ky2slLc+CmaEs2zCWfYLiTwpTKs+lLW1cgjyTPNcjOSsd9LyPL24C\nkS76h59l71J9aFubyEReVOgbxS5DJLyNMUWePWTy/je4R70CfYZvb6MbnQjzzFGE53okexo7V2Zs\nY8/JAMN0PLOPPFdKw2pbITKevn5gHZ6zTT7owZqAdlnONoxlGV9dg5s2ltnb6EYvwi+T1UTnOixo\n3tKSMIv548e3AAAgAElEQVRqMBs4+lle0gEwnr7yW7TGVatQcbczQ6j0s3RzlXSNwDli6ugTX1dS\nZu9o1m9bRn5JcyDzvo9P5J2elLv6nLrF+HnZHO4edrYzt5alofkJCxOESAeDfaK9/CRinwgOSI/A\npRGbSdC+IaKde7rFxNHHdOJtouXdu8Qn8p6fwi/V59TN5s/EK1XGsX2jszy+X5aOttzOTOYF93Jk\nQcckeHEIrjqo1AzgUeB64GHnQm8XK9BbIRcHo6MhTRx9/PCrrUfjj6hsh6RIFtUjyGPJ2w+93f0R\nwa2PIpkn6rgvN54H9Vq4lySbjcjWHYyf5PzvL6WpaFyihwqIHMQ6cSR2v8D8GKm7XGCjT9MQgYtD\n0jacit+f6l92aSfZkt5/PWc4/sG6so+mUuRkJrr1yYrHKu62nkxvOIl0r4/PIyeNGzjwrMxE6DlK\n8xMXJgiRQ1m7IzIRQXWwX7ztjgjskLhj4OQJTk/PH6xjgSRtrWzw3OgqyTwWjl/xC5qgQEjjCZMt\ncDEbR9JFVxJ4WTovxfVM3xWAN4XnLi87bs1PXJggRDoZ+HNkIuJ9NXYKPCYwo9CAm//Gahy7Q0nm\nsaSX2bAjaEzvn8m6Da+8nS3Yh+Da0O0P3MsrdsmYN/CTj5Qdt+YnLkyQ7tztKQOUbDWvl7msxrE7\nFPOTmX7Jey9u1m13VRlfkw4QHE3kJs7cpYkcxprXlh2z5ictTJDuXPTWO1tsaZfi2Taimkr6b9Jv\nu4tPRZDfhSBjC/4GfvJpn01kZtnxaNcAvO1NE1ApbDLmkY24lIlwS840h/6TlIOJCygNBvytR4f8\n5wv61LR+gbjTTaeNn6nAiUzp05m2POJlNAmRkewibZE+f1npHYJHxGZHvJ5n9CEUcyGYjZfvdRD4\npxj6pjr/DgGbDetNhBUi9cP6k4xsFJu/sPDRKJfTxgz+360imk0eYF/n32dFGDasNxEjW4hUFYvg\n1dNTQ2xDHU5GFq1D0fmLCp88iamKZsMz+52riZR3NKMt84n8rcDATujfARueFLn7qIQHo/k/NPLZ\nHoL1DKITNQXziZSFvbh7ZKPI/Jle1t2AvUwp7gTmAreKML90hY1bukMl6IT65s0pFujwcVhy3EK6\nJTvsnBO1aOe33NugPFvco9ZLYk9i9PfZJzbR50vzFsgah9V/WEU/23U7Y4KwmpkWt5CGdWgNBGCY\nMtsOa0Qdvci7dXbydgDXATcl/M6/5TkcWJxYf/gi8HK8Vel2ZuQKkWhm7lVogZBXCByCl2t2EHgP\n7tYov33EGlFHI4q9HEx4IS5QdFaCwEq+XjMHlGIP9NV3sNsLEfAfh4GW+oeQnBk+CWGN5gbn8yIa\nRbIRrj0S0lgUQ5GXQ7ZBVvPoPGCN77n1eLx3byg6vQq8xPf3bihEkhdinCOP2e/jrdnFNIoky7jd\n5ox0rCOvlmt6uqJTfx5H/F03/i1O1kXgptjX93clQqR541PE6HOR6PLWPnjV6gQjVFKCoGQX5HxJ\nm6sNuqsjIY0trSl5jZ/VtBcfyl9BDBfIGb4zhHlV0Nz8JEU7ucLp4NLQ4JpEQCYPcFo8QfJkVhN0\nZyOBR25p4gWQFahXooC8zSdEjqqiznbczvzc+fd4pTjQ93n6HjPNkScpniArc1VVN9bZazRHMoo7\nCxa1g4W3OEXvp4lve6rv71FrE/m57+/X7/qr3EKMxhNo1G+ncCcTqEwoWVSL7DSI+fmurB2szEss\nvW1XiAwDm3LXHYN2FCL34EU3nhf4xj+w+aR8XDxB/cex1qDa/ojOUTT0odiCbvK4P61tV4g8JxXE\nzUAbChGnY79w/jtfKSZFHsq7OOPfJq2IaTFnJHsE3BTCc7SYaoR+kzFTaW27pzPVnMzQhkLEgbul\nGQOcFfN9fikffpu0xk5hxkhWY2kS/jlajz5iLa89RJ0hizgvVtN2kLcr9VaFNgzAA1CKscCzwJ7A\n90V4e+gBs+CmdoB2FjoH+F+SrgONXhg+D8+JzqJuaH46AX1j4qeBmVTJV2mXxdcNzX/n7sXxp77A\nS6fD4XNgzHjY9hd4bBVs6BW567JSbTR+hJZ8FHWjcwz1PMiYmGOw9s97auqbYo+A22melosO5qxu\nDpryE9JHxdsF5BROGwrGmLrlgkVl22nX7Qx4W5q98ML8PVR5BFsfzLZd9gi4afjnaSawveI5aMo+\nci4wHqADqW2tt7MQ+V90+jYIn9K0C7KNoebMMzKE4mhFfYvcyxdyNvX4faThV0AfwDCqkpOYOLSt\nEBFhE15aufOUQgUeaPVpRrg9E2Oo1TBGBvLMUx6+C/LITRRNSlXU8K5tcIcBlyxh7z/lbtcQbStE\nHLhbmoOBl+/6tNWnGfHtmW9V8mgY9qi3GZjMU36+q8pXpHg9Ik8i8o2dTBpXsO1MtOuVES5+jnZX\nB72lud/5O25Qqz3N8Keti2/PVYHdE6LyKnDYim96TYBFq5CX76rikfh6cqVW3KcbrkIbU9fcBYMD\n+vMNvQVp8tC4ZTyjgCx3LMn3xljTi59mpKWai56q9MS2V/UJkY32be9ShO+Sb9HLl+YweueucVQ6\nyL4gO5119P2qx6X5ickiEPmU70hqeurk5GeG+AmIW8xee8VuJauLSW1pbSn74qjivl1dj/ELB+Qj\nvjV0ctVj0vykZBGIHO8bgPdWxAimFyvHaR7lGSCbydrb/8WWMvNb1X27Ri8ckE6Qdc76WQ6iqu5T\nuxtWAe4FHnf+ruqoNzutQLy1vv6gKnvUO9qRfZxsYlw3P1E6Gy/T33Va/lSLtnR7D0MprgPejU4N\nN1WEFyqoNHiXiImRqil3e3uXb/0oM8Z5f5t2j42Ji3yO9pTi12hBshU4UITq+adx9c6ggJzp29Jc\nWMgwZaYamqZOzL/dKEpzK7ZQu3spM8ZRl/kFpebIfKttYlA9DGTYWTdfrmv8mp9AEyI56evwr4Nw\npcD7n5nD/G2nctrwhcx4tpJFVfepSDkmtSc2dZcyYxz87bDoFJzFc7Fm2TryGVQ/63v5zqpr/Jqf\nQBMiuWBRXPDQqcwbrmRR1ZjTMu/EGzOVp9nUd1q0u5Qyp2LebwccISJO6S08J2narrlBdTzIcw45\ni+ocv5FgWE3EDjq3U9bJy7up7BDcO2v051V6jRaPzYgzoAU9Jx/G5iGJh6n3b5aR0ix94pnouXBx\nMEUM77qNOcDEQrR6WAjs7fx9XW468qDxt4BBSdJEujj/9greQmEt4RznLZLvioAsm0eVfiZV3x88\nGkt1/hh57GXlNFrd1nJHoxl2/i5EN8ifHNZ4EmSPOsd6RGsig3QMZT+VCb+W8BDwn+hLg7LvR3WR\nFlPhT9SsNZCbSMvnmZ/mPppJwdfuaH3cSt4s7VENZ7bThnLKkUXoVorj0doMwNdE6M9bRx6MaCFS\nCYLq4RXAQaEnTNTSeEYLCxc9seXzeQZpPgwbJRyHcuH9nvBfZ1RP3qz+8S+eFU4b4pQHc9Ot8W7n\n3yHg+gK/z4V2D8BzsKFXb/EAph8J3fvpv7fGpxvMCz3hdzsT6QY6CfptYMKASYFWYeEivufi8nma\nBxG6NGtUMw6jCdp2dApJ/hhp0CkFF6PnZxWew1Z8PcUCJ6MvHpG7UeokvMu6l+Z9MSjFFOBtzn9/\nIcLGPL8vhMb3rvn3ei/zmQK+mLG/TAuwS/vOtV2Y2zCSA62ClvRg/TZOpspi6ouTdrKVdo1lcn35\nT99qipOazPP+OJnTWzHuzU98EaKRm51BehFk75QJSru3N8+dvMWNc9nHdWaOa1U72I22kj+fbb/o\n/KPB56NG6+yj2qICoeI4qbUcOulgHt0BIofwyI61HDqpFWPf/OQXIRo53SdtPxYzOclvhjxvjeJv\nmKKeqaapCawgMZ0r/7jqcqkknWzp7xeIPhXZ6QiQGUbzmf2yqP0FcBHfutzt0ue4YtCIXysozU9+\nEaIRBXK/M2BPgYyNmbT4N4PJWyOo7pq/YYou9iKpCYqO32jVaJK3jn6X9OXiaSA7ff/6c8b4M777\nPyujidbzAgjN5Rh2/hJExvOiPMNLHmjVHDc/+UUJR/7G9zJ5V8IAB20aQeGQ5RHoT0hkuuUottij\nv5sfWOhV7Z9HmkaTV+CFtYHguA44xR3jiwNzG59DprzwritsITSXZ/HrI0GGQORgHv15K+e2eUYp\nSjiyB8hGR4is3JUnIaq+xr2J4rSTuZLETPkntsje2P3dGoEVETqr2D+PpDic6uxR7riuEFibODfp\nmkxx4Z1P8y0cUzWb5d/0vVRf2cq5ap5ZyhDPZXfroLwrBS5e3sX5t89h/rZLeOmQM2ELUt5E/j1z\ndirEfExTJMrX9Xb0x2BUu9CzGLqdtjrVJu+Z73uBJHshJ5+wlRXeJrEwRbfAO/sYe79i6GlHgNzd\n6rlqllHKEs+Ff4xzh5/HPJfx5vsWjauJhAPZ4tTY1mcXqzoaNLmdpIXiGhTbY6tT5RGoidG1uX6W\n1XxP3JenLvLx/zta3YfmmKQK4tOje8N+GcG/gxPRvL9GvOpd/4L22g1rQJdU2m4xlb2aE4+4mBZd\nljv9zhejUqXwqYD/QG5zeP85kHGt5t2WNlY58QlCZArn3VcZs7ayeHT4t2H12i7iNaCo/0T5flVn\n0M1TX1BYrBFXs9NjPOzr9/xa+uJpecnJikrwX8j58t+b4NtRGTvzPHtsIY+7cLvkNXXpgCUUifso\ndvGVP8ZkBTp+qItq88hWnZs2XN9FKLUgod9znOe70HFGR1XcdnJfND13AL9zyh2J6QSK858bJyPA\nVwv8vjRGpRBpe2Qt9iLXbxa/atHf1knAtwkLsLgrRPMJq6rvuvXXNwx8kbRFGsTRzjNLnHoGnH+X\nFmg7qy9xUbknVJWrRikmAX/j/PcmER4pW2chNKH+VFXgxOv1luaCRXDFE+5Jzb6cvbjxrUmy2lqP\nAbNah7QexybSE6O+F3PAivPbKT+Wl4h34iYOTXE5Sd3tTF+A7uInaWa/89p284OsqHLuQd7j28qc\n0xRfN9JoLR1BpsPwThBZwO+Gq5ikSku8AbPfeC+u6+gR7bYdPbGpzyEtbJ+5pLCwqsc2kp3ExxM4\nrfeR8Y6Y58eMZWEaHK/tFY4AeRSksynebqTRusoMem9wJfMtnBZ9KzVZogbMfNmrtADZ7vx+e4og\nqdohzX9MHu9HY3paUYezW3CRmgRT1nMKZzIGURrStTKvzshzIKf6tJAPN8nbjTVcR3kj/zNjLH3D\nIHI8S7Y9y97tqInsFH18G3V8S//9peLjGoGLW0BnvNofPTbPGxWdfyFXcaxa1ylc/jHwp4JIipdK\njTYG+aHDCjtBpjbJ2401XFeZwLZrfWvtjKbpSWCgGZI3F6eJJmJOg8kbM32xefXkU9GLLOQqtkF1\nOpalR43Ht5t9v4z/e/E/B7I/yIDz8Xeb5utGG6+lQ8hUkG2uCzD+u0fbw0PRvyDyeaRqQXJxSQFS\n3iYRrCfeE7hYnfFzU3YbVLUtJrn+sDd0crtZWlnwe3+0cTfIx32yZW5jvOyUEXGNZl4o9d77YOor\n9P82PgBbNnUx3Plm7j/qB6ydRNL1hPkaKXbtos7DuRjtZ9APzEP7htSPvG0n9TFaz9mAvr6jyJhm\nXR1Z9vrSVoy5pvEEYAI6efYS9Nglt5t2nWbw+/U46RkV0gc8CkwDlgGv1DKnQTQtxeooSTE1p3Ja\nNYFtZd5sdRv4qmq7zFs0P13ZmkaebVBYq6n7cjKvzfBJUblgzljeljf4ePrSlvFOGk1NE1BLpxLc\n4ecwf1slE1pkDxz8fXNu9uY+Dll79mr6EPSdMRVuWSca/q3WuWISwVt+XOdKnM9KxXMN8luniRdA\nJracf2LKCMn2Xg3uY8qfgQ9STu2eA4xHp/OfiVav1/uuF7iJrKzfwUztrYVJ27qfEwj2MeiZqbOp\nrwRmo1S+LV2wHXcb8yB6W7Q6sU6zrOp+t/TZwM/QntkKvSU4mKTs+MnbN5Otq3vdw2zn//q6hwrm\nWqm518P0I2DceDjUuU9m81b40xfgrsvK1F0JmpZidZQkTQTesbTEmybO+9BNoed6RLqRt5Kolrd7\nib7J4/0vqjkxSfJJKZ4mMt6pbziTzqT+5D++zfZZqYyfL1jUOL/IKA3AS8ZBxyjFYZGPzWJBwnEQ\nR6CNiUfjBXgdCjxGOK6iWGBc/Yiny/8mnwlsJ/7tW0VQXTgORWXUmR23ErwbdwVeYOFZpBtkk/oT\n/jw59kUH0t3ilN3mIrFRup3xX3YFMHUaTD0MJo4BfqcUJwtqK5pB1mGyBUlSV73rCl38I/Acripb\n7GKj+pFMV9JFXGGsc8rBGc8lI3zBlEZy26YXUunPb3EugjK9vGodMIgWFkPoExEIjsdDwLXoQLoW\nzuXYcfW3UQJNq0KtKiBXu2pgB4MrnWzYrrEtHBuSpvIG1VVvm+Oq//Vlaq+yZBuHk42BZXxdkunx\nu3i33uhsNh6ty/Pi8e0B8C997bydaZyAlnVUByx91Z2AudwxvI0JLjO4x3/FkvGkLbomj3Szac5H\nV1EvVXNaTOwWdXmd+scjXjC24qg4yLN76yC7K2MEiLSNEBmVzmZJUIpO4Ps4e50zuVl+xhseGMfO\ns4BzgOuowyEpy6moKeShK3qSAt7JTVnHvWxnsCyHtCoQvYPXayPY/jqHxtruQFaKicDvgRPhGuCZ\nJ2Fjb/CpDb0i9nSm5QV91cRvXGm+Bzt+DNLRthpDu5T4k5Rqth0mY9+KbWFVNycW6/8uDQtkrJ9H\nnWC7xkL9s0rjBDTSaWRPJ67GnaSvgKjUbUnVpR3iePLTW3covYkdprxDWpE+1tX/0FbuPo6dDHKD\njzdvAtmj8flPKY0T0FjHkX3Ql165k/WJ2tsNGg/rCwirl/6shV6fYDQR8mX9V7LtW25yocoz0g2h\ndh7CIz/z8eQd7eKVmlYaJ6DRziMHgqzzTdrltbUXPdFovxOb8v0rdgVDfF3FhFH92450AZWXdp+G\n816+9LSPF5eDTGl8Xg1K4wQ0XUAOB/FP3l/X8kaNMnfLrPwxtNTRv2JXMMTTVlaTqGfbZRZPFM5H\naxJHteAkbv+qjwcfBqknxqeG0jgB7VBAXuEENAkMD/6QhY9UvtWIMnf9/hBxwqIKd/X4tqoSIuU1\nibpsW1kCKv5FkaW1LLueSwZ9AuQJkENr44kaSuMEtEtB56zsA5FxbJfbOFkKM3FSaZXhNhgZG44F\nqUfdz3K6y1dPOU3C639520VYEJv7BGVvWWHujzl/oINBAZEu+l8AmV0rb9RQdis/kSwoxetAfgqq\ncxIvcDNn9c7l7uNpJ9+OLHj+DLOATnQ8iud7EUzw8xD6sqollfSxKn8Y03riomu9C6Pc8IQVwEmF\n6CnimxJMJHQToURKXkQudLDnPsNMmw0ddNAlM7jgjIdk5h9y09k0mpZi7VZA3uGqls5N6zNy1dH0\n0W00N2c0o7x3ylD+DpSm+pscdRuf16P8WBZNyxjQWpIicjt45wON8EsFZTeL4s2GCN9Bv50ROvZF\nB+wdsOuBtIjcpFvoWhvFuwLtUeliCPgngm/q2Xg3shWPwi166141SIq6dQMlxSluoGQRlLu5L8f1\nmMNse64QhW2AURrFWw4iXKsU+wAfh2sOgS29Sj26rIsBeSXzXzGO4QkHsHHTD5R6aWhxXojH2LPQ\nYeNLaWUUr450nYde2AejmX+pj0a/63py0iEzxC3k/DlbiyE+2lj3/yR0vlOApbFtmdBiGjVsWLdS\ndMD+hxjVMZLQtCrUrsUJ2PuvpOCnU5k3vEu9DarWfRLMs9nyyE8fTUEDYNWu6/m9SIPbj7JboaKG\n6rpOqFLqBukG+Vm7B9MVKXY7kwDND7wPtv0l7vsddOrs5hr+N3IX+pJphX7LC9VeZm2GeFU6rJ4v\njXkmGeFtWb6Lx6PJfcpuhXJsFzJoKbaVi9+iRupWihloDe283O2MANjtTApEGFJqw2pgqvfpNcAO\nlrD3oOKCX6IW0sX5nW/m/i0/YG03+sQDvG3CUvRCK3baUG2HiqnnHm1J2zJlUEN4+zHBoaMLk61Q\ntViB3sq5J1T5BHv6WAT6eTDr9kOf0uylv97xGLz1MRgaCla6IRShO4LQtCrU7iVqTb8yVh3t4vzb\nd6nWnpod9FhMdv4yj6dp7jQkelKRd1sQHJfsi7irpd8bt7Iu+gaeq/10nTiZ5z8KMuTjk0/TxtG4\nRUvjBLR7MRUikT1tdIG5V2eGbQLp8TRR5vcnUa4uECyrxCXkMXMDjwq84O/6pah3qznt4bnIb6cK\nOrCl3icDMh7kOz7+2A5yYdO8XFex25lMBPO1dsAJw1oVz0J4b3wLMN35zlXf/YmJDyacszTq7PTP\nBK9DuNl5rt4Tn2CynnXA2eitUXI+1hwqP+7pUX0Iz4Vk0G3iwHYmzq10BE9gpgE/BY53PnoMeIMI\nf66na22ApqXYSCtdnH97vCby4RdAZu56NtkFWpz/d4eeicbTpF+pUM1tfllF09jro90sH2urLr8y\n70NQc4g/vSruwAbdl3PtZY6DovvobSD7Ns2zdZfGCRhpJfkOkCvFib354K59b9QG4N5N40VoJtlP\nvO/imN/1Nq0/CjjqAdtr1F6d0bTF+mGSi2SBT1iEt5TJNhzo/gL/+NgYdvp54jraPJlQVcXGzuSE\nP/ZBo6MD9j8U9jsAPuqeUvwJeJcIq5wfueqwqz4HYznSYjSS4kiqiFMxOQ0KxtqsJ09u0Spzy9Z9\ncpUVc+Nd2A0+BzalGDODNd9fy+FvBhhDP6/mzmsWyWkfrZzGdkXTUmy0FJCTQHp9b6KdIB8F6TJQ\n7Vt/rUSeE4rsyNWiqQjNflenc1j8HCQbe310g0wFudWd8315Sn7DGWsa17paXBonYDQVxyr/2dCx\n3tJXcs+cVNW+CdW/ivwfRRd3/qPhViRpjrNPJeZiuZMTH1IMrXfnuZOBP/8373j97iZARKwQqWdQ\nkRNBVvsESf+ebPnU00w9KZHJWmlo1O1VIUSKLe68vysqZPNqSUH7VJKBtf8G3iwT2Ca++f0eyPim\n+a6p0jgBo7WAjAP5N79W0snAsv/DVX/TFm8rbztTPIlQ9ATKLKVfEaGQV8iW2QIlGFjXcuiky7n2\nKU94DA87hnTV+Hw2WBonYLQXkBNAVnierf1yBZ976n94495N01aJ9uM5oeXd0vSIvrK0nlyixbQd\n13M4chIDMhnklz4BshnkrMbnsA1K4wTsDgVk7GyWf7PT52owka1rQY6rvL1Wu8UX2dK0xlBaNMLY\n79PTLzAf5IjQ9nQ1yBFN81W7FHvE2yoo1X0Hr77n3fzX4Q/wcvcoeAj4DPBJEXYWrRf36FOj3qsm\n49t3j4DNrtQ0uTazOtrSj5i9PDBfcen5aw7r28C0STvo3H4PB68bZtqR0NEJ44CP/Ap4uwhbKqd3\npKJpKbZbFeh+nJ6T92TL1SADvjfbSpA5ReoLvdHbJ3eJGd1NX5nhN6Bud+kZy5vujHco/If1IB2N\n81GbFZtPpJUQ2XqAPPHHrdL9L+jYCjee4mjgLqX4jFKMy1FjUkxIcu6SOlI15s3rkS8PSbUIpnRc\njDd+ncB7TmDJJTuZPj3+x089KsJwiygdMbDbmQahFGOADwFXohkZuOoFWP8IvBhSl2NugI/bSmjE\nq/BFspePNkS3Uuu30H3wN7j46Q/y2SeH6JoDV6FLGAsXi9xwWstoHSGwUbwNQoQB4Gql+DnwLbR2\nMhm+9Yro0wujH3lJhk7ATQykhUKSfSFfTtQkmLvL1+emXhwrgFXDqKP+wILH3syN925jz2nDdE7H\ni7K2yAG7nWkDiLACmAt8RO+9MxDdklyLTgtwR8Y2pVz2crftrIz2zWaBD9Ia2ropZMJkNt/YzdYn\nXsvvZmxh8oXDdI53vn4C+DQ8vKQRekcorCbSJhBhEPiMUo+ejxfo5cO0mUrxMkGtI7gl+TjeFRCz\nnd/ektBI8fSIHqLajFIrSc570urUhxq+rdsAXateqjZe/TjT3gacu4XJfr4fBH4JfAP4jQiDSq2d\nCgv7opWO4BSGNcIKkbbDju3xn0/aH1i+D8/e803eNetcftXVyfBR6ERB5kjf7pggLhGRedKf1mH2\nGmYc/S3eOebbXHTMExx4Q+j7B9GC47siPO3/ImJ7skiFNay2GZRauAhumBf95ir8xr7DWEs3H3xx\nNV0rj2HTrHEMT9hBx/b7mPLnQR5fLXLXZYXsEub2Dk+byWvgrRDj1Zxvjqfn2K2MeXGQjiGdmmGv\nqTBlL/i3/UOPvwj8CC087tKnvRZlYTWRtkMwHaOHrU8CTwIXA5MeZgZwzES4ao5vAz8ROBkWDoVS\nGppdmpWe0tBDWJtJ3ibVs4XxBN26WZyx8F5+PjH60FW7/upk8E9DdH0NuEGEdjLyjgpYIdJmyFKl\nleJK4G+By4EZsc9wwBFf5e/uew237n8EvShzu0Tx05vy26QAlEIBex/DssNnsfLVN3PWwCb2mTqW\nHYecwG1veI599tzINNnK5xMOB4YGgC8C3xyUrlVV0WURhRUiIwzOm/RLSvEV2LgMeFnkGfbqebfz\nJp7CJo7h/sF7OP512xR7AUtE2JRQfXLi5QqhFJ3AvsA0Xzkw5u9x93Ms93Psrt/uZBx/3LVbSrvv\npvcuET5QA/kWIVghMkIhwrBSWxKEwfAwzvH98+zNIl4zAfiY+61SPIRO4Xg3nHc6jH0JIHABXQxv\n7WZwZR9PLOuTJblVf6XYAziAdOFwANpDNCdEFPLMLFZOOpRHxu7F5k3f4y/bh+CguGfz129RBFaI\njEo8+MeXsfxje7H5vCXMOXAn445D38jnYqZT3gGvwG8/GASe5xrg3kOVWnhosN6nHoHbPkOycJiG\n1jCKYBB43CkbgY2T2fzs53n/3x1B7wH789Satcw4+Sy5+XnUy3cZdr/DBb8kVohYtApWiIxoJBlh\nN0RvSdoAAAE0SURBVPQul5ffgU48DIBS7A3MAV4FnOj8OyW+3h3AjyejY1t8uGoe8M4ChPbhCAan\nPB7z/2eicSl7gfrWl3EExgxZqzUjv/1FzU0cgwJ0WhSAFSIjGHn8GRw7yM1OQSk6gMPhqZ8BR5Yg\nYzPpwmEjsLnwcWqGwdb6dDQPK0R2Uzhv/YeU2vQ0xkLk2UfRwYKucHhchBfrotFiZMAKEYsceOYx\nEb7bNBUW7QXrsWphYVEKNorXwsKiFKwQsbCwKAUrRCwsLErBChELC4tSsELEwsKiFKwQsbCwKAUr\nRCwsLErBChELC4tSsELEwsKiFKwQsbCwKAUrRCwsLErBChELC4tSsELEwsKiFKwQsbCwKAUrRCws\nLErBChELC4tSsELEwsKiFKwQsbCwKAUrRCwsLErh/wOp7eD9plBd/gAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "donut = {p for p in square if 0.2 < (p.x ** 2 + p.y ** 2) < 1}\n", + "plot_convex_hull(donut)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "19 of 720 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\nBv8fLdTLMnE7hQAAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def rad(degrees): return degrees * math.pi / 180.0\n", + "\n", + "sine = {Point(rad(d), 5 * math.sin(rad(d))) for d in range(720)}\n", + "plot_convex_hull(noisy(sine))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "38 of 360 points on hull\n" + ] + }, + { + "data": { + "image/png": "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\nYSAIguX/A4KDcggsT5ndAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "donut2 = noisy({Point(5 * math.sin(rad(d)), 5 * math.cos(rad(d))) for d in range(360)})\n", + "\n", + "plot_convex_hull(donut2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tests\n", + "\n", + "So far, everything looks good! But I would gain even more confidence if we could pass a test suite:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'tests pass'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " # Tests of `turn`\n", + " assert turn(octagon[0], octagon[1], octagon[2]) == 'left'\n", + " assert turn(octagon[2], octagon[3], octagon[4]) == 'left'\n", + " assert turn(octagon[1], octagon[0], octagon[7]) == 'right'\n", + " assert turn(octagon[5], octagon[6], octagon[7]) == 'left'\n", + " assert turn(octagon[2], octagon[1], octagon[0]) == 'right'\n", + " assert turn(pacman[1], pacman[2], pacman[3]) == 'left'\n", + " assert turn(pacman[3], pacman[4], pacman[5]) == 'right'\n", + " assert turn(Point(0, 0), Point(0, 1), Point(0, 2)) == 'straight'\n", + " assert turn(Point(2, 1), Point(3, 1), Point(4, 1)) == 'straight'\n", + " assert turn(Point(2, 1), Point(4, 1), Point(3, 1)) == 'straight'\n", + " assert turn(Point(0, 0), Point(1, 1), Point(2, 2)) == 'straight'\n", + " assert turn(Point(0, 0), Point(-1, -1), Point(2, 2)) == 'straight'\n", + " # More tests of `turn`, covering negative denominator\n", + " A, B = Point(-2, -2), Point(0, 0)\n", + " assert turn(A, B, Point(1, 3)) == 'left'\n", + " assert turn(A, B, Point(2, 2)) == 'straight'\n", + " assert turn(A, B, Point(3, 1)) == 'right'\n", + " assert turn(A, B, Point(-1, 1)) == 'left'\n", + " assert turn(A, B, Point(-1, -4)) == 'right'\n", + " assert turn(A, B, Point(-1, -1)) == 'straight'\n", + " assert turn(B, A, Point(-3, -4)) == 'left'\n", + " assert turn(B, A, Point(-4, -3)) == 'right'\n", + " assert turn(B, A, Point(-1, -1)) == 'straight'\n", + " assert turn(B, A, Point(-3, -3)) == 'straight'\n", + " \n", + " # Tests of convex_hull\n", + " assert convex_hull(octagon)== octagon\n", + " assert convex_hull(circle) == convex_hull(donut)\n", + " assert convex_hull(circle) == convex_hull(convex_hull(circle))\n", + " for n in (0, 1, 2, 3):\n", + " assert convex_hull(Points(n)) == Points(n)\n", + " collinear = {Point(x, 0) for x in range(100)}\n", + " assert convex_hull(collinear) == [min(collinear), max(collinear)]\n", + " P = Point(5, 5)\n", + " assert convex_hull(collinear | {P}) == [min(collinear), max(collinear), P]\n", + " grid1 = {Point(x, y) for x in range(10) for y in range(10)}\n", + " assert convex_hull(grid1) == [Point(0, 0), Point(9, 0), Point(9, 9), Point(0, 9)]\n", + "\n", + " return 'tests pass'\n", + " \n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "## How Many Points on the Hull?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The number of points on the hull for `Points(N)` seems to increase slowly as `N` increases. \n", + "How slowly? Let's try to find out. We'll average the number of points on the hull for `Points(N)` over, say, 60 random trials:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def average_hull_size(N, trials=60):\n", + " \"\"\"Compute the average hull size of N random points\n", + " (averaged over the given number of random trials).\"\"\"\n", + " return sum(len(convex_hull(Points(N, seed=trials+i)))\n", + " for i in range(trials)) / trials" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll do this for several values of *N*, taken as powers of 2:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " N Hull Size\n", + " 1: 1.0\n", + " 2: 2.0\n", + " 4: 3.7\n", + " 8: 5.1\n", + " 16: 7.1\n", + " 32: 8.6\n", + " 64: 11.0\n", + " 128: 12.6\n", + " 256: 14.6\n", + " 512: 16.4\n", + "1024: 18.1\n", + "2048: 19.8\n", + "4096: 21.6\n", + "8192: 23.2\n" + ] + } + ], + "source": [ + "hull_sizes = [average_hull_size(2**e) \n", + " for e in range(14)]\n", + "\n", + "print(' N Hull Size')\n", + "for e in range(14): \n", + " print('{:4}: {:4.1f}'.format(2**e, hull_sizes[e]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we'll plot the results, with *N* on a log2 scale:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_hull_sizes(hull_sizes):\n", + " plt.plot(hull_sizes, 'bo-')\n", + " plt.ylabel('Hull size')\n", + " plt.xlabel('log_2(number of points)')\n", + "\n", + "plot_hull_sizes(hull_sizes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That sure looks like a straight line! \n", + "\n", + "That means we can define `estimated_hull_size` by computing a slope and intercept of the line. (I won't bother doing linear regression; I'll just draw a straight line from the first to the last point in `hull_sizes`.)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def estimated_hull_size(N):\n", + " \"Estimated hull size for N random points, (inter/extra)polating from hull_sizes.\"\n", + " slope = (hull_sizes[-1] - hull_sizes[0]) / (len(hull_sizes) - 1)\n", + " return hull_sizes[0] + slope * math.log(N, 2)\n", + "\n", + "# Plot actual average hull sizes in blue, and estimated hull sizes in red\n", + "plot_hull_sizes(hull_sizes)\n", + "plt.plot([estimated_hull_size(2**e) \n", + " for e in range(len(hull_sizes))], \n", + " 'r--');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's an estimate of the number of points on the hull of a quadrillion random points:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "86.15634904778565" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "estimated_hull_size(10**15)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Concluding Remarks and Further Reading\n", + "\n", + "The convex hull problem is an interesting exercise in algorithm design.\n", + "The algorithm covered here is called [Andrew's Monotone Chain](https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain).\n", + "It is a variant of the [Graham Scan](https://en.wikipedia.org/wiki/Graham_scan).\n", + "You can read more from [Tamassia](http://cs.brown.edu/courses/cs016/docs/old_lectures/ConvexHull-Notes.pdf) or [Wikipedia](https://en.wikipedia.org/wiki/Convex_hull)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Countdown.ipynb b/pytudes/ipynb/Countdown.ipynb new file mode 100644 index 0000000..bf97dd4 --- /dev/null +++ b/pytudes/ipynb/Countdown.ipynb @@ -0,0 +1,2867 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "
Peter Norvig
5 January 2016
\n", + "\n", + "# Countdown to 2016\n", + "\n", + "Alex Bellos [posed](http://www.theguardian.com/science/2016/jan/04/can-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) this New Year's puzzle:\n", + "\n", + "\n", + "> Fill in the blanks so that this equation makes arithmetical sense:\n", + "\n", + "> `10 _ 9 _ 8 _ 7 _ 6 _ 5 _ 4 _ 3 _ 2 _ 1 = 2016`\n", + "\n", + "> You are allowed to use *only* the four basic arithmetical operations: +, -, ×, ÷. But brackets (parentheses) can be used wherever needed. So, for example, the solution could begin\n", + "\n", + "> `(10 - 9) / (8` ...\n", + "\n", + "> or\n", + "\n", + "> `10 + (9 - 8)` ...\n", + "\n", + "Let's see if we can solve this puzzle, and some of the related ones from Alex's [first](http://www.theguardian.com/science/2016/jan/04/can-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) and [second](http://www.theguardian.com/science/2016/jan/04/did-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) post. We'll start with a simpler version of the puzzle." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Four Operators, No Brackets\n", + "\n", + "Suppose for the moment we are not allowed to use brackets. Then there are nine blanks, each of which can be filled by one of four operators, so the total number of possible expressions is:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "262144" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "4 ** 9" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The function `itertools.product` can enumerate all the ways of filling 9 blanks with one of the four operators:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "262144" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import itertools\n", + "\n", + "operators = ('+', '-', '*', '/')\n", + " \n", + "len(set(itertools.product(operators, repeat=9)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "So we can fill in the equation with each possible sequence of operations, and evaluate each string to see if it equals 2016. But we need to catch errors such as dividing by zero, so we'll define a wrapper function, `evaluate`, to do the `eval`:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def evaluate(exp):\n", + " \"eval exp, or return None if there is an arithmetic error.\"\n", + " try:\n", + " return eval(exp)\n", + " except ArithmeticError:\n", + " return None\n", + "\n", + "def solve_no_brackets(operators, target=2016):\n", + " \"All solutions to the countdown puzzle (with no brackets).\"\n", + " exps = ('10{}9{}8{}7{}6{}5{}4{}3{}2{}1'.format(*ops)\n", + " for ops in itertools.product(operators, repeat=9))\n", + " return [exp for exp in exps if evaluate(exp) == target]\n", + "\n", + "solve_no_brackets(operators)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Too bad; we did all that work and didn't find a solution. What years *can* we find solutions for? Let's modify `solve_no_brackets` to take a collection of target years rather than a single one, and return a dict of the form `{year: 'expression'}` for each expression that evaluates to one of the target years:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{1979: '10*9*8+7*6*5*4*3/2-1',\n", + " 1980: '10*9*8+7*6*5*4*3/2/1',\n", + " 1981: '10*9*8+7*6*5*4*3/2+1',\n", + " 2013: '10*9*8*7/6/5*4*3-2-1',\n", + " 2014: '10*9*8*7/6/5*4*3-2/1',\n", + " 2015: '10*9*8*7/6/5*4*3-2+1',\n", + " 2017: '10*9*8*7/6/5*4*3+2-1',\n", + " 2018: '10*9*8*7/6/5*4*3+2/1',\n", + " 2019: '10*9*8*7/6/5*4*3+2+1'}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def solve_no_brackets(operators, targets):\n", + " \"All solutions to the countdown puzzle (with no brackets).\"\n", + " exps = ('10{}9{}8{}7{}6{}5{}4{}3{}2{}1'.format(*ops)\n", + " for ops in itertools.product(operators, repeat=9))\n", + " return {int(evaluate(exp)): exp for exp in exps if evaluate(exp) in targets}\n", + "\n", + "solve_no_brackets(operators, range(1900, 2100))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Interesting: in the 20th and 21st centuries, there are only two \"golden eras\" where the countdown equation works: the three year period centered on 1980, and the seven year period that is centered on 2016, but omits 2016. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Four Operators, With Brackets\n", + "\n", + "Now let's return to the original puzzle, with the brackets. How many ways are there of bracketing an expression with 9 binary operators? I happen to remember that this is given by the [Catalan numbers](https://en.wikipedia.org/wiki/Catalan_number), and we can [look it up](http://www.wolframalpha.com/input/?i=9th+catalan+number) to find that there are 4862 diffferent bracketing. If we enumerated and evaluated all of them, it would take about 4862 times longer than doing a single `solve_no_brackets`, which took about 6 seconds, so the estimated time would be about 8 hours. I'm impatient, so I'd like a faster approach. \n", + "\n", + "I'll use the idea of [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming): break the problem down into simpler subparts, and compute an answer for each subpart, and store intermediate results in a table so we don't need to re-compute them when we need them again.\n", + "\n", + "How do we break the problem into parts? In general, any expression must consist of an operator with two operands (which might in turn be complex subexpressions). For example, a complete countdown expression might be of the form\n", + "\n", + " (10 ... 8) + (7 ... 1)\n", + " \n", + "where `(10 ... 8)` means some expression that starts with 10 and ends with 8. Of course we need not use `'+'` as the operator, and we need not split after the 8; we could use any of the four operators and split anywhere. Let's start by defining `c10` as the tuple of integers forming the countdown from 10 to 1, and the function `splits` to split a tuple in all ways: " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "c10 = (10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n", + "\n", + "def splits(items):\n", + " \"Split sequence of items into two non-empty parts, in all ways.\"\n", + " return [(items[:i], items[i:]) \n", + " for i in range(1, len(items))]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[((10,), (9, 8, 7, 6, 5, 4, 3, 2, 1)),\n", + " ((10, 9), (8, 7, 6, 5, 4, 3, 2, 1)),\n", + " ((10, 9, 8), (7, 6, 5, 4, 3, 2, 1)),\n", + " ((10, 9, 8, 7), (6, 5, 4, 3, 2, 1)),\n", + " ((10, 9, 8, 7, 6), (5, 4, 3, 2, 1)),\n", + " ((10, 9, 8, 7, 6, 5), (4, 3, 2, 1)),\n", + " ((10, 9, 8, 7, 6, 5, 4), (3, 2, 1)),\n", + " ((10, 9, 8, 7, 6, 5, 4, 3), (2, 1)),\n", + " ((10, 9, 8, 7, 6, 5, 4, 3, 2), (1,))]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "splits(c10)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now what I would like to do is build up a table that says, for every subsequence of the numbers, what are the expressions we can make with those numbers, and what do they evaluate to? We'll call the table `EXPS`. For example, with the subsequence `(10, 9, 8)`, we would have:\n", + "\n", + " EXPS[(10, 9, 8)] = {\n", + " 27: '((10+9)+8)',\n", + " 8: '((10-9)*8)', \n", + " -7: '(10-(9+8))', \n", + " ...}\n", + " \n", + "We'll do the same for every other subsequence, for example:\n", + "\n", + " EXPS[(7, 6, 5, 4, 3, 2, 1)] = {\n", + " 1: '((((7/((6/5)-4))+3)*2)*1)',\n", + " 2: '((((7/((6/5)-4))+3)*2)+1)',\n", + " 3.5: '((((7/((6/5)-4))+3)+2)+1)',\n", + " 4: '((7-((6/5)*((4/3)+2)))+1)',\n", + " ...}\n", + " \n", + "Once we have the tables for these two subsequences, we can put them together to get the table for the complete `countdown(10)` by considering all ways of taking a value from the first table, then one of the four operators, then a value from the second table. For example, taking the first entry from each table, and the operator `'+'`, we would have:\n", + "\n", + " EXPS[(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)] = { \n", + " 28: '(((10+9)+8)+((((7/((6/5)-4))+3)*2)*1))',\n", + " ...}\n", + "\n", + "\n", + "I can implement `EXPS` as a defaultdict of dicts, and define `expressions(numbers)` to fill in `EXPS` entries for `numbers` and all sub-sequences of `numbers`. Within `fill_tables`, note that `Lnums` and `Rnums` are sequences of numbers, such as `(10, 9, 8)` and `(7, 6)`. `L` and `R` are values, such as `27` and `1`. And `Lexp` and `Rexp` are strings, such as `\"((10+9)+8)\"` and `\"(7-6)\"`. Rather than catching division-by-zero errors, we just avoid the division when the denominator is 0." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from collections import defaultdict, Counter\n", + "\n", + "EXPS = defaultdict(dict) # e.g., EXPS[(10, 9, 8)][27] == '((10+9)+8)'\n", + "\n", + "def expressions(numbers):\n", + " \"Fill EXPS table for numbers, and all sub-sequences of numbers. Return EXPS[numbers]\"\n", + " if numbers in EXPS: # Already did the work\n", + " pass\n", + " elif len(numbers) == 1: # Only one way to make an expression out of a single number\n", + " expr(numbers, numbers[0], str(numbers[0]))\n", + " else: # Split in all ways; fill tables for left and right; combine tables in all ways\n", + " for (Lnums, Rnums) in splits(numbers):\n", + " for (L, R) in itertools.product(expressions(Lnums), expressions(Rnums)):\n", + " Lexp, Rexp = '(' + EXPS[Lnums][L], EXPS[Rnums][R] + ')'\n", + " if R != 0: \n", + " expr(numbers, L / R, Lexp + '/' + Rexp)\n", + " expr(numbers, L * R, Lexp + '*' + Rexp)\n", + " expr(numbers, L - R, Lexp + '-' + Rexp)\n", + " expr(numbers, L + R, Lexp + '+' + Rexp)\n", + " return EXPS[numbers]\n", + "\n", + "def expr(numbers, value, exp): \n", + " \"Record exp as an expression with the given value, covering the sequence of numbers.\"\n", + " EXPS[numbers][value] = exp" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's give it a try:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{-62: '(10-(9*8))',\n", + " -7: '((10-9)-8)',\n", + " -6.888888888888889: '((10/9)-8)',\n", + " 0.125: '((10-9)/8)',\n", + " 0.1388888888888889: '((10/9)/8)',\n", + " 0.5882352941176471: '(10/(9+8))',\n", + " 2.375: '((10+9)/8)',\n", + " 8: '((10-9)*8)',\n", + " 8.875: '(10-(9/8))',\n", + " 8.88888888888889: '((10/9)*8)',\n", + " 9: '((10-9)+8)',\n", + " 9.11111111111111: '((10/9)+8)',\n", + " 10.0: '(10*(9-8))',\n", + " 11: '((10+9)-8)',\n", + " 11.125: '(10+(9/8))',\n", + " 11.25: '((10*9)/8)',\n", + " 27: '((10+9)+8)',\n", + " 82: '((10*9)-8)',\n", + " 98: '((10*9)+8)',\n", + " 152: '((10+9)*8)',\n", + " 170: '(10*(9+8))',\n", + " 720: '((10*9)*8)'}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expressions((10, 9, 8))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'((10+9)+8)'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EXPS[(10, 9, 8)][27]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "That looks reasonable. Let's solve the whole puzzle.\n", + "\n", + "# Countdown to 2016: A Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 29.1 s, sys: 713 ms, total: 29.8 s\n", + "Wall time: 29.8 s\n" + ] + }, + { + "data": { + "text/plain": [ + "'(((((((10+((9*8)*7))-6)-5)*4)+3)+2)-1)'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time expressions(c10)[2016]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We have an answer! And in a lot less than 8 hours, thanks to dynamic programming! \n", + "\n", + "Removing unnecessry brackets, this equation is equivalent to:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2016" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(10 + 9 * 8 * 7 - 6 - 5) * 4 + 3 + 2 - 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Counting Solutions\n", + "\n", + "Alex Bellos had another challenge: \n", + "\n", + "> I was half hoping a computer scientist would let me know exactly how many solutions there are with only the four basic operations. Maybe someone will. \n", + "\n", + "As it stands, my program can't answer that question, because I only keep one expression for each value. \n", + "\n", + "Also, I'm not sure what it means to be a distinct solution. For example, are `((10+9)+8)` and `(10+(9+8))` different, or are they same, because they both are equivalent to `(10+9+8)`? Similarly, are `((3-2)-1)` and `(3-(2+1)` different, or the same because they both are equivalent to `(3 + -2 + -1)`? I think the notion of \"distinct solution\" is just inherently ambiguous, and each of these questions could reasonably be answered either way. My choice is to count each of these as distinct: every expression has exactly ten numbers, nine operators, and nine pairs of brackets, and if an expression differs in any character, it is different. But I won't argue with anyone who has a different definition of \"distinct solution.\"\n", + "\n", + "So how can I count expressions? One approach would be to go back to enumerating every equation (all 4862 × 49 = 1.2 bilion of them) and checking which ones equal 2016. That would take about 40 hours with my Python program, but I could get it under 40 minutes in a more efficient language.\n", + "\n", + "Another approach is to count subexpressions as the table is filled in. We won't enumerate all the expressions, just count them. I'll introduce a second table, `COUNTS`, such that\n", + "\n", + " COUNTS[(10, 9, 8)][27] == 2\n", + " \n", + "because there are 2 ways to make 27 with the numbers `(10, 9, 8)`, namely, `((10+9)+8)` and `(10+(9+8))`.\n", + "How do we compute the counts? By looking at every split and operator choice that can make the value, and summing up (over all of these) the product of the counts for the two sides. For example, there are 2 ways to make 27 with `(10 ... 8)`, and it turns out there are 3526 ways to make 1 with `(7 ... 1)`. So there are 2 × 3526 = 7052 ways to make 28 with this split by adding 27 and 1. \n", + "\n", + "I'll make `expr` handle `COUNTS` as well as `EXPS`. And I'll define `clear` to clear out the cache of `COUNTS` and `EXPS`, so that we can fill the tables with our new, improved entries." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "COUNTS = defaultdict(Counter) # e.g., COUNTS[(10, 9, 8)][27] == 2\n", + "\n", + "def expressions(numbers):\n", + " \"Fill EXPS table for numbers, and all sub-sequences of numbers. Return EXPS[numbers]\"\n", + " if numbers in EXPS: # Already did the work\n", + " pass\n", + " elif len(numbers) == 1: # Only one way to make an expression out of a single number\n", + " expr(numbers, numbers[0], str(numbers[0]), 1)\n", + " else: # Split in all ways; fill tables for left and right; combine tables in all ways\n", + " for (Lnums, Rnums) in splits(numbers):\n", + " for (L, R) in itertools.product(expressions(Lnums), expressions(Rnums)):\n", + " Lexp, Rexp = '(' + EXPS[Lnums][L], EXPS[Rnums][R] + ')'\n", + " count = COUNTS[Lnums][L] * COUNTS[Rnums][R]\n", + " if R != 0: \n", + " expr(numbers, L / R, Lexp + '/' + Rexp, count)\n", + " expr(numbers, L * R, Lexp + '*' + Rexp, count)\n", + " expr(numbers, L - R, Lexp + '-' + Rexp, count)\n", + " expr(numbers, L + R, Lexp + '+' + Rexp, count)\n", + " return EXPS[numbers]\n", + "\n", + "def expr(numbers, val, exp, count):\n", + " \"Fill EXPS[numbers][val] with exp, and increment COUNTS.\"\n", + " EXPS[numbers][val] = exp\n", + " COUNTS[numbers][val] += count\n", + " \n", + "def clear(): EXPS.clear(); COUNTS.clear()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{-62: '(10-(9*8))',\n", + " -7: '((10-9)-8)',\n", + " -6.888888888888889: '((10/9)-8)',\n", + " 0.125: '((10-9)/8)',\n", + " 0.1388888888888889: '((10/9)/8)',\n", + " 0.5882352941176471: '(10/(9+8))',\n", + " 2.375: '((10+9)/8)',\n", + " 8: '((10-9)*8)',\n", + " 8.875: '(10-(9/8))',\n", + " 8.88888888888889: '((10/9)*8)',\n", + " 9: '((10-9)+8)',\n", + " 9.11111111111111: '((10/9)+8)',\n", + " 10.0: '(10*(9-8))',\n", + " 11: '((10+9)-8)',\n", + " 11.125: '(10+(9/8))',\n", + " 11.25: '((10*9)/8)',\n", + " 27: '((10+9)+8)',\n", + " 82: '((10*9)-8)',\n", + " 98: '((10*9)+8)',\n", + " 152: '((10+9)*8)',\n", + " 170: '(10*(9+8))',\n", + " 720: '((10*9)*8)'}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clear()\n", + "expressions((10, 9, 8))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({-62: 1,\n", + " -7: 2,\n", + " -6.888888888888889: 1,\n", + " 0.125: 1,\n", + " 0.1388888888888889: 2,\n", + " 0.5882352941176471: 1,\n", + " 2.375: 1,\n", + " 8: 1,\n", + " 8.875: 1,\n", + " 8.88888888888889: 2,\n", + " 9: 2,\n", + " 9.11111111111111: 1,\n", + " 10.0: 2,\n", + " 11: 2,\n", + " 11.125: 1,\n", + " 11.25: 2,\n", + " 27: 2,\n", + " 82: 2,\n", + " 98: 1,\n", + " 152: 1,\n", + " 170: 1,\n", + " 720: 2})" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COUNTS[(10, 9, 8)]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COUNTS[(10, 9, 8)][27]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Looks good to me. Now let's repeat the computation, this time keeping track of `COUNTS`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1min 4s, sys: 1.12 s, total: 1min 5s\n", + "Wall time: 1min 5s\n" + ] + }, + { + "data": { + "text/plain": [ + "'(((((((10+((9*8)*7))-6)-5)*4)+3)+2)-1)'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clear()\n", + "\n", + "%time expressions(c10)[2016]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The Answer (?)\n", + "\n", + "Now we can read off the answer:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "30066" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COUNTS[c10][2016]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "This says there are 30,066 distinct expressions for 2016. \n", + "\n", + "**But I don't believe it.**\n", + "\n", + "Why not? Because floating point division can have round-off errors. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2015.9999999999998" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "2015 + 1/3 + 1/3 + 1/3" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "2015 + 1/3 + 1/3 + 1/3 == 2016" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Dealing with Round-off Errors\n", + "\n", + "So there might be perfectly good solutions that are hiding in the `EXPS` table under `2015.9999999999998` (or some similar number) when they should be exactly `2016`. Let's find all the values that are very near to `2016`:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2015.999999999997,\n", + " 2015.999999999999,\n", + " 2015.9999999999993,\n", + " 2015.9999999999995,\n", + " 2015.9999999999998,\n", + " 2016.0,\n", + " 2016.0000000000002,\n", + " 2016.0000000000005,\n", + " 2016.0000000000018,\n", + " 2016.000000000002,\n", + " 2016.0000000000023}" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{val for val in expressions(c10)\n", + " if abs(val - 2016) < 0.000001}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I suspect that all of these actually should be exactly 2016. \n", + "\n", + "To find out for sure, let's re-do all the calculations using exact rational arithmetic, as provided by the `fractions.Fraction` data type. From experience I know that this will be an order of magnitude slower, so we're looking at 10 minutes or more of computation.\n", + "\n", + "I'll replace the computation `L / R` with `divide(L, R)`, which calls `Fraction`. To mitigate the expense of this computation, I make two optimizations. First, `divide` replaces a whole fraction, such as `Fraction(6, 2)`, with an `int`, such as `3`. Second, I modify `expr` to *not* fill in `EXPS[c10]`, except for `EXPS[c10][2016]`. The rationale is that we don't need the other entries, and by not storing them, we save a lot of memory, and thus save garbage collection time." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from fractions import Fraction\n", + "\n", + "def expressions(numbers):\n", + " \"Fill EXPS table for numbers, and all sub-sequences of numbers. Return EXPS[numbers]\"\n", + " if numbers in EXPS: # Already did the work\n", + " pass\n", + " elif len(numbers) == 1: # Only one way to make an expression out of a single number\n", + " expr(numbers, numbers[0], str(numbers[0]), 1)\n", + " else: # Split in all ways; fill tables for left and right; combine tables in all ways\n", + " for (Lnums, Rnums) in splits(numbers):\n", + " for (L, R) in itertools.product(expressions(Lnums), expressions(Rnums)):\n", + " Lexp, Rexp = '(' + EXPS[Lnums][L], EXPS[Rnums][R] + ')'\n", + " count = COUNTS[Lnums][L] * COUNTS[Rnums][R]\n", + " if R != 0: \n", + " expr(numbers, divide(L, R), Lexp + '/' + Rexp, count)\n", + " expr(numbers, L * R, Lexp + '*' + Rexp, count)\n", + " expr(numbers, L - R, Lexp + '-' + Rexp, count)\n", + " expr(numbers, L + R, Lexp + '+' + Rexp, count)\n", + " return EXPS[numbers]\n", + "\n", + "def divide(L, R):\n", + " \"Exact rational division of L/R.\"\n", + " f = Fraction(L, R)\n", + " return (f.numerator if f.denominator == 1 else f)\n", + "\n", + "def expr(numbers, value, exp, count):\n", + " \"Fill EXPS[numbers][val] with exp, and increment COUNTS.\"\n", + " if numbers == c10 and value != 2016: \n", + " return\n", + " EXPS[numbers][value] = exp\n", + " COUNTS[numbers][value] += count" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The Answer (!)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 12min 25s, sys: 1.44 s, total: 12min 26s\n", + "Wall time: 12min 27s\n" + ] + }, + { + "data": { + "text/plain": [ + "44499" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clear()\n", + "\n", + "%time expressions(c10)[2016]\n", + "\n", + "COUNTS[c10][2016]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "That did indeed take about ten times longer, but we now have an answer that I have more confidence in (but I wouldn't accept it as definitive until it was independently verified and had an extensive test suite). And of course, if you have a different definition of \"distinct solution,\" you will get a different answer." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Dealing with the Exponentiation Operator\n", + "\n", + "Now let's turn to another of Alex's puzzles: making 2016 and other target values from a string of four or five `4`s, with exponentiation allowed. Exponentiation is tricky for five reasons:\n", + "\n", + "- **Division by zero**: `(0 ** -1)` is the same as `(1 / 0)`, and gives a `ZeroDivisionError`.\n", + "- **Irrationals**: `(3 ** (1 / 2))` is an irrational number; so we can't do exact rational arithmetic.\n", + "- **Imaginaries**: `(-1 ** (1 / 2))` is an imaginary number, but Python gives a `ValueError`.\n", + "- **Overflow**: `(10. ** (9. ** 8.))`, as a `float`, gives a `OverflowError`.\n", + "- **Finite memory**: [`(10 ** (9 ** (8 * 7)))`](http://www.wolframalpha.com/input/?i=10+%5E+9+%5E+56), as an `int`, gives an `OutOfMemoryError` (even if your memory was expanded to use every atom on Earth).\n", + "\n", + "How do we deal with this? We can't do exact rational arithmetic. We could try to do exact *algebra*, perhaps using [SymPy](http://www.sympy.org/en/index.html), but that seems difficult\n", + "and computationally expensive, so instead I will abandon the goal of exact computation, and do everything in the domain of floats (reluctantly accepting that there will be some round-off errors). We'll coerce numbers to floats when we first put them in the table, and all subsequent operations will be with floats. I define a new function, `expr2`, to call `expr`, catching arithmetic errors. Since we are making some rather arbitrary decisions about what expressions are allowed (e.g. imaginary numbers are not), I'll give up on trying to maintain `COUNTS`." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from operator import add, sub, mul, truediv\n", + "\n", + "def expressions(numbers):\n", + " \"Fill EXPS table for numbers, and all sub-sequences of numbers. Return EXPS[numbers]\"\n", + " if numbers in EXPS: # Already did the work\n", + " pass\n", + " elif len(numbers) == 1: # Only one way to make an expression out of a single number\n", + " expr(numbers, float(numbers[0]), str(numbers[0]))\n", + " else: # Split in all ways; fill tables for left and right; combine tables in all ways\n", + " for (Lnums, Rnums) in splits(numbers):\n", + " for (L, R) in itertools.product(expressions(Lnums), expressions(Rnums)):\n", + " Lexp, Rexp = '(' + EXPS[Lnums][L], EXPS[Rnums][R] + ')'\n", + " expr2(numbers, L, pow, R, Lexp + '**' + Rexp)\n", + " expr2(numbers, L, truediv, R, Lexp + '/' + Rexp)\n", + " expr2(numbers, L, mul, R, Lexp + '*' + Rexp)\n", + " expr2(numbers, L, add, R, Lexp + '+' + Rexp)\n", + " expr2(numbers, L, sub, R, Lexp + '-' + Rexp)\n", + " return EXPS[numbers]\n", + "\n", + "def expr2(numbers, L, op, R, exp): \n", + " \"Fill table entries for op(L, R), catching errors.\"\n", + " try:\n", + " expr(numbers, op(L, R), exp)\n", + " except (ArithmeticError, ValueError):\n", + " pass\n", + " \n", + "def expr(numbers, value, exp): EXPS[numbers][value] = exp" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can solve the \"2016 with five fours\" puzzle:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'(((4**4)-4)*(4+4))'" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clear()\n", + "\n", + "expressions((4, 4, 4, 4, 4))[2016]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I'll define a function to create a table of makeable integers:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def makeable(numbers):\n", + " \"A table of {i: expression} for all integers i from 0 up to first unmakeable.\"\n", + " return {i: expressions(numbers)[i]\n", + " for i in range(unmakeable(numbers))}\n", + "\n", + "def unmakeable(numbers):\n", + " \"Smallest positive integer than can't be made by numbers.\"\n", + " return next(i for i in itertools.count(1) if i not in expressions(numbers))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We'll use this to see if we can solve the \"0 to 9 with four fours\" puzzle:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: '(((4+4)-4)-4)',\n", + " 1: '(((4+4)-4)/4)',\n", + " 2: '((4/(4+4))*4)',\n", + " 3: '(((4+4)+4)/4)',\n", + " 4: '(((4-4)*4)+4)',\n", + " 5: '(((4*4)+4)/4)',\n", + " 6: '(((4+4)/4)+4)',\n", + " 7: '((4-(4/4))+4)',\n", + " 8: '(((4+4)-4)+4)',\n", + " 9: '(((4/4)+4)+4)'}" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "makeable((4, 4, 4, 4))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Yes: we can get 0 to 9 (but not 10).\n", + "\n", + "Now I'll see what integers we can make with five fives. Legend has it that you can get all the way up to 55:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: '((((5-5)*5)-5)+5)',\n", + " 1: '(((5-(5*5))/5)+5)',\n", + " 2: '((((5+5)/5)-5)+5)',\n", + " 3: '((((5*5)-5)-5)/5)',\n", + " 4: '((((5-5)-5)/5)+5)',\n", + " 5: '((5/((5**5)**5))+5)',\n", + " 6: '((((5/5)+5)*5)/5)',\n", + " 7: '(((5/5)+(5/5))+5)',\n", + " 8: '((((5+5)+5)/5)+5)',\n", + " 9: '((((5+5)*5)-5)/5)',\n", + " 10: '((((5*5)-5)-5)-5)',\n", + " 11: '((((5+5)*5)+5)/5)',\n", + " 12: '((((5+5)/5)+5)+5)'}" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ff = (5, 5, 5, 5, 5)\n", + "\n", + "makeable(ff)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We didn't get there. \n", + "\n", + "# More Operations\n", + "\n", + "With some research, I [see](http://www.infobarrel.com/Five_Fives_Problem_Recreational_Mathematics) that others who got up to 55 with five 5s used these three concepts:\n", + "\n", + "- **digit concatenation**: `55`\n", + "- **decimal point**: `.5`\n", + "- **unary operations**: `5!` and √ `5`\n", + "\n", + "\n", + "We'll refactor `expressions` to call these three new subfunctions:\n", + "\n", + "- `digit_expressions`: For every subsequence of numbers, we'll smush the digits together, and then make a table entry for those resulting digits as an integer, and with a decimal point in each possible position.\n", + "- `binary_expressions`: The code that previously was the main body of `expressions`.\n", + "- `unary_expressions`: Apply the unary operators to every entry in the table. (Because it applies to entries already in the table, make sure to call `unary_expressions` last.)\n", + "\n", + "We'll still do all computation in the domain of floats." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import sqrt, factorial\n", + "\n", + "def expressions(numbers):\n", + " \"Fill EXPS table for numbers, and all sub-sequences of numbers. Return EXPS[numbers]\"\n", + " if numbers not in EXPS: \n", + " digit_expressions(numbers)\n", + " binary_expressions(numbers)\n", + " unary_expressions(numbers)\n", + " return EXPS[numbers]\n", + "\n", + "def digit_expressions(numbers):\n", + " \"Fill tables with expressions made from the digits of numbers, and a decimal point.\"\n", + " exp = ''.join(str(n) for n in numbers)\n", + " expr(numbers, float(exp), exp)\n", + " for d in range(len(exp)):\n", + " decimal = exp[:d] + '.' + exp[d:]\n", + " expr(numbers, float(decimal), decimal)\n", + " \n", + "def binary_expressions(numbers):\n", + " \"Fill tables with all expressions formed by splitting numbers and combining with an op.\"\n", + " for (Lnums, Rnums) in splits(numbers):\n", + " for (L, R) in itertools.product(expressions(Lnums), expressions(Rnums)):\n", + " Lexp, Rexp = '(' + EXPS[Lnums][L], EXPS[Rnums][R] + ')'\n", + " if 1 <= R <= 10 and (L > 0 or int(R) == R):\n", + " expr2(numbers, L, pow, R, Lexp + '**' + Rexp)\n", + " expr2(numbers, L, truediv, R, Lexp + '/' + Rexp)\n", + " expr2(numbers, L, mul, R, Lexp + '*' + Rexp)\n", + " expr2(numbers, L, add, R, Lexp + '+' + Rexp)\n", + " expr2(numbers, L, sub, R, Lexp + '-' + Rexp)\n", + " \n", + "def unary_expressions(numbers):\n", + " for v in list(EXPS[numbers]):\n", + " exp = EXPS[numbers][v]\n", + " if v > 0: \n", + " expr(numbers, sqrt(v), '√' + exp)\n", + " if 2 <= v <= 6 and v == int(v):\n", + " expr(numbers, factorial(v), exp + '!')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now that we have more variety in the types of expressions formed, I want to choose a \"good\" expression to represent each value. I'll modify `expr` so that when there are multiple expressions for a value, it chooses the one with the least \"weight,\" where I define `weight` as the length of the string, plus a penalty of 1 for every square root sign (just because square root feels \"heavier\" than the other operations):" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def expr(numbers, value, exp): \n", + " if value not in EXPS[numbers] or weight(exp) < weight(EXPS[numbers][value]):\n", + " EXPS[numbers][value] = exp\n", + " \n", + "def weight(exp): return len(exp) + exp.count('√')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We'll try again:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 43.5 s, sys: 1.44 s, total: 45 s\n", + "Wall time: 45 s\n" + ] + }, + { + "data": { + "text/plain": [ + "{0: '(5*(55-55))',\n", + " 1: '((55/55)**5)',\n", + " 2: '(55/(.5*55))',\n", + " 3: '√(5!-(555/5))',\n", + " 4: '(5-(55/55))',\n", + " 5: '(5.55-.55)',\n", + " 6: '(5+(55/55))',\n", + " 7: '(((5+55)/5)-5)',\n", + " 8: '(.5*(5+(55/5)))',\n", + " 9: '(5!-(555/5))',\n", + " 10: '(5!-(55+55))',\n", + " 11: '(5.5/(5.5-5))',\n", + " 12: '(5!/(55/5.5))',\n", + " 13: '((5+(5+55))/5)',\n", + " 14: '((5*5)-(55/5))',\n", + " 15: '(5+(55/5.5))',\n", + " 16: '(5+(5.5+5.5))',\n", + " 17: '(5+((5+55)/5))',\n", + " 18: '(5+((5!-55)/5))',\n", + " 19: '((5*5)-(.5+5.5))',\n", + " 20: '(55/(5*.55))',\n", + " 21: '(5+(5+(55/5)))',\n", + " 22: '((55+55)/5)',\n", + " 23: '((5+(55/.5))/5)',\n", + " 24: '(5-(55/55))!',\n", + " 25: '(55-(5+(5*5)))',\n", + " 26: '(55-(5+(5!/5)))',\n", + " 27: '(.5*(55-(5/5)))',\n", + " 28: '(.5*(.5+55.5))',\n", + " 29: '(5+(5!/(5.5-.5)))',\n", + " 30: '(5*((55/5)-5))',\n", + " 31: '(55-(5-(5/5))!)',\n", + " 32: '(55-((5!-5)/5))',\n", + " 33: '(.55*(5+55))',\n", + " 34: '((5!+(55-5))/5)',\n", + " 35: '(5+(55-(5*5)))',\n", + " 36: '((5*5)+(55/5))',\n", + " 37: '((5!+(5!-55))/5)',\n", + " 38: '(5+(.5*(5!*.55)))',\n", + " 39: '(((5*5)-5.5)/.5)',\n", + " 40: '(55-(5+(5+5)))',\n", + " 41: '(5!-((5!/5)+55))',\n", + " 42: '((5+5.5)/(.5*.5))',\n", + " 43: '(55-(5!/(5+5)))',\n", + " 44: '(55-(55/5))',\n", + " 45: '((5*5!)-555)',\n", + " 46: '(55-((5-.5)/.5))',\n", + " 47: '((5!/5)+((5!-5)/5))',\n", + " 48: '(5!/(5*(5.5-5)))',\n", + " 49: '(55-(.5+5.5))',\n", + " 50: '(55.5-5.5)',\n", + " 51: '(.5+(55.5-5))',\n", + " 52: '(55-(.5+(.5*5)))',\n", + " 53: '(55.5-(.5*5))',\n", + " 54: '(((5*55)-5)/5)',\n", + " 55: '(.5*(55+55))',\n", + " 56: '((5+(5*55))/5)',\n", + " 57: '(55+((5+5)/5))',\n", + " 58: '((.5*5)+55.5)',\n", + " 59: '(5+(55-(5/5)))',\n", + " 60: '(5+(55.5-.5))',\n", + " 61: '(5.5+55.5)',\n", + " 62: '((55-(5!/5))/.5)',\n", + " 63: '(5.5+(.5*(5!-5)))',\n", + " 64: '(5!-(.5+55.5))',\n", + " 65: '(.5+(5!-55.5))',\n", + " 66: '(55+(55/5))',\n", + " 67: '(55+(5!/(5+5)))',\n", + " 68: '(5.5+(.5*(5+5!)))',\n", + " 69: '(5!-((.5+(5*5))/.5))',\n", + " 70: '(5+(5+(5+55)))',\n", + " 71: '((.5*5!)+(55/5))',\n", + " 72: '((.5+5.5)!/(5+5))',\n", + " 73: '((5*5)+(5!/(.5*5)))',\n", + " 74: '((5!/5)+(55-5))',\n", + " 75: '((5*5)+(55-5))',\n", + " 76: '(5+(5+(5!*.55)))',\n", + " 77: '(5+(.5*(5!+(5!/5))))',\n", + " 78: '(55+((5!-5)/5))',\n", + " 79: '(55+(5-(5/5))!)',\n", + " 80: '(5*(5+(55/5)))',\n", + " 81: '((√.5+(5!/√(5-.5)))/√.5)',\n", + " 82: '(5!-(((5!/5)-5)/.5))',\n", + " 83: '((.5*5!)+((5!-5)/5))',\n", + " 84: '(5+((5!/5)+55))',\n", + " 85: '(5+((5*5)+55))',\n", + " 86: '((55/.5)-(5!/5))',\n", + " 87: '((555-5!)/5)',\n", + " 88: '(.5+(.5*(5!+55)))',\n", + " 89: '(5!-(55-(5!/5)))',\n", + " 90: '(5!-(55-(5*5)))',\n", + " 91: '((5*5)+(5!*.55))',\n", + " 92: '(5!-(.5+(.5*55)))',\n", + " 93: '(.5+(5!-(.5*55)))',\n", + " 94: '(5!-((5/5)+(5*5)))',\n", + " 95: '(((55-5)/.5)-5)',\n", + " 96: '(5!-(5!/(5.5-.5)))',\n", + " 97: '(5!-((5!/5)-(5/5)))',\n", + " 98: '(5!-(55/(.5*5)))',\n", + " 99: '((55-5.5)/.5)',\n", + " 100: '((55/.5)-(5+5))',\n", + " 101: '((55.5-5)/.5)',\n", + " 102: '(5+(5!-((5!-5)/5)))',\n", + " 103: '(55+(5!/(.5*5)))',\n", + " 104: '(5!-(5+(55/5)))',\n", + " 105: '(55+(55-5))',\n", + " 106: '((555/5)-5)',\n", + " 107: '(5!-((5!-55)/5))',\n", + " 108: '(5!-((5+55)/5))',\n", + " 109: '(5!-(5.5+5.5))',\n", + " 110: '((555-5)/5)',\n", + " 111: '(555/√(5*5))',\n", + " 112: '((5+555)/5)',\n", + " 113: '(5!-(5+((5+5)/5)))',\n", + " 114: '(5+(5!-(55/5)))',\n", + " 115: '(5+(55+55))',\n", + " 116: '(5+(555/5))',\n", + " 117: '(5!-(5.5-(.5*5)))',\n", + " 118: '(5!-(5!/(5+55)))',\n", + " 119: '(5!-(55/55))',\n", + " 120: '(5.55-.55)!',\n", + " 121: '(5!+(55/55))',\n", + " 122: '(5!+(5!/(5+55)))',\n", + " 123: '(5!+(5.5-(.5*5)))',\n", + " 124: '(5!+√(5+(55/5)))',\n", + " 125: '(.5*(5*(55-5)))',\n", + " 126: '(5!+((55/5)-5))',\n", + " 127: '((5!/(5/5.5))-5)',\n", + " 128: '(5!+(5.5+(.5*5)))',\n", + " 129: '((5!-55.5)/.5)',\n", + " 130: '(5!+(55/5.5))',\n", + " 131: '(5!+(5.5+5.5))',\n", + " 132: '(5!*(.55+.55))',\n", + " 133: '(5!+((5!-55)/5))',\n", + " 134: '((5!/5)+(55/.5))',\n", + " 135: '((5!+555)/5)',\n", + " 136: '(5+(5!+(55/5)))',\n", + " 137: '(5+(5!/(5/5.5)))',\n", + " 138: '(.5+(.5*(5*55)))',\n", + " 139: '(((.5+5.5)!/5)-5)',\n", + " 140: '(.5*(5+(5*55)))',\n", + " 141: '(5!+((5+5.5)/.5))',\n", + " 142: '(5!+(55/(.5*5)))',\n", + " 143: '(((.5+5.5)!-5)/5)',\n", + " 144: '(((55/5)-5)!/5)',\n", + " 145: '(5!+(.5*(55-5)))',\n", + " 146: '(5!+((5/5)+(5*5)))',\n", + " 147: '(5!+((.5*55)-.5))',\n", + " 148: '(.5+(5!+(.5*55)))',\n", + " 149: '(5+((.5+5.5)!/5))',\n", + " 150: '(5*(55-(5*5)))',\n", + " 151: '(5!+(55-(5!/5)))',\n", + " 152: '(5!+(((5+5)/5)**5))',\n", + " 153: '(5!+(.5*(5!*.55)))',\n", + " 154: '(5+(5+(5!+(5!/5))))',\n", + " 155: '(5*(55-(5!/5)))',\n", + " 156: '((5!+(5!*5.5))/5)'}" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clear()\n", + "\n", + "%time makeable(ff)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Wow! We almost tripled the 55 goal! I have to say, I would never have come up with the solution for 81 on my own. It works because (√(5 - .5) \\* √0.5) = √(4.5 \\* 0.5) = (√2.25) = 1.5." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Even More Operations \n", + "\n", + "At the risk of making the computation take even longer, I'm going to add two more operations:\n", + "\n", + "- **Floor**: ⌊*x*⌋ is the largest integer less than or equal to *x* (in other words, rounding down).\n", + "- **Ceiling**: ⌈*x*⌉ is the smallest integer greater than or equal to *x* (in other words, rounding up).\n", + "\n", + "These operations are useful because they produce integers, and our targets are the integers (from 0 up to whatever). \n", + "\n", + "In addition, I'll allow two consecutive applications of unary operators, thus allowing expressions such as\n", + "\n", + "- ⌊√5⌋ = 2\n", + "- ⌈5.5⌉! = 720\n", + "\n", + "But still not allowing three consecutive applications, such as\n", + "\n", + "- ⌈√5⌉! = 6\n", + "\n", + "To compensate for these new expressions, I'll be pickier about when I allow the square root function to apply." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import floor, ceil\n", + "\n", + "def unary_expressions(numbers):\n", + " for i in range(2):\n", + " for v in list(EXPS[numbers]):\n", + " exp = EXPS[numbers][v]\n", + " if 0 < v <= 100 and 4*v == round(4*v):\n", + " expr(numbers, sqrt(v), '√' + exp)\n", + " if 2 <= v <= 6 and v == round(v):\n", + " expr(numbers, factorial(v), exp + '!')\n", + " if v != round(v):\n", + " uexp = unbracket(exp)\n", + " expr(numbers, floor(v), '⌊' + uexp + '⌋')\n", + " expr(numbers, ceil(v), '⌈' + uexp + '⌉')\n", + " \n", + "def unbracket(exp):\n", + " \"Remove outer brackets from exp if they are there.\"\n", + " if exp.startswith('(') and exp.endswith(')'):\n", + " return exp[1:-1]\n", + " else:\n", + " return exp" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's try:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2min 25s, sys: 1.42 s, total: 2min 26s\n", + "Wall time: 2min 26s\n" + ] + }, + { + "data": { + "text/plain": [ + "{0: '⌊.55555⌋',\n", + " 1: '⌈.55555⌉',\n", + " 2: '⌊5*.5555⌋',\n", + " 3: '⌈5*.5555⌉',\n", + " 4: '⌊5-.5555⌋',\n", + " 5: '⌊5.5555⌋',\n", + " 6: '⌈5.5555⌉',\n", + " 7: '⌈.5+5.555⌉',\n", + " 8: '⌈√55+.555⌉',\n", + " 9: '⌊55/5.55⌋',\n", + " 10: '⌊555/55⌋',\n", + " 11: '⌈555/55⌉',\n", + " 12: '⌈55.55/5⌉',\n", + " 13: '⌈√5*5.555⌉',\n", + " 14: '⌈√55/.555⌉',\n", + " 15: '(5+(55/5.5))',\n", + " 16: '(5+⌊55.5/5⌋)',\n", + " 17: '(5+⌈55.5/5⌉)',\n", + " 18: '⌊55/⌈5*.55⌉⌋',\n", + " 19: '⌈55/⌈5*.55⌉⌉',\n", + " 20: '(5*⌊5-.555⌋)',\n", + " 21: '⌊5!/5.555⌋',\n", + " 22: '⌈5!/5.555⌉',\n", + " 23: '⌈555/(5*5)⌉',\n", + " 24: '⌊5-.5555⌋!',\n", + " 25: '(5*⌊5.555⌋)',\n", + " 26: '(⌈.55*55⌉-5)',\n", + " 27: '⌊5*5.555⌋',\n", + " 28: '⌈5*5.555⌉',\n", + " 29: '(5+⌊5-.555⌋!)',\n", + " 30: '⌊55*.555⌋',\n", + " 31: '⌈55*.555⌉',\n", + " 32: '(5+⌊5*5.55⌋)',\n", + " 33: '(5+⌈5*5.55⌉)',\n", + " 34: '⌈⌈5.5⌉*5.55⌉',\n", + " 35: '(5+⌊.55*55⌋)',\n", + " 36: '(5+⌈.55*55⌉)',\n", + " 37: '⌊5*(55/√55)⌋',\n", + " 38: '⌊⌊√55⌋*5.55⌋',\n", + " 39: '⌊√.5*55.55⌋',\n", + " 40: '⌊5.5*√55.5⌋',\n", + " 41: '⌊√55*5.55⌋',\n", + " 42: '⌈√55*5.55⌉',\n", + " 43: '(55-⌊5+√55⌋)',\n", + " 44: '(55-(55/5))',\n", + " 45: '(5*⌊5/.555⌋)',\n", + " 46: '⌊5555/5!⌋',\n", + " 47: '⌈5555/5!⌉',\n", + " 48: '⌈55-√55.5⌉',\n", + " 49: '⌊55-5.55⌋',\n", + " 50: '⌊55.55-5⌋',\n", + " 51: '⌈55.55-5⌉',\n", + " 52: '(55-⌈5*.55⌉)',\n", + " 53: '⌊55.55-√5⌋',\n", + " 54: '⌊55-.555⌋',\n", + " 55: '⌊55.555⌋',\n", + " 56: '⌈55.555⌉',\n", + " 57: '⌈.5+55.55⌉',\n", + " 58: '⌈√5+55.55⌉',\n", + " 59: '(5+⌊55-.55⌋)',\n", + " 60: '⌊5+55.55⌋',\n", + " 61: '⌈5+55.55⌉',\n", + " 62: '⌊√55+55.5⌋',\n", + " 63: '⌈√55+55.5⌉',\n", + " 64: '⌊5!-55.55⌋',\n", + " 65: '⌈5!-55.55⌉',\n", + " 66: '⌊5!*.5555⌋',\n", + " 67: '⌈5!*.5555⌉',\n", + " 68: '(5+⌈55+√55⌉)',\n", + " 69: '⌊555/⌈√55⌉⌋',\n", + " 70: '⌈555/⌈√55⌉⌉',\n", + " 71: '(5+⌊5!*.555⌋)',\n", + " 72: '(5+⌈5!*.555⌉)',\n", + " 73: '(5!-⌊55-√55⌋)',\n", + " 74: '⌊555/√55⌋',\n", + " 75: '⌈555/√55⌉',\n", + " 76: '(55+⌊5!/5.5⌋)',\n", + " 77: '(55+⌈5!/5.5⌉)',\n", + " 78: '⌊55.55/√.5⌋',\n", + " 79: '⌊555/⌊√55⌋⌋',\n", + " 80: '⌊(5*5)+55.5⌋',\n", + " 81: '⌈(5*5)+55.5⌉',\n", + " 82: '(55+⌊.5*55⌋)',\n", + " 83: '(55+⌈.5*55⌉)',\n", + " 84: '(5+((5!/5)+55))',\n", + " 85: '(5+(55+(5*5)))',\n", + " 86: '⌊⌈5+55.5⌉/√.5⌋',\n", + " 87: '((555-5!)/5)',\n", + " 88: '⌈√5**5.555⌉',\n", + " 89: '(5!-⌈.55*55⌉)',\n", + " 90: '⌊(55-5)/.55⌋',\n", + " 91: '⌈(55-5)/.55⌉',\n", + " 92: '⌊555/⌈5.5⌉⌋',\n", + " 93: '⌈555/⌈5.5⌉⌉',\n", + " 94: '(⌊55/.55⌋-5)',\n", + " 95: '(⌈55/.55⌉-5)',\n", + " 96: '⌊.55*(5!+55)⌋',\n", + " 97: '⌈.55*(5!+55)⌉',\n", + " 98: '(⌊55-5.5⌋/.5)',\n", + " 99: '⌊55/.555⌋',\n", + " 100: '⌊555/5.5⌋',\n", + " 101: '⌈555/5.5⌉',\n", + " 102: '⌈⌈55.5⌉/.55⌉',\n", + " 103: '⌊⌊√5+55⌋/.55⌋',\n", + " 104: '(5+⌊55/.55⌋)',\n", + " 105: '(55+(55-5))',\n", + " 106: '((555/5)-5)',\n", + " 107: '(55+⌊55-√5⌋)',\n", + " 108: '(5!-⌈55.5/5⌉)',\n", + " 109: '(55+⌊55-.5⌋)',\n", + " 110: '⌊55+55.5⌋',\n", + " 111: '⌈55+55.5⌉',\n", + " 112: '⌈555.5/5⌉',\n", + " 113: '(55+⌈√5+55⌉)',\n", + " 114: '⌊5!-5.555⌋',\n", + " 115: '⌈5!-5.555⌉',\n", + " 116: '(5+(555/5))',\n", + " 117: '(5!-⌈5*.555⌉)',\n", + " 118: '(5!-⌈5.55/5⌉)',\n", + " 119: '⌊5!-.5555⌋',\n", + " 120: '⌊5.5555⌋!',\n", + " 121: '⌈5!+.5555⌉',\n", + " 122: '(5!+⌈5.55/5⌉)',\n", + " 123: '⌊555/(5-.5)⌋',\n", + " 124: '⌊√5*55.55⌋',\n", + " 125: '⌊5!+5.555⌋',\n", + " 126: '⌈5!+5.555⌉',\n", + " 127: '⌊⌊5**5.5⌋/55⌋',\n", + " 128: '⌈⌊5**5.5⌋/55⌉',\n", + " 129: '(5!+⌊5/.555⌋)',\n", + " 130: '⌊√5.5*55.5⌋',\n", + " 131: '⌈√5.5*55.5⌉',\n", + " 132: '(5!+⌈55.5/5⌉)',\n", + " 133: '⌈55*(√55-5)⌉',\n", + " 134: '⌊55*√⌈5.55⌉⌋',\n", + " 135: '(5*⌊5*5.55⌋)',\n", + " 136: '⌈√⌈5.5⌉*55.5⌉',\n", + " 137: '⌊5.5*⌈55/√5⌉⌋',\n", + " 138: '⌊5*(5*5.55)⌋',\n", + " 139: '⌈5*(5*5.55)⌉',\n", + " 140: '(5*⌈5*5.55⌉)',\n", + " 141: '(5!+⌊5!/5.55⌋)',\n", + " 142: '(5!+⌈5!/5.55⌉)',\n", + " 143: '(5+⌈.5*(5*55)⌉)',\n", + " 144: '(⌈5.555⌉!/5)',\n", + " 145: '(5+(5*⌈.5*55⌉))',\n", + " 146: '⌊55*(5-√5.5)⌋',\n", + " 147: '(5!+⌊5*5.55⌋)',\n", + " 148: '(5!+⌈5*5.55⌉)',\n", + " 149: '⌈5.5*⌊.5*55⌋⌉',\n", + " 150: '(5*⌊.55*55⌋)',\n", + " 151: '⌊.55*(5*55)⌋',\n", + " 152: '⌈.55*(5*55)⌉',\n", + " 153: '⌊55*(√5+.55)⌋',\n", + " 154: '(5.5*⌈.5*55⌉)',\n", + " 155: '(5*⌈.55*55⌉)',\n", + " 156: '⌈(55+55)/√.5⌉',\n", + " 157: '(⌊.5*555⌋-5!)',\n", + " 158: '(⌈.5*555⌉-5!)',\n", + " 159: '(5!+⌊√.5*55.5⌋)',\n", + " 160: '(5*(5+⌊.5*55⌋))',\n", + " 161: '⌊(.5*5)**5.55⌋',\n", + " 162: '⌈(.5*5)**5.55⌉',\n", + " 163: '(⌊5!/.55⌋-55)',\n", + " 164: '(⌈5!/.55⌉-55)',\n", + " 165: '(55*⌈5*.55⌉)',\n", + " 166: '⌊⌈.5*5⌉*55.5⌋',\n", + " 167: '⌈⌈.5*5⌉*55.5⌉',\n", + " 168: '(5!+⌈55-√55⌉)',\n", + " 169: '(5!+⌊55-5.5⌋)',\n", + " 170: '(5!+⌊55.5-5⌋)',\n", + " 171: '(5!+⌈55.5-5⌉)',\n", + " 172: '⌈5.555**⌈√5⌉⌉',\n", + " 173: '⌊55*√⌊5+5.5⌋⌋',\n", + " 174: '(5!+⌊55-.55⌋)',\n", + " 175: '⌊5!+55.55⌋',\n", + " 176: '⌈5!+55.55⌉',\n", + " 177: '(55+⌊√5*55⌋)',\n", + " 178: '(55+⌈√5*55⌉)',\n", + " 179: '⌊55*(5.5-√5)⌋',\n", + " 180: '(5+⌊5!+55.5⌋)',\n", + " 181: '(5+⌈5!+55.5⌉)',\n", + " 182: '(⌊5.5*55⌋-5!)',\n", + " 183: '(⌈5.5*55⌉-5!)',\n", + " 184: '(5!+⌊5!-55.5⌋)',\n", + " 185: '(555/⌈.5*5⌉)',\n", + " 186: '⌈555.5/⌈√5⌉⌉',\n", + " 187: '(5!+⌈5!*.555⌉)',\n", + " 188: '((⌈.5*5⌉**5)-55)',\n", + " 189: '(⌊√55⌋*⌊.5*55⌋)',\n", + " 190: '(5*⌈5*√55.5⌉)',\n", + " 191: '⌈55*√⌊5+√55⌋⌉',\n", + " 192: '(⌈5.55⌉/(.5**5))',\n", + " 193: '⌊5!**(.55+.55)⌋',\n", + " 194: '⌊(555-5!)/√5⌋',\n", + " 195: '⌈(555-5!)/√5⌉',\n", + " 196: '(.5*⌊√.5*555⌋)',\n", + " 197: '⌈.5*⌈√.5*555⌉⌉',\n", + " 198: '(⌊55/.55⌋/.5)',\n", + " 199: '⌊55/(.5*.55)⌋',\n", + " 200: '(⌈55/.55⌉/.5)',\n", + " 201: '⌈555/(5-√5)⌉',\n", + " 202: '⌊555/(.5+√5)⌋',\n", + " 203: '⌊.5*⌊55*√55⌋⌋',\n", + " 204: '(.5*⌈55*√55⌉)',\n", + " 205: '(5*⌈5.5*√55⌉)',\n", + " 206: '⌈⌈5!-√55⌉/.55⌉',\n", + " 207: '⌊(5!-5)/.555⌋',\n", + " 208: '⌈(5!-5)/.555⌉',\n", + " 209: '(5.5*⌈5*√55⌉)',\n", + " 210: '⌈⌈5!-5.5⌉/.55⌉',\n", + " 211: '(⌊5!/.555⌋-5)',\n", + " 212: '(⌈5!/.555⌉-5)',\n", + " 213: '⌈⌊5!/.55⌋-5.5⌉',\n", + " 214: '⌈⌈5!/.55⌉-5.5⌉',\n", + " 215: '⌊⌊5!/.555⌋-.5⌋',\n", + " 216: '⌊5!/.5555⌋',\n", + " 217: '⌈5!/.5555⌉',\n", + " 218: '⌈.5*(555-5!)⌉',\n", + " 219: '(5!+⌊55/.55⌋)',\n", + " 220: '((5*55)-55)',\n", + " 221: '(5+⌊5!/.555⌋)',\n", + " 222: '(555/(.5*5))',\n", + " 223: '⌊5.5+⌊5!/.55⌋⌋',\n", + " 224: '⌊5.5+⌈5!/.55⌉⌋',\n", + " 225: '⌊(5+5!)/.555⌋',\n", + " 226: '⌈(5+5!)/.555⌉',\n", + " 227: '⌈555/√⌈5.5⌉⌉',\n", + " 228: '(⌊5!-5.55⌋/.5)',\n", + " 229: '⌈(5!-5.55)/.5⌉',\n", + " 230: '(5!+(55+55))',\n", + " 231: '(5!+(555/5))',\n", + " 232: '⌈(5!+√55)/.55⌉',\n", + " 233: '⌈⌈5!+√55⌉/.55⌉',\n", + " 234: '(5!+⌊5!-5.55⌋)',\n", + " 235: '(5*⌊55-√55⌋)',\n", + " 236: '⌊555/√5.5⌋',\n", + " 237: '⌈555/√5.5⌉',\n", + " 238: '⌈5*(55-√55)⌉',\n", + " 239: '(5!+⌊5!-.555⌋)',\n", + " 240: '(5*⌈55-√55⌉)',\n", + " 241: '(5!+⌈5!+.555⌉)',\n", + " 242: '(⌈5!+.555⌉/.5)',\n", + " 243: '(⌈5*.555⌉**5)',\n", + " 244: '⌊55*(5-.55)⌋',\n", + " 245: '(5*⌊55-5.5⌋)',\n", + " 246: '⌈(555-5)/√5⌉',\n", + " 247: '⌊5*(55-5.5)⌋',\n", + " 248: '⌊555.5/√5⌋',\n", + " 249: '⌈555.5/√5⌉',\n", + " 250: '(5*⌊55.5-5⌋)',\n", + " 251: '⌈(5+555)/√5⌉',\n", + " 252: '⌊5*(55.5-5)⌋',\n", + " 253: '⌈5*(55.5-5)⌉',\n", + " 254: '(5+⌈555/√5⌉)',\n", + " 255: '(5*⌈55.5-5⌉)',\n", + " 256: '(⌊55*√5.5⌋/.5)',\n", + " 257: '⌊55/(.5/√5.5)⌋',\n", + " 258: '(⌈55*√5.5⌉/.5)',\n", + " 259: '⌊5!/(55.5/5!)⌋',\n", + " 260: '(5*⌊55-√5.5⌋)',\n", + " 261: '⌈(5*.55)**5.5⌉',\n", + " 262: '⌈555/√(5-.5)⌉',\n", + " 263: '⌊5*(55-√5.5)⌋',\n", + " 264: '⌈5*(55-√5.5)⌉',\n", + " 265: '(5*⌈55-√5.5⌉)',\n", + " 266: '⌊5*(55.5-√5)⌋',\n", + " 267: '⌊(5*55)-√55⌋',\n", + " 268: '⌈(5*55)-√55⌉',\n", + " 269: '⌊(5*55)-5.5⌋',\n", + " 270: '(5*⌊55-.55⌋)',\n", + " 271: '(⌈.5-5⌉+(5*55))',\n", + " 272: '(⌊.5*555⌋-5)',\n", + " 273: '(⌈.5*555⌉-5)',\n", + " 274: '⌊(5*55)-.55⌋',\n", + " 275: '(5*⌊55.55⌋)',\n", + " 276: '⌈.55+(5*55)⌉',\n", + " 277: '⌊5*55.55⌋',\n", + " 278: '⌈5*55.55⌉',\n", + " 279: '⌈.5+⌈.5*555⌉⌉',\n", + " 280: '(5*⌈55.55⌉)',\n", + " 281: '⌈5.5+(5*55)⌉',\n", + " 282: '(5+⌊.5*555⌋)',\n", + " 283: '(5+⌈.5*555⌉)',\n", + " 284: '⌊5*((5**5)/55)⌋',\n", + " 285: '(5*⌊√5+55.5⌋)',\n", + " 286: '(5.5*⌊55-√5⌋)',\n", + " 287: '(555-⌊√5*5!⌋)',\n", + " 288: '(⌈55*√55⌉-5!)',\n", + " 289: '⌈55*√(.5*55)⌉',\n", + " 290: '(5*⌈√5+55.5⌉)',\n", + " 291: '⌊5.5*⌈55-√5⌉⌋',\n", + " 292: '⌈5.5*⌈55-√5⌉⌉',\n", + " 293: '⌊5!*√⌈5.555⌉⌋',\n", + " 294: '⌈5!*√⌈5.555⌉⌉',\n", + " 295: '(5!+⌊5!+55.5⌋)',\n", + " 296: '(5!+⌈5!+55.5⌉)',\n", + " 297: '(⌊5.5*55⌋-5)',\n", + " 298: '(⌈5.5*55⌉-5)',\n", + " 299: '⌊5.5*(55-.5)⌋',\n", + " 300: '(5*⌊5+55.5⌋)',\n", + " 301: '⌊⌊5.5*55⌋-.5⌋',\n", + " 302: '⌊5*(5+55.5)⌋',\n", + " 303: '⌈5*(5+55.5)⌉',\n", + " 304: '⌈.5+⌈5.5*55⌉⌉',\n", + " 305: '⌊.55*555⌋',\n", + " 306: '⌈.55*555⌉',\n", + " 307: '(5+⌊5.5*55⌋)',\n", + " 308: '(5+⌈5.5*55⌉)',\n", + " 309: '(⌈(√.5+5)*55⌉-5)',\n", + " 310: '(5*⌊55+√55⌋)',\n", + " 311: '⌈(√5**5)*5.55⌉',\n", + " 312: '⌊5*(55+√55)⌋',\n", + " 313: '⌈5*(55+√55)⌉',\n", + " 314: '⌈5.5*⌊√5+55⌋⌉',\n", + " 315: '(5*⌈55+√55⌉)',\n", + " 316: '⌊√(55/5.5)**5⌋',\n", + " 317: '⌈√(55/5.5)**5⌉',\n", + " 318: '⌊(5!+55)/.55⌋',\n", + " 319: '⌈(5!+55)/.55⌉',\n", + " 320: '(5*⌊5!-55.5⌋)',\n", + " 321: '⌊⌈5.555⌉!/√5⌋',\n", + " 322: '⌊5*(5!-55.5)⌋',\n", + " 323: '⌈5*(5!-55.5)⌉',\n", + " 324: '(⌈5.5⌉*⌊55-.5⌋)',\n", + " 325: '(5*⌈5!-55.5⌉)',\n", + " 326: '⌈(5!/55)**√55⌉',\n", + " 327: '(⌈5.5⌉*(55-.5))',\n", + " 328: '⌈.5*(55+(5*5!))⌉',\n", + " 329: '⌊(55*⌈5.5⌉)-.5⌋',\n", + " 330: '(55*⌈5.55⌉)',\n", + " 331: '⌈.5+(55*⌈5.5⌉)⌉',\n", + " 332: '⌊.55*(5+(5*5!))⌋',\n", + " 333: '(⌈5.5⌉*55.5)',\n", + " 334: '⌈5*(5!*.555)⌉',\n", + " 335: '(5*⌈5!*.555⌉)',\n", + " 336: '(5!+⌊5!/.555⌋)',\n", + " 337: '⌊.5*(5!+555)⌋',\n", + " 338: '⌈.5*(5!+555)⌉',\n", + " 339: '⌊55*√⌈5*√55⌉⌋',\n", + " 340: '⌈55*√⌈5*√55⌉⌉',\n", + " 341: '⌊55*(√.5+5.5)⌋',\n", + " 342: '⌈55*(√.5+5.5)⌉',\n", + " 343: '⌊5*(.55*(5+5!))⌋',\n", + " 344: '⌈5*(.55*(5+5!))⌉',\n", + " 345: '(5*⌈.55*(5+5!)⌉)',\n", + " 346: '(⌊55*√(5+5)⌋/.5)',\n", + " 347: '⌊5!*(.55+√5.5)⌋',\n", + " 348: '(⌈5.5⌉*⌈√5+55⌉)',\n", + " 349: '(⌊(5-.55)**5⌋/5)',\n", + " 350: '(⌊5!+55.5⌋/.5)',\n", + " 351: '((5!+55.5)/.5)',\n", + " 352: '(⌈5!+55.5⌉/.5)',\n", + " 353: '⌈⌈555/√5⌉/√.5⌉',\n", + " 354: '⌊(.5*⌈5.5⌉!)-5.5⌋',\n", + " 355: '(5*(5+(5!*.55)))',\n", + " 356: '⌈(55/5)**√⌈5.5⌉⌉',\n", + " 357: '⌊5.5*(5!-55)⌋',\n", + " 358: '⌈5.5*(5!-55)⌉',\n", + " 359: '⌊.5*⌊⌈5.55⌉!-.5⌋⌋',\n", + " 360: '(.5*⌈5.555⌉!)',\n", + " 361: '⌊(√5+5)*(55-5)⌋',\n", + " 362: '⌊.5*(5+⌈5.55⌉!)⌋',\n", + " 363: '(5.5*(5!*.55))',\n", + " 364: '⌈5!*(.55*5.5)⌉',\n", + " 365: '(5+(.5*⌈5.55⌉!))',\n", + " 366: '(5!*(.55+(.5*5)))',\n", + " 367: '(5!+⌊55*(5-.5)⌋)',\n", + " 368: '(5!+⌊555/√5⌋)',\n", + " 369: '(5!+⌈555/√5⌉)',\n", + " 370: '⌊√55*(55-5)⌋',\n", + " 371: '⌈√55*(55-5)⌉',\n", + " 372: '(55+⌈√(5+5)**5⌉)',\n", + " 373: '⌊55*√⌈5.5**√5⌉⌋',\n", + " 374: '⌈55*√⌈5.5**√5⌉⌉',\n", + " 375: '(5*⌈(5+5)*√55⌉)',\n", + " 376: '(55+⌊⌈5.5⌉!/√5⌋)',\n", + " 377: '(55+⌈⌈5.5⌉!/√5⌉)',\n", + " 378: '(⌊√55⌋*⌊55-.5⌋)',\n", + " 379: '⌊5!*√(55/5.5)⌋',\n", + " 380: '⌊55*(√55-.5)⌋',\n", + " 381: '⌈55*(√55-.5)⌉',\n", + " 382: '⌈55**(√55/5)⌉',\n", + " 383: '(5!+⌊5*(55-√5)⌋)',\n", + " 384: '⌊(55*⌊√55⌋)-.5⌋',\n", + " 385: '(55*⌊√55.5⌋)',\n", + " 386: '(555-⌊5!/√.5⌋)',\n", + " 387: '(⌊√.5*555⌋-5)',\n", + " 388: '⌊⌊√55⌋*55.5⌋',\n", + " 389: '⌈⌊√55⌋*55.5⌉',\n", + " 390: '(5*⌊55.5/√.5⌋)',\n", + " 391: '⌊⌊√.5*555⌋-.5⌋',\n", + " 392: '⌊√.5*555.5⌋',\n", + " 393: '⌈√.5*555.5⌉',\n", + " 394: '⌈√.5*⌈555.5⌉⌉',\n", + " 395: '⌊√.5*(5+555)⌋',\n", + " 396: '⌊.55*⌈5.55⌉!⌋',\n", + " 397: '(5!+⌊.5*555⌋)',\n", + " 398: '(5!+⌈.5*555⌉)',\n", + " 399: '⌊⌈5.5⌉!*.555⌋',\n", + " 400: '⌈⌈5.5⌉!*.555⌉',\n", + " 401: '⌊(√5+5)*55.5⌋',\n", + " 402: '(⌊55*√55⌋-5)',\n", + " 403: '(⌈55*√55⌉-5)',\n", + " 404: '⌊√55*(55-.5)⌋',\n", + " 405: '⌈√55*(55-.5)⌉',\n", + " 406: '⌊⌊55*√55⌋-.5⌋',\n", + " 407: '⌊55*√⌊55.5⌋⌋',\n", + " 408: '⌈55*√⌊55.5⌋⌉',\n", + " 409: '⌊55*√55.5⌋',\n", + " 410: '⌈55*√55.5⌉',\n", + " 411: '⌊√55*55.5⌋',\n", + " 412: '⌈√55*55.5⌉',\n", + " 413: '(5+⌈55*√55⌉)',\n", + " 414: '⌈√55.5**⌈.5*5⌉⌉',\n", + " 415: '⌊√55*⌈55.5⌉⌋',\n", + " 416: '⌈√55*⌈55.5⌉⌉',\n", + " 417: '⌊5*(5**(5*.55))⌋',\n", + " 418: '⌊55*√⌈√5+55⌉⌋',\n", + " 419: '⌊(5**5)/√55.5⌋',\n", + " 420: '⌊⌈5*.55⌉**5.5⌋',\n", + " 421: '⌈⌈5*.55⌉**5.5⌉',\n", + " 422: '(5!+⌊5.5*55⌋)',\n", + " 423: '(5!+⌈5.5*55⌉)',\n", + " 424: '⌈5.5*⌊55/√.5⌋⌉',\n", + " 425: '⌊55*(√5+5.5)⌋',\n", + " 426: '⌊55*√(5+55)⌋',\n", + " 427: '⌈55*√(5+55)⌉',\n", + " 428: '⌊⌈5.5*55⌉/√.5⌋',\n", + " 429: '(5.5*⌈55/√.5⌉)',\n", + " 430: '(555-(5+5!))',\n", + " 431: '⌈√55*⌈√5+55⌉⌉',\n", + " 432: '(555-⌈√5+5!⌉)',\n", + " 433: '(555-⌊√5+5!⌋)',\n", + " 434: '(555-⌈.5+5!⌉)',\n", + " 435: '⌊555.5-5!⌋',\n", + " 436: '⌈555.5-5!⌉',\n", + " 437: '(⌊√5-5!⌋+555)',\n", + " 438: '(⌈√5-5!⌉+555)',\n", + " 439: '⌊(⌈√55⌉*55)-.5⌋',\n", + " 440: '(5+(555-5!))',\n", + " 441: '⌈.5+(⌈√55⌉*55)⌉',\n", + " 442: '(5+⌈5!/(.5*.55)⌉)',\n", + " 443: '⌊55*√(5!-55)⌋',\n", + " 444: '(⌈√55⌉*55.5)',\n", + " 445: '⌈√55*(5+55)⌉',\n", + " 446: '⌊55*√(5!*.55)⌋',\n", + " 447: '⌊⌈√5⌉**5.555⌋',\n", + " 448: '⌈⌈√5⌉**5.555⌉',\n", + " 449: '⌈55*(5+√(5+5))⌉',\n", + " 450: '(5!+(55*⌈5.5⌉))',\n", + " 451: '⌊5!*(⌈5.55⌉-√5)⌋',\n", + " 452: '⌊55*(√5+⌈5.5⌉)⌋',\n", + " 453: '⌈55*(√5+⌈5.5⌉)⌉',\n", + " 454: '(⌊(5+5!)/.55⌋/.5)',\n", + " 455: '(⌊√55⌋*(5!-55))',\n", + " 456: '⌊5.5*⌊√5**5.5⌋⌋',\n", + " 457: '⌈5.5*⌊√5**5.5⌋⌉',\n", + " 458: '(⌊5-.5⌋*(5!-5.5))',\n", + " 459: '⌊555/(.5+√.5)⌋',\n", + " 460: '⌈555/(.5+√.5)⌉',\n", + " 461: '⌈55*√⌊√5.5**5⌋⌉',\n", + " 462: '(5.5*⌈√5**5.5⌉)',\n", + " 463: '⌈5*(5!-(.5*55))⌉',\n", + " 464: '(⌈√55⌉*⌈√5+55⌉)',\n", + " 465: '(5*(5!-⌊.5*55⌋))',\n", + " 466: '⌊⌊√.5*5!⌋*5.55⌋',\n", + " 467: '⌊55*(.5+⌈√55⌉)⌋',\n", + " 468: '(5!*(5-(5.5/5)))',\n", + " 469: '⌊55*(5+(√.5*5))⌋',\n", + " 470: '(555-⌈√.5*5!⌉)',\n", + " 471: '(555-⌊√.5*5!⌋)',\n", + " 472: '⌈⌈√.5*5!⌉*5.55⌉',\n", + " 473: '(5.5*⌈5**(5-√5)⌉)',\n", + " 474: '(5!*(5-(.5+.55)))',\n", + " 475: '((5!*⌊5-.55⌋)-5)',\n", + " 476: '(55+⌈⌈√5⌉**5.5⌉)',\n", + " 477: '⌊√.5*(5!+555)⌋',\n", + " 478: '⌈√.5*(5!+555)⌉',\n", + " 479: '((5*5!)-⌈5!+.55⌉)',\n", + " 480: '(5!*⌊5-.555⌋)',\n", + " 481: '((5*5!)-⌊5!-.55⌋)',\n", + " 482: '⌊√55*(5!-55)⌋',\n", + " 483: '⌈√55*(5!-55)⌉',\n", + " 484: '⌈(√5*5!)/.555⌉',\n", + " 485: '⌊√5*⌈5!/.555⌉⌋',\n", + " 486: '⌈√5*⌈5!/.555⌉⌉',\n", + " 487: '⌊5!/(.55**√5.5)⌋',\n", + " 488: '⌊.55*⌊5!*√55⌋⌋',\n", + " 489: '⌊.55*⌈5!*√55⌉⌋',\n", + " 490: '⌈.55*⌈5!*√55⌉⌉',\n", + " 491: '⌈5!*((5/.55)-5)⌉',\n", + " 492: '(⌊5-.5⌋*⌈√5*55⌉)',\n", + " 493: '⌈(⌊5/.55⌋**5)/5!⌉',\n", + " 494: '(⌊55*(5-.5)⌋/.5)',\n", + " 495: '(5*⌊55/.55⌋)',\n", + " 496: '(⌊555/√5⌋/.5)',\n", + " 497: '⌈555/(.5*√5)⌉',\n", + " 498: '(⌈555/√5⌉/.5)',\n", + " 499: '⌊5*(55/.55)⌋',\n", + " 500: '(555-55)',\n", + " 501: '(555-⌈5!/√5⌉)',\n", + " 502: '(555-⌊5!/√5⌋)',\n", + " 503: '⌊⌊5.5**5⌋/(5+5)⌋',\n", + " 504: '⌈⌊5.5**5⌋/(5+5)⌉',\n", + " 505: '(5!+(55*⌊√55⌋))',\n", + " 506: '⌊(5-.5)*(5!-√55)⌋',\n", + " 507: '(⌊5*(5!+5.5)⌋-5!)',\n", + " 508: '(⌈5*(5!+5.5)⌉-5!)',\n", + " 509: '⌊√.5*⌈5.555⌉!⌋',\n", + " 510: '⌈√.5*⌈5.555⌉!⌉',\n", + " 511: '⌈⌊5!*√5.5⌋/.55⌉',\n", + " 512: '(5!+⌊√.5*555⌋)',\n", + " 513: '(5!+⌈√.5*555⌉)',\n", + " 514: '⌈√5.5*⌈5!/.55⌉⌉',\n", + " 515: '(5!+(5!+(5*55)))',\n", + " 516: '(5!+⌊.55*⌈5.5⌉!⌋)',\n", + " 517: '(5!+⌈.55*⌈5.5⌉!⌉)',\n", + " 518: '(555-⌈5**√5⌉)',\n", + " 519: '(555-⌊5**√5⌋)',\n", + " 520: '((5*(5!-5))-55)',\n", + " 521: '⌈(5**5)/⌈5.55⌉⌉',\n", + " 522: '⌊55*(5+(5-.5))⌋',\n", + " 523: '⌈55*(5+(5-.5))⌉',\n", + " 524: '(⌈5!*(5!/55)⌉/.5)',\n", + " 525: '(5*((55/.5)-5))',\n", + " 526: '(⌊5*(55-√5)⌋/.5)',\n", + " 527: '(5!+⌊55*√55⌋)',\n", + " 528: '(5!+⌈55*√55⌉)',\n", + " 529: '((5!*(5-.55))-5)',\n", + " 530: '(555-(5*5))',\n", + " 531: '(555-(5!/5))',\n", + " 532: '⌊5**(5-(5.5/5))⌋',\n", + " 533: '⌊5!*(5-.555)⌋',\n", + " 534: '⌈5!*(5-.555)⌉',\n", + " 535: '(55+(5!*⌊5-.5⌋))',\n", + " 536: '⌈(5-.5)*⌊5!-.55⌋⌉',\n", + " 537: '⌊5.5*((.5*5)**5)⌋',\n", + " 538: '⌈5.5*((.5*5)**5)⌉',\n", + " 539: '(5+(5!*(5-.55)))',\n", + " 540: '((5+5)*⌊55-.5⌋)',\n", + " 541: '⌈.55+(5!*(5-.5))⌉',\n", + " 542: '(⌊5*(5!-.5)⌋-55)',\n", + " 543: '(555-⌈√5*5⌉)',\n", + " 544: '(555-⌊√5*5⌋)',\n", + " 545: '(555-(5+5))',\n", + " 546: '((5!*5.55)-5!)',\n", + " 547: '⌊555-√55⌋',\n", + " 548: '⌈555-√55⌉',\n", + " 549: '⌊555-5.5⌋',\n", + " 550: '⌈555-5.5⌉',\n", + " 551: '⌈555.5-5⌉',\n", + " 552: '⌊555-√5.5⌋',\n", + " 553: '⌊555.5-√5⌋',\n", + " 554: '⌊555-.55⌋',\n", + " 555: '⌊555.55⌋',\n", + " 556: '⌈555.55⌉',\n", + " 557: '⌊√5+555.5⌋',\n", + " 558: '⌈√5+555.5⌉',\n", + " 559: '(5+⌊555-.5⌋)',\n", + " 560: '⌊5+555.5⌋',\n", + " 561: '⌈5+555.5⌉',\n", + " 562: '⌊√55+555⌋',\n", + " 563: '⌈√55+555⌉',\n", + " 564: '⌈(5**5)/5.55⌉',\n", + " 565: '(5+(5+555))',\n", + " 566: '(⌊√5*5⌋+555)',\n", + " 567: '(⌈√5*5⌉+555)',\n", + " 568: '(⌈5*(5!-5.5)⌉-5)',\n", + " 569: '⌊(5*(5!-5))-5.5⌋',\n", + " 570: '(5*⌊5!-5.55⌋)',\n", + " 571: '⌊√55*⌊55/√.5⌋⌋',\n", + " 572: '⌊5*(5!-5.55)⌋',\n", + " 573: '⌈5*(5!-5.55)⌉',\n", + " 574: '(5+⌈(5**5)/5.5⌉)',\n", + " 575: '(5*⌈5!-5.55⌉)',\n", + " 576: '⌈.55+(5*(5!-5))⌉',\n", + " 577: '⌊55*(5+5.5)⌋',\n", + " 578: '⌈55*(5+5.5)⌉',\n", + " 579: '((5!/5)+555)',\n", + " 580: '((5*5)+555)',\n", + " 581: '⌈5.5+(5*(5!-5))⌉',\n", + " 582: '⌈5!*(5.55-√.5)⌉',\n", + " 583: '(55/(5/⌊5!/√5⌋))',\n", + " 584: '⌈5*(5!-√(55/5))⌉',\n", + " 585: '(5*(5!-⌈5*.55⌉))',\n", + " 586: '⌊5*(5!-(5*.55))⌋',\n", + " 587: '((⌊√5⌋**5)+555)',\n", + " 588: '⌈5!*√⌊5-.555⌋!⌉',\n", + " 589: '((5*5!)-(55/5))',\n", + " 590: '⌈5!*(5-(5/55))⌉',\n", + " 591: '(⌊5**√5⌋+555)',\n", + " 592: '(⌈5**√5⌉+555)',\n", + " 593: '⌈(5*5!)-√55.5⌉',\n", + " 594: '⌊(5*5!)-5.55⌋',\n", + " 595: '(5*⌊5!-.555⌋)',\n", + " 596: '⌈√(5+5)**5.55⌉',\n", + " 597: '⌊5*(5!-.555)⌋',\n", + " 598: '⌈5*(5!-.555)⌉',\n", + " 599: '⌊(5*5!)-.555⌋',\n", + " 600: '(5*⌊5.555⌋!)',\n", + " 601: '⌈(5*5!)+.555⌉',\n", + " 602: '⌊5*(5!+.555)⌋',\n", + " 603: '⌈5*(5!+.555)⌉',\n", + " 604: '(⌊5.5*55⌋/.5)',\n", + " 605: '(55*(55/5))',\n", + " 606: '(⌈5.5*55⌉/.5)',\n", + " 607: '⌊(5*5!)+√55.5⌋',\n", + " 608: '(⌊5!/√5⌋+555)',\n", + " 609: '(⌈5!/√5⌉+555)',\n", + " 610: '(55+555)',\n", + " 611: '(⌈√5**5⌉+555)',\n", + " 612: '(5+⌊(5*5!)+√55⌋)',\n", + " 613: '⌊5*(5!+(5*.55))⌋',\n", + " 614: '(((5**5)-55)/5)',\n", + " 615: '((.5*5!)+555)',\n", + " 616: '(5.5*⌊5!-√55⌋)',\n", + " 617: '⌊5*(.5+⌈√5*55⌉)⌋',\n", + " 618: '⌈5*(.5+⌈√5*55⌉)⌉',\n", + " 619: '⌊√5*⌊.5*555⌋⌋',\n", + " 620: '(5*⌊√5*55.5⌋)',\n", + " 621: '(.5*⌈√5*555⌉)',\n", + " 622: '⌈√5*⌈.5*555⌉⌉',\n", + " 623: '⌊5!*√⌊5*5.55⌋⌋',\n", + " 624: '⌈5!*√⌊5*5.55⌋⌉',\n", + " 625: '(5**⌊5-.555⌋)',\n", + " 626: '(⌊5.5+(5**5)⌋/5)',\n", + " 627: '⌊5*(5!+5.55)⌋',\n", + " 628: '⌈5*(5!+5.55)⌉',\n", + " 629: '⌊5.5*(5!-5.5)⌋',\n", + " 630: '(5*⌈5!+5.55⌉)',\n", + " 631: '⌈5.5+(5*(5+5!))⌉',\n", + " 632: '⌊5.5*⌈5!-5.5⌉⌋',\n", + " 633: '⌈5.5*⌈5!-5.5⌉⌉',\n", + " 634: '⌊5!*√⌈5*5.55⌉⌋',\n", + " 635: '(5*⌊5!+√55.5⌋)',\n", + " 636: '(((5**5)+55)/5)',\n", + " 637: '⌊5*(5!+√55.5)⌋',\n", + " 638: '⌊(5!-5)*5.55⌋',\n", + " 639: '⌈(5!-5)*5.55⌉',\n", + " 640: '(5*⌊55*√5.5⌋)',\n", + " 641: '⌈.5+(5*⌈5!+√55⌉)⌉',\n", + " 642: '(5+⌊5*(5!+√55)⌋)',\n", + " 643: '⌊5.5*⌊5!-√5.5⌋⌋',\n", + " 644: '⌊5*(55*√5.5)⌋',\n", + " 645: '(5*⌈55*√5.5⌉)',\n", + " 646: '⌈5*(5!+(5/.55))⌉',\n", + " 647: '⌊5.5*(5!-√5.5)⌋',\n", + " 648: '(5!*(⌊.5*55⌋/5))',\n", + " 649: '⌊⌊5!-√5⌋*5.55⌋',\n", + " 650: '((5+5)*(5!-55))',\n", + " 651: '(⌈√5⌉*⌈5!/.555⌉)',\n", + " 652: '⌊(5!*5.5)-√55⌋',\n", + " 653: '⌊(5!-√5)*5.55⌋',\n", + " 654: '⌊5.5*⌊5!-.55⌋⌋',\n", + " 655: '⌊(5*5!)+55.5⌋',\n", + " 656: '⌈(5*5!)+55.5⌉',\n", + " 657: '⌈5.5*(5!-.55)⌉',\n", + " 658: '⌈5!*√⌊.55*55⌋⌉',\n", + " 659: '⌊(5!*5.5)-.55⌋',\n", + " 660: '(5.5*⌊5.55⌋!)',\n", + " 661: '((5!*5.55)-5)',\n", + " 662: '⌊(5!-√.5)*5.55⌋',\n", + " 663: '⌊5.5*(5!+.55)⌋',\n", + " 664: '⌊⌈5.5⌉!-55.5⌋',\n", + " 665: '(⌈5.55⌉!-55)',\n", + " 666: '⌊5!*5.555⌋',\n", + " 667: '⌈5!*5.555⌉',\n", + " 668: '⌊(.5+5!)*5.55⌋',\n", + " 669: '⌈(.5+5!)*5.55⌉',\n", + " 670: '(5!+(555-5))',\n", + " 671: '(5+(5!*5.55))',\n", + " 672: '(5!+⌊555-√5⌋)',\n", + " 673: '(5!+⌈555-√5⌉)',\n", + " 674: '(5!+⌊555-.5⌋)',\n", + " 675: '⌊5!+555.5⌋',\n", + " 676: '⌈5!+555.5⌉',\n", + " 677: '(5!+⌊√5+555⌋)',\n", + " 678: '(5!+⌈√5+555⌉)',\n", + " 679: '⌈(5.5**5)/√55⌉',\n", + " 680: '(5+(5!+555))',\n", + " 681: '⌈5!*(5+(5/√55))⌉',\n", + " 682: '⌊55*(5+√55)⌋',\n", + " 683: '⌈55*(5+√55)⌉',\n", + " 684: '(⌈5.5⌉*⌊5!-5.5⌋)',\n", + " 685: '(5*⌊.5*(5*55)⌋)',\n", + " 686: '⌊(√5-⌈.5⌉)*555⌋',\n", + " 687: '⌊5.5*⌊5!+5.5⌋⌋',\n", + " 688: '⌈5.5*⌊5!+5.5⌋⌉',\n", + " 689: '(5!+⌈(5**5)/5.5⌉)',\n", + " 690: '⌊5.5*(5!+5.5)⌋',\n", + " 691: '⌈5.5*(5!+5.5)⌉',\n", + " 692: '(5+⌊5.5*(5+5!)⌋)',\n", + " 693: '⌊(5+5!)*5.55⌋',\n", + " 694: '⌈(5+5!)*5.55⌉',\n", + " 695: '(⌈5.55⌉!-(5*5))',\n", + " 696: '(⌈5.55⌉!-(5!/5))',\n", + " 697: '(⌈(.5*√55)**5⌉-5)',\n", + " 698: '⌊5.5*⌊5!+√55⌋⌋',\n", + " 699: '⌈5.5*⌊5!+√55⌋⌉',\n", + " 700: '(5*(5*⌈.5*55⌉))',\n", + " 701: '⌈5.5*(5!+√55)⌉',\n", + " 702: '⌊(5**5)/(5-.55)⌋',\n", + " 703: '⌈(5**5)/(5-.55)⌉',\n", + " 704: '(5.5*⌈5!+√55⌉)',\n", + " 705: '(5*(5!+⌊5!/5.5⌋))',\n", + " 706: '⌊(5!-√5)*⌈5.55⌉⌋',\n", + " 707: '(⌈5.5⌉!-⌈5+√55⌉)',\n", + " 708: '(⌈5!-√5⌉*⌈5.55⌉)',\n", + " 709: '(⌈5.5⌉!-(55/5))',\n", + " 710: '(⌈5.55⌉!-(5+5))',\n", + " 711: '(⌈5.5⌉!-⌊5/.55⌋)',\n", + " 712: '⌊⌈5.55⌉!-√55⌋',\n", + " 713: '⌈⌈5.55⌉!-√55⌉',\n", + " 714: '⌊⌈5.55⌉!-5.5⌋',\n", + " 715: '(⌈5.555⌉!-5)',\n", + " 716: '(⌈5.5⌉!-⌊5-.55⌋)',\n", + " 717: '⌊⌈5.555⌉!-√5⌋',\n", + " 718: '⌈⌈5.555⌉!-√5⌉',\n", + " 719: '⌊⌈5.555⌉!-.5⌋',\n", + " 720: '⌈5.5555⌉!',\n", + " 721: '⌈.5+⌈5.555⌉!⌉',\n", + " 722: '⌊√5+⌈5.555⌉!⌋',\n", + " 723: '⌈√5+⌈5.555⌉!⌉',\n", + " 724: '(⌊5!/√.5⌋+555)',\n", + " 725: '(5+⌈5.555⌉!)',\n", + " 726: '⌈5.5+⌈5.55⌉!⌉',\n", + " 727: '⌊√55+⌈5.55⌉!⌋',\n", + " 728: '⌈√55+⌈5.55⌉!⌉',\n", + " 729: '(⌈√5⌉**⌈5.555⌉)',\n", + " 730: '(5+(5+⌈5.55⌉!))',\n", + " 731: '(⌈5.5⌉!+(55/5))',\n", + " 732: '(5!*(5+(5.5/5)))',\n", + " 733: '(5+⌈⌈5.5⌉!+√55⌉)',\n", + " 734: '(5!+⌊√5*(5*55)⌋)',\n", + " 735: '(5*(5!+⌊.5*55⌋))',\n", + " 736: '⌊√5.5**√(5+55)⌋',\n", + " 737: '⌊5*(5!+(.5*55))⌋',\n", + " 738: '(⌈5.5⌉*⌈√5*55⌉)',\n", + " 739: '⌊5!*√⌈5*√55.5⌉⌋',\n", + " 740: '(5*(5!+⌈.5*55⌉))',\n", + " 741: '(⌈5.5⌉!+⌊5!/5.5⌋)',\n", + " 742: '(⌈5.5⌉!+⌈5!/5.5⌉)',\n", + " 743: '⌊⌊5!**√5⌋/(5+55)⌋',\n", + " 744: '((5!/5)+⌈5.55⌉!)',\n", + " 745: '((5*5)+⌈5.55⌉!)',\n", + " 746: '(5!+((5+(5**5))/5))',\n", + " 747: '(⌈5.5⌉!+⌊.5*55⌋)',\n", + " 748: '(⌈5.5⌉!+⌈.5*55⌉)',\n", + " 749: '⌈5!*(√5+⌊5-.55⌋)⌉',\n", + " 750: '((5+5!)*⌈5.55⌉)',\n", + " 751: '⌈5!*(√.5+5.55)⌉',\n", + " 752: '(5!+⌊5.5*(5!-5)⌋)',\n", + " 753: '(⌈5.5⌉*(5!+5.5))',\n", + " 754: '(5!+⌊5!*√⌈.5*55⌉⌋)',\n", + " 755: '((5*(5!+55))-5!)',\n", + " 756: '(⌈5.5⌉*⌈5!+5.5⌉)',\n", + " 757: '(⌈5.5⌉!+⌊5*√55⌋)',\n", + " 758: '(⌈5.5⌉!+⌈5*√55⌉)',\n", + " 759: '⌈5!*√⌊5.5*√55⌋⌉',\n", + " 760: '(5*⌊55*(5-√5)⌋)',\n", + " 761: '⌈5*(55*(5-√5))⌉',\n", + " 762: '(⌈5.5⌉*⌊5!+√55⌋)',\n", + " 763: '⌈5*(5!**(.5+.55))⌉',\n", + " 764: '⌊⌈5.5⌉*(5!+√55)⌋',\n", + " 765: '(5*⌈55*(5-√5)⌉)',\n", + " 766: '⌈(⌈√5⌉**5.5)/.55⌉',\n", + " 767: '⌈((5*5)-5.5)**√5⌉',\n", + " 768: '⌊√⌈5.55⌉**√55⌋',\n", + " 769: '⌊55**√(5*.55)⌋',\n", + " 770: '(55*⌊√55/.5⌋)',\n", + " 771: '⌈(5*5.55)**⌊√5⌋⌉',\n", + " 772: '(55+⌊⌈5.5⌉!-√5⌋)',\n", + " 773: '(⌊5!*√55.5⌋-5!)',\n", + " 774: '(55+⌊⌈5.5⌉!-.5⌋)',\n", + " 775: '(55+⌈5.55⌉!)',\n", + " 776: '⌈⌈5.5⌉!+55.5⌉',\n", + " 777: '⌊(555-5)/√.5⌋',\n", + " 778: '⌈(555-5)/√.5⌉',\n", + " 779: '(⌊555/√.5⌋-5)',\n", + " 780: '(⌈555/√.5⌉-5)',\n", + " 781: '⌊(5**5)/⌊5-.55⌋⌋',\n", + " 782: '⌈(5**5)/⌊5-.55⌋⌉',\n", + " 783: '⌊⌊555/√.5⌋-.5⌋',\n", + " 784: '⌊√⌊.5*5⌋*555⌋',\n", + " 785: '⌊555.5/√.5⌋',\n", + " 786: '⌈555.5/√.5⌉',\n", + " 787: '⌈⌈555.5⌉/√.5⌉',\n", + " 788: '⌈(5-.5)*(5!+55)⌉',\n", + " 789: '(5+⌊555/√.5⌋)',\n", + " 790: '(5+⌈555/√.5⌉)',\n", + " 791: '⌊(5+555)/√.5⌋',\n", + " 792: '⌈(5+555)/√.5⌉',\n", + " 793: '⌈⌈5.5⌉!*(5.5/5)⌉',\n", + " 794: '(⌈.55*⌈5.5⌉!⌉/.5)',\n", + " 795: '(5!+(5!+555))',\n", + " 796: '⌈55**(5/⌈.5*5⌉)⌉',\n", + " 797: '⌊5.5*(5!+(5*5))⌋',\n", + " 798: '((⌈√5⌉**5)+555)',\n", + " 799: '⌈5!*(5+√(5*.55))⌉',\n", + " 800: '(5*((⌈√5⌉*55)-5))',\n", + " 801: '⌊⌊√55⌋*(5!-5.5)⌋',\n", + " 802: '⌈⌊√55⌋*(5!-5.5)⌉',\n", + " 803: '⌊⌊5!**√5⌋/55.5⌋',\n", + " 804: '⌈⌊5!**√5⌋/55.5⌉',\n", + " 805: '((5!-5)*⌊√55.5⌋)',\n", + " 806: '⌊(5-.5)**(5-.55)⌋',\n", + " 807: '(5!+⌊5.5*(5+5!)⌋)',\n", + " 808: '(5!+⌈5.5*(5+5!)⌉)',\n", + " 809: '(⌊5!*√(5+55)⌋-5!)',\n", + " 810: '(⌈√5⌉*((5*55)-5))',\n", + " 811: '⌈(5+(5!**√5))/55⌉',\n", + " 812: '⌈(5*⌊5-.55⌋)**√5⌉',\n", + " 813: '(⌊5!*(√5+5)⌋-55)',\n", + " 814: '(⌊55*√55⌋/.5)',\n", + " 815: '⌊55/(.5/√55)⌋',\n", + " 816: '(⌈55*√55⌉/.5)',\n", + " 817: '⌊5**(5/(⌈5.5⌉/5))⌋',\n", + " 818: '((5*5!)+⌊5!/.55⌋)',\n", + " 819: '((5*5!)+⌈5!/.55⌉)',\n", + " 820: '((⌈√5⌉*(5*55))-5)',\n", + " 821: '⌊5!/(√.5**5.55)⌋',\n", + " 822: '⌊5!*√⌊55-√55⌋⌋',\n", + " 823: '(⌊√5*5!⌋+555)',\n", + " 824: '(⌈√5*5!⌉+555)',\n", + " 825: '(55*(5+(5+5)))',\n", + " 826: '⌊(5*5!)**(.5+.55)⌋',\n", + " 827: '⌊(5-.55)**(5-.5)⌋',\n", + " 828: '⌈(5-.55)**(5-.5)⌉',\n", + " 829: '⌈(√5+5)*(5!-5.5)⌉',\n", + " 830: '(5*⌊⌈√5⌉*55.5⌋)',\n", + " 831: '(⌈√5⌉*⌊.5*555⌋)',\n", + " 832: '⌊(.5+⌈.5⌉)*555⌋',\n", + " 833: '⌈(.5+⌈.5⌉)*555⌉',\n", + " 834: '(⌊5!*√55⌋-55)',\n", + " 835: '(⌈5!*√55⌉-55)',\n", + " 836: '⌊⌊√55⌋*(5!-.55)⌋',\n", + " 837: '⌈⌊√55⌋*(5!-.55)⌉',\n", + " 838: '⌊(5.5**5)/⌈5.5⌉⌋',\n", + " 839: '⌈(5.5**5)/⌈5.5⌉⌉',\n", + " 840: '(5!+⌈5.555⌉!)',\n", + " 841: '(5!+⌈.5+⌈5.55⌉!⌉)',\n", + " 842: '(⌈5.5⌉!+⌊√5*55⌋)',\n", + " 843: '(⌈5.5⌉!+⌈√5*55⌉)',\n", + " 844: '⌊5!*√(55-5.5)⌋',\n", + " 845: '⌊√55*⌊5!-5.5⌋⌋',\n", + " 846: '⌈√55*⌊5!-5.5⌋⌉',\n", + " 847: '(⌊√55⌋*⌈5!+.55⌉)',\n", + " 848: '⌊5!*√⌊55.5-5⌋⌋',\n", + " 849: '⌊√55*(5!-5.5)⌋',\n", + " 850: '(5*(5!+(55-5)))',\n", + " 851: '⌊⌊(5!-5)*√55⌋-.5⌋',\n", + " 852: '⌊5!*√(55.5-5)⌋',\n", + " 853: '⌈5!*√(55.5-5)⌉',\n", + " 854: '(5+⌈5!*√(55-5)⌉)',\n", + " 855: '(5*⌈5.55**⌈√5⌉⌉)',\n", + " 856: '⌊(5!-5)*√55.5⌋',\n", + " 857: '⌈(5!-5)*√55.5⌉',\n", + " 858: '(5+⌈(5!-5)*√55⌉)',\n", + " 859: '⌊55**(√5-.55)⌋',\n", + " 860: '⌈55**(√5-.55)⌉',\n", + " 861: '⌊5!*(5+(5!/55))⌋',\n", + " 862: '⌈5!*(5+(5!/55))⌉',\n", + " 863: '⌈5**(⌊5!/5.5⌋/5)⌉',\n", + " 864: '(⌊.5*55⌋/(.5**5))',\n", + " 865: '(5*⌊55*√(5+5)⌋)',\n", + " 866: '⌈5!*√⌊55-√5.5⌋⌉',\n", + " 867: '⌊√55*⌊5!-√5.5⌋⌋',\n", + " 868: '⌈√55*⌊5!-√5.5⌋⌉',\n", + " 869: '⌊5*(55*√(5+5))⌋',\n", + " 870: '((555-5!)/.5)',\n", + " 871: '⌊5!**√⌈5.55/5⌉⌋',\n", + " 872: '⌊5*(5!+(55-.5))⌋',\n", + " 873: '⌈5*(5!+(55-.5))⌉',\n", + " 874: '⌊(5*(5!+55))-.5⌋',\n", + " 875: '(5*⌊5!+55.5⌋)',\n", + " 876: '⌈.5+(5*(5!+55))⌉',\n", + " 877: '⌊5*(5!+55.5)⌋',\n", + " 878: '⌈5*(5!+55.5)⌉',\n", + " 879: '⌈√5*⌈√.5*555⌉⌉',\n", + " 880: '(5*⌈5!+55.5⌉)',\n", + " 881: '⌊5!*√⌊55-.55⌋⌋',\n", + " 882: '⌊√55*⌊5!-.55⌋⌋',\n", + " 883: '⌊⌊5!*√55⌋-5.5⌋',\n", + " 884: '⌊⌈5!*√55⌉-5.5⌋',\n", + " 885: '⌈⌈5!*√55⌉-5.5⌉',\n", + " 886: '⌈√55*(5!-.55)⌉',\n", + " 887: '⌈⌊5!-.5⌋*√55.5⌉',\n", + " 888: '(⌊5!*√55.5⌋-5)',\n", + " 889: '⌊5!*(55/√55)⌋',\n", + " 890: '⌈5!*(55/√55)⌉',\n", + " 891: '⌈.55+(5!*√55)⌉',\n", + " 892: '⌊⌊5!*√55.5⌋-.5⌋',\n", + " 893: '⌊⌊5.5⌋!*√55.5⌋',\n", + " 894: '⌊5.5+⌊5!*√55⌋⌋',\n", + " 895: '⌈5.5+⌊5!*√55⌋⌉',\n", + " 896: '⌈5.5+⌈5!*√55⌉⌉',\n", + " 897: '⌊5!*√⌈55.55⌉⌋',\n", + " 898: '⌈5!*√⌈55.55⌉⌉',\n", + " 899: '(5+⌈5!*√55.5⌉)',\n", + " 900: '(5*(5+(5!+55)))',\n", + " 901: '⌊⌈.5+5!⌉*√55.5⌋',\n", + " 902: '⌊(5-(5.5/5))**5⌋',\n", + " 903: '⌈(5-(5.5/5))**5⌉',\n", + " 904: '(5!+⌊555/√.5⌋)',\n", + " 905: '(5!+⌈555/√.5⌉)',\n", + " 906: '(⌈√5⌉*⌊5.5*55⌋)',\n", + " 907: '⌊⌈√5⌉*(5.5*55)⌋',\n", + " 908: '⌈⌈√5⌉*(5.5*55)⌉',\n", + " 909: '(⌈√5⌉*⌈5.5*55⌉)',\n", + " 910: '⌊√5*⌊55*√55⌋⌋',\n", + " 911: '⌈√5*⌊55*√55⌋⌉',\n", + " 912: '⌊√5*⌈55*√55⌉⌋',\n", + " 913: '⌈√5*⌈55*√55⌉⌉',\n", + " 914: '⌊⌊5.5**5⌋/5.5⌋',\n", + " 915: '⌊5.5**⌊5-.55⌋⌋',\n", + " 916: '⌈5.5**⌊5-.55⌋⌉',\n", + " 917: '⌈⌈√5+5!⌉*√55.5⌉',\n", + " 918: '⌊5.5*⌈5.5**⌈√5⌉⌉⌋',\n", + " 919: '⌈5.5*⌈5.5**⌈√5⌉⌉⌉',\n", + " 920: '(5+⌊5.5**⌊5-.5⌋⌋)',\n", + " 921: '⌊(.5*5)**√55.5⌋',\n", + " 922: '⌈(.5*5)**√55.5⌉',\n", + " 923: '(55+⌊5!*(√5+5)⌋)',\n", + " 924: '(55+⌈5!*(√5+5)⌉)',\n", + " 925: '(5*(555/⌈√5⌉))',\n", + " 926: '⌊⌊(5+5!)*√55⌋-.5⌋',\n", + " 927: '⌊√55*⌊5!+5.5⌋⌋',\n", + " 928: '⌈√55*⌊5!+5.5⌋⌉',\n", + " 929: '⌊5!*√⌊5+55.5⌋⌋',\n", + " 930: '⌈5!*√⌊5+55.5⌋⌉',\n", + " 931: '⌊(5+5!)*√55.5⌋',\n", + " 932: '⌈(5+5!)*√55.5⌉',\n", + " 933: '⌊5!*√(5+55.5)⌋',\n", + " 934: '⌈5!*√(5+55.5)⌉',\n", + " 935: '(55*⌈5!/√55⌉)',\n", + " 936: '⌈(5+5!)*√⌈55.5⌉⌉',\n", + " 937: '⌊5!*√⌈5+55.5⌉⌋',\n", + " 938: '⌈5!*√⌈5+55.5⌉⌉',\n", + " 939: '⌊5.5/(.5**√55)⌋',\n", + " 940: '⌈5.5/(.5**√55)⌉',\n", + " 941: '⌊√55*⌊5!+√55⌋⌋',\n", + " 942: '⌊⌊5**5.5⌋/√55⌋',\n", + " 943: '⌈⌊5**5.5⌋/√55⌉',\n", + " 944: '(55+⌊5!*√55⌋)',\n", + " 945: '(55+⌈5!*√55⌉)',\n", + " 946: '(5.5*⌊(5+5)**√5⌋)',\n", + " 947: '⌊(√.5+⌈.5⌉)*555⌋',\n", + " 948: '⌊5.55**⌊5-.5⌋⌋',\n", + " 949: '⌈5.55**⌊5-.5⌋⌉',\n", + " 950: '(5*(5*⌈5*√55⌉))',\n", + " 951: '⌊5.5*⌈(5+5)**√5⌉⌋',\n", + " 952: '⌊5!*√⌈55+√55⌉⌋',\n", + " 953: '⌈5!*√⌈55+√55⌉⌉',\n", + " 954: '⌊(5!+555)/√.5⌋',\n", + " 955: '⌊5!*(.55+√55)⌋',\n", + " 956: '⌈5!*(.55+√55)⌉',\n", + " 957: '⌊5!*(.5+√⌈55.5⌉)⌋',\n", + " 958: '⌈5!*(.5+√⌈55.5⌉)⌉',\n", + " 959: '⌊(5!*⌈√55⌉)-.55⌋',\n", + " 960: '(5!*⌈55/√55⌉)',\n", + " 961: '⌊√⌈.5*5⌉*555⌋',\n", + " 962: '⌊5.5*(5!+55)⌋',\n", + " 963: '⌈5.5*(5!+55)⌉',\n", + " 964: '⌈(√5-.5)*555⌉',\n", + " 965: '⌊(5!/5.55)**√5⌋',\n", + " 966: '⌈(5!/5.55)**√5⌉',\n", + " 967: '⌊5!*√⌈5!-55.5⌉⌋',\n", + " 968: '⌈5!*√⌈5!-55.5⌉⌉',\n", + " 969: '((⌊5-.5⌋**5)-55)',\n", + " 970: '(5*⌈5!**(5.5/5)⌉)',\n", + " 971: '(⌈5*(5!/.55)⌉-5!)',\n", + " 972: '⌊√5*(555-5!)⌋',\n", + " 973: '⌈√5*(555-5!)⌉',\n", + " 974: '⌊5!*√⌊5!*.555⌋⌋',\n", + " 975: '⌈5!*√⌊5!*.555⌋⌉',\n", + " 976: '(⌈√55⌉*⌊√5*55⌋)',\n", + " 977: '⌈(5+5)*((.5*5)**5)⌉',\n", + " 978: '⌊5!*(√.5+√55.5)⌋',\n", + " 979: '⌊5!*(5+√⌊5+5.5⌋)⌋',\n", + " 980: '⌈5!*(5+√⌊5+5.5⌋)⌉',\n", + " 981: '((5-.5)*⌊5!/.55⌋)',\n", + " 982: '⌊5!*√⌈5!*.555⌉⌋',\n", + " 983: '⌈5!*√⌈5!*.555⌉⌉',\n", + " 984: '(⌈√55⌉*⌈√5*55⌉)',\n", + " 985: '⌊(5-.5)*⌈5!/.55⌉⌋',\n", + " 986: '⌈(5-.5)*⌈5!/.55⌉⌉',\n", + " 987: '⌊√⌈√5*5⌉**5.55⌋',\n", + " 988: '⌊5!*(√5+⌈5.55⌉)⌋',\n", + " 989: '⌈5!*(√5+⌈5.55⌉)⌉',\n", + " 990: '((555/.5)-5!)',\n", + " 991: '⌊5!*(5-(√5-5.5))⌋',\n", + " 992: '⌈5!*(5-(√5-5.5))⌉',\n", + " 993: '⌈√5*⌊⌈√5⌉**5.55⌋⌉',\n", + " 994: '⌊5!*(5*√(5*.55))⌋',\n", + " 995: '(⌈5.5⌉!+(5*55))',\n", + " 996: '⌊⌈5**(5-√.5)⌉-5.5⌋',\n", + " 997: '⌊5!*(5+√(55/5))⌋',\n", + " 998: '⌊⌊5**5.5⌋/⌊√55⌋⌋',\n", + " 999: '⌈⌊5**5.5⌋/⌊√55⌋⌉',\n", + " ...}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clear()\n", + "\n", + "%time makeable(ff)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The output got truncated by Jupyter Notebook after 1000 entries. Let's see what the first unmakeable integer actually is:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "23308" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "unmakeable(ff)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I think we've conquered the five 5s problem.\n", + "\n", + "# Conclusion\n", + "\n", + "We were able to solve the puzzles, and we now have some tools to explore new puzzles. What can you discover?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Differentiation.ipynb b/pytudes/ipynb/Differentiation.ipynb new file mode 100644 index 0000000..318e0f1 --- /dev/null +++ b/pytudes/ipynb/Differentiation.ipynb @@ -0,0 +1,1392 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Symbolic Math: Differentiation Program\n", + "\n", + "This notebook describes how to write a program that will manipulate mathematical expressions, with an emphasis on differentiation. The program can compute $\\frac{d}{dx} x^2 + \\sin(x)$ to get the result $2x + \\cos(x)$. Usually in a programming language, when we say `sin(x)` we are computing with *numbers*, not *symbolic expressions*. That is, programming languages have built-in functions like `sin` and numbers like 0 so that we can ask for the value of `sin(0)` and get back 0. But now we want to do something different: treat $\\sin(x)$ as a *symbolic expression* that represents any value of $x$. That facility is not built-in to most programming languages, so we need a way to represent and manipulate these symbolic expressions. Python has a large system called `sympy` to do just that, but we will develop a smaller, simpler system from scratch.\n", + "\n", + "# Representing Symbolic Expressions as Tuples\n", + "\n", + "Here is one simple way to represent symbolic expressions: We will represent numbers as themselves, because they are already built-in to Python. We will represent math variable (such as $x$) and constants (such as $\\pi$) as Python strings (such as `'x'` and `'pi'`). And we will represent compound expressions (such as $x + 1$) as Python tuples, such as `('x', '+', 1)`. \n", + "\n", + "We will use the notion of [arity](http://en.wikipedia.org/wiki/Arity) of an expression. An expression can be: \n", + "\n", + "* Binary (arity = 2): $(x + y)$ is a binary expression because it has two sub-expressions, $x$ and $y$.\n", + "* Unary (arity = 1): $-x$ and $\\sin(x)$ are both unary expressions, because they each have one sub-expression, $x$.\n", + "* Nullary (arity = 0): $x$ and $3$ are both nullary, or *atomic* expressions, because they have no sub-expressions,\n", + "\n", + "We can define this as a Python function:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def arity(expr):\n", + " \"The number of sub-expressions in this expression.\"\n", + " if isinstance(expr, tuple):\n", + " return len(expr) - 1\n", + " else:\n", + " return 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "exp = ('x', '+', 1)\n", + "arity(exp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This table summarizes the kinds of expressions and how we will represent them:\n", + "\n", + "\n", + "
Math
Expression
Math TypeArityPython
Representation
Python
Type\n", + "
$3$Integer03int\n", + "
$3.14$Number03.14float\n", + "
$x$Variable0'x'str\n", + "
$\\pi$Constant0'pi'str\n", + "
$-x$Unary op1('-', 'x')tuple\n", + "
$\\sin(x)$Unary func1('sin', 'x')tuple\n", + "
$x+1$Binary op2('x', '+', 1)tuple\n", + "
$3x - y/2$Nested
Binary op
2((3, '*', 'x'), '-',
 ('y', '/', 2))
tuple\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Differentiation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In Calculus, *differentiation* is the process of computing the *derivative* of a function: the rate of change of the function with respect to a variable. We denote the dirivative of $y$ with respect to the variable $x$ as $\\frac{dy}{dx}$. \n", + "\n", + "We can compute the derrivative by consulting a [table of differentiation rules](http://myhandbook.info/form_diff.html). Here are the rules for variables, constants, unary negation, and the four basic binary arithmetic operations: " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$\\frac{d}{dx} (x) = 1$\n", + "\n", + "$\\frac{d}{dx} (c) = 0$\n", + "\n", + "$\\frac{d}{dx} (-u) = - \\frac{du}{dx}$\n", + "\n", + "$\\frac{d}{dx} (u + v) = \\frac{du}{dx} + \\frac{dv}{dx}$\n", + "\n", + "$\\frac{d}{dx} (u - v) = \\frac{du}{dx} - \\frac{dv}{dx}$\n", + "\n", + "$\\frac{d}{dx} (u \\times v) = v \\frac{du}{dx} + u \\frac{dv}{dx}$\n", + "\n", + "$\\frac{d}{dx} (u \\; / \\; v) = (v \\frac{du}{dx} - u \\frac{dv}{dx}) \\; / \\; v^2$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Defining `D(y, x)`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will define the Python function `D(y, x)` to compute the symbolic derivative of the expression `y` with respect to the variable `x`. We can handle each of the seven rules, one by one. If the input is of a form that does not match one of the rules, we will raise a `ValueError`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def D(y, x='x'):\n", + " \"\"\"Return the symbolic derivative, dy/dx.\n", + " Handles binary operators +, -, *, /, and unary -, over variables and constants.\"\"\"\n", + " if y == x: \n", + " return 1 # d/dx (x) = 1\n", + " if arity(y) == 0:\n", + " return 0 # d/dx (c) = 0\n", + " if arity(y) == 1:\n", + " (op, u) = y # y is a compund expression of the form (op, u)\n", + " if op == '-': return ('-', D(u, x)) # d/dx (-u) = - du/dx \n", + " if arity(y) == 2: \n", + " (u, op, v) = y # y is a compound expression of the form (u, op, v)\n", + " if op == '+': return D(u, x), '+', D(v, x)\n", + " if op == '-': return D(u, x), '-', D(v, x)\n", + " if op == '*': return (v, '*', D(u, x)), '+', (u, '*', D(v, x))\n", + " if op == '/': return ((v, '*', D(u, x)), '-', (u, '*', D(v, x))), '/', (v, '*', v)\n", + " raise ValueError(\"D can't handle this: \" + str(y))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what `D` can do:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, '+', 0)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(('x', '+', 1), 'x')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((('x', '*', 0), '+', (3, '*', 1)), '+', 0)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(((3, '*', 'x'), '+', 'c'), 'x')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(('y', '*', 1), '+', ('y', '*', 1))" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(('y', '*', 'y'), 'y')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These answers are all mathematically *correct*, but they are not *simplified*—better answers would be `1`, `3`, and `(2, '*', 'y')`, respectively. So we have solved the basic problem, but there are enhancements we could make in several directions:\n", + "\n", + "* *Simplify*: Return `1` instead of `(1, '+', 0)`.\n", + "* *Diversify*: Handle more types of expressions, like $x^2$, and $\\sin(x)$.\n", + "* *Refactor*: Maker the code cleaner by introducing a better representation for expressions.\n", + "\n", + "I choose to refactor first (because that will make the other two tasks easier). \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Representing Symbolic Expressions as Class Objects" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I will refactor the representation of expressions, replacing tuples with a user-defined class, `Expression`. Why do that? Three reasons:\n", + "\n", + "* **Hygiene**: The code is cleaner with a separate type. A tuple can be used for a lot of things; when I have an expression I want to know for sure it is an expression. \n", + "* **Ease of Coding**: I will be able to form a new expression with the simple code `x + 1` rather than the more verbose `(x, '+', 1)`.\n", + "* **Prettier Output**: We can see the prettier `(x + 1)` form on output, rather than the uglier `('x', '+', 1)`.\n", + "\n", + "Here's what I have in mind:\n", + "\n", + "\n", + "\n", + "
Math
Expression
Math
Type
ArityPython
Representation
Python
Type\n", + "
$3$Integer03int\n", + "
$3.14$Number03.14float\n", + "
$x$Variable0Expression('x')Expression\n", + "
$\\pi$Constant0Expression('pi')Expression\n", + "
$-x$Unary op1Expression('-', 'x')Expression\n", + "
$\\sin(x)$Unary func1Expression('sin', 'x')Expression\n", + "
$x+1$Binary op2Expression('+', x, 1) (given def for `x`)Expression\n", + "
$3x - y/2$Nested
Binary op
23 * x - y / 2   (given defs for `x`, `y`)Expression\n", + "
\n", + "\n", + "Note that not every math expression is an instance of the new class `Expression`; we still use good old Python `int` and `float` for numbers. But variables, constants (like $\\pi$ or $c$), and unary and binary expressions are all instances of `Expression`. Note also that I considered having separate subclasses of `Expression` for each of these, but I decided the complication was not worth it.\n", + "\n", + "To understand the implementation of `Expression`, you need to understand Python's [special method names](https://docs.python.org/3/reference/datamodel.html#special-method-names), the method names that begin and end with double underscores, like `__init__` and `__add__`. If you're not familiar with the concept, glance at [the documentation](https://docs.python.org/3/reference/datamodel.html#special-method-names), but here is a quick summary:\n", + "\n", + "* `__init__(self, ...)` *The constructor that defines what happens when a new object is created.*\n", + "* `__add__(self, other)` *The method called when the code asks for `self + other`. Similar for `__sub__`, etc.*\n", + "* `__radd__(self, other)` *'r' for reverse. Called when the code asks for, say, `1 + self`, where `1` is not an `Expression`. Similar for `__rsub__`, etc.*\n", + "* `__neg__(self)` *The method called when the code says `(- self)`. Similar for `__pos__`.*\n", + "* `__hash__(self)` *Computes a hash value, an integer, used as a key into a hash table (`dict`).*\n", + "* `__eq__(self, other)` *Called to check whether `self == other`.*" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from __future__ import division\n", + "\n", + "class Expression(object): \n", + " \"A mathematical expression (other than a number).\"\n", + " def __init__(self, op, *args): self.op, self.args = op, args\n", + " \n", + " def __add__(self, other): return Expression('+', self, other)\n", + " def __sub__(self, other): return Expression('-', self, other)\n", + " def __mul__(self, other): return Expression('*', self, other)\n", + " def __truediv__(self, other): return Expression('/', self, other)\n", + " def __pow__(self, other): return Expression('**', self, other)\n", + " \n", + " def __radd__(self, other): return Expression('+', other, self)\n", + " def __rsub__(self, other): return Expression('-', other, self)\n", + " def __rmul__(self, other): return Expression('*', other, self)\n", + " def __rtruediv__(self, other): return Expression('/', other, self)\n", + " def __rpow__(self, other): return Expression('**', other, self)\n", + " \n", + " def __neg__(self): return Expression('-', self)\n", + " def __pos__(self): return self\n", + " \n", + " def __hash__(self): return hash(self.op) ^ hash(self.args)\n", + " def __ne__(self, other): return not (self == other)\n", + " def __eq__(self, other): return (isinstance(other, Expression) \n", + " and self.op == other.op \n", + " and self.args == other.args)\n", + " def __repr__(self):\n", + " \"A string representation of the Expression.\"\n", + " op, args = self.op, self.args\n", + " n = arity(self)\n", + " if n == 0: \n", + " return op\n", + " if n == 2: \n", + " return '({} {} {})'.format(args[0], op, args[1])\n", + " if n == 1:\n", + " arg = str(args[0])\n", + " if arg.startswith('(') or op in {'+', '-'}:\n", + " return '{}{}'.format(op, arg)\n", + " else:\n", + " return '{}({})'.format(op, arg)\n", + "\n", + "def arity(expr):\n", + " \"The number of sub-expressions in this expression.\"\n", + " if isinstance(expr, Expression):\n", + " return len(expr.args)\n", + " else:\n", + " return 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's first define some symbols:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "a, b, c, d, u, v, w, x, y, z, pi , e = map(Expression, [\n", + "'a', 'b', 'c', 'd', 'u', 'v', 'w', 'x', 'y', 'z', 'pi', 'e'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, for example, `a` is now an object of type `Expression` such that `a.op` is the string `'a'` and `a.args` is the empty tuple, and `arity(a)` is 0. The Python expression `a + 1` is equivalent to `a.__add__(1)`, which invokes the `Expression.__add__` method to create a new object of type `Expression`:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(a + 1)" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a + 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Python expression `1 + a` is equivalent to `1.__add__(a)`. But since the integer `1` doesn't know how to add a `Symbol`, Python instead calls `a.__radd__(1)`, where `radd` stands for \"reversed add\":" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1 + a)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1 + a" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try something more interesting:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((-b + ((b ** 2) - ((4 * a) * c))) / (2 * a))" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(-b + (b**2 - 4*a*c)) / (2 * a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Rewriting `D(y, x)` with the Expression Class\n", + "===\n", + "\n", + "We can now rewrite `D`; notice that the code is a bit neater, since we don't have to create tuples, we can just use operators like `+`. " + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def D(y, x=x):\n", + " \"\"\"Return the symbolic derivative, dy/dx.\n", + " Handles binary operators +, -, *, /, and unary -, over variables and constants.\"\"\"\n", + " if y == x: \n", + " return 1 # d/dx (x) = 1\n", + " if arity(y) == 0:\n", + " return 0 # d/dx (c) = 0\n", + " op = y.op\n", + " if arity(y) == 1:\n", + " u = y.args[0]\n", + " if op == '-': return -D(u, x) # d/dx (-u) = - du/dx\n", + " if arity(y) == 2: \n", + " (u, v) = y.args\n", + " if op == '+': return D(u, x) + D(v, x)\n", + " if op == '-': return D(u, x) - D(v, x)\n", + " if op == '*': return D(u, x) * v + D(v, x) * u\n", + " if op == '/': return (v * D(u, x) - u * D(v, x)) / v ** 2\n", + " raise ValueError(\"D can't handle this: \" + str(y))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(x + 2, x)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(((0 * x) + 3) + 0)" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(3 * x + c, x)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((1 * y) + (1 * y))" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(y * y, y)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((0 * x) + (1 * -c))" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(- c * x, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Representing Functions\n", + "===\n", + "\n", + "Let's represent expressions like $\\sin(x)$. We'll need to be clear of the difference between the function `sin` and the functional expression `sin(x)`. I choose to do that by making `sin` be an object of type `Function`, which is a subtype of `Expression`, and making `sin(x)` be an `Expression` whose `op` is `sin`:\n", + "\n", + "\n", + "
ExpressionTypeArityopargs\n", + "
`sin``Function`0`'sin'``()`\n", + "
`sin(x)``Expression`1`sin``(x,)`\n", + "
\n", + " \n", + "\n", + "What operations does `Function` need to support? We need to be able to create a new one, with an op and no args; it can inherit the `__init__` method from `Expression` to do this. Once we create a new one, it needs to be able to create a functional expression, like `sin(x)`. We can do that with the `__call__` method of `Function`:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class Function(Expression):\n", + " \"A mathematical function of one argument, like sin or ln.\"\n", + " def __call__(self, x): return Expression(self, x)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sin, cos, tan, cot, sec, csc, ln, sqrt = map(Function, [\n", + "'sin', 'cos', 'tan', 'cot', 'sec', 'csc', 'ln', 'sqrt'])" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "sin" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sin" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'args': (), 'op': 'sin'}" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vars(sin)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "sin(x)" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sin(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'args': (x,), 'op': sin}" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vars(sin(x))" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((-b + sqrt((b ** 2) - ((4 * a) * c))) / (2 * a))" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(-b + sqrt(b**2 - 4*a*c)) / (2 * a)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((sin(x) ** 2) + (cos(x) ** 2))" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sin(x)**2 + cos(x)**2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "Extending `D(y, x)` to handle Exponentiation and Functions\n", + "====\n", + "\n", + "In this section, we extend `D(y, x)` to handle:\n", + "\n", + "* The binary exponentiation operator, $u^v$, denoted with `u ** v`.\n", + "* The six trigonometric functions sin, cos, tan, cot, csc, sec, and the natural logarithm functions, ln.\n", + "* The chain rule for nested functions.\n", + "\n", + "Here are the rules:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$\\frac{d}{dx} (x^n) = n x^{(n-1)}$ *if n is an integer*\n", + "\n", + "$\\frac{d}{dx} (u^v) = v u^{(v-1)} * \\frac{du}{dx} + u^v * \\ln(u) * \\frac{dv}{dx}$\n", + "\n", + "$\\frac{d}{dx} \\sin(x) = \\cos(x)$\n", + "\n", + "$\\frac{d}{dx} \\cos(x) = -\\sin(x)$\n", + "\n", + "$\\frac{d}{dx} \\tan(x) = \\sec(x)^2$\n", + "\n", + "$\\frac{d}{dx} \\cot(x) = -\\csc(x)^2$\n", + "\n", + "$\\frac{d}{dx} \\sec(x) = \\sec(x) \\tan(x)$\n", + "\n", + "$\\frac{d}{dx} \\csc(x) = - \\csc(x) \\cot(x)$\n", + "\n", + "$\\frac{d}{dx} \\ln(x) = 1 / x$\n", + "\n", + "$\\frac{dy}{dx} = \\frac{dy}{du} \\frac{du}{dx}$\n", + "\n", + "We can add these rules to the ones we had before, giving us:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def D(y, x=x):\n", + " \"\"\"Return the symbolic derivative, dy/dx.\n", + " Handles binary operators +, -, *, /, and unary -, as well as\n", + " transcendental trig and log functions over variables and constants.\"\"\"\n", + " if y == x: \n", + " return 1 # d/dx (x) = 1\n", + " if arity(y) == 0:\n", + " return 0 # d/dx (c) = 0\n", + " if arity(y) == 1:\n", + " op, (u,) = y.op, y.args\n", + " if op == '+': return D(u, x)\n", + " if op == '-': return -D(u, x)\n", + " if u != x: return D(y, u) * D(u, x) ## CHAIN RULE\n", + " if op == sin: return cos(x)\n", + " if op == cos: return -sin(x)\n", + " if op == tan: return sec(x) ** 2\n", + " if op == cot: return -csc(x) ** 2\n", + " if op == sec: return sec(x) * tan(x)\n", + " if op == csc: return -csc(x) * cot(x)\n", + " if op == ln: return 1 / x \n", + " if arity(y) == 2: \n", + " op, (u, v) = y.op, y.args\n", + " if op == '+': return D(u, x) + D(v, x)\n", + " if op == '-': return D(u, x) - D(v, x)\n", + " if op == '*': return D(u, x) * v + D(v, x) * u\n", + " if op == '/': return (v * D(u, x) - u * D(v, x)) / v ** 2\n", + " if op == '**': return (v * u**(v-1) if u == x and isinstance(v, int) else\n", + " v * u**(v-1) * D(u, x) + u**v * ln(u) * D(v, x))\n", + " raise ValueError(\"D can't handle this: \" + str(y))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Chain Rule\n", + "---\n", + "\n", + "The trickiest part is the chain rule. Consider $\\frac{d}{dx} \\sin(\\ln(x))$. Let:\n", + "\n", + "$y = \\sin(\\ln(x))$\n", + "\n", + "$u = \\ln(x)$\n", + "\n", + "According to the chain rule, \n", + "\n", + "$\\frac{dy}{dx} = \\frac{dy}{du} \\frac{du}{dx}$. \n", + "\n", + "So we have:\n", + "\n", + "$\\frac{dy}{du} = \\frac{d}{du} \\sin(u) = \\cos(u) = \\cos(\\ln(x))$\n", + "\n", + "$\\frac{du}{dx} = \\frac{d}{dx} \\ln(x) = \\frac{1}{x}$\n", + "\n", + "Finally, we can multiply them together to get:\n", + "\n", + "$\\frac{dy}{dx} = \\frac{dy}{du} \\;\\frac{du}{dx} = \\cos(\\ln(x)) \\; \\frac{1}{x} = \\cos(\\ln(x)) / x$.\n", + "\n", + "\n", + "Now let's do the same thing in Python. Let:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "Y = sin(ln(x))\n", + "U = ln(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So let's go on with the computation of the derivative, `D(y, x) = D(y, u) * D(u, x)`. We'll look at the two terms on the right:" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "cos(ln(x))" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(Y, U)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1 / x)" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(U, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And multiply the two terms together:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(cos(ln(x)) * (1 / x))" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(Y, U) * D(U, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can do the same computation all in one step:" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(cos(ln(x)) * (1 / x))" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(Y, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More Examples of Differentiation\n", + "===\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First an example where all is well:" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(3 * (x ** 2))" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(x ** 3, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But most of the time, `D` gives an answer that is technically correct, but not in simplified form. The example below should yield `2*a*x + b`:" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((((0 * (x ** 2)) + ((2 * (x ** 1)) * a)) + ((0 * x) + (1 * b))) + 0)" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(a*x**2 + b*x + c, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The next example should give `50 * (5*x - 2)**9`:" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(((10 * (((5 * x) - 2) ** 9)) * (((0 * x) + 5) - 0)) + (((((5 * x) - 2) ** 10) * ln((5 * x) - 2)) * 0))" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D((5*x - 2)**10, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And for the next example, we should get $\\frac{d}{dx} \\sin(\\ln(x^2)) = 2 \\cos(\\ln(x^2)) / x$." + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(cos(ln(x ** 2)) * ((1 / (x ** 2)) * (2 * (x ** 1))))" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D(sin(ln(x**2)), x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In each case, the answer is correct, but not simplified." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Simplification: `simp(y)`\n", + "------\n", + "\n", + "\n", + "Now let's work on simplification. We'll define `simp(y)` to return an expression that is equivalent to the expression $y$, but simpler. We should say that the notion of *simpler* is not at all precise. Which is simpler, $x^2 -x -12$ or $(x + 3)(x - 4)$? It depends on what you want to do next. But we can all agree that $x$ is simpler than $(2 - 1)x + 0$. Our version of `simp` will just do the easiest of simplifications. There's lots we could add to make it better.\n", + "\n", + "Another difficult issue is dealing with indeterminate results like dividing by 0. We would like to be able to simplify $x/x$ to 1. But that is only true if $x$ is not 0. We'll ignore that problem and go ahead and simplify $x/x$ to 1, but we'll feel a little uneasy about it. We'll also simplify 0/0 to `undefined` and 1/0 to `infinity`." + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def simp(y):\n", + " \"Simplify an expression.\"\n", + " if arity(y) == 0:\n", + " return y \n", + " y = Expression(y.op, *map(simp, y.args)) ## Simplify the sub-expressions first\n", + " op = y.op\n", + " if arity(y) == 1:\n", + " (u,) = y.args\n", + " if y in simp_table:\n", + " return simp_table[y]\n", + " if op == '+':\n", + " return u # + u = u\n", + " if op == '-':\n", + " if arity(u) == 1 and u.op == '-':\n", + " return u.args[0] # - - w = w\n", + " if arity(y) == 2:\n", + " (u, v) = y.args\n", + " if evaluable(u, op, v): # for example, (3 + 4) simplifies to 7\n", + " return eval(str(u) + op + str(v), {})\n", + " if op == '+':\n", + " if u == 0: return v # 0 + v = v\n", + " if v == 0: return u # u + 0 = u\n", + " if u == v: return 2 * u # u + u = 2 * u\n", + " if op == '-':\n", + " if u == v: return 0 # u - v = 0\n", + " if v == 0: return u # u - 0 = u\n", + " if u == 0: return -v # 0 - v = -v\n", + " if op == '*':\n", + " if u == 0 or v == 0: return 0 # 0 * v = u * 0 = 0\n", + " if u == 1: return v # 1 * v = v\n", + " if v == 1: return u # u * 1 = u\n", + " if u == v: return u ** 2 # u * u = u^2\n", + " if op == '/':\n", + " if u == 0 and v == 0: return undefined # 0 / 0 = undefined\n", + " if u == v: return 1 # u / u = 1\n", + " if v == 1: return u # u / 1 = u\n", + " if u == 0: return 0 # 0 / v = 0\n", + " if v == 0: return infinity # u / 0 = infinity\n", + " if op == '**':\n", + " if v == 1: return u # u ** 1 = u\n", + " if u == v == 0: return undefined # 0 ** 0 = undefined\n", + " if v == 0: return 1 # u ** 0 = 1 \n", + "\n", + " # If no rules apply, return y unchanged.\n", + " return y\n", + "\n", + "from numbers import Number\n", + "\n", + "# Deal with infinity and with undefined numbers (like infinity minus infinity)\n", + "infinity = float('inf') \n", + "undefined = nan = (infinity - infinity)\n", + "\n", + "# Table of known exact values for certain functions.\n", + "# Use this, for example, to simplify sin(pi) to 0 or ln(e) to 1.\n", + "\n", + "simp_table = {\n", + " sin(0): 0, sin(pi): 0, sin(pi/2): 1, sin(2*pi): 0,\n", + " cos(0): 1, cos(pi): -1, cos(pi/2): 1, cos(2*pi): 1,\n", + " tan(0): 0, tan(pi): 0, tan(pi/2): infinity, tan(2*pi): 0, tan(pi/4): 1,\n", + " ln(1): 0, ln(e): 1, ln(0): -infinity}\n", + "\n", + "def evaluable(u, op, v):\n", + " \"Can we evaluate (u op v) to a number? True if u and v are numbers, and not a special case like 0^0.\"\n", + " return (isinstance(u, Number) and isinstance(v, Number)\n", + " and not (op == '/' and (v == 0 or u % v != 0))\n", + " and not (op == '^' and (u == v == 0)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try it out. First an easy one; $1x + 0$ should be $x$: Simplifying " + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "x" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simp(x*(y/y) + 0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similarly, $(2 - 1)x^{\\cos(y-y)} + \\tan(\\pi)$ should be just $x$:" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "x" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simp((2 - 1) * x ** cos(y-y) + tan(pi))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are two examples where `simp` helps, but does not do all the simplifications it could:" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(cos(ln(x ** 2)) * ((1 / (x ** 2)) * (2 * x)))" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simp(D(sin(ln(x**2)), x))" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((10 * (((5 * x) - 2) ** 9)) * 5)" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simp(D((5 * x - 2)**10, x))" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simp(cos(pi - pi))" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simp(D(3 * x + c, x))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Economics.ipynb b/pytudes/ipynb/Economics.ipynb new file mode 100644 index 0000000..84ef6a5 --- /dev/null +++ b/pytudes/ipynb/Economics.ipynb @@ -0,0 +1,1500 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Economics Simulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a simulation of an economic marketplace in which there is a *population* of actors, each of which has a level of wealth. On each time step two actors (chosen by an *interaction function*) engage in a transaction that exchanges wealth between them (according to a *transaction function*). The idea is to understand the evolution of the population's wealth over time. I heard about the problem when I visited the Bard College Computer Science Department in 2008. *Update:* In 2017, a version posed by Uri Wilensky [became popular](http://www.decisionsciencenews.com/2017/06/19/counterintuitive-problem-everyone-room-keeps-giving-dollars-random-others-youll-never-guess-happens-next/). We cover his version [below](#Uri-Wilensky-Version).\n", + "\n", + "![](money.png)\n", + "\n", + "Why is this interesting? \n", + "- It is an example of using simulation to model the world. The model is simple but captures some aspects of a complex world.\n", + "- Many students will have preconceptions about how economies work that will be challenged by the results shown here.\n", + "- It reveals subtle differences between computational thinking, mathematical thinking, and statistical thinking." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Population Distributions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will model a population as a list of `N` numbers, each number being one actor's wealth. We'll start with a Gaussian distribution (also known as a *normal* distribution or *bell-shaped curve*), with a mean wealth of 100 [simoleons](http://en.wiktionary.org/wiki/simoleon) and a standard deviation of 1/5 the mean:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import random\n", + "\n", + "N = 5000 # Default size of the population\n", + "MU = 100. # Default mean of the population\n", + "\n", + "population = [random.gauss(mu=MU, sigma=MU/5) for actor in range(N)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Population Statistics and Visualization\n", + "\n", + "How evenly is the wealth in a population distributed? The traditional measure is the [Gini coefficient](http://en.wikipedia.org/wiki/Gini_coefficient), which Wikipedia says is computed by this formula (which assumes the *y* values are sorted):\n", + "\n", + "![Gini](https://upload.wikimedia.org/math/b/b/5/bb50601acc135c45a24bb0493f7555b4.png)\n", + "\n", + "A Gini index of 0 means total equality (everyone has the same amount), and values closer to 1 mean more inequality (most of the money in the hands of a few individuals). Here's a table of Gini coefficients for several countries:\n", + "\n", + "\n", + "
Sweden 0.250\n", + "
Canada 0.326\n", + "
Switzerland 0.337\n", + "
United States 0.408\n", + "
Chile 0.521\n", + "
South Africe 0.631\n", + "
\n", + "\n", + "\n", + "The Gini coefficient is traditionally computed over *income*, but we will be dealing with *wealth*. Here is the computation:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def gini(y):\n", + " \"Compute the Gini coefficient (a measure of equality/inequality) in a population, y.\"\n", + " y = sorted(y)\n", + " n = len(y)\n", + " numer = 2 * sum((i+1) * y[i] for i in range(n))\n", + " denom = n * sum(y)\n", + " return (numer / denom) - (n + 1) / n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.11285526402866708" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gini(population)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We'll define the function `hist` to plot a histogram of a population. Our `hist` wraps `plt.hist`, but with some specific keyword values:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "\n", + "def hist(population, label='pop', **kwargs):\n", + " \"A custom version of `hist` with better defaults.\"\n", + " label = label + ': G=' + str(round(gini(population), 2))\n", + " h = plt.hist(list(population), bins=30, alpha=0.5, label=label, **kwargs)\n", + " plt.xlabel('wealth'); plt.ylabel('count'); plt.grid(True)\n", + " plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEPCAYAAABRHfM8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X2UXHWd5/H3NwIqT+kETLIhNA2CCPFIFJawiBqBzYQZ\nN0QcETCztHH36IhgnHE0PCUNsgbGnWM8CGddFTrIk4g8eXTlKbZjNIBIB5CwGMRKtyEdNoQAxpCQ\n8N0/6lZT6XSnb/e9t+t+k8/rnD6pe+tW9SfVt+pb9/u7D+buiIiIDGZUowOIiEgMKhgiIpKKCoaI\niKSigiEiIqmoYIiISCoqGCIikkrhBcPMKmb2uJl1mtkjybwxZnafmT1jZvea2ei65S80s5Vm9rSZ\nTS86n4iIpDMSWxhvANPc/X3ufnwybx7wgLsfCSwBLgQws6OBM4GjgNOAa83MRiCjiIgMYiQKhvXz\ne04HFie3FwOzktszgVvdfau7V4CVwPGIiEjDjUTBcOB+M/utmf23ZN54d18L4O49wLhk/kFAd91j\nVyfzRESkwfYYgd/xAXdfY2bvAO4zs2eoFpF6Oj+JiEjJFV4w3H1N8u//M7O7qLaY1prZeHdfa2YT\ngBeSxVcDB9c9fFIybztmpgIjIjIM7j7sceFCW1JmtreZ7Zvc3geYDjwJ3AO0JoudC9yd3L4HOMvM\n9jKzQ4HDgUf6e253L/3PggULGp5BOZUzcs4IGSPlzKroLYzxwJ3JFsEewE3ufp+ZPQrcZmZzgFVU\n94zC3VeY2W3ACuB14POex/+yQSqVSqMjpKKc+VLO/ETICHFyZlVowXD3PwFT+pm/Hjh1gMcsBBYW\nmUtERIZOR3oXqLW1tdERUlHOfClnfiJkhDg5s7KIHR8zi9ypEhFpCDPDyzrovbvr6OhodIRUlDNf\nUXJOnDgRM9PPLvjT0tJSyDozEsdhiEgJrVmzJpc9Z6R8rKAzKqklJbKbStoTjY4hBRjob6uWlIiI\njAgVjAJF6WUrZ76i5BQZKhUMERFJRWMYIrupvn3u+fMX0dW1obDf19zcxOWXzy3s+fPy7LPPcuml\nl/Lggw+yZcsWxo8fz4wZM/jqV7/KxIkTh/RcDz74IF/4whfo7u5m6tSpXH/99TQ3N/e77DXXXEN7\neztPPvkk55xzDtddd13vfa+//jrnnHMOjz76KKtWraKjo4MPfehDA/7eosYwtJeUSAppP0yjfCj2\np6trAy0tbYU9f6VS3HPn5dlnn2Xq1KnMmTOH5cuXM3HiRNatW8fNN9/M0qVLOfPMM1M/14svvsjH\nP/5xrrvuOj760Y9yySWX8MlPfpJly5b1u/xBBx3EpZdeyr333sumTZt2uP+DH/wgX/rSl/jEJz4x\n7P9fVmpJFShKL1s5B1f7MB3sp6trQ5jXs8wOPfRQrrzySiZPnswBBxzAZz7zGbZs2dJ7/3e/+12O\nOOIIDjzwQGbNmsWaNWt67xs1ahRXX30173znOxk3bhxf+cpXUv/eyy67jJNOOolvfOMbvVsTBx54\nIBdccMGQigXAHXfcwXve8x7OOOMM9tprL9ra2nj88cf5wx/+0O/ys2bNYubMmYwdO3aH+/bcc08u\nuOACTjzxREaNatzHtgqGiJTSzTffzP33388f//hHnnnmGa644goAlixZwkUXXcTtt9/OmjVraG5u\n5qyzztrusXfddRePPfYYjz32GHfffXdve6e7u5uxY8fy5z//ud/f+cADD/Dxj398p7m6u7sZM2YM\nY8eOZcyYMdvdHjt2LLfeeisATz31FMccc0zv4/bee28OP/xwnnrqqWG/Jo2mglGgadOmNTpCKsqZ\nryg5y+78889n4sSJNDU1cfHFF3PLLbcA1ULymc98hmOOOYY999yThQsXsmzZMrq6unofO2/ePEaP\nHs2kSZOYO3du72MPPvhg1q9fz6RJk/r9nevWrWPChAm909dccw1jxoxhv/3247Of/Wzvc7z00kus\nX7+el156abvb69ev7y1ef/nLXxg9evR2z7///vvz6quv5vcijTCNYYjkqLPzcVpb2wZdLvJYx0ip\n/1A/5JBDeP755wF4/vnnOfbYY3vv22effTjggANYvXp174DyQI8dzAEHHLBde+u8887jvPPO49JL\nL2X16h2u5bZT++67L6+88sp2815++WX222+/IT1PmahgFKijoyPEt03lzM/GjQ5Mo6Vl2k6XizAA\n3Gjd3d29t1etWtU7pjBx4kRWrVrVe9/GjRt58cUXtysS3d3dHHXUUQB0dXWl3rvplFNO4Y477uDc\nc8/daa6jjz56h9NvuDtmxne+8x3OPvtsJk+ezOLFi7fL+cc//pHJkyenylJGakmJSCldc801rF69\nmvXr1/P1r3+9t9Vz9tlnc/311/PEE0+wefNmLrroIk444QQOPvjNqzt/4xvfYMOGDXR3d/Otb31r\n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\nq0OMAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "hist(population)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Transactions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In a transaction, two actors come together and exchange some of their wealth. For now we will use a wealth-conserving transaction function in which all the wealth from both actors is put into a pot, which is then split randomly and uniformly between the two actors:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def random_split(A, B):\n", + " \"Take all the money uin the pot and divide it randomly between the two actors.\"\n", + " pot = A + B\n", + " share = random.uniform(0, pot)\n", + " return share, pot - share" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(39.32170492026867, 160.67829507973133)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random_split(100, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Interactions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How do we decide which parties interact with each other? We will define an interaction function that, given the size of the population, randomly selects any two actors in the populations (denoted by their index numbers in the list). We'll call this function `anyone`, meaning that any actor can interact with any other actor:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def anyone(N): return random.sample(range(N), 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1593, 1439]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "anyone(N)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The function `simulate` takes an initial population, calls an interaction function to select two actors, and a transaction function to split their wealth, and repeats this T times. After each transaction, we yield the population, so `simulate` yields the complete history of the simulation." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def step(population, transaction=random_split, interaction=anyone):\n", + " \"Modify the population by doing one transaction.\"\n", + " i, j = interaction(len(population))\n", + " population[i], population[j] = transaction(population[i], population[j]) \n", + " return population\n", + " \n", + "def simulate(population, T, step=step, transaction=random_split, interaction=anyone):\n", + " \"Run simulation on population for T transactions; yield population at each time step.\"\n", + " population = population.copy()\n", + " yield population\n", + " for t in range(T):\n", + " yield step(population, transaction, interaction)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a simple example of simulating a population of 4 actors for 8 time steps:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[100, 100, 100, 100]\n", + "[100, 100, 166.07034848304477, 33.92965151695522]\n", + "[100, 129.37411310873642, 166.07034848304477, 4.555538408218797]\n", + "[100, 21.916292438917807, 166.07034848304477, 112.01335907803742]\n", + "[100, 21.916292438917807, 89.32137618847126, 188.7623313726109]\n", + "[88.88749715846127, 33.028795280456535, 89.32137618847126, 188.7623313726109]\n", + "[88.88749715846127, 0.008026672184755057, 122.34214479674304, 188.7623313726109]\n", + "[88.88749715846127, 0.008026672184755057, 147.86216819550745, 163.24230797384647]\n", + "[88.88749715846127, 54.73884147345122, 147.86216819550745, 108.51149317257999]\n" + ] + } + ], + "source": [ + "for pop in simulate([100] * 4, 8):\n", + " print(pop)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SImulation Visualization\n", + "\n", + "If we want to do larger simulations we'll need a better way to visualize the results.\n", + "The function `show` does that:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import statistics\n", + "\n", + "def show(population, k=40, percentiles=(1, 10, 50, 90, 99), **kwargs):\n", + " \"Run a simulation for k*N steps, printing statistics and displaying a plot and histogram.\"\n", + " N = len(population)\n", + " start = list(population)\n", + " results = [(t, sorted(pop)) # Sort results so that percentiles work\n", + " for (t, pop) in enumerate(simulate(population, T=k * N, **kwargs))\n", + " if t % (N / 10) == 0]\n", + " # Printout:\n", + " print(' t Gini stdev' + (' {:3d}%' * len(percentiles)).format(*percentiles))\n", + " print('------- ---- -----' + ' ----' * len(percentiles))\n", + " fmt = '{:7,d} {:.2f} {:5.1f}' + ' {:4.0f}' * len(percentiles)\n", + " for (t, pop) in results:\n", + " if t % (k * N // 10) == 0: # Print 11 report lines (initial plus 10 as t varies)\n", + " data = [percent(pct, pop) for pct in percentiles]\n", + " print(fmt.format(t, gini(pop), statistics.stdev(pop), *data))\n", + "\n", + " plt.title('/'.join(map(str, percentiles)) + ' Percentile Plots')\n", + " times = [t for (t, pop) in results]\n", + " plt.hold(True); plt.xlabel('wealth'); plt.ylabel('time'); plt.grid(True)\n", + " for pct in percentiles:\n", + " line = [percent(pct, pop) for (t, pop) in results]\n", + " plt.plot(line, times)\n", + " plt.show()\n", + " \n", + " plt.title('Histograms') \n", + " R = (min(pop+start), max(pop+start))\n", + " hist(start, 'start', range=R)\n", + " hist(pop, 'end', range=R)\n", + " plt.show()\n", + "\n", + " plt.title('Ordered Curves')\n", + " order = list(range(len(pop)))\n", + " start.sort()\n", + " pop.sort()\n", + " plt.plot(sorted(start), order, label='start')\n", + " plt.plot(sorted(pop), order, label='end')\n", + " plt.xlabel('wealth'); plt.ylabel('order'); plt.grid(True)\n", + " plt.legend()\n", + "\n", + " \n", + "def percent(pct, items):\n", + " \"The item that is pct percent through the sorted list of items.\"\n", + " return items[min(len(items)-1, len(items) * pct // 100)]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.11 20.1 54 75 100 126 148\n", + " 20,000 0.50 99.4 1 11 71 231 454\n", + " 40,000 0.49 98.0 1 11 71 231 452\n", + " 60,000 0.50 99.1 1 10 69 233 441\n", + " 80,000 0.49 96.6 1 11 71 230 442\n", + "100,000 0.50 100.4 1 11 69 230 465\n", + "120,000 0.50 101.1 1 10 69 230 468\n", + "140,000 0.50 101.8 1 10 69 230 466\n", + "160,000 0.50 102.7 1 11 68 227 477\n", + "180,000 0.49 98.4 1 11 72 229 450\n", + "200,000 0.49 99.0 1 11 70 231 464\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEZCAYAAABSN8jfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XucVXW9//HXB0UNuY3GJUUYETHwl4Gal9CiNFHPUbwd\n5Ggqpj3KzEvWT5CS2+lI0C9vlXnMy4ilZKUoJ1EsHRTERGVEARWtDUIMKndFmBnm8/tjrT3uuQBr\n2LPX/g68n4/HfrDX2muv9d7DzHxmfT/rYu6OiIhIPtoUO4CIiLR+KiYiIpI3FRMREcmbiomIiORN\nxURERPKmYiIiInlTMREBzOwNM/tKsXOItFYqJrJbMLN/mtnXG8y7xMyeB3D3/+Puz+1gHb3MrNbM\n9HMj0oB+KGR315yzdi1e3goRxMz2KMR6RdKgYiJC/T0XM/uSmc0zs/VmttLM/l+82Kz433VmtsHM\njrXIT8wsY2aVZlZmZh1z1ntx/NoH8XK52xlrZn80swfMbB1wSbztF8xsrZmtMLNfmtmeOeurNbMr\nzOztON8EM+ttZnPMbJ2ZTc0ub2b7m9n0eF2rzSybX6TFqZjI7mxbexi3Abe6eyfgEODheH62p9LR\n3Tu6+9+BS4GLga8CvYEOwK8AzKw/8GvgP4HPAZ2AAxps60zgYXfvDPweqAGuBfYDjge+DnyvwXtO\nAQYCxwHXA/8DXAAcBHwh3h7AD4H3gP2BrsDoHX1BRHaWionsTqaZ2Zrsg+gXfVOqgD5mtr+7b3L3\nlxq8nluELgBudvel7r4JuAE4P+6rnAs87u5z3b0GGNPEtua6+3QAd9/i7vPd/SWPLAPuIipUuSa5\n+8fuvhh4A5gZb38jMIOo0ABUExWxg919q7vP2fGXSGTnqJjI7mSou++XfdD4L/6sy4DDgDfN7O9m\n9m/bWecBwNKc6aXAnkC3+LX3si+4+yfA6gbvfy93wswOjYemVsZDX/8NfLbBe97Pef4JsKrBdPv4\n+c+Bd4GZZvaOmY3czucQyYuKiexOEjXO3f1dd7/A3bsAk4E/mdlnaLpZ/y+gV850L6KhqlXASqBH\n3cajdezfcHMNpn8DLAYOiYe+fpw0dxOf4yN3/5G7H0I0nHadmX1tZ9YlsiMqJiINmNmFZpbdG1hP\n9Au/Fvgg/veQnMUfAn5gZqVm1p5oT2Kqu9cCfwLOMLPjzKwtMC7B5jsAG9x9k5l9Hrgij8/xb2aW\nzbqRqMjV7uz6RLZHxUR2Fzs6BDj39VOBhWa2AbgFOD/uZ3xCVCzmxH2XY4B7gQeA54iGlDYBVwO4\n+yLgKuAPRHswG4iGqLZsJ8ePgAvjbf8PMHUHn2N7n+tQ4K9mthGYA/za3XVElxSEFfLmWGa2N9EP\n2V5E48h/cvfxZlZC9APWC8gAw9x9ffyeG4BvEf0VdY27z4znHwmUAfsAT7j7tQULLlIAZrYvsA7o\n4+5Ld7S8SGtS0D0Td98CfM3dBwIDgNPiv+ZGAX9198OAZ4iOgMkeSjkM6AecBtxhZtnx4t8Al7l7\nX6CvmQ0pZHaRlmBm/25mn4kLyS+ABSoksisq+DBXfLgkwN5EeycODAXuj+ffD5wVPz+TaLy5xt0z\nwBLgGDPrDnRw93nxclNy3iMSsqFEQ1zLiXotw4sbR6QwCl5MzKyNmc0HKoGn44LQzd1XAbh7JdEJ\nVQAHUv9QyRXxvAOJfhizlsfzRILm7t9295L48Q13X1LsTCKFkMaeSW08zNWDaC/jcJrXRBQRkcDt\nueNFWoa7bzCzcqIjZVaZWTd3XxUPYWVPwlpBdEmIrB7xvG3Nb8TMVJhERHaCu+/0RUwLumdiZp81\ns07x888A3yA6IetxYES82CXAY/Hzx4HhZraXmR0M9AFeiofC1pvZMXFD/uKc9zTi7kE9xo4dW/QM\nyrRr5VImZWrpR74KvWfyOeD++DpFbYA/uPsTZvYi8LCZfYvo8hPDIDou38weBhYRXVfoe/7pp7yS\n+ocGP1ng7C0mk8kUO0IjypRciLmUKRllSk9Bi4m7vw4c2cT8NcDJ23jPRGBiE/NfIboiqoiIBEZn\nwKdgxIgRxY7QiDIlF2IuZUpGmdJT0DPgi8HMfFf7TCIihWZmeKgNeImUl5cXO0IjypRciLlaIlNp\naSlmpsdu9igtLc37e6cpqR0aLCJhWbp0aYscxSOti9lO73xsf7272jeThrlEkomHNYodQ1K2rf/3\neL6GuUREpHhUTFKwq465t7QQM0GYuULMJLs3FRMREcmbeiYiu6mmxs7HjLmVZcvWFWybPXt2ZsKE\n/O5rN378eN59912mTJmy0+uYNWsW3/zmN3nvvfd2vHCOl19+mfHjxzNnzhwADjjgAM4++2x+9KMf\n0alTp2at68EHH2T06NGsXr2ab3zjG9x777107ty5yWXHjBnDtGnTWLx4MTfeeCNjxoype62yspLv\nfOc7vPzyy6xcuZJMJkPPnj23ud1C9Ux0NJeI1Fm2bB2lpeMKtv5MpnDrTmrr1q24e7OPanrhhRcY\nMmQIN954I/feey9dunRh+fLl3HPPPbz22mt85StfSbyuhQsX8t3vfpcZM2YwcOBAvv3tb3PFFVfw\n0EMPNbn8oYceys9//nPuvPPORq+1adOG0047jdGjR/PlL3+5WZ+pJWmYKwUhjm8rU3Ih5goxU0ub\nNGkSPXr0oGPHjvTr149nn32Wp556iptuuok//OEPdOjQgYEDBwJQVlZG//796dixI3369OGuu+6q\nW8+sWbM46KCDmDx5Mp/73Oe44IILOP300/nXv/5Fhw4d6NixI5WVlTvMM3LkSC677DKuv/56unTp\nAkCPHj0YO3ZsswoJRHslZ555JoMGDaJdu3b813/9F4888ggff/xxk8tfdNFFDBkyhPbt2zd6rWvX\nrnz3u9/l6KOPLurReSomIhKct99+m1//+te88sorbNiwgaeeeorS0lKGDBnC6NGjOf/889m4cSPz\n588HoFu3bjzxxBNs2LCB++67jx/84AdUVFTUra+yspJ169axbNkypkyZwowZMzjggAPYuHEjGzZs\noHv37syZM4f99tuvyTybNm1i7ty5nHPOOdvNPWfOHEpKSthvv/0oKSmp93y//fbjhRdeAKI9ky9+\n8Yt17+vduzd77703b7/9dr5fuqJRMUnB4MGDix2hEWVKLsRcIWZqSXvssQdVVVW88cYb1NTU0LNn\nTw4++OBtLn/aaafVndl94okncsopp/D888/XW9/48eNp27Yte++9d5PrGDRoEGvWrGnytbVr11Jb\nW0v37t3r5o0cOZKSkhLat2/PTTfdVLeOtWvXsmbNGtauXVvv+Zo1a+qGoT766KNGPZaOHTuycePG\nHX9xAqViIiLBOeSQQ7j11lsZN24c3bp144ILLtjuUNSMGTM4/vjj2X///SkpKWHGjBl8+OGHda93\n6dKFtm3b7nSekpIS2rRpw8qVK+vmTZo0ibVr13L22WdTU1PTrPW1b9+eDRs21Ju3fv16OnTosNMZ\ni03FJAUhjm8rU3Ih5goxU0sbPnw4zz//PEuXLgWiPQFofDmQqqoqzjvvPK6//no++OAD1q5dy2mn\nnVavf9DwPc1tvrdr145jjz2WRx55ZLvLzZ49u64Pk/vIzsseBXb44Yfz2muv1b3v3Xffpbq6mr59\n+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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(population)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are four parts to this output:\n", + "\n", + "**The printout:** For the starting population and for every 20,000 transactions along the way, we \n", + "print the Gini coefficient and standard deviation of the population, and the wealths at five percentile points in the population: the 1%, 10%, 50% (median), 90% and 99% marks.\n", + "\n", + "**The plots:** This shows the same information as the printout (except for the Gini index), but with more data points along the way. The leftmost (blue) line is the 1% mark, the rightmost (purple) is the 99% mark, and the inner lines are the 10%, 50% and 90% marks, respectively. For the plot, time goes from bottom to top rather than top to bottom. So, the 99% (purple) line starts at around 150, and over time increases to over 400, indicating that the richest 1% are getting richer. The fact that the lines are going more or less straight up after about 50,000 transactions suggests that the system has converged.\n", + "\n", + "**The histograms:** The starting and ending populations are plotted as histograms. \n", + "\n", + "**The ordered curves:** Here the initial (blue) and final (green) populations are sorted, and the curves show wealth versus ordinal number. The poorest actor (ordinal number 0) has wealth 0 in both the initial and final populations. The 2000th poorest actor (a bit below the median; at the 40th percentile) has wealth of almost 100 in the initial population, but only about 50 in the final population.\n", + "\n", + "The results show that income inequality is increasing over time. How can you tell? Because the Gini coefficient is increasing over time, the standard deviation is increasing, and the 1% and 10% marks are decreasing (the blue and olive lines are moving left as time increases) while the 90% and 99% marks are increasing (the aqua and purple lines are moving right as time increases).\n", + "\n", + "\n", + "\n", + "Would the population continue to change if we let the simulation run longer? It looks like only the 1% line is changing, the other lines remain pretty much in one place from about T=15,000 to T=25,000. This suggests that running the simulation longer would not have too much effect." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Effect of Starting Population\n", + "\n", + "What happens to the final result if we vary the starting population? I'll introduce the function `samples` to sample from a distribution function `n` times, normalizing the result to have the specified mean:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def samples(distribution, *args, n=N, mu=MU):\n", + " \"Sample from the distribution n times, then normalize results to have mean mu.\"\n", + " numbers = [distribution(*args) for _ in range(N)]\n", + " return normalize(numbers, mu)\n", + "\n", + "def normalize(numbers, mu):\n", + " \"Make the numbers non-negative, and scale them so they have mean mu.\"\n", + " numbers = [max(0, n) for n in numbers]\n", + " factor = len(numbers) * mu / sum(numbers)\n", + " return [x * factor for x in numbers]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can easily make an initial population from a distribution function. I'll start with a uniform distribution:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.33 57.9 2 19 102 181 200\n", + " 20,000 0.49 97.1 1 11 72 224 447\n", + " 40,000 0.50 102.7 1 10 69 229 486\n", + " 60,000 0.50 101.1 1 11 68 233 460\n", + " 80,000 0.50 101.0 1 10 69 229 490\n", + "100,000 0.51 101.7 1 10 67 234 465\n", + "120,000 0.50 99.7 1 10 70 229 462\n", + "140,000 0.50 99.5 1 11 71 229 444\n", + "160,000 0.51 102.6 1 10 66 235 469\n", + "180,000 0.50 102.3 1 10 68 229 455\n", + "200,000 0.51 102.3 1 10 70 232 472\n" + ] + }, + { + "data": { + "image/png": "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\n0QAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nq1atuPjii5kyZQonnnhivfqTTkosIlKhpGQb+fnjIlt/LBbdulN14MAB3L3eZ0ctWLCAq666ip/9\n7Gc88cQTdOrUibVr1zJ16lQ+/PBDLr744pTXtXTpUr7zne8wY8YMzj77bO666y5GjBjBH//4x2rb\nT548mTPOOIPWrVuzaNEiLr/8clauXElubi69e/dmxowZdO7cmf379/PTn/6UESNGMG1arbdUjJSG\nwrKYrt0IKRahphKLiRMn0qVLF9q1a0fPnj2ZO3cus2bN4le/+hV/+tOfaNu2LWeffTYABQUF9OrV\ni3bt2tGjRw8ee+yxivW8+eabnHTSSUyaNIkTTjiBIUOGcM011/Dpp5/Stm1b2rVrR2lpaZ39uf/+\n+7njjjv48Y9/TKdOnQDo0qULY8eOrVdSgfjRyqBBg+jXrx9HHXUUP//5z3n55ZfZvXt3te3PPPNM\nWrduXVEuLy+vONrq1KkTnTvHH1F18OBBWrRowapVq+rVn3TTEYuINDorVqzgd7/7He+//z65ubmU\nlJRw4MABunXrxujRoz83FJabm8vrr79Ofn4+b731FldffTV9+/alT58+AJSWlrJt2zZKSko4ePAg\nb7/9NrfddhslJSUV65g/fz4DBw5ky5Ytn+vPnj17WLhwIb/85S9r7ff8+fP5+te/XumU3sR7M+O1\n117jggsuYOnSpfTr16/ic927d+fII49kxYoVFcmyqoEDB/LGG2+wb98+BgwYwLnnnluxbM2aNZx1\n1lns2LGDVq1a8fjjj6cQ5egosWQxzSuEFItQU4hFy5YtKSsr46OPPqJjx4507dq11vYDBgyoeH/R\nRRdx5ZVX8tZbb1UklpYtWzJ+/PhKv/qr6tevX7VJBWDr1q0cPHiQvLy8irr777+fxx57jP379zN6\n9GhGjx5Nv3792Lq1uqexV7Zr167Pzcm0a9eOnTt31viZ6dOnc+DAAd544w2WL19eadlJJ53E1q1b\n2bZtG3/4wx847bTT6uxDlDQUJiKNzimnnMLDDz/MuHHjyM3NZciQIbUOV82YMYPzzz+fjh070qFD\nB2bMmMGmTZsqlnfq1KnWpFKXDh060KJFC9avX19RN3HiRLZu3cp1111HeXl5vdZ3zDHHsGPHjkp1\n27dvp23btrV+rmXLllx11VXMmjWL11577XPLc3JyuP322xk8eHBGL6lQYsliTWUsvSEoFqGmEoub\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nGGNMUP1/exnBzk1/HEAAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(samples(random.uniform, 0, 200))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And try a constant distribution, where everyone starts out the same:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.00 0.0 100 100 100 100 100\n", + " 20,000 0.48 94.0 1 11 72 226 424\n", + " 40,000 0.49 97.3 1 11 71 235 446\n", + " 60,000 0.50 98.1 1 11 68 233 443\n", + " 80,000 0.50 99.1 1 11 69 227 472\n", + "100,000 0.50 99.2 1 11 68 229 452\n", + "120,000 0.50 100.9 1 11 67 235 444\n", + "140,000 0.50 100.9 1 11 70 228 472\n", + "160,000 0.50 101.3 1 10 70 229 474\n", + "180,000 0.50 100.4 1 11 70 226 455\n", + "200,000 0.51 101.6 1 9 68 233 471\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZYAAAEZCAYAAAC0HgObAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt8VOW97/HPj4t4IxAQgoIQ8FbhVKNusYpa1FbEHsW7\niFXipS+Lbi91uxVsq4HdrcI5u4WyveweLxGrRVsRpYqiYqwiKloiClrwMiBIUCFcxEK4/M4fs5Jn\ngoFMYFaSmXzfr9e8nPXkmTXP+krml/WsNWuZuyMiIpIprZp6ACIikltUWEREJKNUWEREJKNUWERE\nJKNUWEREJKNUWEREJKNUWEQAM/vAzE5s6nGI5AIVFmkRzOwzMzt5m7bhZvYagLv/L3f/Wz3r6GVm\nW81MvzciO6BfEGnpGvINYYv6WxwDMbPWcaxXpLGpsIhQe4/GzI42szlmtsbMlpvZ/426vRr9d7WZ\nrTWzYyzpV2aWMLMKMys1s7yU9V4a/eyrqF/q+9xuZn82s0fMbDUwPHrvN8ys0syWmdlEM2uTsr6t\nZjbCzBZG4xtjZn3MbJaZrTazydX9zayzmU2L1rXSzKrHLxIrFRZpyba35zEBGO/uHYADgCei9upj\nMHnunufubwGXAZcCPwT6AO2B/wYws77A3cBFwL5AB2C/bd7rTOAJd+8IPApsBm4AOgHHAicDV2/z\nmlOBI4AfADcD/wMMA/YHvh+9H8C/AZ8DnYGuwK31BSKSCSos0pJMNbNV1Q+SH/p1qQIONLPO7v6t\nu7+9zc9TC9Iw4LfuvtjdvwVGARdGx2HOBZ5x99nuvhm4rY73mu3u0wDcfaO7z3X3tz1pCfAHkkUr\n1Vh3X+/uHwIfADOi918HTCdZdAA2kSxovd19i7vPqj8ikV2nwiItyRB371T94Lt7AtWuAA4BPjKz\nt8zsJztY537A4pTlxUAboCD62efVP3D3fwIrt3n956kLZnZQNH21PJoe+09gn21e82XK838CK7ZZ\n3jt6/n+AT4AZZvaxmd2yg+0QyRgVFmlJ0jro7u6fuPswd+8CjAP+YmZ7UPeB/i+AXinLvUhOZ60A\nlgM9at48uY7O277dNsv3Ah8CB0TTY79Md9x1bMc37n6Tux9AcsrtRjM7aWfWJdIQKiwi2zCzi82s\nei9hDckP/63AV9F/D0jp/ifgF2ZWaGZ7k9zDmOzuW4G/AGeY2Q/MrC1QksbbtwfWuvu3ZvY9YMQu\nbMdPzKx6rOtIFrytO7s+kXSpsEhLUd9pxak/Pw2Yb2Zrgd8BF0bHP/5JsnDMio7T9AceBB4B/kZy\n2ulb4DoAd18AXAs8TnLPZi3JaayNOxjHTcDF0Xv/DzC5nu3Y0XYdBLxkZuuAWcDd7q4zwyR2FveN\nvswsQfKvvq3AJnfvb2b5JH/ZegEJ4AJ3XxP1HwVcTvKvq+vdfUbUfiRQCuwOPOfuN8Q6cJEMM7O9\ngNXAge6+uL7+ItmqMfZYtgID3f0Id+8ftY0EXnL3Q4CZJM+kqT498wLgUGAwcI+ZVc8v3wtc4e4H\nAweb2aBGGLvILjGz/21me0RF5b+AeSoqkusao7BYHe8zBHg4ev4wcFb0/EyS89Ob3T0BLAL6m1k3\noL27z4n6TUp5jUhzNoTkNNhSksdmhjbtcETi1xiFxYEXo28yXxm1Fbj7CgB3ryD55S2A7tQ+/XJZ\n1Nad5C9mtaVRm0iz5u4/c/f86PFjd1/U1GMSiVub+rvssgHuvtzMupA8n/4fNOwApIiIZJHYC4u7\nL4/++5WZTQX6AyvMrMDdV0TTXNVf+FpG8rIU1XpEbdtr/w4zU5ESEdkJ7p6RC6zGWljMbE+glbt/\nEx28PBUYDTwDFANjgeHA09FLngEeNbPfkZzqOhB42909uuBef2AOyWsz/X577xv3mW71KS4uobCw\nJK2+iUQJpaXp9W2okpISSkriWXe2URaBsgiURRDOk9p1ce+xFABPRXsRbYBH3X2Gmb0DPGFml5O8\nBMYFkDzv38yeABaQvM7R1R6qxDXUPt34+ZjHnvUSiURTD6HZUBaBsgiURTxiLSzu/hlQVEf7KuBH\n23nNncCddbS/S/LKrSIi0ozpm/c5rLi4uKmH0Gwoi0BZBMoiHiosOWzgwIFNPYRmQ1kEyiJQFvFQ\nYclhZWVlTT2EZkNZBPVlUVhYiJnpkaOPwsLC2P+NNcb3WEQkiyxevLjJz6yU+GTy7K/t0R5LDtNu\nfqAsAmUhcVNhERGRjFJhyWE6rhAoi0BZSNxUWEREJKN08D6HaS49UBbBzmRx223jWbJkdeYHE+nZ\nsyNjxuz8vftGjx7NJ598wqRJk3Z6Ha+++io//elP+fzzz+vvnOKdd95h9OjRzJo1C4D99tuPs88+\nm5tuuokOHTo0aF2PPfYYt956KytXruTHP/4xDz74IB07dqyz7+LFi7nssst466236NWrFxMnTuSU\nU05p0PvFRYVFROq1ZMnqtK9/tzMSifjWnY4tW7bg7g0+Y+qNN95g0KBB/PrXv+bBBx+kS5cuLF26\nlAceeID33nuPE088Me11zZ8/n5///OdMnz6dI444gp/97GeMGDGCP/3pT3X2v+iiixgwYADTp0/n\n2Wef5bzzzuPjjz+mc+fODdqGOGgqLIdpLj1QFkE2ZzF27Fh69OhBXl4ehx56KK+88govvPACd9xx\nB48//jjt27fniCOOAKC0tJS+ffuSl5fHgQceyB/+8Iea9bz66qvsv//+jBs3jn333Zdhw4Zx+umn\n88UXX9C+fXvy8vKoqKiodzy33HILV1xxBTfffDNdunQBoEePHtx+++0NKiqQ3Fs588wzGTBgAHvu\nuSf/8R//wZQpU1i/fv13+i5atIi5c+dSUlJCu3btOOecczjssMN48sknG/SecVFhEZGssHDhQu6+\n+27effdd1q5dywsvvEBhYSGDBg3i1ltv5cILL2TdunXMnTsXgIKCAp577jnWrl3LQw89xC9+8QvK\ny8tr1ldRUcHq1atZsmQJkyZNYvr06ey3336sW7eOtWvX0q1bN2bNmkWnTp3qHM+3337L7NmzOeec\nc3Y47lmzZpGfn0+nTp3Iz8+v9bxTp0688cYbQHKP5fDDD695XZ8+fWjXrh0LFy78zjrnz59Pnz59\n2GuvvWraDj/8cObPn59+oDFSYclhOq4QKIsgW7No3bo1VVVVfPDBB2zevJmePXvSu3fv7fYfPHhw\nzbfMTzjhBE499VRee+21WusbPXo0bdu2pV27dnWuY8CAAaxatarOn1VWVrJ161a6detW03bLLbeQ\nn5/P3nvvzR133FGzjsrKSlatWkVlZWWt56tWreK4444D4JtvvvnOMZm8vDzWrVv3nfduSN+moMIi\nIlnhgAMOYPz48ZSUlFBQUMCwYcN2OF01ffp0jj32WDp37kx+fj7Tp0/n66+/rvl5ly5daNu27U6P\nJz8/n1atWrF8+fKatrFjx1JZWcnZZ5/N5s2bG7S+vffem7Vr19ZqW7NmDe3bt9+lvk1BhSWHZfNc\neqYpiyCbsxg6dCivvfYaixcvBpJ7CPDdy5RUVVVx3nnncfPNN/PVV19RWVnJ4MGDa12qZtvXNPTA\n/Z577skxxxzDlClTdtjv9ddfrzluk/qobqs+m6xfv3689957Na/75JNP2LRpEwcffPB31tmvXz8+\n/fTTWsdf3nvvPfr169egbYiLCouIZIWFCxfyyiuvUFVVxW677cYee+xBq1bJj7CCggISiURN4aiq\nqqKqqop99tmHVq1aMX36dGbMmLHD9RcUFLBy5crv7AnsyLhx43jwwQcZN24cX331FQBLly7ls88+\nq+lz/PHH1xy3SX1Utw0YMACAiy++mGnTpjFr1izWr1/PbbfdxrnnnlvrOEq1gw46iKKiIkaPHs3G\njRuZMmUKH3zwAeeee27aY4+TTjfOYdk6lx4HZRHsTBY9e3aM9ZTgnj3r/q5Gqo0bNzJy5Eg++ugj\n2rZty3HHHVdzptf555/PH//4Rzp37kyfPn145513mDBhAueffz5VVVWcccYZDBkyZIfrP+SQQ7jo\noovo06cPW7duZcGCBXz88cecfvrp2y02AwYMYObMmZSUlHDXXXcBybPChgwZwrXXXtugDPr27ct9\n993HsGHDWLVqVc33WKqNGDECM+Oee+4BYPLkyQwfPpz8/Hx69erFk08+2SxONQawXLuKqZl5U29T\nc7nnvcjOMDNd3TiHbe//b9SekUsfayosh2XzXHqmKYtAWUjcVFhERCSjVFhymI4rBMoiUBYSNxUW\nERHJKBWWHKa59EBZBMpC4qbCIiIiGaXCksM0lx4oi0BZSNxUWEREJKNUWHKY5tIDZREoi6TLLruM\n2267ramHkZN0SRcRqddtd97GkhVLYlt/z4KejBk1Jrb1Z0JFRQW33XYbzz77LOvWraNr166ceOKJ\njBw5ss4LRe5IeXk5V155JR9++CF9+/bl/vvvr3UvllSXXXYZjz32GO3atau5y+WaNWtqLpp51VVX\n8eqrr7Jo0SIeeughLr300l3e1l2lwpLDNJceKItgZ7JYsmIJhWcVZnws1RJTE7GtOxOq75syYMAA\nZs2aRWFhIWvXruWpp57ixRdfbFBh2bRpE2eddRY33ngjI0aM4L777mPIkCF8/PHHtGlT90fyLbfc\nwpgxdRfeoqIihg4dWnOl5+ZAU2EikjWWL1/OeeedR9euXTnggAOYOHFizc9Gjx7NhRdeyPDhw8nL\ny+P73/8+f//732t+PnfuXI466ig6dOjA0KFD2bBhQ9rv+9vf/pYOHTrwyCOP1Nw8LC8vj+HDh3PN\nNdc0aBvKysrYsmUL1113HW3btuXaa6/F3Zk5c2aD1lNtxIgRnHTSSdu9WVlTUGHJYZpLD5RFkK1Z\nuDtnnHEGRxxxBMuXL+fll19mwoQJvPjiizV9pk2bxrBhw1izZg1nnHFGzYf+pk2bOPvssxk+fDir\nVq3i/PPP/8794fPz82tuE7ytl19+mbPPPrveMe7oFsTjxo0DkrcVPuyww2q9rr7bCt9zzz3ss88+\nHH300fXe/6U5UGERkawwZ84cvv76a375y1/SunVrCgsLufLKK5k8eXJNn+OPP55BgwZhZlxyySXM\nmzcPgNmzZ7N582auu+46WrduzbnnnsvRRx9da/2VlZU1twne1tdff13rFsTTpk0jPz+fvLw8Tjvt\ntFrr2N4tiG+++Wag4bcVvv7661m0aBFffvklY8aMobi4mNmzZzcgucanYyw5TMcVAmURZGsWixcv\nZtmyZXTq1AlI7sFs3bqVE088saZP6of/nnvuyYYNG9i6dSvLly+ne/futdbXq1evtN+7c+fOtW5B\nfMYZZ1BZWckDDzzAo48+2qDtaOhthYuKimqeDx48mIsvvpgpU6Zw7LHHNuh9G5P2WEQkK+y///70\n6dOHVatW1ewJrFmzhmnTptX72n333Zdly5bValuyJP2z3E455RSmTp1ab78d3YK4+kZg/fr1q9mT\nqjZv3ry0byucDffLUWHJYdk6lx4HZRFkaxb9+/enffv2jBs3jg0bNrBlyxbmz5/PO++8s93XVH8A\nH3vssbRp04aJEyeyefNmpkyZwttvv532e994441UVlZyySWX8OmnnwKwbt06ysvLa/Xb0S2IR44c\nCST3GFu3bs3EiROpqqri97//Pa1ateLkk0+u872ffPJJ1q9fj7szY8YMHn300Vp3w9y0aRMbNmzA\n3amqqmLjxo1NXng0FSYi9epZ0DPWU4J7FvSst0+rVq3461//yo033kjv3r2pqqrikEMO4Te/+c12\nX1P9XY+2bdsyZcoUrrzySn71q19x+umnf+f+8O3bt+f555+vuQd9qs6dO/Pmm2/y61//muOPP55v\nvvmGgoICjj/+eO69994GbWvbtm2ZOnUqV1xxBSNHjuTQQw/l6aefrjnV+LHHHuPOO+/k/fffB2DC\nhAlceeWVuDu9e/fm/vvv54QTTqhZ36mnnsqrr76KmTF79myuuuoqXnnllVpThI2tUW5NbGatgHeA\npe5+ppnlA48DvYAEcIG7r4n6jgIuBzYD17v7jKj9SKAU2B14zt1v2M576dbEIrsgG6ZaZOfl0q2J\nrwcWpCyPBF5y90OAmcAoADPrC1wAHAoMBu6x6j854F7gCnc/GDjYzAY10thFRKQBYi8sZtYDOB24\nP6V5CPBw9Pxh4Kzo+ZnAZHff7O4JYBHQ38y6Ae3dfU7Ub1LKa2Q7snUuPQ7KIlAWErfG2GP5HfDv\nQOq+V4G7rwBw9wqga9TeHfg8pd+yqK07sDSlfWnUJiIizUysB+/N7CfACncvN7OBO+ia0Qnd4uLi\nmssudOzYkaKioppz96v/WotzuaIiQfT2JBLJnxcWDqxzuaIiQVlZWSzjGThwYKNsr5azb7lafT+X\n3FVWVkZpaSlAzedlpsR68N7M7gB+SvJA/B5Ae+Ap4F+Age6+IprmesXdDzWzkYC7+9jo9c8DtwOL\nq/tE7UOBH7r7iDreUwfvRXaBDt7ntqw/eO/ut7p7T3fvAwwFZrr7JcA0oDjqNhx4Onr+DDDUzHYz\ns97AgcDb0XTZGjPrHx3MvzTlNbId+uszUBaBspC4NdX3WO4CnjCzy0nujVwA4O4LzOwJkmeQbQKu\nTtn9uIbapxs/3+ijFmkBevXqRTgZU3JNQy5ls7Ma5XssjUlTYSIiDZc1U2EiItLyqLDkMM2lB8oi\nUBaBsoiHCouIiGSUCksOy9b7bsRBWQTKIlAW8VBhERGRjFJhyWGaPw6URaAsAmURDxUWERHJKBWW\nHKb540BZBMoiUBbxUGEREZGMUmHJYZo/DpRFoCwCZREPFRYREckoFZYcpvnjQFkEyiJQFvFQYRER\nkYxSYclhmj8OlEWgLAJlEQ8VFhERySgVlhym+eNAWQTKIlAW8VBhERGRjFJhyWGaPw6URaAsAmUR\nDxUWERHJKBWWHKb540BZBMoiUBbxUGEREZGMUmHJYZo/DpRFoCwCZREPFRYREckoFZYcpvnjQFkE\nyiJQFvFQYRERkYxSYclhmj8OlEWgLAJlEQ8VFhERySgVlhym+eNAWQTKIlAW8VBhERGRjFJhyWGa\nPw6URaAsAmURDxUWERHJKBWWHKb540BZBMoiUBbxUGEREZGMUmHJYZo/DpRFoCwCZREPFRYREcmo\nWAuLmbUzs7fMbK6ZvW9mt0ft+WY2w8z+YWYvmFmHlNeMMrNFZvahmZ2a0n6kmc0zs4VmNj7OcecK\nzR8HyiJQFoGyiEeshcXdNwInufsRQBEw2Mz6AyOBl9z9EGAmMArAzPoCFwCHAoOBe8zMotXdC1zh\n7gcDB5vZoDjHLiIiOyf2qTB3/zZ62g5oAzgwBHg4an8YOCt6fiYw2d03u3sCWAT0N7NuQHt3nxP1\nm5TyGtkOzR8HyiJQFoGyiEfshcXMWpnZXKACeDEqDgXuvgLA3SuArlH37sDnKS9fFrV1B5amtC+N\n2kREpJlpjD2WrdFUWA+Sex/9SO611OoW9zhaIs0fB8oiUBaBsohHm8Z6I3dfa2ZlwGnACjMrcPcV\n0TTXl1G3ZcD+KS/rEbVtr71OxcXFFBYWAtCxY0eKiopq/gFV7/rGuVxRkSB6exKJ5M8LCwfWuVxR\nkaCsrKxRx6dlLWtZy2VlZZSWlgLUfF5mirnHt7NgZvsAm9x9jZntAbwA3AX8EFjl7mPN7BYg391H\nRgfvHwWOITnV9SJwkLu7mb0JXAfMAZ4Ffu/uz9fxnh7nNqWjuLiEwsKStPomEiWUlqbXt6HKUgpW\nS6csAmURKIvAzHB3q79n/eLeY9kXeNjMWpGcdnvc3Z+LisQTZnY5sJjkmWC4+wIzewJYAGwCrk6p\nEtcApcDuwHN1FRUREWl6se6xNAXtsYiINFwm91j0zXsREckoFZYcVn2gTpRFKmURKIt4qLCIiEhG\nqbDkMJ3tEiiLQFkEyiIeKiwiIpJRKiw5TPPHgbIIlEWgLOKhwiIiIhmVVmExs5fTaZPmRfPHgbII\nlEWgLOKxw2/em9nuwJ7APmaWD1R/eSYPXV1YRETqUN8ey1XAu8D3ov9WP54G/jveocmu0vxxoCwC\nZREoi3jscI/F3ScAE8zsWnef2EhjEhGRLJbWRSjdfaKZHQcUpr7G3SfFNC7JAM0fB8oiUBaBsohH\nWoXFzB4BDgDKgS1Rs5O8RbCIiEiNdE83/hdggLtf7e7XRo/r4hyY7DrNHwfKIlAWgbKIR7qF5QOg\nW5wDERGR3JDujb72ARaY2dvAxupGdz8zllFJRmj+OFAWgbIIlEU80i0sJXEOQkREckdaU2Hu/mpd\nj7gHJ7tG88eBsgiURaAs4pHuWWHrSJ4FBrAb0BZY7+55cQ1MRESyU7rfY2lf/dzMDBgC/CCuQUlm\naP44UBaBsgiURTwafHVjT5oKDIphPCIikuXSvbrxOSmP88zsLmBDzGOTXaT540BZBMoiUBbxSPes\nsDNSnm8GEiSnw0RERGpJ9xjLZXEPRDJP88eBsgiURaAs4pHuVFgPM3vKzL6MHk+aWY+4ByciItkn\n3YP3DwHPAPtFj2lRmzRjmj8OlEWgLAJlEY90C0sXd3/I3TdHj1KgS4zjEhGRLJVuYVlpZj81s9bR\n46fAyjgHJrtO88eBsgiURaAs4pFuYbkcuACoAJYD5wHFMY1JRESyWLqFZQww3N27uHtXkoVmdHzD\nkkzQ/HGgLAJlESiLeKRbWA5z98rqBXdfBRwRz5BERCSbpVtYWplZfvWCmXUi/S9XShPR/HGgLAJl\nESiLeKRbHP4LmG1mf46Wzwf+M54hiYhINkv3fiyTgHOAFdHjHHd/JM6Bya7T/HGgLAJlESiLeKQ9\nneXuC4AFMY5FRERyQIMvmy/ZQ/PHgbIIlEWgLOIRa2GJrjE208zmm9n7ZnZd1J5vZjPM7B9m9oKZ\ndUh5zSgzW2RmH5rZqSntR5rZPDNbaGbj4xy3iIjsvLj3WDYDN7p7P+BY4Boz+x4wEnjJ3Q8BZgKj\nAMysL8kvYh4KDAbuie5YCXAvcIW7HwwcbGa60Vg9NH8cKItAWQTKIh6xFhZ3r3D38uj5N8CHQA+S\n93J5OOr2MHBW9PxMYHJ0PbIEsAjob2bdgPbuPifqNynlNSIi0ow02jEWMysEioA3gQJ3XwHJ4gN0\njbp1Bz5PedmyqK07sDSlfWnUJjug+eNAWQTKIlAW8WiUwmJmewN/Aa6P9lx8my7bLouISJaK/dvz\nZtaGZFF5xN2fjppXmFmBu6+Iprm+jNqXAfunvLxH1La99joVFxdTWFgIQMeOHSkqKqr5y6R6TjXO\n5YqKBNHbk0gkf15YOLDO5YqKBGVlZbGMJ3X+uDG3vzkuV7c1l/E05XJ5eTk33HBDsxlPUy6PHz++\n0T8fmstyWVkZpaWlADWfl5li7vHuLJjZJOBrd78xpW0ssMrdx5rZLUC+u4+MDt4/ChxDcqrrReAg\nd3czexO4DpgDPAv83t2fr+P9PO5tqk9xcQmFhSVp9U0kSigtTa9vQ5WlFKyWTlkEyiJQFoGZ4e5W\nf8/6xbrHYmYDgIuB981sLskpr1uBscATZnY5sJjkmWC4+wIze4LkFzE3AVenVIlrgFJgd+C5uoqK\n1KZfmEBZBMoiUBbxiLWwuPssoPV2fvyj7bzmTuDOOtrfBb6fudGJiEgc9M37HJZ6fKGlUxaBsgiU\nRTxUWEREJKNUWHKY5o8DZREoi0BZxEOFRUREMkqFJYdp/jhQFoGyCJRFPFRYREQko1RYcpjmjwNl\nESiLQFnEQ4VFREQySoUlh2n+OFAWgbIIlEU8VFhERCSjVFhymOaPA2URKItAWcRDhUVERDJKhSWH\naf44UBaBsgiURTxUWEREJKNUWHKY5o8DZREoi0BZxEOFRUREMkqFJYdp/jhQFoGyCJRFPFRYREQk\no1RYcpjmjwNlESiLQFnEQ4VFREQyqk1TDyAOV4+6ut4+7dq0Y+S/jqSgoKARRtQ0ysrK9BdZRFkE\nyiJQFvHIycLS6aRO9fb54s0vWLNmTU4XFhGRppCThaXNbvVvVqvWuT8LqL/EAmURKItAWcQj9z9d\nRUSkUamw5DCdox8oi0BZBMoiHiosIiKSUSosOUzzx4GyCJRFoCziocIiIiIZpcKSwzR/HCiLQFkE\nyiIeKiwiIpJRKiw5TPPHgbIIlEWgLOKhwiIiIhmlwpLDNH8cKItAWQTKIh4qLCIiklEqLDlM88eB\nsgiURaAs4qHCIiIiGRVrYTGzB8xshZnNS2nLN7MZZvYPM3vBzDqk/GyUmS0ysw/N7NSU9iPNbJ6Z\nLTSz8XGOOZdo/jhQFoGyCJRFPOLeY3kIGLRN20jgJXc/BJgJjAIws77ABcChwGDgHjOz6DX3Ale4\n+8HAwWa27TpFRKSZiLWwuPvrQOU2zUOAh6PnDwNnRc/PBCa7+2Z3TwCLgP5m1g1o7+5zon6TUl4j\nO6D540BZBMoiUBbxaIpjLF3dfQWAu1cAXaP27sDnKf2WRW3dgaUp7UujNhERaYaawx0kPdMrnHrX\nVDp26wjA7nvvTrcDu1FYVAhAojwBQBvaMOEPE/gk8QkA3Xp0A6BiaUWdy/2P6s+YUWNq5mSr/9Kp\na7miIkFh8u1IJJI/LywcWOdyRUWi1n2301l/usup88dxrD+blqvbmst4mnK5vLycG264odmMpymX\nx48fT1FRUbMZT2Mul5WVUVpaCkBh9QdWhph7xj/Xa7+BWS9gmrsfFi1/CAx09xXRNNcr7n6omY0E\n3N3HRv2eB24HFlf3idqHAj909xHbeT+//ZXb6x3X0llLWfnxSg4ffnha25GYmqB0fGlafYuLSygs\nLElvvYkSSkvT69tQZSkFq6VTFoGyCJRFYGa4u9Xfs36NMRVm0aPaM0Bx9Hw48HRK+1Az283MegMH\nAm9H02VrzKx/dDD/0pTXyA7oFyZQFoGyCJRFPGKdCjOzx4CBQGczW0JyD+Qu4M9mdjnJvZELANx9\ngZk9ASwANgFXe9idugYoBXYHnnP35+Mct4iI7Ly4zwob5u77uXs7d+/p7g+5e6W7/8jdD3H3U919\ndUr/O90Cry/oAAAI3ElEQVT9QHc/1N1npLS/6+7fd/eD3P36OMecS1KPL7R0yiJQFoGyiIe+eS8i\nIhmlwpLDNH8cKItAWQTKIh4qLCIiklEqLDlM88eBsgiURaAs4qHCIiIiGaXCksM0fxwoi0BZBMoi\nHiosIiKSUc3hWmFZYW75XIpvKE6v70efpX1JlzjpchWBsgiURaAs4qHCkqb1VespPKswrb6vv14e\n72BERJoxTYXlMP0lFiiLQFkEyiIeKiwiIpJRKiw5TOfoB8oiUBaBsoiHCouIiGSUCksO0/xxoCwC\nZREoi3iosIiISEapsOQwzR8HyiJQFoGyiIcKi4iIZJQKSw7T/HGgLAJlESiLeOib9zFYuaqCqWXF\nafX1DZ8BJXEOR0SkUamwxGCzVdFxYGFafZf+Nb7Lv+g6SIGyCJRFoCzioakwERHJKBWWHKa/xAJl\nESiLQFnEQ4VFREQySsdYmtjKVRVp3+elZ0FPxowak/a6NX8cKItAWQTKIh4qLE1ss1WlfZ+XxNRE\nrGMREckETYXlMP0lFiiLQFkEyiIeKiwiIpJRKiw5TNdBCpRFoCwCZREPFRYREckoHbzPInPL58Z2\nBlmu01x6oCwCZREPFZYssr5qvc4gE5FmT4UlR80tn8tp551Gtx7d6u3bEvZu9H2FQFkEyiIeKiw5\nan3Verod343CosJ6+2rvRkQySQfvc1g6RaWl0F+lgbIIlEU8tMciOilARDIqqwqLmZ0GjCe5p/WA\nu49t4iE1a4nyRFp7LS3hpADNpQfKIlAW8ciawmJmrYD/Bk4BvgDmmNnT7v5R046s+ar4uCLj02EN\n2bsB+HTRp/Q5qE9afePcGyovL9cHSERZBMoiHllTWID+wCJ3XwxgZpOBIYAKy3Zs+GZDxtfZkL0b\ngNdvfZ2Tzzo5rb5PlTzFkhVL0urb0CK0evXqtPvmOmURKIt4ZFNh6Q58nrK8lGSxkRzRkKLV0CLU\nSuepiDSabCosaSubVFZvnzYb2pC3e178g2lCqyty96+xhhah9V+uJ7E6UW/fhkzdNYe+OzN9mEgk\nGtQ/lymLeJi7N/UY0mJmPwBK3P20aHkk4NsewDez7NggEZFmxt0tE+vJpsLSGvgHyYP3y4G3gYvc\n/cMmHZiIiNSSNVNh7r7FzP4VmEE43VhFRUSkmcmaPRYREckOOXOqjJmdZmYfmdlCM7ulqccTNzPr\nYWYzzWy+mb1vZtdF7flmNsPM/mFmL5hZh5TXjDKzRWb2oZmd2nSjzzwza2VmfzezZ6LlFpkDgJl1\nMLM/R9s338yOaal5mNkvzOwDM5tnZo+a2W4tJQsze8DMVpjZvJS2Bm+7mR0Z5bfQzMan9ebunvUP\nkgXyY6AX0BYoB77X1OOKeZu7AUXR871JHn/6HjAWuDlqvwW4K3reF5hLcvqzMMrLmno7MpjHL4A/\nAs9Eyy0yh2gbS4HLoudtgA4tMQ9gP+BTYLdo+XFgeEvJAjgeKALmpbQ1eNuBt4Cjo+fPAYPqe+9c\n2WOp+fKku28Cqr88mbPcvcLdy6Pn3wAfAj1IbvfDUbeHgbOi52cCk919s7sngEXkyPeAzKwHcDpw\nf0pzi8sBwMzygBPc/SGAaDvX0ELzAFoDe5lZG2APYBktJAt3fx2o3Ka5QdtuZt2A9u4+J+o3KeU1\n25UrhaWuL092b6KxNDozKyT5l8mbQIG7r4Bk8QG6Rt22zWgZuZPR74B/B1IPGLbEHAB6A1+b2UPR\n1OAfzGxPWmAe7v4F8F/AEpLbtcbdX6IFZpGiawO3vTvJz9NqaX225kphabHMbG/gL8D10Z7Ltmdj\n5PTZGWb2E2BFtPe2o3PwczqHFG2AI4G73f1IYD0wkhb27wLAzDqS/Au9F8lpsb3M7GJaYBY7EMu2\n50phWQb0TFnuEbXltGj3/i/AI+7+dNS8wswKop93A76M2pcB+6e8PFcyGgCcaWafAn8CTjazR4CK\nFpZDtaXA5+7+TrT8JMlC09L+XQD8CPjU3Ve5+xbgKeA4WmYW1Rq67TuVSa4UljnAgWbWy8x2A4YC\nzzTxmBrDg8ACd5+Q0vYMUBw9Hw48ndI+NDorpjdwIMkvmWY1d7/V3Xu6ex+S/99nuvslwDRaUA7V\nommOz83s4KjpFGA+LezfRWQJ8AMz293MjGQWC2hZWRi19+QbtO3RdNkaM+sfZXhpymu2r6nPXMjg\nGRCnkTwzahEwsqnH0wjbOwDYQvIMuLnA36MMOgEvRVnMADqmvGYUybM9PgRObeptiCGTHxLOCmvJ\nORxO8o+tcmAKybPCWmQewO3Rds0jebC6bUvJAniM5C1GNpIsspcB+Q3dduAo4P3os3VCOu+tL0iK\niEhG5cpUmIiINBMqLCIiklEqLCIiklEqLCIiklEqLCIiklEqLCIiklEqLCJNJLqe1znR8+vNbPeU\nn61rupGJ7BoVFpHm4QZgr5RlfcFMspYKi0iazOym6PbYmNnvzOzl6PlJZvZHM/uxmb1hZu+Y2ePR\nVYUxs1+b2VvRzZLuq2O915K8SOLM6nUmm+03ZlYerbNLI22myC5TYRFJ32vACdHzo0heLbd11DYP\n+BVwirv/C/Au8G9R34nufoy7HwbsGV2RuYa7TyR56Y2B7n5K1LwX8Ia7F0Xv+7MYt0sko1RYRNL3\nLnCUmbUnef2l2cDRJAvLP0nehW+Wmc0lebG+6itun2Jmb0a3iD0J6Led9adeLHCjuz+X8r6FmdwQ\nkTi1aeoBiGQLd99sZgmSV4edRXIv5STgAJK3wJ3h7henvsbM2gF3A0e6+xdmdjuwO/XblPJ8C/pd\nlSyiPRaRhnkNuAn4G/A68HOSV5d+CxhgZgcAmNmeZnYQySLiwMropmznbWe9a4G8lOUd3bRMpFlT\nYRFpmNeAbsBsd/+S5BTY39z9a5J7Mn8ys/eAN4BDPHm/+ftJ3hNlOrXv75F65tf/A55POXivs8Ik\na+my+SIiklHaYxERkYxSYRERkYxSYRERkYxSYRERkYxSYRERkYxSYRERkYxSYRERkYxSYRERkYz6\n/5Ieek/2qQ0nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZYAAAEZCAYAAAC0HgObAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmYFfWV//H3YV9kXxoEodkFo0FUCBojiREE97gENUZc\n8hijER0zLplfRpmJ6zgzEqKZMYugxqAGMgICggpIFJAdWWRNszbNJg2yL+f3x62mLkhDA7e67vJ5\nPU8/VtWtW/fUsbmn63xrMXdHREQkVSrEHYCIiGQXFRYREUkpFRYREUkpFRYREUkpFRYREUkpFRYR\nEUkpFRbJWWZ2iZmtLsfP+4eZfa+8Pk8kLioskpHMrJ+ZzTOzHWa2zsxeNrM6J7GptLmQy8y6mtl7\nZvalmW0ys6lm1i/uuEROlAqLZBwzexh4BngYqA18C2gJjDezSqW8p2KKY0j19roDHwITgDbu3hC4\nF+h1ktvTv22JjX75JKOYWS3gSeB+dx/v7gfcfRVwE5AP/ChY7wkze8fMXjezrcDtZlbNzAab2RYz\nmw9ccMS2m5rZX81sg5ktN7OfJ712tO2ZmT1mZsvMbKOZDTWzuknvuc3MCoLXfnmcXXseeNXdX3D3\nLQDuPtvdbw62dbuZTT4i3oNm1jqYfjU4anvPzLYDvzCzQjOzpPWvM7O5wXSpsZtZ1WA/NwVHT9PM\nrFEZ/xeJqLBIxrkQqAr8LXmhu+8ARgOXJS2+Gnjb3esCb5IoSK2Cn17A7SUrBl/AI4HZQFPgUqC/\nmZW2vT8DDwTLLgZOB74EXg621ymYvjV4rQHQ7Gg7ZGbVge7AsOPs+5FtuyPnbwb+3d1rAQOBr4Dv\nHfH6G8F0qbGTyEvtIN76wE+BXceJTeQQFRbJNA2BTe5+8CivFQavl5ji7iMB3H03cCPwa3cvdve1\nwG+S1u0KNHT3p4KjoALgD0DfUra3B7gH+Bd3L3T3fcC/ATcEbajrgZHu/knw2q8ofTynHol/i4Vl\nTwMAdsT8u+4+NSm+ocAtcOhIrw/wl2DdY8W+j0QhbO8Js939qxOMTXLYUfvRImlsE9DQzCocpbg0\nDV4vceQZX6cDa5LmVyZNtwCamdmWYN5IfNl/fIzttQT+ZmYHk96zD8gLPuvQ+u6+08w2l7JPXwIH\ng/iXlLJOWRwZ35vAJ2b2U+AHwEx3L9n/Y8X+OtAcGBqcEPEGiSJ04BRikxyiIxbJNFOAPSS+KA8x\ns9OA3sAHSYuPPEJYB5yRNN8yaXo1sMLd6wc/9dy9jrtfdYztrQJ6H/Gemu5eSOLo49BnmVkNEkcB\nX+Puu4L9uv7ouwzADqBG0vaaHG1TR2x3EYni2YdEG+zNssTu7vvd/d/d/SwSrcergB8fIzaRw6iw\nSEZx920k2jaDzKyXmVUys3zgLRJflm8c4+3vAI+bWV0zaw7cn/TaZ8B2M3skGOSvaGZnmdn5x9je\n/wJPm1kLADNrZGZXB6/9FbjSzC40s8pBzEe2rpI9AvQzs4fNrH6wvW+aWUnrai5wlpmdY2ZVgSco\n26nSbwL9SYylvFOW2M2sh5l9I2iLfUXiSOZorUeRo1JhkYzj7v8B/BJ4ASgm8df+SuD7wXhBaQaQ\nKD7/AMYCryVt8yBwJdA5eH0D8HsSg9ilGQi8C4wzs2LgUxJjNbj7QuA+EmMa64DNHN6GO3KfppAY\naL8UWG5mm4D/Ad4LXl9Kojh9SKJdNrmUTR1pKPAd4MOSs82OFzvQhERhLAYWkDgF+vUyfp4IFvWD\nvsysgMQv6EFgn7t3NbN6JP7CbAkUADe5e3Gw/uPAncB+oL+7jwuWdwEGA9WA0e7+YKSBi4jISSmP\nI5aDQA93P9fdS/4iegz4wN07AB8Bj8OhUzRvAjqS6Je/nHQe/u+Au9y9PdDezE7qwjEREYlWeRSW\nkrNrkl0DDAmmhwDXBtNXA0ODwcMCYCnQNRiorOXu04P1Xkt6j4iIpJHyKCxO4lYb083s7mBZnrsX\nAbj7eqBxsLwZh58yuTZY1ozD+9NrKOViMxERiVd5XMdykbsXBreEGGdmizn+FcQiIpKhIi8swTn9\nuPtGM/s/EmeeFJlZnrsXBW2uDcHqazn8OoPmwbLSln+NmalIiYicBHc/1inxZRZpYQkuCqvg7l+Z\nWU2gJ4lTPkcA/YDnSNyX6N3gLSOAP5vZf5NodbUFPnN3N7NiM+sKTCdxsdZvKEXUZ7ody/Dh8MYb\nif/G7cknn+TJJ5+MO4y0cCq5OOgH2blvJ+u/Ws+0NdMo2FrA1t1bEz97tlK8u5jiPcUUbi9k3fZ1\n1KtejwbVG1CzSk1qVq759f8ebVmVmtSqUot61etRr1o96larS51qdahSsUpqE4F+L5IpF6Gk+5We\nsqiPWPJI3DbCg8/6s7uPM7MZwNtmdieJ6w9ugsS5/2b2NrCQxEVZP/OwStzH4acbj4049oxXUFAQ\ndwhp41i5OHDwAIVfFbJk8xKWbVnG4k2LmVE4g8WbFrN973Z27dtF9crVqVetHt3P6E7bem1pXLMx\n7Rq0SxSAqnWoW60uDWo0IL9uPpUqpPedkvR7EVIuohHpvwB3/weJC86OXL4F+H4p73mGxLM2jlw+\nEzg71TFKdnJ31m5fy9LNS9m8azOLNy3m2b8/y+adm9m4cyMbdmxg486NbNyxkaIdRdStVpe29dvS\nvn572tZvy6++8ys6NepE7aq1qVG5BhX0eBORMkvvP63klPTr1y/uEMrF/oP7Wbp5KZ+s/oTxK8Yz\nZ/0cVhWvokblGnRs2JG80/Ko370+X+76koY1GtKxUUca12xM45qNaVSjEY1qNuK0KqfFvRvlJld+\nL8pCuYhG5Ffelzczc42xZJed+3byjy//wariVaz4cgXzN8ynaEcR679az+ptq9mwYwMt67TkvNPP\n49JWl3LRGRfRok4LalapGXfoIhnDzDJj8F7iNXHiRHr06BF3GCdk446NrNm2hrXb17JsyzKmrZ3G\nqCWjaF67OS3qtKBlnZac3fhsLm19KXk182hRpwVNTmtC1UpVj7ndTMxFVLI9F/n5+axcufL4K+ao\nli1bRj62pMIisdt/cD9T10zlqclP8enqT2lVtxVNazWlXf12fC//ewzqPYiGNRoef0MiwMqVK2M9\nMzTdpfLsr1I/I9v+B6gVlv6+2vsVc9fPZWbhTGYVzmLE4hE0rdWUe8+/lzs636EWlpySoKUTdxhp\nq7T8qBUmGadweyHDFw3nzflvMqtwFmc3PpsuTbvQtVlXnrjkCVrVaxV3iCKSIiosWSwdeumLNy1m\n0GeDGDJ3CH3a9eHRix6lZ5ueVKtUrVzjSIdcpAvlQqKmwiIpd+DgAd5f/j4Dpw1k7vq53P7N21n2\n82XknZYXd2giUg40xpJiuTzGcuDgAYYtGsaASQOoWrEq93e9n5u/cTPVK1ePOzTJIZk4xjJgwACW\nL1/Oa6+9dvyVSzFp0iR+9KMfsXr16mOupzEWSXvuzmdrP2NCwQRenfMqdarW4YXLXqBX2166Wl2k\nnBw4cAB3L5czvspC//Kz2MSJEyPZ7vY92/n9zN/T7//6kT8wn77D+rLiyxX875X/y7S7p9G7Xe+0\nKypR5SITKRfxeu6552jevDm1a9emY8eOjB49mqeffpq33nqLWrVqce655wIwePBgOnXqRO3atWnb\nti2vvPLKoW1MmjSJM844g+eff56mTZtyyy230KdPH9atW0etWrWoXbs269evj2sXdcQiZVe8u5jf\nTPsNv53+W7o160bvtr155KJH6NiwY9r8pSSSzpYsWcJLL73EzJkzycvLY9WqVRw4cIBf/vKXX2uF\n5eXlMXr0aPLz85k8eTKXX345Xbt2pXPnxO0X169fz9atW1m1ahUHDx5k6tSp3HbbbaxatSqu3TtE\nhSWLperMnz379zChYAK/mvArWtVtxUc//oizGp+Vkm2XF50FFcr1XKTqb6CTGcapWLEie/fuZf78\n+TRo0IAWLVqUum7v3r0PTV988cX07NmTyZMnHyosFStWZMCAAVSuXPnEA4lYevUrJK1s2bWFxz94\nnGb/1Yxff/xrbvnGLQy9YWjGFRWRZO6p+TkZbdq04cUXX+TJJ5+kcePG3HLLLRQWFh513TFjxtC9\ne3caNGhAvXr1GDNmDJs2bTr0eqNGjdKyqIAKS1Y72V765p2b+af3/4nWA1uzfsd6pt09jb/f+Xce\n6v5Q2o2dlJXGFULKRbz69u3L5MmTD7WsHn300a+1kvfu3csNN9zAI488wsaNG/nyyy/p3bv3YWdz\nHfmedGpHZ+a3hETC3Rk0bRBnvnQmu/bt4ov7v+DVa16lTf02cYcmkhWWLFnChAkT2Lt3L1WqVKF6\n9epUrFiRJk2aUFBQcKhw7N27l71799KwYUMqVKjAmDFjGDdu3DG3nZeXx+bNm9m2bVt57MoxaYwl\ni51IL/3jlR/z1OSn2LhjI5PvmMyZDc+MLrAY5Pq4QjLlIj579uzhscce44svvqBy5cpceOGFvPLK\nK1SpUoXXX3+dBg0a0Lp1a2bMmMHAgQO58cYb2bt3L1dddRXXXHPNMbfdoUMHbr75Zlq3bs3BgwdZ\nuHAhTZo0Kac9O5wukEyxTLtAcuXWlQyYNIDxK8bzYLcHua/rfeV+uxWRVMrECyTLU3lcIKlWWBY7\nXi999NLRnPu/59KwRkNm3zObhy98OGuLisYVQsqFRE2tsBw1eM5gHhn/CO/2fZeLW14cdzgikkXU\nCkuxdG+FzS6czYBJA5hVOIuxPxpLp0ad4g5JJKXUCjs2tcIkZXbv382tw2/lijev4Lv532Xx/YtV\nVEQkEiosWaykl766eDWXDL6EbXu2seTnS+j/rf45d8dhjSuElAuJmgpLlptVOIvuf+xOn7Z9GNF3\nBKdVOS3ukEQky2nwPoud1/08Or3ciYGXD+T6TtfHHU6sdO1GSLmQqOmIJUu9+8W7nPnSmVzd/uqc\nLyoiUr5UWLLQOwve4Scjf8Ivmv6Cl654Ke5w0oLGFULKRXa44447+Nd//de4wzgqtcKyzFvz3+KB\nsQ8w8uaR7Fq2K+5wRCQHqbBkkY9Xfsz9Y+5nzK1jOP/086F53BGlD40rhJQLiZpaYVnio398xA/e\n+gGDrxmcKCoikpYKCwu54YYbaNy4MW3atGHQoEEADBgwgB/+8Ifcfvvt1K5dm7PPPptZs2Ydet/s\n2bM577zzqFOnDn379mX37t1x7cJxqbBkgXcWvMMP//pDht4wlCvaX3FouXrpIeUipFzEx9256qqr\nOPfccyksLOTDDz9k4MCBjB8/HoCRI0dyyy23UFxczFVXXcV9990HwL59+7juuuu4/fbb2bJlCzfe\neCPDhg2Lc1eOSa2wDObuDJw2kBenvsiom0fRrXm3uEMSSXs2IDUPxPInTvy2MdOnT2fTpk38y7/8\nCwD5+fncfffd/OUvf6Fly5Z8+9vfplevXgDcdtttDBw4EIApU6awf/9+HnjgAQCuv/56LrjggpTs\nRxRUWDLUQT/IvaPu5dM1nzL+tvG0a9Dua+uolx5SLkK5nouTKQipsnLlStauXUv9+vUTsbhz8OBB\nLr74Ylq2bHnY81Nq1KjB7t27OXjwIIWFhTRr1uywbbVs2bJcYz8RaoVlqP/89D+ZWzSXqXdNPWpR\nEZH0c8YZZ9C6dWu2bNnCli1b+PLLLykuLmbUqFHHfF/Tpk1Zu3btYctKHm2cjlRYMsy+A/t4evLT\n/Men/8EbP3iDmlVqlrqueukh5SKkXMSna9eu1KpVi+eff57du3dz4MABFixYwIwZM466fsldiLt3\n706lSpUYNGgQ+/fvZ/jw4Xz22WflGfoJUWHJIO7ObX+7jXHLxzHlrim0rd827pBE5ARUqFCBUaNG\nMWfOHFq1akXjxo35yU9+Uupz6s0S40GVK1dm+PDhvPrqqzRo0IB33nmH669P3ztqlMvzWMysAjAD\nWOPuV5tZPeAtoCVQANzk7sXBuo8DdwL7gf7uPi5Y3gUYDFQDRrv7g6V8VtY+j2XammncPOxmFt63\nMGuf9ChyqvQ8lmPLpuex9AcWJs0/Bnzg7h2Aj4DHAcysE3AT0BHoDbxsJSUbfgfc5e7tgfZm1quc\nYk8LK7eu5K4Rd/Fw9+x9fLCIZIfIC4uZNQf6AH9IWnwNMCSYHgJcG0xfDQx19/3uXgAsBbqaWROg\nlrtPD9Z7Lek9WW/P/j30ebMPt51zGz+74Gdlfp966SHlIqRcSNTK44jlv4F/BpKPvfLcvQjA3dcD\njYPlzYDVSeutDZY1A9YkLV8TLMsJL3z6AqfXOp1HLnqE8ABORCQ9RXodi5ldARS5+xwz63GMVVPa\nEO3Xrx/5+fkA1K1bl86dOx86d7/kr7Wo5ufPn8jGjQCp2d7QUUN5buRzzH9+PmZ2Qu/v0aNH5Pur\n+cycL5Eu8US1f1K6iRMnMnjwYIBD35epEungvZk9DfyIxEB8daAW8DfgfKCHuxcFba4J7t7RzB4D\n3N2fC94/FngCWFmyTrC8L3CJu997lM/MqsH7u0fcTV7NPJ669KnUbFAky2nw/tgyfvDe3X/p7i3c\nvTXQF/jI3W8DRgL9gtVuB94NpkcAfc2sipm1AtoCnwXtsmIz6xoM5v846T1Za8TiEYxYPIKHL3z4\npN6vv95CykVIuZCoxXVLl2eBt83sThJHIzcBuPtCM3ubxBlk+4CfJR1+3MfhpxuPLfeoy9G8onnc\n+e6djLplFPWr1487HJGM0bJlS41FHkN53AqmXK5jKU/Z0ArbsGMDF/3pIp685EluPefW1AUnIlKK\njGmFyYlzd378tx9zbYdrVVREJCOpsKSZMcvGsKp4Fc98/5lT3pZ66SHlIqRchJSLaOi2+Wlkz/49\nPPT+Qzxz6TNUqqD/NSKSmTTGkmKnMsYycOpAxi4fy5hbx6Q+MBGRY0jlGIv+LE4Ta7at4deTf83k\nOybHHYqIyCnRGEsacHf6j+3PPefdw5kNz0zZdtU/DikXIeUipFxEQ0csaeC1ua+xbMsy/vyDP8cd\niojIKdMYS4qd6BjLtj3b6PDbDozoO4ILml0QbXAiIqXQdSxZwt25a8RdXNnuShUVEckaKiwxmlAw\ngc+LPmdQn0GRbF/945ByEVIuQspFNFRYYrLvwD5+Me4XPPbtx/RESBHJKhpjSbGyjrH826R/Y8qa\nKYy+ZbRumCcisdN1LBlu4caF/Paz3zLrnlkqKiKSddQKi8Ezf3+G/t3607x280g/R/3jkHIRUi5C\nykU0VFjK2Zptaxi9dDQ/7/bzuEMREYmExlhS7HhjLA+OfRB3Z2DvgeUbmIjIMWiMJUMt3byUN+a9\nwef3fh53KCIikVErrBw9/feneehbD9G0VtNy+Tz1j0PKRUi5CCkX0dARSzlZVbyKd794l/k/mx93\nKCIikdIYS4qVNsZy4zs3clajs3iyx5OxxCUiciwaY8kwkwomMX3tdF679rW4QxERiZzGWMrBExOf\n4Nff+zXVK1cv189V/zikXISUi5ByEQ0VlojNK5rHsi3LuOmsm+IORUSkXGiMJcWOHGPpP6Y/p1U5\njacufSq2mEREjkdjLBli255tvD7vdebdOy/uUEREyo1aYREaMmcIl7W5LPJ7gpVG/eOQchFSLkLK\nRTR0xBKRLbu28OwnzzLspmFxhyIiUq40xpJiJWMsbe99hK27t/LKVa/EFouISFlpjCXN7a5UxB9m\n/UH3BBORnKQxlgisaDiIvt/oS7PazWKNQ/3jkHIRUi5CykU0dMSSYvsO7qGg/u/p3+3juEMREYmF\nxlhSrP8f32DootcoemFcbDGIiJyoVI6xqBWWQu7O/216njYbH4o7FBGR2KiwpNDMwpnsOrCNvO29\n4g4FUP84mXIRUi5CykU0VFhSxN15eNzDXNvoUUxpFZEcFuk3oJlVNbNpZjbbzD43syeC5fXMbJyZ\nLTaz982sTtJ7HjezpWa2yMx6Ji3vYmbzzGyJmb0YZdwnY9LKSRR9VcRl9X8SdyiH9OjRI+4Q0oZy\nEVIuQspFNCItLO6+B/iuu58LdAZ6m1lX4DHgA3fvAHwEPA5gZp2Am4COQG/gZTMrGUz6HXCXu7cH\n2ptZevSbAm8veJt+nftR0XSinYjktsh7Nu6+M5isSuL0ZgeuAYYEy4cA1wbTVwND3X2/uxcAS4Gu\nZtYEqOXu04P1Xkt6T+z27N/DOwvfSbtb46t/HFIuQspFSLmIRuSFxcwqmNlsYD0wPigOee5eBODu\n64HGwerNgNVJb18bLGsGrElaviZYlhaGLxrOOXnn0Lpe67hDERGJXXkcsRwMWmHNSRx9nEXiqOWw\n1aKOI0q/n/V77jnvnrjD+Br1j0PKRUi5CCkX0Si3AQF332ZmE4HLgSIzy3P3oqDNtSFYbS1wRtLb\nmgfLSlt+VP369SM/Px+AunXr0rlz50O/QCWHvqmaf3vU28z4dAZX3nIlAPPnT2TjRoBoPk/zmte8\n5lMxP3HiRAYPHgxw6PsyZdw9sh+gIVAnmK4OfAz0AZ4DHg2WPwo8G0x3AmYDVYBWwDLCuwNMBboC\nBowGLi/lM708vfDJC37Xu3cdmh82zP2668o1hFJNmDAh7hDShnIRUi5CykUo+O5MyXd/1EcsTYEh\nZlaBRNvtLXcfbWZTgbfN7E5gJYkzwXD3hWb2NrAQ2Af8LNhhgPuAwUA1YLS7j4049jIZtXQUD3d/\nOO4wRETShu4Vdgq27dlGs/9qxvqH11OzSk3g68+8FxHJBLpXWJr46B8f0a1Zt0NFRUREVFhOyVsL\n3uL6jtfHHUapSgbqRLlIplyElItoqLCcpB17dzBm6Riu75S+hUVEJA4qLCdp5JKRfKv5t2hcs/Hx\nV45JySmGolwkUy5CykU0VFhO0ojFI7iy/ZVxhyEiknZUWE7C7v27eW/pe/T9Rt+4Qzkm9Y9DykVI\nuQgpF9FQYTkJkwom8Y3G36BhjYZxhyIiknaOW1jMrKKZ/bk8gskUf5rzp7Q+G6yE+sch5SKkXISU\ni2gct7C4+wGgpZlVKYd40t6WXVsYu2wsd3e5O+5QRETSUllbYSuAT8zsV2b2TyU/UQaWrobOH0rv\ntr2pXbV23KEcl/rHIeUipFyElItolPVeYcuDnwpArejCSX9D5w/l0YsejTsMEZG0dUL3CjOzGh4+\nETItRXmvsH0H9lH/+fqsenAV9arXO+o6uleYiGSicr9XmJl1N7OFwBfB/DfN7OVUBJBJPlv7Ge3q\ntyu1qIiISNnHWF4EegGbAdx9LvCdqIJKVyOXjKRXm15xh1Fm6h+HlIuQchFSLqJR5utY3H31EYsO\npDiWtObuDF80XPcGExE5jrIO3q82swsBN7PKQH9gUXRhpZ8FGxew98Bezmt6XtyhlJnO0Q8pFyHl\nIqRcRKOsRyw/JfEEx2YknjXfOZjPGR+u+JBebXphlpKxLRGRrFWmwuLum9z9VnfPc/fG7v4jd98c\ndXDpZPyK8fTI7xF3GCdE/eOQchFSLkLKRTSO2Qozs0FAqefuuvsDKY8oDe3ev5sJBRN48/o34w5F\nRCTtHe+IZQYwE6gGdAGWBj+dgZy5xcsnqz7hnLxzMuJq+2TqH4eUi5ByEVIuonHMIxZ3HwJgZvcC\n33b3/cH8/wCTow8vPby39D36tO0TdxgiIhmhrIP39YDkP9dPC5blhPeWvscV7a+IO4wTpv5xSLkI\nKRch5SIaZT3d+FlgtplNAIzExZFPRhVUOlm2ZRnb92zn3Cbnxh2KiEhGOO69wixxfm1zYB/QLVg8\nzd3XRxzbSUn1vcIGTh3I5xs+5w9X/6FM6+teYSKSiVJ5r7DjHrG4u5vZaHc/G3g3FR+aSd5b+h73\nnn9v3GGIiGSMso6xzDKzCyKNJA19tfcrpq6Zyvdbfz/uUE6K+sch5SKkXISUi2iUdYylG/AjMysA\ndpAYZ3F3PyeqwNLBBys+oFvzbtSqmtOPoBEROSFlLSy9SJwFdnEw/zGwNZKI0sj45eO5vM3lcYdx\n0nSOfki5CCkXIeUiGmVthV0LvA40BBoF01dHFVS6eH/5+3yv1ffiDkNEJKOUtbDcBXzL3Z9w938F\nugM/iS6s+K0uXk3xnmI6N+kcdygnTf3jkHIRUi5CykU0ylpYjMOfv3IgWJa1Pl75Md9u8W3dzVhE\n5ASVdYzlVWCamf0tmL8W+GM0IaWHj1d+TI+WPeIO45SofxxSLkLKRUi5iEZZb5v/X8AdwJbg5w53\nfzHKwOL28arEEYuIiJyYE3k08Sx3/03wMzvKoOK2ZtsaNu7YmNHjK6D+cTLlIqRchJSLaJS5sOSS\n8cvHc2nrS6lYoWLcoYiIZBwVlqMYt2IcPVv3jDuMU6b+cUi5CCkXIeUiGpEWFjNrbmYfmdkCM/vc\nzB4Iltczs3FmttjM3jezOknvedzMlprZIjPrmbS8i5nNM7MlZhbZ+M5BP8iHKz7ksjaXRfURIiJZ\nLeojlv3AP7n7WSSufbnPzM4EHgM+cPcOwEfA4wBm1gm4CegI9AZetvB8398Bd7l7e6C9mfWKIuC5\n6+dSv3p9WtRpEcXmy5X6xyHlIqRchJSLaERaWNx9vbvPCaa/AhaRuAX/NcCQYLUhJE5fhsTV/EPd\nfb+7F5B4DHJXM2sC1HL36cF6ryW9J6XGLR9HzzaZ3wYTEYlLuY2xmFk+0BmYCuS5exEkig/QOFit\nGbA66W1rg2XNgDVJy9cEy1Ju/IrxXNY6O9pg6h+HlIuQchFSLqJRLoXFzE4D/gr0D45cjnwSV+qe\nzHUKdu/fzbS10+iR3yPuUEREMlZZr7w/aWZWiURRed3dSx4UVmRmee5eFLS5NgTL1wJnJL29ebCs\ntOVH1a9fP/Lz8wGoW7cunTt3PvSXSUlP9WjzM9fN5PRNpzNzyswyrX+0+fnzJ7JxI8DJvT+V88n9\n4zg+P53mS5alSzxxzs+ZM4cHH3wwbeKJc/7FF18s8/dDts1PnDiRwYMHAxz6vkwZd4/0h8R4yH8d\nsew54NFg+lHg2WC6EzAbqAK0ApYRPj55KtCVxD3KRgOXl/J5frIGTh3o94y856Tf7+4+bJj7dded\n0iZSZsJyDeBbAAAPE0lEQVSECXGHkDaUi5ByEVIuQsF3Z0q+9yM9YjGzi4Bbgc/NbDaJltcvg8Ly\ntpndCawkcSYY7r7QzN4GFgL7gJ8FOwxwHzAYqAaMdvexqY53ypopWTO+AuofJ1MuQspFSLmIRqSF\nxd0/AUq7fP2oz/t192eAZ46yfCZwduqi+7opq6fwxCVPRPkRIiJZT1feB5ZvWc6u/bvo0KBD3KGk\nTPL4Qq5TLkLKRUi5iIYKS2DkkpFc0+EaPX9FROQUqbAEPln9Cd9p+Z24w0gp9Y9DykVIuQgpF9FQ\nYQnMWT+HLk27xB2GiEjGU2EBCrcXsnnn5qwaXwH1j5MpFyHlIqRcREOFBZi0chIXt7xYz18REUkB\nFRZgUsEkLml5SdxhpJz6xyHlIqRchJSLaKiwABNXTszKwiIiEoecLyxFXxWxbvs6zm16btyhpJz6\nxyHlIqRchJSLaOR8YRm7bCw92/SkguV8KkREUiLnv03nFs3l/Kbnxx1GJNQ/DikXIeUipFxEI+cL\ny6zCWXRu0jnuMEREskZOF5b9B/czs3AmXZt1jTuUSKh/HFIuQspFSLmIRk4XlnlF8zij9hnUq14v\n7lBERLJGTheWKaun0L1597jDiIz6xyHlIqRchJSLaOR0YZm6dirdz8jewiIiEoecLizZfsSi/nFI\nuQgpFyHlIho5W1g27NjApp2b6NioY9yhiIhklZwtLFPXTKVrs65ZfWGk+sch5SKkXISUi2hk77fq\ncUxfO51uzbrFHYaISNbJ2cIyo3AG55+enVfcl1D/OKRchJSLkHIRjZwsLHv272HK6ilceMaFcYci\nIpJ1crKwzFg3g7b129KoZqO4Q4mU+sch5SKkXISUi2jkZGGZVTgr69tgIiJxyc3Csn4W5zbJvuev\nHEn945ByEVIuQspFNHKysMwunE2Xpl3iDkNEJCuZu8cdQ0qZmR9rn3bv30395+qz5dEtVKtULeWf\nP3w4vPFG4r8iIpnCzHB3S8W2cu6IZf6G+bRr0C6SoiIiIjlYWGYV5sb4Cqh/nEy5CCkXIeUiGjlZ\nWDS+IiISnZwrLNPXTee8pufFHUa50Dn6IeUipFyElIto5FRh2b5nO4s3LeaCZhfEHYqISNbKqcKy\ncONC2jdoT5WKVeIOpVyofxxSLkLKRUi5iEZOFZaSW+WLiEh0cqqwTF+XW7fKV/84pFyElIuQchGN\nnCosc4vm8s0m34w7DBGRrBZpYTGzP5pZkZnNS1pWz8zGmdliM3vfzOokvfa4mS01s0Vm1jNpeRcz\nm2dmS8zsxZOJZde+XSzbsoyzGp11ajuVQdQ/DikXIeUipFxEI+ojlleBXkcsewz4wN07AB8BjwOY\nWSfgJqAj0Bt42cxKbi/wO+Aud28PtDezI7d5XJ9v+JwODTpQtVLVk9sTEREpk0gLi7v/HfjyiMXX\nAEOC6SHAtcH01cBQd9/v7gXAUqCrmTUBarn79GC915LeU2azC2dzbtPcuOK+hPrHIeUipFyElIto\nxDHG0tjdiwDcfT3QOFjeDFidtN7aYFkzYE3S8jXBshMye/3snLmVi4hInCrFHQCQ8tsr9+vXj/z8\nfADq1q1L586dmb1+NreefeuhnmrJXyqpnp8/fyIbNwJEs/0TmU/uH8fx+ek0X7IsXeKJc37OnDk8\n+OCDaRNPnPMvvvginTt3Tpt4ynN+4sSJDB48GODQ92XKuHukP0BLYF7S/CIgL5huAiwKph8DHk1a\nbyzQLXmdYHlf4HfH+Dw/0r4D+7zGUzW8eHfx115LtWHD3K+7LvKPKZMJEybEHULaUC5CykVIuQgF\n350p+d4vj1aYBT8lRgD9gunbgXeTlvc1sypm1gpoC3zmiXZZsZl1DQbzf5z0njJZvGkxp9c6ndpV\na5/CbmSekr9SRLlIplyElItoRNoKM7M3SfSEGpjZKuAJ4FngHTO7E1hJ4kww3H2hmb0NLAT2AT8L\nqijAfcBgoBow2t3Hnkgcc9bP0fiKiEg5ifqssFvc/XR3r+ruLdz9VXf/0t2/7+4d3L2nu29NWv8Z\nd2/r7h3dfVzS8pnufra7t3P3/icax6zCWXRu0jlVu5UxkscXcp1yEVIuQspFNHLiyvvFmxfTsWHH\nuMMQEckJOVNYzmx4ZtxhlDv1j0PKRUi5CCkX0cj6wrJr3y7WbFtD2/pt4w5FRCQnZH1hWbx5MW3q\ntaFyxcpxh1Lu1D8OKRch5SKkXEQj6wvLoo2L6NhI4ysiIuUl+wvLpkV0atgp7jBiof5xSLkIKRch\n5SIaWV9YFmxcQKdGuVlYRETikP2FZcMCzmqcO89gSab+cUi5CCkXIeUiGlldWHbu28mq4lW0b9A+\n7lBERHJGVheWaWum8c0m36RKxSpxhxIL9Y9DykVIuQgpF9HI6sKycONCzml8TtxhiIjklKwuLHPW\nz+HsvLPjDiM26h+HlIuQchFSLqKR1YVl9vrZdGnaJe4wRERyioV3ps8OZubuzs59O2n0H43Y/Mhm\nqlWqVm6fP3w4vPFG4r8iIpnCzHB3O/6ax5e1RyzLtywnv25+uRYVERHJ4sJSco+wXKb+cUi5CCkX\nIeUiGllbWOYVzcvJh3uJiMQtawvLwo0Lc/IZLMl0jn5IuQgpFyHlIhpZW1gWbVrEWY1y81YuIiJx\nytrCsmbbGlrUaRF3GLFS/zikXISUi5ByEY2sLCxbd2/lwMED1K1WN+5QRERyTlYWloKtBbSq1wqz\nlJySnbHUPw4pFyHlIqRcRCMrC8viTYtpV79d3GGIiOSkrCwsn2/4nHPydPNJ9Y9DykVIuQgpF9HI\nysKyaNMiPTVSRCQmWVlYFm5cSMeGHeMOI3bqH4eUi5ByEVIuopGVhaVga4GeGikiEpOsLCxNTmtC\n1UpV4w4jduofh5SLkHIRUi6ikZWFpVmtZnGHICKSs7KysOT6PcJKqH8cUi5CykVIuYhGVhaWDg06\nxB2CiEjOysrC0rpe67hDSAvqH4eUi5ByEVIuopGVhaVt/bZxhyAikrOy8pn3O/fupHrl6rF8vp55\nLyKZSM+8P464ioqIiGRYYTGzy83sCzNbYmaPxh1PulP/OKRchJSLkHIRjYwpLGZWAfgt0As4C7jZ\nzHRe8THMmTMn7hDShnIRUi5CykU0MqawAF2Bpe6+0t33AUOBa2KOKa1t3bo17hDShnIRUi5CykU0\nMqmwNANWJ82vCZaJiEgayaTCIieooKAg7hDShnIRUi5CykU0MuZ0YzP7FvCku18ezD8GuLs/d8R6\nmbFDIiJpJlWnG2dSYakILAYuBQqBz4Cb3X1RrIGJiMhhKsUdQFm5+wEzux8YR6KF90cVFRGR9JMx\nRywiIpIZsmbwPtcunjSz5mb2kZktMLPPzeyBYHk9MxtnZovN7H0zq5P0nsfNbKmZLTKznvFFn3pm\nVsHMZpnZiGA+J/MAYGZ1zOydYP8WmFm3XM2HmT1kZvPNbJ6Z/dnMquRKLszsj2ZWZGbzkpad8L6b\nWZcgf0vM7MUyfbi7Z/wPiQK5DGgJVAbmAGfGHVfE+9wE6BxMn0Zi/OlM4DngkWD5o8CzwXQnYDaJ\n9md+kC+Lez9SmI+HgDeAEcF8TuYh2MfBwB3BdCWgTi7mAzgdWAFUCebfAm7PlVwA3wY6A/OSlp3w\nvgPTgAuC6dFAr+N9drYcseTcxZPuvt7d5wTTXwGLgOYk9ntIsNoQ4Npg+mpgqLvvd/cCYCmJvGU8\nM2sO9AH+kLQ45/IAYGa1gYvd/VWAYD+LydF8ABWBmmZWCagOrCVHcuHufwe+PGLxCe27mTUBarn7\n9GC915LeU6psKSw5ffGkmeWT+MtkKpDn7kWQKD5A42C1I3O0luzJ0X8D/wwkDxjmYh4AWgGbzOzV\noDX4ipnVIAfz4e7rgP8EVpHYr2J3/4AczEWSxie4781IfJ+WKNN3a7YUlpxlZqcBfwX6B0cuR56N\nkdVnZ5jZFUBRcPR2rHPwszoPSSoBXYCX3L0LsAN4jBz7vQAws7ok/kJvSaItVtPMbiUHc3EMkex7\nthSWtUCLpPnmwbKsFhze/xV43d3fDRYXmVle8HoTYEOwfC1wRtLbsyVHFwFXm9kK4C/A98zsdWB9\njuWhxBpgtbvPCOaHkSg0ufZ7AfB9YIW7b3H3A8DfgAvJzVyUONF9P6mcZEthmQ60NbOWZlYF6AuM\niDmm8vAnYKG7D0xaNgLoF0zfDrybtLxvcFZMK6AtiYtMM5q7/9LdW7h7axL/3z9y99uAkeRQHkoE\nbY7VZtY+WHQpsIAc+70IrAK+ZWbVzMxI5GIhuZUL4/Aj+RPa96BdVmxmXYMc/jjpPaWL+8yFFJ4B\ncTmJM6OWAo/FHU857O9FwAESZ8DNBmYFOagPfBDkYhxQN+k9j5M422MR0DPufYggJ5cQnhWWy3n4\nJok/tuYAw0mcFZaT+QCeCPZrHonB6sq5kgvgTWAdsIdEkb0DqHei+w6cB3wefLcOLMtn6wJJERFJ\nqWxphYmISJpQYRERkZRSYRERkZRSYRERkZRSYRERkZRSYRERkZRSYRGJSXA/rx8E0/3NrFrSa9vj\ni0zk1KiwiKSHB4GaSfO6wEwylgqLSBmZ2S+Cx2NjZv9tZh8G0981szfM7DIz+9TMZpjZW8FdhTGz\nX5nZtOBhSf9zlO3+nMRNEj8q2WZisf3azOYE22xUTrspcspUWETKbjJwcTB9Hom75VYMls0D/h9w\nqbufD8wEHg7WHeTu3dz9HKBGcEfmQ9x9EIlbb/Rw90uDxTWBT929c/C5P4lwv0RSSoVFpOxmAueZ\nWS0S91+aAlxAorDsIvEUvk/MbDaJm/WV3HH7UjObGjwi9rvAWaVsP/lmgXvcfXTS5+anckdEolQp\n7gBEMoW77zezAhJ3h/2ExFHKd4E2JB6BO87db01+j5lVBV4Curj7OjN7AqjG8e1Lmj6A/q1KBtER\ni8iJmQz8AvgY+DvwUxJ3l54GXGRmbQDMrIaZtSNRRBzYHDyU7YZStrsNqJ00f6yHlomkNRUWkRMz\nGWgCTHH3DSRaYB+7+yYSRzJ/MbO5wKdAB088b/4PJJ6JMobDn++RfObX74GxSYP3OitMMpZumy8i\nIimlIxYREUkpFRYREUkpFRYREUkpFRYREUkpFRYREUkpFRYREUkpFRYREUkpFRYREUmp/w/o/QiM\nyIPw0QAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def constant(mu=MU): return mu\n", + "\n", + "show(samples(constant))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The resulting histogram looks different, but only because the starting distribution is so narrow and tall; the end distribution has a Gini coefficient of about 1/2 and standard deviation of about 100, just like we get from the other starting distributions.\n", + "\n", + "Here is one that statisticians call the [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) (with carefully chosen parameters):" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.50 97.5 1 9 71 230 442\n", + " 20,000 0.50 101.2 1 10 68 237 474\n", + " 40,000 0.50 98.8 1 11 70 230 451\n", + " 60,000 0.50 100.6 1 11 68 232 460\n", + " 80,000 0.50 98.3 1 10 71 229 444\n", + "100,000 0.50 99.1 1 11 71 228 457\n", + "120,000 0.50 99.3 1 11 70 232 450\n", + "140,000 0.51 100.7 1 10 68 232 465\n", + "160,000 0.49 98.2 1 11 70 232 445\n", + "180,000 0.51 101.7 1 10 69 233 480\n", + "200,000 0.51 103.2 1 10 67 233 494\n" + ] + }, + { + "data": { + "image/png": "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\nSfElq1bGAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def beta(): return random.betavariate(0.9, 12)\n", + " \n", + "show(samples(beta))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Surprise:** We can confirm that the starting population doesn't matter much. I thought it would make a real difference, but we showed that three very different starting populations—Gaussian, uniform, and beta—all ended up with very similar final populations; all with G around 1/2 and standard deviation around 100. The final distribution in all three cases looks similar to the normalized beta(0.9, 12) distribution." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Effect of Transaction Function\n", + "\n", + "Does the transaction function have an effect on the outcome? So far we've only used the `random_split` transaction function; we'll now compare that to the `winner_take_all` function, in which the wealth from both actors is thrown into a pot, and one of them takes all of it:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def winner_take_all(A, B): return random.choice(([A + B, 0], [0, A + B]))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.11 20.1 54 75 100 126 148\n", + " 20,000 0.89 287.7 0 0 0 364 1448\n", + " 40,000 0.94 398.9 0 0 0 111 2135\n", + " 60,000 0.96 475.2 0 0 0 0 2576\n", + " 80,000 0.97 560.1 0 0 0 0 3066\n", + "100,000 0.97 629.9 0 0 0 0 3346\n", + "120,000 0.98 683.4 0 0 0 0 3569\n", + "140,000 0.98 729.2 0 0 0 0 3843\n", + "160,000 0.98 800.1 0 0 0 0 4144\n", + "180,000 0.99 859.6 0 0 0 0 4140\n", + "200,000 0.99 902.2 0 0 0 0 4140\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nkcSL0HJzcxk8eDBDhw6t0TkUFhayZ88ebrzxRho1asQNN9yAuzN37tyvrfvFF19QWFjIqFGjyMnJ\n4fjjj+eiiy5KPDhz9uzZnH766Zxyyink5OQwfPhw1q9fz7x582pUp7qmJJPF6mPbe2UUi1AmxMLd\n6du3L927d2fDhg288MIL3HvvvcyZMyexzvTp0xk0aBDbtm2jb9++iQRQWlrK+eefz+DBg9myZQsX\nX3wxTz/99F77z8vLS7wKeV8vvPAC559//n7rWNVrlidMmADEXrN8/PHH77Xdd77zHZYvX17hOe/7\n8Ep355133qnw+OXl5VUuTxdKMiKSdhYvXsxnn33GbbfdRoMGDSgoKODqq6/miSeeSKxz2mmn0bt3\nb8yMyy67jGXLlgGwcOFCysrKuPHGG2nQoAEXXngh3/ve9/baf3FxceJVyPv67LPP9nrN8vTp08nL\nyyM3N5dzzjlnr31U9prlW2+9FajZa5abNm1Kz549+dWvfsXu3bt54403ePrpp/nyyy8B+NGPfsS8\nefN46aWXKC0t5c4776S0tDSxPF0pyWQx9UOEFItQJsRizZo1rF+/npYtWyauEO666y4+/fTTxDrJ\niaBJkyaJl3pt2LCB9u3b77W/Tp06VfvYrVq12us1y3379qW4uJh77rmHkpKSGp1HTV+z/Nhjj/Hh\nhx/SsWNHhg4dymWXXUaHDh2A2DtwJk+ezNChQ2nXrh1btmyhW7duieXpSklGRNLO4YcfTufOndmy\nZUviCmHbtm1Mnz59v9sedthhrF+/fq+ytWurP2Luhz/8IdOmTdvvelW9Zjn+UrPjjjsucYUVt2zZ\nMo477rgK93n44Yczffp0Nm3axMKFC9m8eTM9evRILL/gggt4++232bx5M2PHjuWjjz762lVaulGS\nyWKZ0PZeVxSLUCbEokePHjRr1owJEyawa9cu9uzZw/Lly1myZEml28T7Mk455RQaNmzIfffdR1lZ\nGVOnTmXRokXVPvawYcMoLi7msssu48MPPwRgx44dLF26dK/1qnrN8ogRI4DYVWODBg247777KCkp\n4Q9/+AM5OTn84Ac/qPDY7777Ljt37qS0tJRHH32UOXPmMGzYsMTyN954g/LycjZv3sx//Md/cN55\n59V4SHVd0xBmEUnomN8x0mHGHfM7Vmu9nJwc/vWvfzFs2DCOOOIISkpK6NKlC7/+9a8r3Sb+auJG\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\ns9z8fxaFwGo/qVU+AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(population, transaction=winner_take_all)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the results look **very** different: most of the wealth goes to the 99th percentile (purple line on the far right of the plot), with everybody else getting wiped out (although the 90th percentile holds out until around 50,000 transactions). The Gini coefficient is all the way up to 0.99 and the standard deviation is over 800, and still rising.\n", + "\n", + "That makes sense: any time two actors with non-zero wealth interact, one of them will end up with zero—the number of actors with zero wealth increases monotonically until all the wealth is with one actor, and from then on the wealth just gets swapped around.\n", + "\n", + "At the other end of the spectrum, let's try a transaction function, `redistribute`, that taxes both parties 31% (the average income tax rate in the US) and splits that tax revenue evenly among the two parties; the non-taxed part is split with `random_split`:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def redistribute(A, B, rate=0.31):\n", + " \"Tax both parties at rate; split the tax revenue evenly, and randomly split the rest.\"\n", + " tax = rate * (A + B)\n", + " Arand, Brand = random_split(A + B - tax, 0)\n", + " return tax / 2 + Arand, tax / 2 + Brand" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.11 20.1 54 75 100 126 148\n", + " 20,000 0.32 59.8 18 36 88 183 285\n", + " 40,000 0.33 62.1 16 34 86 187 289\n", + " 60,000 0.33 61.9 18 35 85 185 297\n", + " 80,000 0.33 60.8 17 35 87 181 287\n", + "100,000 0.33 61.7 17 34 87 183 297\n", + "120,000 0.33 61.2 18 35 88 183 291\n", + "140,000 0.33 61.1 16 35 87 185 291\n", + "160,000 0.33 61.6 17 35 86 186 294\n", + "180,000 0.33 61.6 17 35 86 183 301\n", + "200,000 0.33 61.3 17 34 87 187 295\n" + ] + }, + { + "data": { + "image/png": "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\nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEZCAYAAABSN8jfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt8VNW9///XJ4pWhRBAgQpiRAXBnxq0xVZs5WgV8XwR\nqFopRYlFT6v+vNReuLQies5XRL89aj1avz1Fo3LU2lZRTgXRYjwFL6hlwAoKXkaUEiwQLiokJHy+\nf8ye7CEkZJKZyVzyfj4e83DWmjV7r/kY5jN7rb32NndHREQkFUXZ7oCIiOQ/JRMREUmZkomIiKRM\nyURERFKmZCIiIilTMhERkZQpmYgAZvY3M/tmtvshkq+UTKRDMLMPzezMRnUTzewvAO7+/7n7/7Sw\njSPNbLeZ6d+NSCP6RyEdXWtW7VrQ3jLRETPbLxPbFWkPSiYi7HnkYmZfNbPXzWyrma03s/8TNHsp\n+O8WM9tmZqdazC/MLGpmVWZWYWbFCdu9NHjtH0G7xP3cZGa/N7NHzGwLMDHY98tmVm1m68zsHjPb\nP2F7u83sSjNbHfTvFjPrb2ZLzGyLmT0eb29mPcxsXrCtTWYW779I2imZSEfW3BHG3cBd7t4VOBp4\nIqiPz6kUu3uxu78GXAZcCpwB9Ae6AP8BYGaDgXuB7wJfBroChzfa1/nAE+5eAvwXUAdcD3QHvg6c\nCVzV6D3nAEOArwE/A/4vMB44Ajgh2B/Aj4GPgR5AT2BaSwERaSslE+lI5prZ5viD2Bd9U2qBY8ys\nh7t/4e5LG72emITGA//u7h+5+xfAVODiYF7lAuAZd3/F3euA6U3s6xV3nwfg7jXuvszdl3rMWuA3\nxBJVolnu/rm7rwL+BiwM9r8dmE8s0QDsIpbEjnL3endf0nKIRNpGyUQ6ktHu3j3+YO9f/HGTgIHA\nO2b2mpn98z62eTjwUUL5I2B/oFfw2sfxF9x9B7Cp0fs/TiyY2bHB0NT6YOjrfwOHNnrPpwnPdwAb\nGpU7B8/vAN4HFprZe2Y2eR+fQyQlSibSkSQ1ce7u77v7eHc/DLgd+IOZHUTTk/V/B45MKB9JbKhq\nA7Ae6Nuw89g2ejTeXaPyr4FVwNHB0NfPk+13E5/jM3f/ibsfTWw47QYz+6e2bEukJUomIo2Y2ffM\nLH40sJXYF/5u4B/Bf49OaP4Y8CMzKzWzzsSOJB53993AH4BRZvY1M+sEzEhi912Abe7+hZkdB1yZ\nwuf4ZzOL93U7sSS3u63bE9kXJRPpKFo6BTjx9XOBt81sG3AncHEwn7GDWLJYEsy7DAUeAB4B/ofY\nkNIXwLUA7r4SuAb4HbEjmG3Ehqhq9tGPnwDfC/b9f4HHW/gc+/pcxwIvmNl2YAlwr7vrjC7JCMvk\nzbHMbDbwv4AN7n5iQv01xMar64A/ufuUoH4q8P2g/jp3XxjUnwxUAF8CnnX36zPWaZEMMbNDgC3A\nMe7+UUvtRfJJpo9MHgRGJFaY2XBgFHCCu58A/J+gfhDwHWAQMBK4z8ziY8W/Bia5+wBggJntsU2R\nXGVm/8vMDgoSyS+BFUokUogymkzcfTFQ3aj6SuC24FRJ3H1jUD+a2FhznbtHgTXAUDPrDXRx99eD\ndg8DYzLZb5E0Gk1siOsTYnMt47LbHZHMyMacyQDgm2b2qpm9aGanBPV92PM0yXVBXR9i/xDjPgnq\nRHKeu1/h7t2Cx9nuvibbfRLJhP1bbpKRfXZz96+Z2VeB3xNbOSwiInkqG8nkY+BJAHd/3czqzawH\nsSORfgnt+gZ164hdJqJxfZPMLHNnFIiIFDB3b/NFTNtjmMvYc9HVXGLXG8LMBgAHuPsm4Blil6E4\nwMyOAo4Blrp7FbDVzIYGE/KXAk/va4furoc7N910U9b7kCsPxUKxUCz2/UhVRo9MzOxRYDjQw8zW\nAjcROy//QTN7i9j59pdC7Jx8M3sCWEnsmkJXefgJr2bPU4MXZLLfhSIajWa7CzlDsQgpFiHFIn0y\nmkzcfXwzL13STPuZwMwm6t8kdjVUERHJQVoBX8DKy8uz3YWcoViEFIuQYpE+GV0Bnw1m5oX2mURE\nMs3M8ByfgJcsqayszHYXcoZiEYrHorS0FDPTo4M9SktLM/J3lY1Tg0UkB3z00UdpOYtH8otZmw8+\n9r3dQvtj0jCXSHKCYY1sd0PaWXP/34N6DXOJiEj2KJkUMM0ThBSLkGIhmaBkIiIiKdOciUgH1dTY\n+fTpd7F27ZaM7bNfvxJuuSW1e9vdfPPNvP/++zz88MNt3sZLL73EhAkT+Pjjj1tunOCNN97g5ptv\nZsmSJQAcfvjhjB07lp/85Cd07dq1Vdt69NFHmTZtGps2beLss8/mgQceoKSkpMm206dPZ+7cuaxa\ntYobb7yR6dOnN7xWVVXFD37wA9544w3Wr19PNBqlX79+TW4HMjdnorO5RKTB2rVbKC2dkbHtR6OZ\n23ay6uvrcfdWn9X08ssvM2LECG688UYeeOABDjvsMD755BNmz57N8uXL+eY3v5n0tt5++21++MMf\nMn/+fIYMGcIVV1zBlVdeyWOPPdZk+2OPPZY77riD+++/f6/XioqKGDlyJNOmTeO0005r1WdKJw1z\nFTCNjYcUi1C+xGLWrFn07duX4uJiBg0axIsvvshzzz3Hrbfeyu9+9zu6dOnCkCFDAKioqGDw4MEU\nFxdzzDHH8Jvf/KZhOy+99BJHHHEEt99+O1/+8pcZP3485513Hn//+9/p0qULxcXFVFVVtdifyZMn\nM2nSJH72s59x2GGHAdC3b19uuummViUSiB2VnH/++QwbNoyDDz6Yf/3Xf+XJJ5/k888/b7L9JZdc\nwogRI+jcufNer/Xs2ZMf/vCHfOUrX8nq2XlKJiKSc1avXs29997Lm2++ybZt23juuecoLS1lxIgR\nTJs2jYsvvpjt27ezbNkyAHr16sWzzz7Ltm3bePDBB/nRj35EJBJp2F5VVRVbtmxh7dq1PPzww8yf\nP5/DDz+c7du3s23bNnr37s2SJUvo3r17k/354osveOWVV/j2t7+9z34vWbKEbt260b17d7p167bH\n8+7du/Pyyy8DsSOTk046qeF9/fv358ADD2T16tWphi5rlEwK2PDhw7PdhZyhWITyIRb77bcftbW1\n/O1vf6Ouro5+/fpx1FFHNdt+5MiRDSu7v/GNb3DOOefwl7/8ZY/t3XzzzXTq1IkDDzywyW0MGzaM\nzZs3N/ladXU1u3fvpnfv3g11kydPplu3bnTu3Jlbb721YRvV1dVs3ryZ6urqPZ5v3ry5YRjqs88+\n22uOpbi4mO3bt7ccnBylZCIiOefoo4/mrrvuYsaMGfTq1Yvx48fvcyhq/vz5fP3rX6dHjx5069aN\n+fPns3HjxobXDzvsMDp16tTm/nTr1o2ioiLWr1/fUDdr1iyqq6sZO3YsdXV1rdpe586d2bZt2x51\nW7dupUuXLm3uY7ZpAj4PJXvGTVVVlKFDy1I+e6YQVFZW5sUv8vaQL7EYN24c48aN47PPPuNf/uVf\nmDx5Mg899NBeE+e1tbVceOGFzJkzh9GjR1NUVMTYsWP3mD9o/J7WTr4ffPDBnHrqqTz55JOcccYZ\nzbZbvHgxI0eO3Gv78Qn/+fPnM2zYMI4//niWL1/e8Pr777/Prl27GDBgQKv6lUuUTPJQ8mfcVLJ2\nbWWGeyOSfqtXr2bdunUMGzaMAw44gIMOOojdu3cDsfmRF154oeELura2ltraWg499FCKioqYP38+\nCxcu5IQTmr8FUq9evdi0aRPbtm2juLg4qT7dfvvtnHvuufTp04fLLrus4WyuDz/8kGOPPRaA008/\nPamhqu9973ucdtppLFmyhLKyMqZPn84FF1zAIYcc0mT7uro66urq2L17N7t27aKmpoZOnTpRVBQb\nXKqpqWk4Otq5cyc1NTXNDudlipJJASstHU40WpntbuSEfPgl3l72FYt+/Uoyevpuv35Nr6NorKam\nhilTpvDOO+/QqVMnTjvttIYztC666CLmzJlDjx496N+/P2+88QZ33303F110EbW1tYwaNYrRo0fv\nc/sDBw7ku9/9Lv3792f37t2sXLmS9957j/POO2+v4ae4YcOGsWjRImbMmMFtt90GxM7mGj16NNdc\nc00rogCDBw/m/vvvZ/z48WzevLlhnUnclVdeiZlx3333AXDFFVfscVR266238uCDD3LppZcCcNBB\nBzVcFfi4447DzKivr29Vn1KlRYt5qLx8RtJrAZ56aixDhpzUckPSs6BM8ocu9NgxadGitFo0Wsnn\nn3vSiScXFpRlSr7ME7QHxUIyIaNnc5nZbDPbYGYrmnjtx2a228y6J9RNNbM1ZrbKzM5JqD/ZzFaY\n2WozuyuTfRYRkdbL9KnBDwIjGleaWV/gbOCjhLpBwHeAQcBI4D4LT4n4NTDJ3QcAA8xsr23K3kpL\nh2e7CzlDv8RDioVkQkaTibsvBqqbeOlO4KeN6kYDj7t7nbtHgTXAUDPrDXRx99eDdg8DYzLUZRER\naYN2X7RoZucDH7v7W41e6gMkXsJzXVDXB/gkof6ToE5aoDO5QvlyPar2oFhIJrTrBLyZHQRMIzbE\nJSIiBaK9z+Y6GigFlgfzIX2Bv5rZUGJHIokX4e8b1K0Djmiivlnl5eUN1+kpKSmhrKysYZw4/qss\nn8tVVVGCj9dw9BGfH0ksl5YO5/nnf0E0Wtnk602Vc+HzqZz5skhlZSUVFRUADd+Xqcj4OhMzKwXm\nuftey1HN7EPgZHevNrPBwH8BpxIbxnoeONbd3cxeBa4FXgf+BPzK3Rc0sz+tM0kwZ84YJkyYm1Tb\naHQGFRXJbVfyn9aZdEyZWmeS6VODHwVeJnYG1lozu6xREwcMwN1XAk8AK4FngasSssLVwGxgNbCm\nuUQie9KcSUi/yEMdMRaXXXbZHncnlPTL6DCXu49v4fX+jcozgZlNtHsTaP5COyKSFtNnTmfthrUZ\n236/Xv24ZeotGdt+ulRVVTF9+nT+9Kc/sX37dnr27Mk3v/lNpkyZ0uqLMUYiES6//HJWrVrF4MGD\n+e1vf7vHvUwSTZ48mccee4ytW7fSvXt3fvCDHzBlyhQANm3axOjRo3nnnXeor69n8ODB3HHHHVm9\nu2IirYAvYKWlw1m8WGs8QWsrEu0rFms3rKV0TGnG9h2dG83YttMlft+RYcOGsWTJEkpLS9m2bRtP\nPfUUzz//fKuSya5duxgzZgw33HADV155Jffffz+jR4/mvffeY//99/76nTRpEjfeeCOdO3dm/fr1\nnH322Rx33HGMGTOGzp07M3v2bI499liKiop4+umnGTVqFP/4xz8aLviYTdnvgYhIE9avX8+FF15I\nz549Ofroo7nnnnsaXrv55pu5+OKLmThxIsXFxZxwwgn89a9/bXh92bJlnHLKKXTt2pVx48axc+fO\npPf77//+73Tt2pVHHnmkYWK6uLiYiRMncvXVV7fqM1RWVlJfX8+1115Lp06duOaaa3B3Fi1a1GT7\nAQMGNNyad/fu3RQVFfHee+8BcOCBBzJw4ECKiopwd4qKitiyZUuzN/Rqb0omBUxzJqGOOE/QnHyI\nhbszatQohgwZwvr16/nzn//M3XffzfPPP9/QZt68eYwfP56tW7cyatSohi/6Xbt2MXbsWCZOnMjm\nzZu56KKL+OMf/7jH9rt169ZwC93G/vznPzN27NgW+7iv2/PefvvtQOz2vCeeeOIe7zvppJN4++23\nm93urFmz6NKlC0cccQRffPEF48fvOVtw0kkn8aUvfYkxY8ZwxRVXcOihh7bY1/agYS4RyTmvv/46\nGzdu5Oc//zkQO3X18ssv5/HHH+fss2PL1E4//XRGjIhdWemSSy7h7rvvBuCVV16hrq6Oa6+9FoAL\nLriAr371q3tsv7q6qQtzxGzcuHGP2/POmzePSy+9lPr6ek477TQWLFjQ4jbi2nJ73smTJzN58mSW\nL1/O3Llz93r/8uXLqa2t5amnnqK2trbFPrQXHZkUMF2bK6Q5k1A+xOKjjz5i3bp1dO/eveEX/8yZ\nM/n0008b2iR+4R988MHs3LmT3bt3s379evr02fMiGUceeWTS++7Ro8cet+cdNWoU1dXV3Hnnna3+\n8k7l9rzxI5CmzkI74IADuPjii5k5cyZvvdX4YiLZoWQiIjnniCOOoH///mzevJnNmzdTXV3N1q1b\nmTdvXovv/fKXv8y6dXuua167Nvkz1M466yzmzm15bVaXLl0oLi7e4xGvi9886/jjj2fFij0vmr5i\nxQqOP/74pPpSV1fHBx980Ozru3bt2ufr7UnJpIBpziSUD/ME7SUfYjF06FC6dOnC7bffzs6dO6mv\nr+ftt9/mjTfeaPY98WVpX//619l///255557qKur48knn2Tp0qVJ7/uGG26gurqaSy65pOGLevv2\n7UQikT3abd++nW3btu3xiNfFT+cdPnw4++23H/fccw+1tbX86le/oqioiDPPPLPJ/v/mN79hy5Yt\nACxdupR7772Xb33rWwC89tprLFmyhF27drFz505mzZrFp59+yqmnnpr0Z8skzZmISIN+vfpl9PTd\nfr36tdwIKCoq4r//+7+54YYbOOqoo6itrWXgwIH827/9W7Pvid+xolOnTjz55JNcfvnl/OIXv+C8\n887jggsu2KNtly5dWLBgAcOGDdtrOz169ODVV1/lxhtv5PTTT+ezzz6jV69enH766fz6179uxaeN\n9WXu3LlMmjSJKVOmMGjQIJ5++umG04IfffTRPYaqnnrqKaZNm0ZtbS2HH3441113XcOJBTU1NVx7\n7bV8+OGHdOrUiRNOOIFnn312j+G+bNJte/OQLqci6aDLqXRMeXk5FRER6RiUTAqY5kxC+TBP0F4U\nC8kEJRMREUmZkkkB0zqTUD6srWgvioVkgpKJiIikTMmkgGnOJKR5gpBiIZmgdSYiHdSRRx7ZsDZD\nOo7WXFqmNZRMCpjuZxLSPEEoHotoNJrVfkhh0TCXiIikTMmkgGnOJKR5gpBiEVIs0iejycTMZpvZ\nBjNbkVB3u5mtMrOImf3RzIoTXptqZmuC189JqD/ZzFaY2Woz07iNiEiOyfSRyYPAiEZ1C4Hj3b0M\nWANMBTCzwcB3gEHASOA+C2cHfw1McvcBwAAza7xNaYLWmYQ0ZxJSLEKKRfpkNJm4+2KgulHdC+6+\nOyi+CvQNnp8PPO7ude4eJZZohppZb6CLu78etHsYGJPJfouISOtke87k+8CzwfM+wMcJr60L6voA\nnyTUfxLUSQs0ZxLS2HhIsQgpFumTtVODzeznwC53fyzd2y4vL6e0tBSAkpISysrKGg5n4388+Vyu\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n9v9HM64ItJCNRQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(population, transaction=redistribute)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Another surprise:** This transaction function does indeed lead to less inequality than `split_randomly` or `winner_take_all`, but surprisingly (to me) it still increases inequality compared to the initial (Gaussian) population.\n", + "\n", + "Here's one more interaction function, `status_quo`, in which both actors keep half of their wealth out of the transaction, and the other half is randomly split using a triangular distribution in such a way that the most likely outcome is that each actor keeps what they started with, but from there probability falls off on either side, making larger and larger deviations from the status quo less and less likely:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def status_quo(A, B):\n", + " \"A transaction that is most likely to leave things unchanged, but could move any amount of wealth around.\"\n", + " a = random.triangular(0, (A + B) / 2, A / 2)\n", + " return (A / 2 + a), (A + B) - (A / 2 + a)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.11 20.1 54 75 100 126 148\n", + " 20,000 0.21 38.5 34 56 95 152 210\n", + " 40,000 0.22 40.5 31 53 95 155 222\n", + " 60,000 0.22 40.3 31 53 95 155 217\n", + " 80,000 0.23 41.3 31 52 95 154 222\n", + "100,000 0.23 41.8 32 52 94 158 224\n", + "120,000 0.23 41.0 32 53 95 157 223\n", + "140,000 0.23 40.9 31 53 94 155 216\n", + "160,000 0.23 41.2 31 53 94 156 223\n", + "180,000 0.23 40.9 31 52 95 156 219\n", + "200,000 0.22 40.6 31 53 95 155 219\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nBlVVNXkdXNFemUzh1p2vDRs24O5tPqrp+eefZ+TIkVx99dXceuut7LjjjixYsIBbbrmFV199lUMP\nPTTvdb355pucf/75PPLII+y7776cd955XHDBBdxzzz1Nth88eDA//elPufnmmzdZ1q1bN4466iiu\nuuoqDjrooDZ9po6kbq4iE3O/t8ZMwoo9f2PXXXcdAwYMoHfv3uy99948/fTTPPbYY1x77bX8/ve/\np1evXuy7774AlJeXM2TIEHr37s2gQYP49a9/3bCeZ555hl133ZWpU6ey0047cdppp3H00Ufzr3/9\ni169etG7d2+qq6tbzXPllVdyzjnncMUVV7DjjjsCMGDAACZOnNimQgLZvZJjjz2WYcOGsc022/Df\n//3f3H///axatarJ9mPGjGHkyJH07Nlzk2V9+/bl/PPP56tf/WrQo/NUTESk6Lzzzjv88pe/5JVX\nXmHFihU89thjlJaWMnLkSK666ipOOeUUVq5cSWVlJQD9+vXjr3/9KytWrOC2227j0ksvZc6cOQ3r\nq66upqamhqqqKu644w4eeeQRdt55Z1auXMmKFSvo378/s2bNYvvtt28yzyeffMILL7zA8ccf32Lu\nWbNm0adPH7bffnv69Omz0fPtt9+e559/HsjumXzpS19qeN0ee+zBVlttxTvvvJN20wWjYlJkYu63\n15hJWLHnz9W9e3fWrVvHG2+8QW1tLQMHDmT33Xdvtv1RRx3VcGb3IYccwogRI3juuec2Wt/kyZPp\n0aMHW221VZPrGDZsGEuXLm1y2bJly6irq6N///4N86688kr69OlDz549ufbaaxvWsWzZMpYuXcqy\nZcs2er506dKGbqiPP/54kzGW3r17s3LlytY3TpHSmIkUTGXlq5SVTWqxjc6Sl6bsueee3HDDDUya\nNIm5c+cycuRIrr/++o3+mOd65JFHuOaaa3jnnXeoq6tj9erVfPGLX2xYvuOOO9KjR4925+nTpw/d\nunVj0aJFfO5znwOy3XDXXXcdY8aMoba2tk3r69mzJytWrNho3vLly+nVq1e7M4amPZMiE3O/d+Mx\nk1WrnNLSSS0+CnnkUFvFvO0h/vyNnXrqqTz33HPMnz8fyO4JwKaXA1m3bh0nnngiV1xxBR9++CHL\nli3jqKOO2mj8oPFr2jr4vs0223DAAQdw//33t9hu5syZDeMwuY/6efVHge2zzz68+uqrDa97//33\nWb9+fUOhipGKiYgUnXfeeYenn36adevWseWWW7L11lvTrVv2z1W/fv3IZDINxWLdunWsW7eOz372\ns3Tr1o1HHnmEGTNmtLj+fv36sWTJkk32DloydepUbr31VqZOncqHH34IwIIFC/jnP//Z0Obggw9u\nGIfJfdTPGzZsGACnn346Dz/8MLNmzWLVqlVMmDCBE044gW233bbJ966trWXNmjXU1dWxfv161q5d\nS11dXcPytWvXsmbNGgDWrFnD2rVr8/5cHUXdXEUm5n5vjZmE1RH5Bw4sKejhuwMHNn0eRWNr165l\n3LhxvPXWW/To0YODDjqo4Qitk046ibvuuosddtiBPfbYg5dffplp06Zx0kknsW7dOo455hhGjRrV\n4vr32msvvvWtb7HHHntQV1fH3Llzee+99zj66KObLTDDhg3jqaeeYtKkSfzkJz8BskdzjRo1iosu\nuqgNWwGGDBnCzTffzGmnncbSpUsbzjOpd8EFF2Bm3HTTTQCcd9553H777Q17VNdeey233XYbZ555\nJgBbb711w1WBP//5z2NmbNiwoU2Z0tKFHqXN8r3Q4113jeaMM6a32EYXgwxHF3rsmnShxy4i5n5v\nnWcSVuz5JW4qJiIikpqKSZGJud9eYyZhxZ5f4qZiIiIiqamYFJmY+701ZhJW7PklbiomIiKSmopJ\nkYm531tjJmHFnl/ipmIiIiKpqZgUmZj7vTVmElbs+QvprLPO2ujuhNLxdDkVEWkwYcoEqhZXFWz9\nA/sN5Jrx1xRs/R2lurqaCRMm8Je//IWVK1fSt29fDj30UMaNG9fmizHOmTOHc889l3nz5jFkyBB+\n+9vfbnQvk1yXX345Dz74IIsXL2aXXXZh/PjxjBkzBoB3332Xyy+/nOeff566ujr2228/pk2bVjQX\nh1QxKTIx93trzCSsjshftbiK0tGlqdfTnMz0TMHW3VHq7zsybNgwZs2aRWlpKStWrOCBBx7g8ccf\nb9Mf7/Xr1zN69Gguu+wyLrjgAm6++WZGjRrFe++9xxZbbPrnt2fPnvzlL39h8ODBzJ49myOPPJLB\ngwdz4IEHUlNTw6hRoygvL6dXr15MnjyZUaNGMW/evI78+O2mbi4RKUqLFi3ixBNPpG/fvuy5557c\neOONDcsmT57MKaecwtixY+nduzdf+MIX+Pvf/96wvLKykq985Stst912nHrqqQ1X1M3H9ddfz3bb\nbcedd97ZcMOt3r17M3bsWL7zne+06TNUVFSwYcMGLr74Ynr06MFFF12Eu/PUU0812X7ixIkMHjwY\ngP33359DDjmEF154AYD99tuPs846i5KSErp3786ll17K22+/zbJly9qUqVBUTIpMzP3eGjMJK/b8\nudydY445hn333ZdFixbx5JNPMm3aNB5//PGGNg8//DCnnXYay5cv55hjjmn4Q79+/XqOO+44xo4d\ny9KlSznppJP405/+tNH6+/Tp03AL3caefPJJjjvuuFYztnR73qlTpwLZ2/Pm3qQL4Etf+hJvvvlm\nq+tfvXo1L730Evvss0+Ty5955hl22mkn+vTp0+q6OoO6uUSk6Lz00kt89NFH/OAHPwCgtLSUc889\nl3vvvZcjjjgCyN47ZOTIkQCMGTOGadOmAfDCCy9QW1vLxRdfDMAJJ5zAfvvtt9H6W/o2/9FHH210\nR8eHH36YM888kw0bNnDQQQfx6KOPtrqOemluz3v++eez7777MmLEiE2WLViwgAsvvJCf//znra6n\ns6iYFJmY++01ZhJW7PlzzZ8/n4ULF7L99tsD2T2Vuro6Dj300IY2uX/wt9lmm4abRy1atIhddtll\no/Xttttueb/3DjvswKJFixqmjznmGJYtW8Ytt9zC7373uzZ9jvbenvfyyy9n7ty5PP3005ss+/DD\nDxk5ciQXXnghJ598cpvyFJKKiWxkwoQbWr2VbmXlXJKuZJGC2HXXXdljjz14++232/zanXbaiYUL\nF240r6qqikGDBuX1+sMPP5zp06czceLEFtv16tVrk9v/ujtmxlVXXcW4cePYZ599uP766zdq89pr\nr7V4M62JEyfy2GOP8eyzz9KzZ8+NltXU1DBy5EhGjx7NuHHj8vo8nUVjJkUmdL93VVVNq/dtX7Vq\nXZOv1ZhJWLHnz7X//vvTq1cvpk6dypo1a9iwYQNvvvkmL7/8crOvqb/h09e+9jW22GILbrzxRmpr\na7n//vuZPXt23u992WWXsWzZMsaMGcM//vEPAFauXMmcOXM2atfS7Xnr/9APHz6c7t27c+ONN7Ju\n3Tp+8Ytf0K1bNw477LAm33vKlCncc889PPHEE5SUbHxXypUrVzJixAgOPvhgfvzjH+f9eTqL9kxE\npMHAfgMLevjuwH4D82rXrVs3/vznP3PZZZex++67s27dOvbaay9+9KMfNfua+r2EHj16cP/993Pu\nuefywx/+kKOPPpoTTjhho7a9evXi0Ucfbbgne64ddtiBF198kauvvpqDDz6Yjz/+mH79+nHwwQfz\nq1/9qg2fNptl+vTpnHPOOYwbN469996bBx98sOGw4LvvvpspU6bw+uuvA/CDH/yArbbaikGDBm2y\nl/PAAw/wyiuvMG/ePG677baGzzx37lwGDBjQplyFEOy2vWZ2KXAOUAe8DpwFbAv8HtgNyAAnu/vy\npP144GygFviuu89oZr26bW8K+dySN5/b8ebbTrftDUe37e2aNqvb9prZzsBFwJfd/Ytk95C+BYwD\nnnD3vYCngPFJ+yHAycDewFHATda4s1JERIIJOWbSHdjWzLYAtgYWAqOA25PltwOjk+fHAve6e627\nZ4B3gf07N27niLnfW2MmYcWeX+IWpJi4+7+AnwFVZIvIcnd/Aujn7ouTNtVA3+QluwAf5KxiYTJP\nRESKQJABeDMrIbsXshuwHPiDmZ0ONO7Ia1eHbllZWcNlEEpKShg6dGjDMfj1396Kdbp+Xqj3r67O\nABUN54zU723kTq9e/VFD1tzlpaXDm2zf0nR1dSbo582dHj58ePCff2fnl66roqKC8vJygIa/l2kE\nGYA3sxOBke5+XjI9BjgQOAwY7u6Lzaw/8LS7721m4wB39+uS9o8CE939b02sWwPwKWgAvuvQAHzX\ntFkNwJPt3jrQzD6TDKQfDswFHgLKkjZjgQeT5w8Bp5rZlma2OzAIyP/A8YjE3O+tMZOwYs8vcQvS\nzeXus83sj0AlsD7599dAL+A+MzsbmE/2CC7cfa6Z3Ue24KwHvq3dD5F0dtttt03O4JbNX1suLdMW\nwU5adPfJwORGs5cC32im/RRgSqFzhRZzX7auzRVWW/NnMpmC5JCuSZdTERGR1FRMikzM/d4aMwlL\n+cOKPX9aKiYiIpKaikmRibnfXmMmYSl/WLHnT0vFREREUlMxKTIx97tqzCQs5Q8r9vxpqZiIiEhq\nKiZFJuZ+V42ZhKX8YcWePy0VExERSU3FpMjE3O+qMZOwlD+s2POnpWIiIiKpqZgUmZj7XTVmEpby\nhxV7/rRUTEREJDUVkyITc7+rxkzCUv6wYs+floqJiIikpmJSZGLud9WYSVjKH1bs+dNSMRERkdRU\nTIpMzP2uGjMJS/nDij1/WiomIiKSmopJkYm531VjJmEpf1ix509LxURERFJTMSkyMfe7aswkLOUP\nK/b8aamYiIhIaiomRSbmfleNmYSl/GHFnj8tFRMREUlNxaTIxNzvqjGTsJQ/rNjzp6ViIiIiqamY\nFJmY+101ZhKW8ocVe/60VExERCQ1FZMiE3O/q8ZMwlL+sGLPn5aKiYiIpLZF6ACysZj7XdszZlJZ\n+SplZZNabTdwYAnXXHNJ20O1QczbHpQ/tNjzp6ViIkGtWuWUlk5qtV0m03obEQlH3VxFJuZ+V42Z\nhKX8YcWePy0VExERSS1YMTGz7czsD2Y2z8zeNLMDzKyPmc0ws7fN7DEz2y6n/XgzezdpPyJU7kKL\nud9V55mEpfxhxZ4/rZB7JtOAv7r73sCXgLeAccAT7r4X8BQwHsDMhgAnA3sDRwE3mZkFSS0iIpsI\nUkzMrDdwiLvfBuDute6+HBgF3J40ux0YnTw/Frg3aZcB3gX279zUnSPmfleNmYSl/GHFnj+tUHsm\nuwMfmdltZvZ3M/u1mW0D9HP3xQDuXg30TdrvAnyQ8/qFyTwRESkCoYrJFsCXgV+6+5eBVWS7uLxR\nu8bTm72Y+101ZhKW8ocVe/60Qp1nsgD4wN1fTqb/RLaYLDazfu6+2Mz6A/9Oli8Eds15/YBkXpPK\nysooLS0FoKSkhKFDhzb8oOt3RTXd9HR1dQaoaCgM9V1XudOrV39EvaaWt2V69eqPyGRafr9cobeP\npjW9uUxXVFRQXl4O0PD3Mg1zD/Pl38yeAc5z93fMbCKwTbJoqbtfZ2ZXAn3cfVwyAP874ACy3VuP\nA4O9ifBm1tTsaFRUVDT84EMoK5vU6kmEd901mjPOmL7J/Nyi0FK7fNa16bonUV7ecq60Qm/7tJQ/\nrNjzmxnu3u4Dm0KeAX8x8Dsz6wH8AzgL6A7cZ2ZnA/PJHsGFu881s/uAucB64NtRVwwRkc1MsGLi\n7q8C+zWx6BvNtJ8CTCloqCIQ8zcbjZmEpfxhxZ4/LZ0BLyIiqamYFJn6AbIY6TyTsJQ/rNjzp6Vi\nIiIiqamYFJmY+101ZhKW8ocVe/60VExERCQ1FZMiE3O/q8ZMwlL+sGLPn5aKiYiIpJZXMTGzJ/OZ\nJ+nF3O+qMZOwlD+s2POn1eJJi2b2GbKXOfmsmfUB6k+1742u2huVCRNuoKqqptV2lZVz6YDL9IhI\nF9PaGfD/BVwC7Ay8wqfFZAXwvwXM1WUV6vo+VVU1rV5zC2DmzNGttmlO42tzxSb2ayspf1ix50+r\nxWLi7tOAaWZ2kbvf2EmZREQkMnldm8vdbzSzg4DS3Ne4+x0FytVlxfzNJua9Eoh724PyhxZ7/rTy\nKiZmdiewJzAH2JDMdkDFRERE8r5q8FeBIbrse+EVqt+18q2nmZPJtNpuySfz2v0eGjMJS/nDij1/\nWvkWkzeA/sCiAmaRAlpVu5wBw0tbbff++08VPoyIbHbyLSafBeaa2Wxgbf1Mdz+2IKm6sJi/2cS8\nVwJxb3tQ/tBiz59WvsVkUiFDSPFYu2450yvKWmyTpitMRDZP+R7N9Uyhg0hW6H7Xui1qKWmlO2zu\nvAeaLDgf11TTs6R/w3RsRSf0tk9L+cOKPX9a+R7NtZLs0VsAWwI9gFXu3rtQwaR4NVtwMlCSc/q8\nxl9Euo5890x61T83MwNGAQcWKlRXFvM3m5LIr8MS87YH5Q8t9vxptfmqwZ41HRhZgDwiIhKhfK8a\nfHzO40Qz+wmwpsDZuqSY74lQk8d5LMUs5m0Pyh9a7PnTyvdormNyntcCGbJdXSIiInmPmZxV6CCS\nFXO/q8ZMwlL+sGLPn1a+3VwDzOwBM/t38viTmQ0odDgREYlDvgPwtwEPkb2vyc7Aw8k86WAx97tq\nzCQs5Q8r9vxp5VtMdnT329y9NnmUAzsWMJeIiEQk32KyxMzOMLPuyeMMYEkhg3VVMfe7aswkLOUP\nK/b8aeVbTM4GTgaqyV45+ESgrECZREQkMvkeGnwNMNbdlwGY2fbA/5AtMtKB2nN9nwlTJlC1uKrF\nNkuWL6LQR0zUZDJR753Efm0l5Q8r9vxp5VtMvlhfSADcfamZ7VugTNJGVYurKB1d2mKb2ofXd04Y\nEemS8u3m6mZmfeonkj2TfAuRtEHM32xi3iuBuLc9KH9osedPK9+C8DPgBTP7QzJ9EvDjwkQSEZHY\n5LVn4u53AMcDi5PH8e5+ZyGDdVUxH6uu80zCUv6wYs+fVt5dVe4+F5hbwCyymdFdG0W6Do17FJnc\nftd8jtICqHytstUB+M7QeMwkn7s2FtMNtGLv81b+sGLPn1bQYmJm3YCXgQXufmwyyP97YDeyVyY+\n2d2XJ23Hkz0UuRb4rrvPCJO68+RzlBbAzNkzCx9GRKQFbb45Vgf7Lht3nY0DnnD3vYCngPEAZjaE\n7EmTewNHATcld3zc7MTc76oxk7CUP6zY86cVrJgkVx0+GvhtzuxRwO3J89uB0cnzY4F7k+uCZYB3\ngf07KaqIiLQi5J7Jz4HLAc+Z18/dFwO4ezXQN5m/C/BBTruFybzNTsz9rjrPJCzlDyv2/GkFKSZm\n9k1gsbvPAVrqrvIWlomISJEINQA/DDjWzI4GtgZ6mdmdQLWZ9XP3xWbWH/h30n4hsGvO6wck85pU\nVlZGafItuaSkhKFDhzZ8a6jv1yzW6RtuuGGjvJk5GQBKh5Y2O716+eqGz95c+3r14xr1exGNp33t\nho2usdVUe1+7ocn15Y6ZtPT63OnaNWvIZCooLU0+bya7PRpP1yvk9s/t8y6W3wflL558m1v+iooK\nysvLARr+XqZh7mG//JvZfwDfS47mmgoscffrzOxKoI+7j0sG4H8HHEC2e+txYLA3Ed7MmpodjYqc\ni8WVXVKW19Fcd111F2dce0aLbX52zi/4ypiLW13XzN/8lIPPu7xdbRpf6DGfdb1yy61875zWD3/O\nZCZRXj6p1XZp5G77GCl/WLHnNzPcvd0HNhXbeSY/Ae4zs7OB+WSP4MLd55rZfWSP/FoPfDvqitGC\nmH8ZCzlmUln5KmVlk1psM3BgCddcc0m73yPmbQ/KH1rs+dMKXkzc/RngmeT5UuAbzbSbAkzpxGhS\nRFatckpLJ7XYJpNpebmIFE7o80ykkdx+19joPJOwlD+s2POnpWIiIiKpqZgUmZj7XXWeSVjKH1bs\n+dNSMRERkdSCD8DLxmI+vLA994DP5zL10DmXqo9524PyhxZ7/rRUTCSofC5TD8V1qXoR2ZS6uYpM\nzN9sNGYSlvKHFXv+tFRMREQkNRWTIhPzseo6zyQs5Q8r9vxpqZiIiEhqKiZFJuZ+V42ZhKX8YcWe\nPy0VExERSU3FpMjE3O+qMZOwlD+s2POnpWIiIiKpqZgUmZj7XTVmEpbyhxV7/rR0BrxEIZ/Lrvia\nfwKTOiOOiDSiPZMiE3O/ayHHTOovu9LSY1Xt8lTvEfO2B+UPLfb8aamYiIhIaiomRSbmfleNmYSl\n/GHFnj8tjZlsBpYsqWH69IoW26xdu65zwohIl6Q9kyLTnn7X2to6SkqGt/ioc+/4sI3oPJOwlD+s\n2POnpWIiIiKpqZgUmZj7XTVmEpbyhxV7/rRUTEREJDUVkyITc7+rxkzCUv6wYs+flo7mCmTClAlU\nLa7aZH71gmrKp5cDUPlaJaWjSzs3mIhIO6iYBFK1uKrJQlHKp/Nmzp7ZeYE6gMZMwlL+sGLPn5a6\nuUREJDUVkyKTmZMJHaHdNGYSlvKHFXv+tFRMREQkNRWTIlM6tDR0hHbTmElYyh9W7PnT0gC8bDaW\nLK2m7JKJ5rYZAAAMiklEQVSyVtsN7DeQa8ZfU/hAIl2IikmRyczJRLt3UpPJBN07qbV1eR1KnZme\naXJ+RUVF1N8ulT+s2POnpW4uERFJTcWkyMS6VwIaMwlN+cOKPX9aKiYiIpJakGJiZgPM7Ckze9PM\nXjezi5P5fcxshpm9bWaPmdl2Oa8Zb2bvmtk8MxsRIndn0Hkm4cR+noDyhxV7/rRC7ZnUApe5+z7A\n14DvmNnngXHAE+6+F/AUMB7AzIYAJwN7A0cBN5mZBUkuIiKbCFJM3L3a3eckzz8G5gEDgFHA7Umz\n24HRyfNjgXvdvdbdM8C7wP6dGrqTaMwknNj7vJU/rNjzpxV8zMTMSoGhwItAP3dfDNmCA/RNmu0C\nfJDzsoXJPBERKQJBzzMxs57AH4HvuvvHZtb4RuXtunF5WVkZpcm35JKSEoYOHdrwraG+XzP0dL36\nMZL6PZIX//gi/Qf1b5huvLyp6drV6xvWVz9uUb+X0Hgco7nl9dO+dsNG54s01d7Xbmhyfbnv1dLr\n2/p+bcmfz/Z6ruK5hpMbqxdUA9B/QP+G5/XTA/sN5LCvHQaE/33JZzr3d6sY8ih/ceVrKm95eTlA\nw9/LNMy9XX+v07+x2RbAn4FH3H1aMm8eMNzdF5tZf+Bpd9/bzMYB7u7XJe0eBSa6+9+aWK+H+kxt\nUXZJWZMn2OWetHjXVXdxxrVntLqun53zC74y5uIW28z8zU85+LzLW11XPu2aa9P4pMU062pPu1fu\n/AXfu6Xl7QDNb9fGJ4xmpmcov6G81fUVi9hPmlP+sMwMd2/3WHTIbq5bgbn1hSTxEFCWPB8LPJgz\n/1Qz29LMdgcGAbM7K2hn0phJODFve4i/z1754xakm8vMhgGnA6+bWSXZ7qyrgOuA+8zsbGA+2SO4\ncPe5ZnYfMBdYD3w7it0PEZEuItTRXLPcvbu7D3X3fd39y+7+qLsvdfdvuPte7j7C3WtyXjPF3Qe5\n+97uPiNE7s6g80zCiXnbQ/znOSh/3IIfzSUiIvFTMSkyMffba8wkrNj77JU/biomIiKSmopJkYm5\n315jJmHF3mev/HHTzbE62IQpE6haXNVqu8rXKvO6kZPkb+3atUyfXtFquyVLalptA1A5p7LVOzfq\nro0iWSomHaxqcVVeRWLm7JlNzo+53z70mEmdQ0nJ8FbbvV/7WpPzG2/7VetWtfqzbO6ujSHE3mev\n/HFTN5eIiKSmYlJkYu6315hJWLH32St/3FRMREQkNRWTIqMxk3Bi3vYQf5+98sdNxURERFJTMSky\nMffba8wkrNj77JU/biomIiKSmopJkYm5315jJmHF3mev/HHTSYtFbMmSmrzO6F67dl3hw4iItEB7\nJkUmt9++traOkpLhrT7qiuQ+YRozCSv2Pnvlj5uKiYiIpKZuriITc799VxwzyedikNA5F4SMvc9e\n+eOmYiKSQj4Xg4TiuiCkSCGom6vIxNxvrzGTsGLvs1f+uKmYiIhIaiomRUZjJuHEvO0h/j575Y+b\niomIiKSmAfg8ddbteDNzMtF+Q67JZKLeOynktu+MWwBXVFRE/e1Y+eOmYpKntLfjla4ttlsAi7SV\nikmRiXWvBOIZM1m7dm2zl6mZk3NE2pIlNZ0TqIPE/q1Y+eOmYiJdTp1DScnwVtu9X/ta4cOIbCY0\nAF9kYj7XIfbzTGLPH/t5DsofN+2ZiBSJYro0i0hbqZgUGY2ZhBM6f9pLs8TeZ6/8cVM3l4iIpKY9\nkyKj80zCiSV/c91h1Quq6T+gPxBnV1js52nEnj8tFZNAmruL4scLahoOT9UdFKUpzXaHzfm0m1Tn\nrEhnUzEJpP4uio2VlHz6vM5f6rxAHSCGb/UtiT1/7h5tjIP5sX+rjz1/WiomIpsh3WdFOltUA/Bm\ndqSZvWVm75jZlaHzFELM5zrEnB3izx/zOUoQ/3kasedPK5o9EzPrBvwvcDjwL+AlM3vQ3d8Km6xj\nfVxdHW13S8zZIf781e9Vt/ngjY68AGU+F0NtaV1z5syJuqso9vxpRVNMgP2Bd919PoCZ3QuMAlIV\nk+dffJ67Hryr1XZvzHsjr26D5gbWG2tucL12zZpWX1usYs4Om+Zv6Rpe9Yrp+l1rPm779s+nO+yB\nSQ/kfcXs4yYc12KblrrVamqKZ1u2R+z504qpmOwCfJAzvYBsgUml+t/VrNl5DTt9bqdm29RtqGP5\ns8vzWl9zA+ubrDOywfWuKJ9reHWF63flO/6SzxWzW9oTmvPiHDI1GaC4DgyQ/MRUTArC65y3Zr3F\nPyr/0UIj2FC7oVPyrIn4203M2SH+/DXVxZ+/pcI05605Dcvy3RvKp+jkey+itOuaOWNmly6G5u6h\nM+TFzA4EJrn7kcn0OMDd/bpG7eL4QCIiRcbdrb2vjamYdAfeJjsAvwiYDXzL3ecFDSYiIvF0c7n7\nBjO7EJhB9pDmW1RIRESKQzR7JiIiUryiOmmxJTGe0GhmGTN71cwqzWx2Mq+Pmc0ws7fN7DEz2y50\nznpmdouZLTaz13LmNZvXzMab2btmNs/MRoRJ/alm8k80swVm9vfkcWTOsqLJb2YDzOwpM3vTzF43\ns4uT+VFs/ybyX5TMj2X7b2Vmf0v+r75uZhOT+bFs/+byd9z2d/foH2SL4nvAbkAPYA7w+dC58sj9\nD6BPo3nXAVckz68EfhI6Z062g4GhwGut5QWGAJVku1JLk5+PFWH+icBlTbTdu5jyA/2BocnznmTH\nDz8fy/ZvIX8U2z/JtE3yb3fgRbKnJkSx/VvI32Hbf3PZM2k4odHd1wP1JzQWO2PTvcNRwO3J89uB\n0Z2aqAXuPhNY1mh2c3mPBe5191p3zwDv0gHnBaXRTH7I/hwaG0UR5Xf3anefkzz/GJgHDCCS7d9M\n/l2SxUW//QHc/ZPk6VZk/8g6kWx/aDY/dND231yKSVMnNO7STNti4sDjZvaSmZ2bzOvn7osh+x8Q\n6BssXX76NpO38c9kIcX7M7nQzOaY2W9zuimKNr+ZlZLdw3qR5n9fYsj/t2RWFNvfzLqZWSVQDTzu\n7i8R0fZvJj900PbfXIpJrIa5+5eBo4HvmNkhfPptoV5sR0jElvcmYA93H0r2P9nPAudpkZn1BP4I\nfDf5hh/V70sT+aPZ/u5e5+77kt0j3N/M9iGi7d9E/iF04PbfXIrJQmBgzvSAZF5Rc/dFyb8fAtPJ\n7kYuNrN+AGbWH/h3uIR5aS7vQmDXnHZF+TNx9w896SQGfsOnu/JFl9/MtiD7h/hOd38wmR3N9m8q\nf0zbv567rwAqgCOJaPvXy83fkdt/cykmLwGDzGw3M9sSOBV4KHCmFpnZNsm3NMxsW2AE8DrZ3GVJ\ns7HAg02uIBxj4z7W5vI+BJxqZlua2e7AILInmoa2Uf7kD0C944E3kufFmP9WYK67T8uZF9P23yR/\nLNvfzD5b3wVkZlsDR5Ad94li+zeT/60O3f4hjy7o4CMVjiR7hMi7wLjQefLIuzvZo84qyRaRccn8\n7YEnks8yAygJnTUn891kL/+/FqgCzgL6NJcXGE/2KJB5wIgizX8H8Frys5hOtg+86PIDw4ANOb8z\nf09+55v9fYkkfyzb/wtJ5jlJ3h8k82PZ/s3l77Dtr5MWRUQktc2lm0tERAJSMRERkdRUTEREJDUV\nExERSU3FREREUlMxERGR1FRMRAIxs9vM7Pjk+XfN7DM5y1aGSybSdiomIsXhEmDbnGmdACZRUTER\nyZOZfd+yt47GzH5uZk8mz79uZneZ2RFm9ryZvWxmvzezbZLlVyc3JnrNzG5uYr0XATsDT9WvMzvb\nfpRczfV5M9uxkz6mSLuomIjk7zngkOT5V4Btzax7Mu814IfA4e7+VeAV4HtJ2xvd/QB3/yKwjZl9\nM3el7n4j2cu8DHf3w5PZ2wLPe/Zqrs8B5xXwc4mkpmIikr9XgK+YWS+y1/d6AdiPbDFZTfbuerOS\ne0acyadXsj7czF607O2Cvw7s08z6cy+gudbd/5rzvqUd+UFEOtoWoQOIxMLda80sQ/YqsbPI7o18\nHdiT7C2YZ7j76bmvMbOtgF8CX3b3fyX33v4MrVuf83wD+r8qRU57JiJt8xzwfeBZYCZwPtmr4P4N\nGGZme0LDLQYGky0cDixJbjlwYjPrXQH0zplu6laqIkVLxUSkbZ4D+gMvuPu/yXZvPevuH5HdY7nH\nzF4Fngf2cvflwG+BN4FH2PieELlHbP0GeDRnAF5Hc0lUdAl6ERFJTXsmIiKSmoqJiIikpmIiIiKp\nqZiIiEhqKiYiIpKaiomIiKSmYiIiIqmpmIiISGr/Hwdbh7UNraS6AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n+399JexSzHrZVgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(population, transaction=status_quo)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `status_quo` transaction increases inequality from the initial population, but not as much as the other transaction functions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Effect of Interaction Function" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have been using `anyone` as our interaction function: anyone can enter into a transaction with anyone else. Suppose that transactions are constrained to be *local*—that you can only do business with your close neighbors. Will that make income more equitable, because there will be no large, global conglomorates? " + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def neighborhood(n, width=5): \n", + " \"Choose two agents in the same neighborhood\"\n", + " i = random.randrange(n - width)\n", + " return random.sample(range(i, i + width + 1), 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.11 20.1 54 75 100 126 148\n", + " 20,000 0.48 94.6 1 12 73 223 431\n", + " 40,000 0.49 96.2 1 11 71 232 428\n", + " 60,000 0.49 95.4 1 11 73 226 426\n", + " 80,000 0.50 98.6 1 11 69 234 449\n", + "100,000 0.49 98.4 1 11 71 228 465\n", + "120,000 0.49 96.7 1 11 72 233 445\n", + "140,000 0.50 99.3 1 10 70 229 460\n", + "160,000 0.49 97.8 1 11 70 231 442\n", + "180,000 0.50 98.3 1 11 70 233 461\n", + "200,000 0.49 96.4 1 11 72 226 437\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEZCAYAAABSN8jfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmYVOWZ9/HvjaIG2VrDoiKUuIKvBjViEHVwj84ouLxq\nXDGSSQxxCZMRJBGQyUQlrxmXicm4okajJqMoURC3VkFUUBoVNK7FFpogNKthafp+/6jTbdH0Us15\nqqtO9+9zXXVR56lT5/yqgb7rPM85zzF3R0REJI42hQ4gIiLJp2IiIiKxqZiIiEhsKiYiIhKbiomI\niMSmYiIiIrGpmIgAZvaBmR1X6BwiSaViIq2CmX1hZifUarvMzF4HcPf/4+6vNbKNXmZWZWb6fyNS\ni/5TSGvXlKt2LVrf8hHEzHbIx3ZFmoOKiQhbH7mY2ZFmNsvMVpvZUjP7f9Fqr0Z/rjKzNWZ2lGX8\nwszSZlZuZhPNrGPWdi+NXlserZe9n7Fm9icze9jMVgGXRft+w8wqzGyJmd1pZjtmba/KzK40s4+j\nfOPNrLeZzTCzVWb2WPX6Zra7mU2OtrXCzKrziwSnYiKtWX1HGLcDt7l7J2Bf4ImovXpMpaO7d3T3\nt4DLgUuBfwJ6Ax2A/wYws77Ab4HvAXsAnYA9a+3rTOAJd+8MPAJUAtcCuwEDgBOAH9d6zynAYcB3\ngOuA/wEuBPYGDon2B/BvwCJgd6ArMLqxH4jI9lIxkdZkkpmtrH6Q+UVfl03Afma2u7t/5e5v13o9\nuwhdCPzG3Re4+1fA9cD50bjKOcAz7j7T3SuBMXXsa6a7TwZw943uPsfd3/aMhcDdZApVtlvcfb27\nfwh8AEyL9r8WmEKm0ABsJlPE9nH3Le4+o/Efkcj2UTGR1mSwu+9W/WDbb/zVrgAOBD4ys7fM7J8b\n2OaewIKs5QXAjkC36LVF1S+4+z+AFbXevyh7wcz2j7qmlkZdX/8JfLPWe/6e9fwfwLJay+2j578G\nPgOmmdmnZjaygc8hEouKibQmOQ2cu/tn7n6hu3cBJgB/NrNvUPdg/d+AXlnLvch0VS0DlgI9anae\n2cbutXdXa/l3wIfAvlHX189zzV3H51jn7j9z933JdKeNMLPjt2dbIo1RMRGpxcwuMrPqo4HVZH7h\nVwHLoz/3zVr9j8BPzSxlZu3JHEk85u5VwJ+BM8zsO2bWFhiXw+47AGvc/SszOwi4Msbn+Gczq866\nlkyRq9re7Yk0RMVEWovGTgHOfv27wDwzWwP8F3B+NJ7xDzLFYkY07tIfuB94GHiNTJfSV8DVAO4+\nH7gKeJzMEcwaMl1UGxvI8TPgomjf/wM81sjnaOhz7Q+8aGZrgRnAb91dZ3RJXlg+b45lZj2Ah8j0\nH1cBd7v7nWY2FvgBX/f9jnb3qdF7rge+T+Zb1DXuPi1qPxyYCOwCPOfu1+YtuEgemNmuwCpgP3df\n0Nj6IkmS72LSHeju7mVRF8A7wGDgfGCtu/+m1vp9gEeBI8n0Nb8I7O/ubmZvAT9x91lm9hxwu7s/\nn7fwIgGY2b8AL5HpBbgVONLdjyhsKpHw8trN5e7l7l4WPV9HZmBxr+jlugYVB5Ppb6509zTwCdA/\nKkod3H1WtN5DwJB8ZhcJZDCZLq7FZMZaLihsHJH8aLYxEzNLAf2At6Kmn5hZmZnda2adora92PpU\nySVR215k/jNWW8zXRUmkaLn7D9y9JHqc7O6fFDqTSD40SzGJurj+TGYMZB1wF9Db3fsB5WQO/0VE\nJKF2bHyVeKJ5gv4MPOzuTwO4+/KsVe4BJkfPl5CZEqJaj6itvva69pe/QSARkRbM3bd7EtPmODK5\nH5jv7rdXN0RjINXOJjMlBMAzwAVmtpOZ7QPsB7zt7uXAajPrb2ZGZi6kp+vbobsX/WPs2LEFz9AS\nMiqnchb7Iyk548rrkYmZDQQuAt43szlkzokfDVxoZv3InC6cBn4ImfPyzewJYD6ZeYV+7F9/yuFs\nfWrw1Hxmz7d0Ol3oCI1KQkZQztCUM6yk5Iwrr8XEMxPL1XWPhnoLgbvfBNxUR/s7ZGZEFRGRIqMr\n4Atk6NChhY7QqCRkBOUMTTnDSkrOuPJ60WIhmJm3tM8kIpJvZoYX+QC81KG0tLTQERqVhIygnNsr\nlUphZnq0skcqlcrLv6e8nxosIsVpwYIFQc7ikWQx2+6Dj4a329L+MambSyQ3UbdGoWNIM6vv7z1q\nVzeXiIgUjopJgRRb/3ldkpARlFOkGKiYiIhIbBozEWml6uo7HzPmNhYuXJW3ffbs2Znx4+Pd1+7G\nG2/ks88+46GHHtrubbz66qtcfPHFLFq0qPGVs8yePZsbb7yRGTNmALDnnnty1lln8bOf/YxOnTo1\n8u6tPfroo4wePZoVK1Zw8sknc//999O5c+c61x0zZgyTJk3iww8/5IYbbmDMmDE1r5WXl/PDH/6Q\n2bNns3TpUtLpND179qx3v/kaM9HZXCJSY+HCVaRS4/K2/XQ6f9vO1ZYtW3D3Jp/V9MYbb3Dqqady\nww03cP/999OlSxcWL17Mfffdx9y5cznuuONy3ta8efP40Y9+xJQpUzjssMP4wQ9+wJVXXskf//jH\nOtfff//9+fWvf83vf//7bV5r06YNp512GqNHj+boo49u0mcKSd1cBZKE/vMkZATlbKluueUWevTo\nQceOHenTpw+vvPIKzz//PL/61a94/PHH6dChA4cddhgAEydOpG/fvnTs2JH99tuPu+++u2Y7r776\nKnvvvTcTJkxgjz324MILL+T000/nb3/7Gx06dKBjx46Ul5c3mmfkyJFcccUVXHfddXTp0gWAHj16\nMHbs2CYVEsgclZx55pkMHDiQdu3a8R//8R88+eSTrF+/vs71L7nkEk499VTat2+/zWtdu3blRz/6\nEd/+9rcLenaeiomIFJ2PP/6Y3/72t7zzzjusWbOG559/nlQqxamnnsro0aM5//zzWbt2LXPmzAGg\nW7duPPfcc6xZs4YHHniAn/70p5SVldVsr7y8nFWrVrFw4UIeeughpkyZwp577snatWtZs2YN3bt3\nZ8aMGey222515vnqq6+YOXMmZ599doO5Z8yYQUlJCbvtthslJSVbPd9tt9144403gMyRybe+9a2a\n9/Xu3Zudd96Zjz/+OO6PrmBUTApk0KBBhY7QqCRkBOVsiXbYYQc2bdrEBx98QGVlJT179mSfffap\nd/3TTjut5sruY489llNOOYXXX399q+3deOONtG3blp133rnObQwcOJCVK1fW+VpFRQVVVVV07/71\n3TNGjhxJSUkJ7du351e/+lXNNioqKli5ciUVFRVbPV+5cmVNN9S6deu2GWPp2LEja9eubfyHU6RU\nTESk6Oy7777cdtttjBs3jm7dunHhhRc22BU1ZcoUBgwYwO67705JSQlTpkzhyy+/rHm9S5cutG3b\ndrvzlJSU0KZNG5YuXVrTdsstt1BRUcFZZ51FZWVlk7bXvn171qxZs1Xb6tWr6dChw3ZnLDQVkwJJ\nQv95EjKCcrZUF1xwAa+//joLFiwAMkcCsO10IJs2beLcc8/luuuuY/ny5VRUVHDaaadtNX5Q+z1N\nHXxv164dRx11FE8++WSD602fPr1mHCb7Ud1WfRbYwQcfzNy5c2ve99lnn7F582YOOOCAJuUqJiom\nIlJ0Pv74Y1555RU2bdrETjvtxDe+8Q3atMn8uurWrRvpdLqmWGzatIlNmzbxzW9+kzZt2jBlyhSm\nTZvW4Pa7devGihUrtjk6aMiECRO4//77mTBhAsuXZ+48vnjxYr744ouadY455piacZjsR3XbwIED\nAbjooouYPHkyM2bMYP369YwZM4ZzzjmHXXfdtc59V1ZWsmHDBqqqqti8eTMbN26kqqqq5vWNGzey\nYcMGADZs2MDGjRtz/lyh6DoTkVaqmK8zef/99xk2bBgfffQRbdu25eijj+buu++me/furFy5ksGD\nBzNv3jx69+7N7Nmzueuuuxg/fjybNm3ijDPOYPPmzey3336MHz+eV199lUsuuYSFCxdutY9hw4Yx\nadIkqqqqmD9/Pp9++imnn356gwVm1qxZjBs3jpkzZwKZs7kGDx7MiBEjKCkpadLP4rHHHmPkyJGs\nXLlym+tMrrzySsyMu+66C4DLL7+cBx98cKsjqgceeIBLL70UyJweXP1a9WnPW7ZsqXO/+brORMVE\npJXSRI+tkyZ6bGGS0H+ehIygnCLFQMVERERiUzeXSCulbq7WSd1cIiJStFRMCiQJ/edJyAjKKVIM\nVExERCQ2jZmItFIaM2mdNGYiIiJFS8WkQJLQf56EjKCc0rjLL798q7sTSni606KI1Bhz0xgWLlvY\n+IrbqWe3noy/fnzeth9KeXk5Y8aM4dlnn2Xt2rV07dqV4447jlGjRjV5MsaysjKGDRvGhx9+SN++\nfbn33nu3updJXSoqKjjggAPo06cPr732Wk375MmTGT16NAsWLODQQw/lnnvuoU+fPtv1GUNTMSmQ\nJNzbIgkZQTlDWrhsIakhqbxtPz0pnbdth1J935GBAwcyY8YMUqkUa9as4amnnuKFF15oUjHZvHkz\nQ4YMYcSIEVx55ZX8/ve/Z/DgwXz66afsuGP9v35HjhzJwQcfvNVkjp9++ikXX3wxU6dO5aijjmLC\nhAmceeaZ/PWvf62ZBLOQCp9ARKQOS5cu5dxzz6Vr167su+++3HnnnTWv3XjjjZx//vlcdtlldOzY\nkUMOOYR333235vU5c+ZwxBFH0KlTJy644IKaGXVz8Zvf/IZOnTrx8MMP19xwq2PHjlx22WUMHz68\nSZ+htLSULVu2cPXVV9O2bVuuuuoq3J2XX3653ve88cYbzJs3j8svv3yr9ueff55jjz2WAQMG0KZN\nG0aOHMmSJUt49dVXm5QpX3RkElius66Wl6fp379fTjOoFkppaWkivk0rZ8vj7pxxxhmcddZZPP74\n4yxatIiTTjqJgw46iJNPPhnIdPk89dRTTJw4kZ///OcMHz6cmTNnsnnzZs466yxGjBjB8OHDmTRp\nEt/73vcYNWpUzfZLSkp49tlna+58mO2ll17irLPOajRjSUnJVmdGVT83M0aNGsV1113HvHnzOPTQ\nQ7d637e+9S3mzZvHKaecss02q6qquOqqq7j33nt57733Gtx/VVUV7s4HH3zA8ccf32jefFMxCWzh\nwlWkUuNyWLOUhQtL85xGJJlmzZrFl19+yc9//nMAUqkUw4YN47HHHqspJscccwynnnoqAJdccgm3\n3347ADNnzqSyspKrr74agHPOOYcjjzxyq+1XVFTUu+8vv/xyq9vzTp48mUsvvZQtW7Zw9NFHM3Xq\n1Ea3Ua2pt+e94447GDBgAIcddtg2xeSkk05i1KhRvPbaawwYMICbb76ZzZs389VXXzWaozmomBRI\nKjWIdLq00DEalJRv0crZ8ixYsIAlS5aw2267AZkjlaqqKo477riadbJ/4bdr167m5lFLly5lr732\n2mp7vXr1ynnfu++++1a35z3jjDOoqKjgvvvu45FHHmnS52jK7XmXLl3KHXfcUdNdV/takAMPPJAH\nH3yQ4cOHU15ezsUXX0zfvn3p0aNHkzLli8ZMRKTo7L333vTu3ZuVK1eycuVKKioqWL16NZMnT270\nvXvssQdLlizZqq32jbEacuKJJzJp0qRG12vo9rw333wzkLk9b+0jjPfee4+DDz54m+29/fbblJeX\n07dvX/bYYw+uvfZa3nrrLfbcc8+awnL22Wfz/vvvs3z5csaNG8cXX3yxzVFXoaiYFEixH5VAcq6L\nUM6Wp3///nTo0IEJEyawYcMGtmzZwrx585g9e3a976n+hTtgwAB23HFH7rzzTiorK3nyySd5++23\nc973iBEjqKio4JJLLuHzzz8HYO3atZSVlW21XkO3560enxk0aBA77LADd955J5s2beKOO+6gTZs2\nnHDCCdvs9/TTTyedTlNWVsbcuXMZP348hx9+OHPnzq25i+K7775LVVUVy5cv51//9V8ZMmRI0dw3\nXt1cIlKjZ7eeeT19t2e3njmt16ZNG/7yl78wYsQI9tlnHzZt2sSBBx7IL3/5y3rfU/0Lt23btjz5\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(population, interaction=neighborhood)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Surprise:** The `neighborhood` interaction is not too different from the `anyone` interaction. \n", + "\n", + "Let's get even more local, allowing trade only with your immediate neighbor (to either side):" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.11 20.1 54 75 100 126 148\n", + " 20,000 0.45 85.3 1 13 79 218 373\n", + " 40,000 0.47 90.1 1 11 76 224 407\n", + " 60,000 0.48 92.0 1 12 73 228 404\n", + " 80,000 0.48 92.5 1 12 73 231 406\n", + "100,000 0.48 94.3 1 12 71 227 421\n", + "120,000 0.48 94.1 1 12 73 226 437\n", + "140,000 0.49 95.7 1 12 71 236 421\n", + "160,000 0.49 97.5 1 11 71 231 454\n", + "180,000 0.48 95.0 1 12 72 227 434\n", + "200,000 0.50 97.8 1 11 70 235 442\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAEZCAYAAADR8/HkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXd4XMW1wH9HW1RWvduq7pY7NtjGgG1I6DUQCCEJkE4J\nAQJJSMiDvISe9iAhkEJooWNCCcUkgGgG94Z7L5LVi9VW2+b9ca/Ytb1rS9ZqizS/77ufdufenT33\neLznzpkz54hSCo1Go9FoIk1CtAXQaDQazdBEGyCNRqPRRAVtgDQajUYTFbQB0mg0Gk1U0AZIo9Fo\nNFFBGyCNRqPRRAVtgDQajUYTFbQB0mg0YUNEHhKRW83X80RkzwB8x+0i8mS4+9VEHm2ANEeFiFwr\nIktFxCki/whxzS0icoeI2ETkBRHZISI+EZkb5Np7RaRBROpF5J4g52eLyEfm650i0iki+83jrYOu\nvcy8pk1EXhKRzIPO28zvSRGR4SLysog0ishuEfn+QddOE5FlItJh3u/UILK9JSJfFBG7iPxBRKrM\n/v4kIpaA68aLyDsi0iIim0XkgsPo9woR8Zj31yIiK0Tk7FDXRwNTxg8D25RSVyul7gxsOsq+HxWR\nbvP+G0TkbREZ29d+zTF3ytHIoBl4tAHSHC1VwK+BRw5zzdnA6+brD4GvAfsOvsj80T8PmAxMAc4V\nke8F6esN87UCzlZKpZvHGQF9TQQeNr+rAOgCHjqor7nASqVUJ/AUsA3IA84B7hKReWZfNuBl4Akg\n0/z7iohYA74vBZgBvA/8DJgOTADGmu2/MK+zAK8ArwJZwPeBf4rI6NDqY5F5f5nAP4DnRSTjMNcf\nQqABHACEozQwveRepVQ6UAzUAY8N4HdpooA2QJqjQin1slLqVaAp2Hlz1jEG+FQp5VZKPaCUWgT4\nglx+OfA7pdQ+pdQ+4LfAlQddcxZ+YwbGj18wLgNeVUp9bBqY/wEuFBHHQX29YbbNA+5SSvmUUmuA\nF4FvmdedDFhM2d1KqT+a3xv4RP0F4GOllBvDgP1RKdWqlGoEHgjoazwwTCl1vzJ4D/gY+EaI+ziY\nfwDJwCgAETlHRFaKSLOIfCQikz9XjPHU/xMRWQ20i0iCiBSLyAIRqTNnfw8EXP8tEVlvztreFJHS\ngHM+Efm+OWNrEpE/me3jMQz78eZMs8lsf1REfhXsBkRkmIi8aMqwTUSu682NK6WcwNPApBD9nici\nn5nyvSsi48z2J4BS4DVzJnWziCSKyD/NWVWziCwWkbzeyKEJP9oAaQaK04F3VO+SDU4EVge8X222\nASAihUC+UirwmqdEpNZ0f00J1ZdSajvQjTEj6eEs4N/4n+ADjZng/6GbAKw5SNYDZONQwxhIAlAs\nImkhzgd+V0jMGdd3gTZgi4gcgzHz/C6QDfwFeNWcsfVwKXAmxswNjPvdgfGDXAQ8a/Z9PnALcAHG\nLPBD4JmDRDgbYzY3FbhERE5TSm0ErgI+UUqlKaWyj3APArwGrASGYRju60Xk1F7cfyrGjHZFkHNj\nMYzTD0353wT+LSJWpdTlwG7gHHMm+VvgCiDN1EG2eQ9dR5JBMzBoA6QZKAJdZkciFWgNeL/fbOvh\nLCBwnecyoBwoAyqBhSKSHqKvnv7SAERkJMasZqtSqh1jFvI/5pPxdOAiIKU3fQXI1nOfb2H8qOaa\nRrPnCT8F2ATUmU/hVhE5DWP2lUJojjdnFtXAV4ALlFJtGIbnYaXUMnM29SSGkZ0d8Nn7lVLVSqlu\nYCbGj/5PlFJOpZTLnI2C4Qq8Wym1WSnlA+4BpolISUBfdyul2pRSe4D3gGmHkTkUM4FcpdSdSimv\nUmon8HcMQxmKH5v3vxlwAN8Mcs0lwL+VUu8qpbwYs+dkYE7ANYEPGG4gBxhr6m6lOQ40UUAbIE3Y\nMZ92T+VAo3E42oH0gPcZZlsPgT/yKKU+UUp1mz+m9wAtwEkh+urpry2grzcDzn0NGInxpPwg8CSw\ntzd9icgkoEUpVWWeuxPjCX8V8BHwL8CtlKpVSnkwZhnnYKyD3Qg8F/BdwfhEKZWtlMpXSs0x3XZg\nGN6bTJdTk4g0Y6yTDA/4bGC/JcAu08AcTBlwf09fQCPGrLAo4JragNedHPhw0FtKgaKDZP4ZkH+Y\nz/zGvP/hSqkLlFI7glwzHNjV88acce85SP5AngAWAs+KyF4RuWeA18k0h0EbIM1AcByw01wH6Q3r\nMNw7PUwz23rcT/OA/xzm84FutAP6EpFRgA3jKRoONWZ7lFLnKqUKlFLHY7hxlgT0Fejew3y/LkRf\nTqXUD5VSxUqp0UAzsDzg/GdKqflKqTyl1JkY6zlL6Dt7gDvNH+dspVSWUipVKfVcwDXqoOtLRSTY\n//fdwPeD9PVpL+ToSwDCHmD7Qd+ToZQ6tw99BKMaw4gGUoLfAB8gozn7+rVSaiLGLOlcjDVITRTQ\nBkhzVIiIRUSSAAtgNV1YPU+Sh6yLiBGinGS+TRSRxIDTTwA/EiMkugj4EfCoee5EYHWPm0RESkRk\njhih1Iki8mMMl8rH5vVPYUTRnWAGGfwKWKCU6hCRZAzj2DOT6AmNTjX7+zrGzO335ulKwCsi15ny\n/xAjiOLdYPdpyj/MfD0bIwLutoDzk02ZU0TkZqCQo4vs+htwlYjMNPt1iMhZcmCgRSBLMGZd95jf\nnSgiPS6qvwA/F5EJZl8ZIvLlXspRi7HGZTvilYYMbWIERySZ42eiiBzby+8KxfPA2SJysunavBlw\nAp+Y52swZrgAiMh8EZlkGuN2DJdcsJmhJgIMqAESI/LmXRFZJyJrzf/AiEiWGHH9m0RkoQSElorI\nz0Rki4hsMP3kPe3TRWSNGNE4/xfQbheRZ83PfCIHRvBcYV6/SUT0U054+QWGO+anGG6sTuBW81yw\n9Z9NQAeGy+QtoLPn30op9ReMBeq1GIv8ryql/hairzSM6KsmjKfc04AzlFLNZl/rMRaWn8b48UkG\nrjU/ewqGW8sV0N/pwHazv+8Bp/fM3MzItgswFq6bMZ6Uz1dKecwxWwEsCuhrFLBIRNoxDOhPlFLv\nBJz/BoYhqMGIsDvV/I4+oZRajrEO9KeANZIrAi856HofxpP+GIwZzx6MtROUUi9jrPs8KyItGEEX\nZ4Tq66D372LMBmtEpO4IMvsw3I/TMIIh6jAM6cEuzlDfG6rfzcDXgT8B9Rjj5VzT5QnGvf2P6fb7\nEYbRfxFjbW8dxsOI3tQaJaR3QUpH2bmxEFuolFplRrIsB87HWExsVErdJyI/BbKUUreYT2FPYTyl\nFgP/BcYopZSILAZ+oJRaKiJvYCyyLhSRq4HJSqlrROQrwJeUUpeKSBawDGNfhpjfPV0pdfCisiaM\niEg+sEIpVRym/tYBF5lRV/3t60FgrVLq4TD0dbEp1+EW0TUazWEY0BmQUqpGKbXKfN0ObMAwLOcD\nj5uXPY7xlAnGZsRnlVIeM0pmCzDTNGRpSqml5nVPBHwmsK8X8e/ROB14Wxl7MlqAtznwyU4zMGQA\nN4WjI9O183g4jI/JSozAgHDQDPwhTH1pNEMS65EvCQ8iUo4x/f4UKFBK1YJhpMynZjAiVz4J+FiV\n2ebhwKievfijXIowXAoopbwi0ioi2YHtB/WlGUCUUlswHhzC0ZcbuC8cfZn9/T2Mff03XH1pNEOV\niAQhmO63F4HrzZnQ4fzK/f66MPal0Wg0mgFiwGdAZhjti8CTSqlXzOZaESlQStWa7rWeBcwqjBDK\nHorNtlDtgZ+pNqOw0pVSTSJSBcw/6DPvcRAiMpC5rDQajWbQopTq1wN/JGZA/wDWK6XuD2h7FX+u\nryswkjT2tF9qRraNAEYDS5RSNUCriMwUEcGIRgr8TE8E0MX4Q2QXAqeaYaVZGOG1C4MJ+M1vKpQ6\n9Hh46cN899XvBj0XE8cZZ6Befjls/d1+++3Rv6cYOcKti1a3m3/W1JD8/vt81NIS9fvT4yJ6unBW\nO2l4vYGdd+9k3aXrWDxhMe8nvc+SSUvY88AenFVOfD5f1O/1SEc4GNAZkIicgBGiu1ZEVmK42n4O\n3IuR2fdbGLuYe0JC14vI88B6jPj8a5T/Tq/F2DORBLyhlOrZZf8I8KSIbMHYxX2p2VeziPwaIxJO\nAf+rjGCEQ2gPkYijvrOenOSco77/AWfaNHjjDTj//LB0t3PnzrD0MxgIty6u27KFj1pbeWTcOE7I\n6FNC66ijx4Wf/ujC2+Vl4zc30vx2M2nHpuGY4iD7zGxKflqCo8JBQuLQ25Y5oAZIKfUxxkbFYHwx\nxGfuBu4O0r4cI13/we3dmAYsyLnH6MVGP48neHt2cjbbm7cf6ePR4+tfhzPPBJcL7PZoS6MJQbPb\nzUetrfxt3DhOycqKtjiaKNG5sZP65+rJPjOb4uuLyT79sPlbhwQRi4KLZUIZoMLUQva1H1K+JnaY\nMAFmzIBbb4Xf/Kbf3V155ZX9l2mQEE5dNHs87HA6ybbG5383PS789EcXacekcfze46l7oY41Z6wh\nbWYa9nw7tgKb8TfPhvIoiq4twpIyNNLTxef/iDATavLwwvoXOG/seZEVpi+IQHY2pB5NbshDmT9/\nflj6GQyEUxdrOzqYnprK5DD9O0UaPS789FcXiUWJlNxQQv7F+Tj3OHHXunHVuejc2Mm2H20DIPdL\nuaSMPlyS9MHD0HM6BiEhhBZ2tuxkauEhFZhjh6YmWLAArroqLN1VVlaGpZ/BQDh1sXT/fpa3t7O+\noyNsfUYSPS78hEsXiUWJOHc6+eyCz9j8vc3s/X3ANkdvWL4iLtAGCPCG+Aff372fNHuoWmIxQEqK\nYT1D+RA1UeetxkYerq7mW4WFFCcmHvkDmiFD6uRUMr+QSfoJ6aTOSCWxOBFLmoWlk5ay7afboi1e\nRBjQXHDxgIio889XvPzyoefG/HEMr176KhV5FZEXrLekpEBNDaSHyumoiSb3793L3/ftY+1xx0Vb\nFE0csObMNTS9ZVS5Tz8+HVuODWuOFRQ4dzkpubmE3HNyoyylgYig+rkPSK8BEXoGNC5nHBsbNsa2\nAXI4oLNTG6AY5cOWFmamxfAsWhM13E1umt9txtvqxdPqwdPiIXl0MtlnZ+Pc7qRteRvKdeAEIfuM\n7JgxQOFAu+AIbYAKHAVUtVUFPxkrzJgBN94Ylq60r99PuHRxx4gRvNXUxPVbtvBec3NY+ow0elz4\nCacuap+uZf3F69n0nU00/KsBsQhJo5LIuyiPEXeMYMobU5i+dDqzts9innce89V8ym45uPZefKNn\nQIReQpmYP5FtTTHui01ONqLhNDHJeIeDe0eO5BsbN/JCfT3rjzuOTFtv6rdpBjuOiQ5jl6QXOrd0\nMuXtKViSh0b4dQ96BkToGVBeSh51nYetsxV9rroK9oVnr5IOt/UTTl3UuIz6dztmz45L46PHhZ9w\n6cK520n1X6o/j3hz1/a5LuGgQBsgQs+AdrbspNBRGFlh+kpmJtTXR1sKzWFoN59wrtq8OcqSaGKF\n7T/fTv1z9ZTdXsbMjTOZ55035GY/oA0QENoAubwuUu0xvnlQBJKSwtKV9vX7Cauv3+1mfmYmD4we\nHbY+I4keF37CpYsx94+h+IZidt+zmyXjl7Duy+vC0m+8oQ0Q4PMFby9MLWTv/r3BT8YK69ZBka6z\nF6vUdHfzdlMT+TYbaXGaikcTfmw5Nkb/YTTlvywHwJI29GY/oIMQAGgJmiPbSEZa01ETWWH6SnMz\nhGmDo/b1+wmXLj7Zv59xKSk8N3FiWPqLBnpc+Am3LspuKaN7bzddm7rC2m+8oA0QoQ3QkqolnFR6\nUmSF6QubNsG998Jrr0VbEk0InD4flS0tTFu6FICXJ02iPDk5ylJpYoH6l+pZd5Hheht570ja17Zj\ny7Nhy7WRYB0azqmhcZdHIFSOyCRrEl5fDCdm8vmMI0wbHbWv30+4dPHVggL2Hn88qzs6WN3REZdp\nvvS48BNOXYhVsOXbyDoti8bXG1k2ZRmfDPuED2wfUCnh+55YRs+AMHJ6BiPFloLT44ysMH2hogLm\nzYOlS43XmpjkdrOI2W9HjWKUnv1oTHLPyyX3PCOrQU+xutYPW3FVuyi7bXBtOA2FngEReh9nniOP\nXa27IitMX3E6YePGsHSlff1+wqWLWpeLP1VVsWXmTG4qKQlLn5FGjws/A6ULS7KF1GmpuKqNPWOd\nmzoH5HtiDT0DOgzJ1mS8KsadJk1NMGZMtKXQBEEpxRM1RhDLyvZ2RqcMjRovmr7hdXpperOJHbfu\nAGCedx6SMDSym+gZEMYkIlgo9qT8SazYtyLyAvWFefNgx46wdKV9/X7CoYvtTic/2b6dqQ4Ho+PY\n9abHhZ+B0MX2W7az7sJ12PJsnNBwwpAxPqANEAAuF3R3H9o+Nmcsu1t3R16gvjB7NugfiJjEZ5Y6\nybHZ6AiV70kz5Bn9u9FMem2SkY5n6NgeQLvgALBYIFhZpLqOOrKTsyMvUF8YPhz27IGuLiMxaT/Q\nvn4/4dDFh62tlCYmsnDKFKyhyu7GAXpc+BkIXYhFsGYaP8WW1KG1IVUbIGDECKOu28Ek25Jp626L\nvEB9Yfp0yM2Fd96Bc86JtjSaAIoSE9nd3c0t27fz2zhNw6MJL656F11bu+je2013Vbfxd3c3ze8a\npTq693aTPDJ+3bV9JX4fy8LI8OHB29fXr2d4WoiTsYLbDdXVUFzc7660r99POHSxo6sLCzAuzoMP\n9Ljw019dLMpfxMo5K9l28zac25zY8+zknp/L9E+nM883b0gZH9AzIABCeUfu+egebj3p1sgK01ea\nm6GuDlpboy2J5iBea2zEC8zNzIy2KJoYYU79HPb+bi91L9RR/ddqbDm2z8tu23Js2LJtKI9C7MKY\nB8cM+owIooItfgwhRESdcYbizTcPPVf8+2I+/tbHlGXG8KawtWthyhTYvt3wJWpihmdra/nqhg18\nOn06s3TJdM1BeDu9uJvceBo9uBvduBvd1D5ZS+NrjQDknJNDYmki1kwrniYPeV/OI+sLWVGW2o+I\noJTqV9iEngFhBCEczI7mHbh9borT++/aGlAWLoSzz4by8mhLojmIcrNMRkocByBoBg5LigVLigUC\nfmLyLsyjc2Mn7gY3bcva2HazvyJz4xuNzNo2a1DNigbPnfSDYL8PIoJP+ejyxHCW2o4OuOsuIyFp\nGMpya1+/n3DoYpvTSOP0QpwXDNTjws9A60IsgmOig8x5mRTfWMyUt6cw+v7R5H81n+7d3Wy9biud\nmwdPlgRtgAg+AyrPLGd28Wxe3fRq5AXqLV6vEYQQx6n+BzNjkpMpTUxkRJgKBmqGFpIgZJ+azbDv\nDCP79GzEKlQ/XM3ymctx1buiLV5Y0C44jN/xYDhsDmJ6jUwpo5yrUmGZAen9Hn76q4sNHR3MWrGC\nHKuVs3JywiNUlNDjwk8kdKF8Ck+rsS7kafSwYraRjSV9Tjpj/zIWR4UDsQyOHavaAAE1IWrOOWwO\nWpwhigXFAhkZkJkJu3bpNaAYo8LhYP1xx/Hjbdu4c9cuHtD5+jRHYOO3NlLzaOgCmPsX7afuqToS\nUhKwpFhISE7A2+7FVeOi8MpCUqeEqCsTw2gDROgZ0LC0YVS3VUdWmL7y9a/DaafBkiWGMeoHlZWV\n+mnXpD+6UErxTnMzf9i7l2Vtbfwgzkum63HhZyB1Mep3oyi4vICEpASUW+Hr9OHt9B7yt+axGro2\nH7g2bc20agMUrwRbAwKYMWwGj6x8JLLC9JXf/AaWLYMPP4Rzz422NBrgqs2bqWxp4SelpSyYOJGk\nUANMownAlmUja/7hw6wb/t1A1+YuEksTGfXbUaRNTyNpZBISBhd8NNAGCEhMDN5e11FHYWphZIXp\nK21tsH49jB/f7670U66f/uhiZXs7vx01inNzc8MnUBTR48JPtHXhmOCg+MZiXLUuNn1rE952L4Xf\nLGT8P/r//z8aaAMEhApSquuoo8BREFlh+opSRirv7BhPmjqESLdYOO+zz3DPnRvXSUg10cHn9tG1\nrYvO9Z04dzpx1bj8R63x19vmJaUihaTyJLLPiN//+9oAETwRKcDaurXMLZsbWWH6ymuvGcEIoaZx\nfUD7+v0crS6UUrzT0sKpWVmsam/n2EGQAUGPCz8DrYv37e+j3IdG3iakJJA8Mpnk0clknZpF8ohk\nLGkWLKkWrFlWuvd1Yy+0x50rThsgYNiwQ9s8Pg8LNizg7+f9PfIC9YU//AH+9jdIjb8FyMGIiLBx\n5kyeq6vjC6tX81RFBecMElecZuCZuWEmrhoXyqvwtnvxdhiHr8NnvDbb2te242n00LaiDed25wF9\nHL/veBIL+/9AGgm0AQLa2w9tq9pfRWFqIemJMf4Em5wc2ofYR/RTrp/+6GJcSgq3lZdT43LxamMj\nZ2Rnx7UrTo8LPwOti+RRySSPOjQjdndVN+2r22lf3U7Xli7a17Tj3O4kaWQSOefmkDQiCUuqBVuu\nDVuubUBlDCfaAAG1tYe22Sw2vL44qGKZnw/btsHcGHcVDkF+XlrKlRs3UrF0KfeOHMmFeXnRFkkT\nh3Tt7GLJuCUol+GaG/bdYUx4egIp41NISIzfBxvQqXgAcDgObWvobMBusce2EVLK2MTU0BCW7nTO\nLz/h0EVxUhL/mTqVv40dy7VbtvBwVVX/BYsCelz4iYYuksuTObH1RKYvnc6Iu0fQ8GoDrnpX3Bsf\n0AYICO7Bmpw/meL0Yl7a8FLkBeot//iHUYzu2mujLYkmBCLC/Kwsnhg/nl/t2hVtcTRxiiXJQvqx\n6ZTdUsaIX41gzalr2PqjrdQvqMfn9kVbvKNGu+AIHkAmIozIGkG3tzvyAvWW9najJHeYKm5qX7+f\ncOjC7fPxTnMz77S08GRNDbeUlvZfsCigx4WfWNDFsO8MI2V8Cq0ft7L7vt00vt7IuEfGxV0EHGgD\nBIArRGLZuo46spNjOMZ+2bLQ9cQ1UaXZ7eb6rVt5o7GRHxYX85+pU5msIxU1YUAShMy5mWTOzST/\nq/ksHrGYpoVNZJyQwej7R5M4LD4i4EC74ADYsiV4e2l6KatrVkdWmL6QlAS28EW8aF+/n/7ooqa7\nm4olS3D5fCyaPp3bysvj2vjoceEnmrpofqeZLTds4bMvf8byWctZNHwRS8YuIaUihYyTMkidnorF\nEV9pn/QMCOgKUXMuMykTj88TWWH6wvXXwymnwHnnwcyZ0ZZGY7K2o4MRyck8PWECCXHoFtHEDsqr\ncDe7cTe4Wf1F42G49JZSSn5UQmJJIvZh9riukCoxXe8mAoiIKilR7N596LmFWxdyx4d38OE3P4y8\nYL3lrrugqgoefDDakmhM6l0uZixfjlcpqubMibY4mjhj93272f7T7Qe02YvsJCQm4NzuZMILE8j/\ncn6UpPMjIiil+vWEpWdAQKh6YXPL5rLy+ZW0u9pJtceoC0Up2L8/2lJoAsiz23mqooK5q1Zx6/bt\n/GrECCx6JqTpJYVXFEICeFu9uJvcNL3ZROnPShn+3cG33hu/c7cwcrhyLV7lxW6xR06YvjJxIrz0\nUvB0Dn1E+/r99FcXJ2VmUjNnDkvb2hi+aBHXb9mCN069DXpc+ImELuwFdkpvLmXEr0eQOS8TT4uH\npPLBWdZ9QA2QiDwiIrUisiag7XYR2SsiK8zjjIBzPxORLSKyQUROC2ifLiJrRGSziPxfQLtdRJ41\nP/OJiJQGnLvCvH6TiFx+ODmtIeaBGxo2MDp7dGwboN//Hv78Z50LLgYpsNt5e+pU7hwxggeqqtjp\ndB75QxpNALZ8Gwg0LWzC3eyOtjhhZ6BnQI8Cpwdp/71Sarp5vAUgIhXAJUAFcCbwZ/EHtj8EfFsp\nNRYYKyI9fX4baFJKjQH+D7jP7CsLuA04DpgF3C4iGaGEDGWA6jvqyUzqX5XRAcXrNWY+YUrxEgt7\nHGKFcOqi2uXilMxMRiUfmuMrHtDjwk8kdOFudLPvsX3sumcXja80goK9v9vLx9kfs/f+vQP+/ZFk\nQA2QUuojoDnIqWAO8fOBZ5VSHqXUTmALMFNECoE0pdRS87ongAsCPvO4+fpF4BTz9enA20qpVqVU\nC/A28PlMq7fUtNdQlBbD5ZQ/+ggaG+GMPt+aJoIMt9vZ5XQy1AN+NL3DuctJ/XP11D1dR83jNXia\njUjcpBFJDPtekNT9cUy01oB+ICKrROTvATOTImBPwDVVZlsREGj295ptB3xGKeUFWkUk+zB9BSXU\n74JXeWM7E8Irr8Cpp0KYMi1rX7+fcOriraYmCu12XHFqgPS48BMJXaRNT2PKm1M4bs1xnNh0Iie2\nnAiAc4eTjzI/4tMRn7Jy7ko2XLmB6r9W07mpc8BlGiiiEQX3Z+BXSiklIncAvwO+E6a+jyrUaNmy\nK/nlL8sByMzMZNq0acyfP5/VNasprC88oAhVzwCMifetrVR2dkKsyhfH73sIR39ndHbyYlERwxYt\n4vjt27m+uJjTTjklpu73cO9XrVoVU/JE8/2qVaui8/3KeP/O2+/QVd/FrKJZNL3RxPNXPU9CYgLX\n1F6DNd06oPJUVlby2GOPAVBeXk44GPB9QCJSBrymlJpyuHMicguglFL3mufeAm4HdgHvKaUqzPZL\ngXlKqat7rlFKLRYRC7BPKZVvXjNfKXWV+ZmHzT6eCyKDuvBCxYIFh8r+vde+xzGFx3D1cVeHRRdh\nRSmjFtCmTVBWFm1pNL1gR1cXIxcvZsesWZTH6XqQJjZw7naydNJSim8opui6Iux5kQ+UCsc+oEi4\n4ISAmYm5ptPDhcBn5utXgUvNyLYRwGhgiVKqBsO1NtMMSrgceCXgM1eYry8G3jVfLwROFZEMMyDh\nVLMtuIAhVLh3/15KMkp6e5+RZfVqIwmpJb5Sbwxlcm020iwWnR1B02+8HV6UW9G2tI2dv9zJjtt3\nUP+v+miL1WcGOgz7aWARRuTabhH5JnCfGVK9CpgH3AiglFoPPA+sB94ArlH+6dm1wCPAZmBLT+Sc\n2ZYrIluAG4BbzL6agV8Dy4DFwP+awQhBCZVOzePzkCAxulVq0SJjB21xcdi6PNj9NJQZCF2kWa38\nqrycqctCn4RdAAAgAElEQVSWsTiONg/rceEnFnThc/lwVbsY9t1hdG7spPrP1ez61S52/HxHtEXr\nMwO6BqSUuixI86OHuf5u4O4g7cuByUHauzFCt4P19RjwWG/kbG0N3j4yayQ7W3b2povIU1QEaWnR\nlkLTR24oKWF5ezv/qq9nVnqMl3vXxCR1z9ex8RsbGfb9YRRdX0TK+BQyTsjAmhZ/iW3iT+IBINQ+\nIFuCDbc3Rjd/3XYbXHRRWLvsWXjUDKwurhk+nLmrVnFdcTFFwYpRxRh6XPiJtC5aP2ml9slauvd2\n013VTffebtx1bsr/t5zy28ojKstAEKP+pcjSHSLS+uM9HzO54JCJV2xwzTXGPqA4De0dysxIS2NU\nUhK374g/l4kmsohNsDgsBxwAHes6cO6K/71l2gABHR3B23e27GRqwdTICtNbLr/ciIB7990jX9tL\nYsG/HSsMpC7eb2khMSGB344aNWDfEU70uPATaV2kH5vOqN+MYsIzEzjmg2OYvX02x1cdj/Iqls9a\nzuKRi/G0xnDJmCOgXXAEN0BKKZweZ+wGISQnG1FwoYoZaWKSmu5ubti6la8VFJAZxmKCmsGBz+PD\n2+41jjYv3v1e3M1uPC0e42g2/tpybGTOzaThlQa87V6sGfH5U67rAYmoY45RrFhx6LmTHj2JG2ff\nyIUVF0ZesN7wn//AZZfBxx/D2LHRlkZzBGq6u5m9YgXfGTaMX4RpI58mfujc1MnOX+/E1+kzjEv7\ngYenzYNyKyypls8Pa4YVa5YVa6Z5BLy2Zdmw5dvInJ+JRCG0X9cDChOhHkQvqriIN7a8EbsGaNIk\n8HggM4YTpmo+J9ViIddmo97txu3zYUuI0dm1Juwon6LlgxbqnqoDoPimYvIuzPMbmzTjb0JSQlSM\nSbTQ/wMAe4hNxEnWJNy+GI2CA1i7FqZNg/zwVEfUvn4/A6GLVKuVlydN4sGqKm6NowAEPS78HI0u\n3M1uPsr+iM3f2/x5W1JJEhlzMkidkkryyGTseXYsyZYhZXxAGyAAHI7g7Qu3LeSk0pMiK0xfuOMO\nOP/8aEuh6QMJIniBbw8bXFmNNaGxZdmYtXkWo37vDzrxuXxRlCh20C44oKAgeHuyNZm27rbICtMX\nJk+GjRvD1p3e7+FnIHThVYqHq6spsNnIjaMABD0u/BytLuz5drJOyfr8ffVfqrEX2LEPt5NYnEjy\niGQSEofefEAbIEJ7sIrTi3F6YriKZUZG6BhyTcyxsbOTu3bt4sWJE8mJIwOkCQ/Jo5MZed9IxCK4\nal00vd2Eq9pF955unHucJJUmkTI+hYKvFZD/lfC41WMdbYAAd4hlHq/PG9vluDs6oLDwyNf1ksqA\nsg5DnYHQxUetrSig2RNf+zb0uPDTH11YHBZKf1wa9JzP5aNrWxcdn3Ww7UfbaHyzkfyv5JN+fDq2\nzMH7sDL05nxBSEkJ3q6I8RD1+vqwbkTVDAxOr5ebt27lFzt28On06XxTr/9oDiLBnoCjwkH+xflM\n+3AanRs7WXvWWj7O/pi6F+qiLd6AoWdAHL6iQUxHpdx3H5SXG6HYoRLa9QH9lOsnnLr4eP9+/t3Y\nyPIZMyhNSgpbv5FCjws/A62LteeupfH1RqyZVkbcNYLMkzNJP27wJq3VMyCgJUShhg5XB0nWGP7B\nKC42FrD27j3ytZqoMTY5md3d3TSF8vVqNIC3y0vHOmNNN3l0MsU/LCZjdgZiieGH4H6iDRDQ1BS8\nfWfrTsozyyMqS5/p6IDU1LB0pfd7+AmnLkqSkpiTns67oZ50Yhw9LvwMpC6UV+Hc4SRzfibDvjOM\nzs2d+NyDO1xbGyCguTl4+47mHbFtgJQCvZs+LuhWinwd+aY5DNZUKye2nEjGCRnsvnc3y6cvZ/lx\ny6Mt1oCi14AIbYBS7ak0dYWYHsUCCxcabrjs7LB0p339fsKpiz/u3ctOp5Mv5eWFrc9IoseFn4HS\nhWe/h4/zP0Z1KxKLE0ksSyR9VjpZX8g68ofjGG2ACG2AhqcNp7a9NrLC9IX8fCMSzuMJnU9IE3Ve\naWjgS7m5OA4X7aIZkqy7ZB31L9ST4EgABanTUpmxYkZsBz+FEe2/IXRBut2tuynNCB63HxM0NkJ7\ne9iK0mlfv59w6uLLeXnUuVxh6y/S6HHhJ9y6aHqriaRRSUz9z1Tmds7l2JXHDhnjA9oAAaFzwc0p\nmcOHuz+MrDC9Zd8+OO00ePJJiIOyzkOZdZ2dPFdfj8c3uBeUNX1nwvMTSCpLYuWclbxvfX/QBx0c\njHbBAVVVwduzkrJiOxVPSgqceWbYutO+fj/h1MW2ri5uLS3FGqcBI3pc+AmnLmqeqGHjFRtJGpFE\n7pdySSqP4S0fA4Q2QIDTaUQzHzwTsllsuL0xunejvd0wQHV1UBrDbsIhjtvno9HtZnpaWrRF0cQY\nvi5jtuPc4eSYD48hsWjoeTLi85EszLjdwdfwyzLKWN+wPvIC9YYxY4xSDI8/HrYuta/fTzh0sb2r\ni+GffEJSQgInx3HRQD0u/IRTF8O/P5wxfx4DwJKKJVRKJYuKFzGUqlRrA4RhfIJt0Th11Km8v/P9\n2B0Q114LDzwQeietJqp0er10er38a9IksvQeII1J17YuWj5ooeafNXiaPQz7/rDP3W+FlxcOqSAE\n7YID0kOkWipKK6LF2UK7q520xBh0oezbZ/wNU3iv9vX7CYcuunw+cm02UuM8/FqPCz/91UXnpk6W\njF9yQNvo+0dTeHkh6bPSB3XanWDoGRChDdCmxk2UZJTEpvEB+M1v4KGHjLpAmphjRFIS1S4Xd+7a\nFW1RNDFCyrgU5nnmMWvrLCa9OgkEMudlkjFncOd8C4U2QIQ2QHUddWQkxvCP+/jx8MwzYetO+/r9\n9FcXSinu2b0bj1I0xnkSUj0u/IRDF2IRkkclk3tuLmP+OIbVX1zNth9vw+v09l/AOEO74Ag9gUi0\nJLK/e39khekLv/udUZCurQ10lFVM0e718nhtLf+ePJmzc3KiLY4mRim6tgif08e2m7fh3OUk+4xs\nkkcnk3FiBpIw+GdEegZE8AAEgO3N25lcMDmywvSFlBSYMAEWLAhLd9rX76e/uhDgmNRUNnV2hkWe\naKLHhZ+B0EXhtwoZ9+g4HJMd7L53N6vmraJ9dXvYvycW0QYIYx9QMGYWzWRZ9bLICtNXbroJXn45\n2lJoDmL2ihV0eL18V1c/1QRBeRWdWztpeKWB6oeqaf5PM/UL6una3EXZ7WWkHTM0PBraBQcUFQVv\nH5k1kuauZva07qEkoySyQvWW5GQjGWkY6E+9+8FGf3Vxdk4Of923j+9t3sy9I0fGZSXUHvS48NNX\nXdS/XE/zf5sREbr3deOqceHaZxy2fBuOiQ4cEx1kn5ZN8Y3FOCocWBzxHTXZF7QBArZsCd5uSbBw\n6aRLWbBhATfMviGyQmnimntHjeLEjAwuXreOa4cPj2sDpDl6Gl9ppOaxms/f516Yy/hHx5M4PHFI\nGZpQSMxusowQIqLGjlVs2hT8/JlPnck3pnyDyyZfFlnBesuaNXDWWbBpU+isqpqI41OK4k8+4fHx\n4zk1TPWaNLGNz+Xjg8QPjnjdSZ0nYUmOf+MjIiil+hUpodeAjsCull2MzBoZbTFCM2UKzJwJ//xn\ntCXRBOBVii6fjw9aW6MtiiZCiE0Y86cxFFxRQN6X/cUHU6enMl/N//wYDMYnXGgDBJSEWN7Z07qH\nfe37mFk0M7IC9QWPB2pqIAzRVnq/h5/+6sKWkEC3zxf3WRBAj4tADqcLEaHo2iIqHqtg4gsTmfDC\nBLJOzaJzfSefjvyUNWeuYcsNW+jcHP+RkeFCGyBCG6DKnZWcNuo0EiSG1dTeDitWwFVXRVsSTQCL\nWlvp8vm4oqAg2qJoooDP5SN1cioZczPwOX0oj8Ln9qG6FcoztJc9AtFBCEBWiLLr6+vXMylvUmSF\n6SuZmXDyyfDgg3Dzzf3qSkc6+emvLmakpZFqsdA1CIrQ6XHh50i66NjYwdKKpQAkjUwieUwyU96e\nQvapeh0wGNoAEXwfUG17LY+uepSXvvJS5AXqK0VFoXfTaqJCu9dLApAUp0XoNL3D3eRm3z/20fRW\nE84dTrp3d39+btbmWUMyv1tf0P87CF7RelfrLkoySphTMifyAvWV2bNhyZIjX3cEtK/fT3904fL5\n+MOePbiVwjMIokz1uPBzsC6qH65m+4+3072rm4wTMhh570gqnqlgysIptK1so2t7F55WT+yWdIky\negZE8H2cbd1tJFuTIy/M0TB5Mvz619GWQmPyWE0Nd+7ezbMTJlCi9/8Masp+XkbO2Tk0v9OMu8lN\n19Yu9i/Zj6fRg7vJTfsKI6XO+MfHU3h5YZSljT30PiARddVVioceOrC9pr2GCQ9OoPqmapKsMf4j\nct11hhU9+CY0UcGnFAvq67lmyxbemzqVSamp0RZJEyU+Hf0pzm1OJi6YiL3Aji3fhi3PhjXDGveF\n58KxD0jPgDBKch9Mmj0Nj89Dp7sztg1QTY2xByhUOgdNxEkQ4eL8fJa0tfHdzZv5ZPr0aIukiRLT\nKqdR+3gtNY/V4K5346p34a534+vyYcu1Ycu3Yc+zY8uzfX7Y8433SSOSSJs2uHPCaQNEcBecNcFK\nRlIGy6qXcdqo0yIvVG9paTECEJL77y7UOb/89FcXp6xaxcr2dv4walT4hIoSelz46asukoqTKLu1\n7JB2X7fvc2PUc7StbKPxtUbalrR9ft0877xBXZbhiEEIIjJWRN4Rkc/M91NE5BcDL1rkCDYDSrQm\nclHFRby3473IC9QXsrLA5YKurmhLogng49ZWri8q4sK8vCNfrBlyJCQmkFScRNoxaWSdmoW33UvN\nIzVYUiwUfruQEXeNYPLrkwe18YFerAGJyPvAj4G/KKWOMds+U0rF+AaZ3iEi6pJLFM89d+i51ze/\nzp+W/ok3v/Zm5AXrLT//ubEZ9YEHoi2JJoCna2t5vKaGJW1tvDZpEidmZkZbJE0MoryKDd/YQPua\ndia+OBHH+PjJ5xipXHApSqmDY3zDk/8/RghVzeCJNU8wq2hWZIXpK7t2ha0cgyZ8XFZQwMKpU7m9\nrIxL1q/XYbiaA1BK4ap30fpxK42vNZL/lfy4Mj7hojdrQA0iMgpQACLyZWDfgEoVYYK54AAaOxs5\noeSEyArTV26/3QjDvv/+fm9G1b5+P+HQhdPr5am6Om4uKYnriCc9LvwcTheNbzTStaUL5VWfHz6n\nD2+rF0+rB89+D95WL646F84dTsQmJI9MJv+r+Qy/anhkbyRG6I0Buhb4KzBeRKqAHcDXe9O5iDwC\nnAPUKqWmmG1ZwHNAGbATuEQp1Wqe+xnwLYwZ1vVKqbfN9unAY0AS8IZS6gaz3Q48AcwAGoCvKKV2\nm+euAG7FMJx3KqWeCCVnKANks9jo9nYHPxkrrF8PJ52kMyHEIP9qaMACXDV8aP64DCV8bh9rz17b\nq2stqRYcUxwkFieSOi2VrFOysOUMzf+/vd4HJCIOIEEp1XbEi/2fORFoB54IMED3Ao1KqftE5KdA\nllLqFhGZADwFHAcUA/8FxiillIgsBn6glFoqIm8A9yulForI1cBkpdQ1IvIV4EtKqUtNI7cMmA4I\nsByY3mPoDpJRXXihYsGCQ+Uv+UMJb3/9bSryKnp7y5Fn7ly47DKdjDQGeb2xkas3b+bDY46hTG9I\nHZL4XD48zR6693bTXeU/XFUunLuctLzXAsTnRtWI7AMSkUzgcqAcsPa4EpRSPzzSZ5VSH4nIwTGI\n5wPzzNePA5XALcB5wLNKKQ+wU0S2ADNFZBeQppRaan7mCeACYKHZ1+1m+4vAH83XpwNvB8ys3gbO\nwJh5HYLLFVz+2cWz+XD3h7FtgGpr4Zhjoi2FJghr2ttRgD2O3W+a/rHlui3s+2voFQtJFIp/WEzm\nyUMzSKU3QQhvYBiftRgziZ7jaMlXStUCKKVqgHyzvQjYE3BdldlWBOwNaN9rth3wGaWUF2gVkezD\n9BWUUCVbTiw5kdU1q3tzT9Fh2zZoaoLS0rB0p3N++QmHLrp8PpRSDAuWbDCO0OPCT191MfbPY5lT\nP4ey/ykj64tZJDiMn1yxC46pDvIvzqfk5hKSSobmDLk3a0BJSqkfDaAM4QwPOqpHzdWrr+SXvywH\nIDMzk2nTpjF//nwKUgv411v/otLhX3jsGYAx8X7FCioTE2HjRuYPGxZ9eQbR+x76099wu51RmzZR\n6XJF/X76837VqlUxJU80369atapP17//4fv4PD4Sfm0YnsafNJJSkcLpXzudBFsClZWV1K6vZX5+\nbNzf4d5XVlby2GOPAVBeXk446M0+oBsx1nH+DXy+Iq+UaurVFxguuNcC1oA2APOVUrUiUgi8p5Sq\nEJFbjG7VveZ1b2G413b1XGO2XwrMU0pd3XONUmqxiFiAfUqpfPOa+Uqpq8zPPGz2cYgLTkTUWWcp\nXn/9UNmfWfsMCzYs4MVLXuzNrUae3bthxAgjG0La4E7ZEY/cvmMHbzQ18avyck7LzsaiXXFDEp/b\nxwf2Dw5oO279cTgq4jvsOlK54FzAb/BHlGH+HdnL7xAOnJm8ClwJ3AtcAbwS0P6UiPwBw102Glhi\nBiG0ishMYCnGetQDAZ+5AlgMXAy8a7YvBO4UkQwMN+OpGOtMQUkI4YhscbaQkZjRy9uMAg0NRiaE\nQVD2eTBye3k53T4fZ61dy2uTJnFObm60RdIMMPX/qjcyYzeYKXbMv2ITxCpYs6w4Jjqw5Q3NqLeD\n6c0a0E3AaKVUuVJqhHn0yviIyNPAImCsiOwWkW8C9wCnisgm4Avme5RS64HngfUY607XKP/07Frg\nEWAzsEUp9ZbZ/giQawYs3IBpZJRSzcCvMSLhFgP/q5RqCSVnqMmDy+si2RbDJRnKyowY8jBtRD3Y\n/TSUCYcuFjY18UhNDQ+NGcPZOTn9FypK6HHh50i6EKuQYE844HDtc6HcCl+Xj5nrZzL17anYc+2R\nETjG6c0MaCvQeTSdK6UuC3HqiyGuvxu4O0j7cmBykPZu4JIQfT2GsXfoiITKlr+1aSujsmI4meSz\nz8IXvwjp6dGWRBOEapeLBrebNq83rjeianpP7rm55J574Ex387Wbqf5zNQCfjvwUx2QHicMTKftF\nGY4J8e2G6y+9MUAdwCoReY8D14COGIYdL4TyYG1q3MSZY86MrDB9objYWAfq7g5e1rWP9Cw8asKj\ni/NzcvhlYiIz4/wBQY8LP0eji7EPjmXsg2NZffpqmt9upvV9Yzti64etjPr9KGx5NpJHJJNUNvQi\n4XrjgnsZuBPDlRaOMOyYI5QHKyclh8bOxsgK0xdOP93YxPTKK0e+VhNxbt+5k7Oys5mbEcPriJqI\n4ao+cMNh995u1n9lPeu+vI6N39wYJamiyxENkFLq8WBHJISLFE5n8PYp+VNYXRvD+4AaG2HvXjgh\nPPnqtK/fTzh0MS4lhQX19Vy+cSN7Qg2yOECPCz/90UXxj4pJqUjBXmTHkma4Xaa8PYUTG05k2rvT\nwiRhfBHSAInI8+bftSKy5qAjhn+V+05WVvD2qYVTY9sAWSzGDMjcA6SJLX5YXMyKY49lX3c353/2\nGXWhUm5ohgTDvjmMmetnMmfvHE7afxLZZ2Xj6/JFW6yocrgZ0PXm3w3AuQHHecCmAZYronSGCLHI\nS8mjqatX252iQ2GhYYT27j3ytb1A+/r9hEsXSQkJzExPZ2V7O3u6YzyxbQj0uPATLl00/beJlndb\ncEzSQQhBUUr1JDAarZTaFXhORMYPqFQRxusN3i4idHti/Efjmmvgpz+FZ56JtiSag3ihro6rN2/m\nwrw81h57LJNChVtqBj3Kq2h6q4mGlxtofq+Z7t3dlNxUQvKIGN7mEQEO54K7WkTWAuMOcr/tANZE\nTsSBp709ePuUgilsbNiIxxfDBd9+8Qv4z3+MwnT9RPv6/fRXFy6fj6s2b+btqVP567hxcW189Ljw\nc7S6qP5rNRu+sYGUihQmvTyJuc65jLy7t3v5By+HC8N+GngTY19OYBaBtt6m4YkXQkUwv775dUZn\nj8aa0Jto9SiRnGyE8e3YYWxM1cQEVd3d7Pd6mZCSEm1RNDHAlmu2ALDn93uoebQGa7YVW7YNa5YV\na7YVe76d4uuLSUjsTWDy4KHX9YAGKyKivvY1xT//eei5a16/htHZo/nR8QOZizUM3HoriMAdd0Rb\nEo3JqrY25q9axRWFhdxUUkKprgc0pFFK4e3w4mn24Gny4G5242ny4Gn2UPNYDa0ftTJj5QzSpsVP\nTsdw5IIbWuY2BKE2qQ9PG86mhjiIt6iqgo8+irYUmgCmpaWxeMYMGtxu7gqDe1QT34gI1lQrSSVJ\npE5NJWt+FrkX5GIfZqf1I2NjauKw+C7bcTRoA0RoA6SUIiMpxjcRtrbC44/D9dcf+dojoH39fsK1\nD+iW0lIWNDTwYFVV/4WKEnpc+AmnLtwNbrbfsh2AhOQEGv/diLcjRETUIEUbIEIboFW1q5hSMCWy\nwvQFpeDMM+Hb34bzzou2NJogTE5N5eNjjuH2HTuiLYomxrDn2zluzXGc0HgCFf+sYO//7WXteWvp\nro7xyNswoteARNTllyseD5Lb4Ya3bqAkvYSb5twUecF6g9NpBCG0tYXOqKqJOkopkj74gHXHHcdo\nHZQw5PB2eGl+r5mOzzrwtnnx7vfiafPg3e/F2+bFs9+Dt81L5+ZOMCdAJ+4/EWtaDAc/Ebl6QIOe\nUDOgMdljWFu3NrLC9IXXXweHA2y6tkgsIyL8oqyMMUuW8OyECXwlP//IH9IMClo+bGHV3FVkzs8k\n7bg0rBlW7IVGKh5ruvWAv5Z0C9Y0K5ZUC2IZGtnTtQvuMIzJGcPmxs3RFiM0p51mhF6/GJ6KrdrX\n7yfcurhq+HAAzsjODmu/kUCPCz991cXO/91J2W1lTHtvGqPuG0XZrWUUX1fMsCuHkXdhHtmnZpM+\nKx3HBAdJxUlYM6xDxviANkCAUdMtGGOyx7C1aWtkhekLVit0dEBNTbQl0RyBHWYy0m9v3EhbmAoI\namIbd4ublndaSDs2fkKrI41eAxJRX/qS4qWXDj3X3NVM6f+V0vDjBhKtMRgiWVVlzIDeew9OOina\n0miOwNbOTk5fs4aflpbyPXNGpIlvlFfhbnTjqnHhqnV9/te5w0n9C/VYHBZm75gdbTEHBL0GFCZC\nLaEkiDFB7PJ0xaYBKioyagHNnWsktEvQE9pYZGtnJw9VV/OPmhouys3lory8aIukOUqUUux7ZB+t\nH7bSvqKdzk2dWDOs2Aps2Avt2Avs2AvtJI9OZup/puKYMrSTjR4JbYAwvFjB8Pg8KKVwe0P46GKB\nL3wBhg+HxYvh+OP71VVlZaXOfGzSX100uFw8WF3Ngvp66lwuLs7PZ9PMmeTb7eETMkLoceHn9T+9\nTuoPU0lISqDoB0VMXDCR5DHJuuT6UaIfmYG6uuDt1gQrHp+HrOQQBYNigaQkKCkxcsFpYoZ1nZ08\nVFVFo9vNe9Om8ccxY+LS+GgOxDHRQcUzFaQdl8ae3+5hybglfFLyCbXP1kZbtLhEGyBCl2P4ZO8n\nzCmZE9vJSLduhc2b4ayz+t2Vfsr1019dzMvMZM/xx/Oz0lJOXLmSS9etoyvUQItx9Ljwc/IpJ9Py\nXgudG/xFxFz7XEO+sNzRog0QobNhd3u6cdhj3Ie7dy+UlkJmZrQl0RyELSGB07KzafF4eK6+nsqW\nlmiLpAkD4/4yjhPqT+DE/Sdy7NpjGX7VcGr+UUPts7W0ftpKd003Qz24q7doA4Tx+x2Myp2VTCuI\n8VrtOTnQ0BA6lrwP6P0efsKlC4sIFhGsIpyUEeN5BUOgx4WfQF1Y06ykTkql5EclpM9Op+GlBrb+\ncCvLpizj/YT3aVvZpg3REdAGCMjNDd6+bN8yJuZPjKwwfWXCBGhuDh1JoYkqo5KT6Z47l1ybjZ3m\nXiDN4CJpZBJl/1PGyPtGMvahsVQ8WQEJsHz6ct5PeB9Pm973FYoYXtyIHHv2BG/PTs6mqSvGa+89\n/TRMmxYWF5z29fsJpy5c5lPwPbt3888JE8LWb6TQ48LP/PnzaXyzkbVnGSm6xGpEvyUkJfiLzOVY\nGX7VcFKPSSV1cmrM53SLJlozQFMIGzO1YCpbGrdEVpijISuGo/Q0JCYksHP2bKYvW8aVGzbwWEVF\ntEXS9IO049LI/2o+dc/UkXthLhVPVAy5SqbhQmsNaGwM3i4I3d4YT41eVQVhSm6pff1+wq2LXU4n\nqRYLxaEiXmIYPS78VFZWYs+1M+HpCeSck0PDSw18UvYJSyYtYdXJq1g+azmLihex7ivroi1qXKBn\nQIROIGCz2HB64sBvr1P8xyxKKb6zaROvNzZyeWEhvywvj7ZImjAx+bXJ+Fw+3I1u3PVulk1d9vm5\n+ufraf9FO8ljkrEkWaIoZWyjc8GJqJNPVrz77qHnrn/zehx2B3d94a7IC9Zb1qyBCy6AbdtC15XQ\nRAWlFK83NnL1li1smjmTFIv+IRrMuFvc7P9kP/sX7ad9TTtdm7vo2tGFvdBO6uRUUqenknZsGjln\n5QyKjNc6F1yYCBWcVNNRw4UlF0ZWmL4yeTK4XPDZZ8ZrTUzwUFUVd+7aRWJCAg+PHauNzxDAlmkj\n58wccs7M+bzN5/Hh3OmkY00HbSva+Oy8zyi+qZiyn5dhy9Z1vPQaENDVFbw9xZZCizPGNw+KwDHH\nGBmx+4n29fvpjy6era3lmi1beHPKFLbOmsXZOTlH/lAMo8eFn77qIsGaQMroFPIuzGPkHSOZsWwG\nbUva2HJdHAQ3RQBtgAi9hOL2umM/yeDWrfDRR3DppdGWRGMyOjmZUUlJnP/ZZ9y4dSsb9R4tjUna\njDTyLs4jIUn/9II2QIelpr2G8szyaItxeC65BG68MSyRcHq/h5/+6OLY9HS2zJrFK5MmYUtIYOLS\npUNp++wAACAASURBVCxvawufcBFGjws/fdWFUgpPm4eunV20rWij6T9N7P90P/YCnZgW9BrQYWlz\ntSHE+Azommvgb3+D226LtiSaAESEiQ4Ha9vb+UZBAdNSU6MtkmYA8Xl8uOuNwnS1/6yl6c0m3E1u\nPE0exC7Ysm3YcmxYs63Y8+0Mv1oXJARtgA5LYWohDZ0N0Rbj8Pz3v6Er6vURXffFTzh0saq9nYXN\nzeyZPRtLrLtyD4MeF356dNG2so3l05d/3i5WwZpjxV5oJ+OEDCY8MwFbvg1btk1vUj0M2gABoSLR\nHTZH7AchLFwIK1dGWwpNECY5HNxUXMzEpUuZnpbGPSNHMis9PdpiafpJzZM17Htk3+fvxSqc1HUS\nCVZtaPqK3gckoo4/XrFo0aHn/r353/z8nZ+z5uo1kRest+TlGQaouDjakmhC0OX1ctfu3dyxaxdN\nJ5xAVphmrJro8H7i+yiXYuS9Iym6tgiLY2iG2Ot9QAOMw+YgPTGGn1g9HtA1ZmKejZ2d3LFrFzNS\nU/EM8Qe+wcCc2jnUP1fPvkf3see3e0idnopjkgPHJAeZczNJHpkcbRHjBj1nPAw2iw2viuEqllYr\n3HILfPvboXfT9gG938NPOHXRs/5zW3k5eXFYlluPCz+VlZXYMm0M//5wZnw6gxnLZlB0bREAu+7Y\nxeJRi1k8fjGueleUJY0P9AzoMJRmlLK7dXe0xTg8l1wC994LGzYYG1I1McW2ri6+9NlnfC0/nxPj\ntCCd5lBcdS4WFRzqt7fl2cg+PZuubV14mjwkFicOWRddb9AGiNDFRH3KhzUhxlX04ovg80EYklzq\nSCc//dWFTyk+bm3lhq1b+UFRETeWlIRHsCigx4WfHl1YM6wU31SMd78Xa4bxG+Fp9eBucFO/oJ6q\nB6oAyDk/h8kv6xRZoYjxX9fIsH9/8Ha7xR772bBvv93IhvDww/Czn0VbmiFPh9fLL3bs4Pm6OnJt\nNr5RUMANOkBkUOFp9bDv7/sQEXxOH+2723HXunHVuXA3uEkqTSL3wlxSp6VSdF1RtMWNabQBAtLS\ngrcXphbS1NVEt6ebRGuM1nFJSDACEcJQEVXv9/BztLro9HrZ1NlJtcvFf6dOpcLhCL9wEUaPCz+V\nlZVMk2lsu3kbALZ8GxknZVB8QzGOSQ7seXa976cPaE0BoVzzXp8XpRR2S4wvHO/fD+PGRVsKDZBn\nt/PGlClMS01lRxgCQzSxR8bcDI5deywTX5xI8fXF7F+0n7ZlbSQVJ2nj00e0tghtgJqdzWQlZ8V+\nQtJJk2DZsiNfdwT0U66f/urijOxszl67FqmsjPtkpHpc+Jk/fz7de7pxN7jx7Pfgc/qwOCz4OnzR\nFi0u0S44INTmdJfXFfu54AAqKmDx4mhLoQnggtxc7t+7l2PT0iiIw9BrTXA6NnSwbOoylNvYz5Vx\nUgalPyul4PKCKEsWn+gZEKFTqWUnZ7O/O0SEQizx0ktGOHY/0fs9/PRXF4kipFssXJibS2Komu9x\ngh4Xfj7d/inps/xPrK0ftrLtx9ti30sSo0Ttf4aI7BSR1SKyUv6/vXMPj6us9v9nZTKXzOTWpGnS\nS3qh94bStLVQKdBiFYogKIqiqFx/DypHRfEUOP5EzqOAnMfLUTkcf0exoCAiqFyEA4UCtlxaCm3a\n0PSStrRN0jRJ01wnc5/398feaYY007TJJHsu7+d55pl3v3vPztore/Z39trvu5bIO2bfGBFZKyK7\nReQlESmI2f5OEakVkZ0iclFM/yIR2S4ie0TkP2P6HSLyZ/Mzb4vI5Hi2NDcP3N/ub2dMzphEHO7I\n4vfDkSNWW6GJoTIvj/ULF7K2rQ3Phg3UpHgYTmMQ8UXoeKPjQ33hY2H+mf1Paq6psciqFEYpZckL\n2A+M6dd3P7DabN8O/MRszwO2YoQMpwJ76ctjtwlYYrZfAC42218HHjTbXwD+HMcOtWSJGpCndjyl\nVjy8YuCVycTzzys1Z47VVmji8NWaGsVrr6nnWlqsNkWTYKLRqNpywRb1Gq+pPd/eY7U5o4ohH8PT\nAStjA8KJd2BXAI+Y7UeAT5vtyzEEJKyUOgDUAmeLSBmQp5TabG73h5jPxO7rKWBlPENy4qRuer/5\nfRaULjjFw7GQFSugoUHnhUtSHpk7l8LsbPKz9SPXdKL5qWY2zdxEoD5A+epyJn5Dz/k5XawUIAW8\nLCKbReQms69UKdUEoJQ6AvSW+ZwI1MV8tsHsmwjUx/TXm30f+oxSKgK0i0jRQIbMnDmwgW/UvcHi\n8YtP76iswOmE3FxoahrWbnSsv49E+eKvLS1ctG0b7eEwjhR9TqDPiz5ifeEqd0EUCs4r4Iz7zsA9\ny22dYSmKlT/JlimlGkWkBFgrIrsxRCmWRKYOjvvtX7/+Ou6+eyoAhYWFVFZWsmLFCj4/7/OseXoN\n5W3lx4ei9p6ASbW8eTMrPB6YPTs57EmD5V6Gu79/efJJLikqov1zn6MgOztpju90lquqqpLKHiuX\nq6qqji/nn5PPzgk76XmxhznMSQr7RnL59ddf5+GHHwZgagJSf0GS1AMSkR8C3cBNwAqlVJMZXntN\nKTVXRO7AiDfeb27/IvBD4GDvNmb/1cBypdTXe7dRSm0SERvQqJQaN8DfVl/5iuIPfzjRrl1Hd3HZ\nny5j77f2jshxJ4ybb4ZZs+C226y2RNOPm3fvZqLTyV0J+sJqkoutF2yle3s35+w9B3uxPaNGwyWi\nHpAlITgRcYtIrtn2ABcB1cCzwHXmZtcCz5jtZ4GrzZFt04AZwDtmmK5DRM4W4z//1X6fudZsXwW8\nGs+ecHjg/skFk6nrrCMZRDouwSA8+yx8/ONWW6Lpx/OtrTzV0sKXS/UckXQlb3Ee9jF23ip5iw15\nG9g0ZxPVn6omGtATU08Fq0JwpcDfRUSZNjymlForIu8CfxGRGzDubj4PoJSqEZG/ADVACPiG6lOF\nW4CHARfwglLqRbP/IeCPIlILtAJXxzMmXjbs7mA3HrsnuX/VRKPQ2goTh/8A9HWd8+s4w/WFLxLh\nsupqHpg5kzPijXJJETL9vAh3hQkeDhI8EuTVda+ypGgJwSNB/Af8eKu9BI8Ecc9x45nvwTPfQ97i\nPMSRxNeMJMISAVJKfQBUDtB/DBjwp7xS6j7gvgH63wNOyHeulApgCthgBOPUjvKH/bjtSf5g0eWC\n73wHPvlJIxtCMotlBrG7pweAn9fVcUsCfhxorCHcFWbj5I2E240wySEOUUQR2YXZFK4oZPLqyRRf\nVoy9WJdZHwpJ8QzISkREffzjipdfPnHdpvpNXP/M9dTckuQTzKJRWLAAHngAli+32hoN8HhTE3cd\nOMCWxYvJ08OvUxoVVQSbgwTqAgTqAwTqAvgP+fHv8+Pb68P7vpfswmw+evij2HIyp/hcyj4DSjbi\nTVJ/Zf8rXDz94tE1ZihkZcF55xkpeTRJwedKSsgCLt6+3WpTNMNEsgRnmZP8JfmUfKaESd+axIyf\nzuDMv5+Ja5oLgJwZOUR9+rnP6aIFCOMGIh52W4rcWpeXG4MR4o2oOAX6D0HOZIbri2/U1gLwo2nT\nEmCNtejzoo/+vii7oQxxCPOfn4+9KEWuFUmEFiCgrGzgfrfdTSAcGF1jhsqaNfDEE6DDPUnBGx0d\n/LWigpVjUiCXoGbI5C3MQwUVe762h4g/YrU5KYcWIOJfs0s8JTR2N46uMUOlogLefHNYu8jkkU79\nGY4vokrhi6TPxUifF33094Vrioulh5Zy9O9H6dnVY41RKYwWIMAW57nhzpadzCuZN7rGDJXLL4cX\nXjh5PFEzKqxvb8cfjVKRBuW4NSenp7aHjVM2MvbTY3FOcFptTsqhBYj4AtTqa03+cty9fOlLRjLS\nNWuGvAsd6+9jqL7Y7/NxSXU103Nyknv+2Gmgz4s++vvCu8MLCmY+OBPHuBS5ViQRWoAAn2/g/lUz\nVvHSvpdG15ih0tNj1AXSc04sZbLTyX+ccQZvdXby7NGjhPUdaVrT8kQLALuu20W4e+gDgDIVLUAn\nwSY27FkpMrLlyiuNsgwXXTTopvHQsf4+huqL7KwsvjlpEn+aO5cfHTzI+VVVBFNchPR50UesL3p2\n99D852ayPFkUXVSUUXOAEoUWICDeXFy7zU4wEidNQjLR2AibN8M99xhzgjSW88XSUtaedRYbOzuJ\nZvhk73TFlmej6NIiVFix73v7OPQfh6w2KeXQV6uTsHzKcrYe2Uq7P8kLvbW1GYMPhvnQW8f6+0iE\nL9w2G66srITWFLECfV708dzPnqP2W7VsXrCZTdM30fVOF7ln5ZJ/bj7OiXoQwumiJ42chBx7DuM8\n4zjSfYRCV6HV5sRn4kRDfGpqYP4JafE0FtE7FHt3Tw+VeXkWW6MZKp2bO+l6rwtvtZd9D+6j4vsV\nzP6f2XjO9GDz6LDbcNC54ETU+ecr1q8/cV04Gsb1Yxfef/PizE7yXzfLl8Pdd8OFF1ptiSaG1fv2\nsamzk38uXGi1KZohEA1E2bJsC95tXlRY4ZjoYOn+pWQ5dPBI54JLEEePDty/tXEr04umJ7/4AAQC\n8etKaCzjU8XF+FJ8EEKmU7iikPxz8wEINgSJBvX/M1FoAcK4dg/EB+0fMK0wBXJ5ffABvPMOzBve\npFkd6+8jUb7oiUbJizfRLEXI5PMi2BSk/mf1TL5zMkvrlqJeVWTn6icXiUJ7kvi54IDkrwcE0NQE\nOudYUuIUoVXfmaYUofYQLU+00PFGB8fWHqN8dTnFq4oBkL3pMbk4WdACBDjiTGDOdeSy6+guAuFA\ncofhli6FlSvhpZfgxhuHvBs936OPRPhie3c33967N+UL0mXCeeE/6Kdzcyc9O3to+kMTEV+Eaf8+\njSk/nIJ7Rt+P0EzwxWiiQ3DET0Z6yYxL8Dg8bDi0YXQNGgqlpdDRYbUVGpNjoRAXVlVxVUkJN40f\nb7U5mkHYfsl2aq6qoemxJspXl7P4ncWMv3H8h8RHk3i0ABG/JLeIYM+y48p2ja5BQ+HSS+H3vx9W\nMtJMjvX3Zzi+iCrF53bsYFVREd+fMoWsFM8JlwnnxcI3FzL+pvH4dvvo3tIdN7FoJvhiNNEhOOLn\ngmvqbmLX0V2cOe7M0TVoKKxcCYcPw/btUFlptTUZzb0HD3LQ7+epioq0SUiabvTs7qH+1/UE6gN4\nt3sJNgXxzPNQdkMZJVeVWG1exqAFiPghuPca3+MjEz6S3JNQe1m7FqZNg7POGvIudHy7j+H4YkFu\nLm3hcNoMv06n8yLij+Db46P2W7V0/LOD2b+fzfT7p5MzIwexDf5jIZ18kQxoASJ+Fet8Zz6tvtbR\nNWaoVFZCXR1UV8OCBVZbk7GEolG6IhHCSpGt736Shj1f38Ph3xwGwD3XTd7ZeUy9aypjPqZHj1qJ\nfgZE/HlAuY7c5M8D18vEiXDNNfDAA0PehY5v9zEUX7SFQnxtzx6+t28fj86dS2m84ZUpRjqcF6Vf\nLcU9xxhQsGDdAuY+PHdI4pMOvkgm9B0Q8RNIV5RUcKT7CK09rRS7i0fXqKHwpS/B2WfDr34FOTlW\nW5NxnL1lC3t9Pt5fskRXQ00yCj5awPibx+N934tzfBJPqcgw9B0Q4IozyM1us/PZuZ/lserHRteg\noTJmDNjt8Sc2DYKOb/cxFF8sLyjgmnHj0k580uW8aHmiBffs4Q2rThdfJAtagICxY+OvW1i2kNrW\n2tEzZjj87GewenX8GuOaEaUxGOS8ggKrzdDEYeI3J9L8eLPVZmhi0AJE/DsgAFe2i+5Q9+gZMxzK\nyuDJJ+HIkSF9XMe3+zhdX3SEw9T6fNTFe6CYwqTLeVG0qgjf/jhzLk6RdPFFsqAFiPgTUQEqxlVQ\n01IzesYMh7vugiuugNtvt9qSjGP1vn0sLyzkx9NSIHlthtG5qZNtq7axadYmnJP0859kQg9CIH5J\nbgCbpFA4SwRuvRUqKoyDOs1hwDq+3cfp+OK/Ghp48dgxti9ZkpYTT1PlvIj4IwQPBwnUBwg0BAgc\nCtD1bhctT7VQcEEBS7YviZvh4FRJFV+kClqABuGs0rPYe2wve1r3MKt4ltXmDM6ECUZ11F27YO5c\nq61Je15ra+Oegwd5e9EiCuLNaNaMKNFglPXOvoqSveWxnZOcFF9RzBn3n4FrmistfxykOjoENwh5\nzjycNifZWSl0cZkyBQ4ePO2P6fh2H6fqi509PZQ5HIyz20fWIAtJ1vMi0BCg+alm6n9ZT8F5xuCP\n/HPzWfTmIir+UsGMn8+g7Mtl5JyRkzDxSVZfpCpagIC8vJOvL3YX09jVODrGJIILLoAvfAG2bbPa\nkrSmORjkltpadvf0UJ+Ggw+SEaUUgYYADb9p4L0l79H0aBPBxiAlXyhh/j/mM/8f8602UXMapNDP\n+pFjsB+vk/In0didQgJ0333w17+ednkGHd/u41R8saWrC4DvTJrETHf6pu234rwItYboruqmu6ob\n704vgYMB/Af9BOoC2HJtFK4sZM4f5lD08aJRtUt/RxKLFiDi54LrpcPfQYEzxeZ3lJWBeYHUjAy7\nenoA+GVDA3dOmYJHz79KCF1bu3hv0XvHl7NcWZTdUMaMX83ANdmFzaP9nC7oEBxQNMiPqBlFM9jR\nsmN0jEkUN98M//qvJx/i1w8d3+7jZL5QSnHHvn38tK6O/zdrFnvPOSetxWckz4toOErzk80cvPcg\nu2/ezbaLt1FzdQ1iF+wldvKW5FH8qWJyK3PxzPVYLj76O5JY9B0Qg1+jr6u8jtUvr+bWpbeOjkGJ\n4BOfgK9/HSKR+PUmNEMipBT319Xxt4oKPlOia8cMh5anWtj5xZ3Y8m1M+cEUxn56LK6pLn2nkyHo\nKxPg9598/dGeo4zPS7Gyyh6PEVsMBk9ZgHR8u4+T+eLJlhZybTbGp0m268EYyfNizMoxkAWRzgie\nMz0Ur0rupL/6O5JYdAiOwQUoOyubUCQ0OsYkCo8HrrwSrr32tMJwmpPz3b17+XZtLW8vXMhSnfdt\nWHh3etl1/S5KPlvCstZlSS8+msSjBQhoHaTmnNvuJhRNMQECeOghePddo0z3KaDj233098WxUIg7\n9u3jF/X1PDd/Pmfm5lpjmAUk6rxQStHwYAM1X6xh4/SNbFu5DU+FhzmPzMFelBrzqPR3JLHoEByD\nC1C+M5/uYIokJI3F6YSLL4Z77oFHHx1ymYZMJqoUv21s5J6DB1lVVMTOJUuYk2blFkaaYEuQtnVt\n+Pf7+eD7HxzvP7/7fP2cJ8MRleHhGRFRc+cqak6Sb7TN18a0X06j7jt15DkHmbWabPj9RqG6w4fh\nlVcgg365J4Kf19XxWFMTv545k3N1yO2UiAaiBBoCdG7s5OjTR2l7uY3CFYXkzMzBNc11fJCBp0IL\neSojIiilhpViQguQiJozR7Fz58m3O3/N+dyx7A4unXXp6BiWSJSCG26AtjZ4/HFdLXUQusJh1rW1\n8fTRo/yjtZVXKys5Swv3gPTs7qHlby10vdNFoD6Av85P+FgYx3gHuZW5jL18LGM/MzZlQmyaU0cL\nUAIQEVVWpmgcJNHBmq1r+MmbP+G5Lz6XGklJ++P3w1e+YoyM+9vfBsyU/frrr2f0KJ8PfD7uPnCA\nZ44eZcbu3Vxz8cVcW1ZGURrneTsV1r24jnNnn0vwSPD4y3/AT+vzrYSPhRl75VgKlxfimuzCWe7E\nUepAbOmZ+DPTvyOxJEKA9DMgjIQBHR1wsgjL9QuvpzPQybLfL+PBTz7IVRVXjZ6BicDlMp4DffSj\ncNNN8POfn/yA0xylFNu9Xl5ra2O710u110ttTw+3lZdTe8457IhEWFFebrWZo06oNUTnO510buqk\na1MXnZs7qe6sxj3BjaPMcfzlnOhk9v/MJn9pPpKVnmKjGXn0HZCImjpV8eKLMHv24Nvfs/4efrT+\nR7x5w5ssnrB45A1MNJ2dRtnuF1+E5583agdlCEopnm1t5bmjR/nfY8fIycriE0VFVObmMt/j4UyP\nh/wMmrQb7gzjrfHS9W6XITYbOwk2Bcn7SB755+STd04e+Wfn4xjv0KUMNCegQ3AJQETUlVcqrrwS\nrrlm8O07A538bsvv+OlbP+WyWZdx38r7KHan4PyFRx81itfdeSd897unXbwulQhGo7zS1sbP6upo\nC4e5tqyMTxYVpXUCUaUU4Y4wwYaYAm315qsugHenl1BLCPdcN3mL+gTHM9eTtuEzTWLRAnQKiMgq\n4D8x5jw9pJS6v9969YtfKHbtgt/85tT32+Hv4Aev/YC/7PgL9668l+sqryNLUmxa1cGD8JnPQGUl\n/Pa3vL5hQ8rHt5VSHAkG2drdzZauLt7q7OSNjg7mud3cNH4815aVYc8a/P+UzLH+iM+s/HnYEJbe\ndrDhw31iF5wTjMJsvS/HRAfOSU7cc9zkTMs5JbFJZl+MNtoXfehnQIMgIlnAA8BK4DCwWUSeUUrt\nit1u/HhYt+709l3gKuBXl/yK6yqv45YXbuHOdXfysWkfY+nEpcweO5vZxbOZXDAZW1YSz3OYMgU2\nbIBLL4XbbqNq6tSU+XL1Ck1NTw81Xi87vN7jbQUsystjUW4uN5SV8ce5cyk+zYEEVVVVlvhCRRSB\n+gC+fT58+334P/CfIDYRbwTnBCeOCcazmN73vIV5hsCY67JzE/P1tsoXyYj2RWJJawECzgZqlVIH\nAUTkz8AVwIcE6Nxz4fbb4YknjDpup8Oi8Yt4+8a3OdB+gHX717GlcQvP7XmOPa17aOlpYfqY6cwq\nnsXs4tnMKJpBsbuYQlchBc4CCl2FFLoKyXfmWydUHg88/TRMn0771VdbYwMQikbpCIdpj3m1hcMc\nC4dpCgZpDgZpCoWOtxuDQRxZWVS43cwzn998ftw45rndlDqG/8yivb19WJ9XUUXEGyHSGSHcGSbS\nZb6by6GWEKHmEMGWoPHe3PduH2sn54wccqbn4JrqIn+ZWWJ6gnEHYy+2j+ozmeH6Ip3Qvkgs6S5A\nE4G6mOV6DFH6EOXl8NhjRuq0//5vY7m8HCZNMt7z8owkAnZ7/FeBYypfmHUjX664EbsdsrLAG/Sy\n99hedrfuZk/rHjYc2kCbv412fzsd/g7a/e20+9vpCnaR68g9QZhiX7H9Y3LGMCl/EuX55eTYEzCn\np7AQbrsNHnkEolHD+ATgjUT4wOfjUCBAUzBovEwRaQoGaQ6FaAuFaA+H8UejFGRnU5idzRjzvTA7\nmzF2O6V2O7Pdbi4wS1+XOhyUOhxxh0erqCIaiqLCChVSxnt44L7+7WgoStQXxfu+l8Y1jUR9USI9\nEaI95rsv+qF277qoL0qkO0K4yxCZiDeCzW3DlmfDlm8jOz/beM8z3u0ldhzjHLjnuXGMc2AfZzf6\nyhzYXEl816zRJJB0F6BTZtky2LHDSJtWV2e8tm0zBop1dxtJpUOhgV8DrcvKArvdg92+AIdjwYCi\nNcYOpQ7ItkeQnC7E1Q6udm6/u52wrU+g2v3t1HfW837L+7T72znmO0Z9Zz0NnQ3kOnKZXDCZhWUL\neeiKh4bugFtv5cC990J1NSxYMOTdPHrkCA8ePsx+n4+OSIRpLheTnc7jojHJ6WRxbi6lDgfjHI7j\nYpNns3HgrgN0vdsVIxZBVChwglh0hBXtoX6iErOeKEi2IHb58Hu/dpY9a8D1NreNPdV7aM9tx+a2\nkeXOwpZjI7sgG9t4G1k5WUaf22gf38YdIza5trR5mH/gwAGrTUgatC8SS1oPQhCRpcDdSqlV5vId\ngIodiCAi6esAjUajGUH0KLiTICI2YDfGIIRG4B3gi0qpQRLvaDQajWakSesQnFIqIiL/Aqylbxi2\nFh+NRqNJAtL6Dkij0Wg0yUuKzZxMLCKySkR2icgeEbndantGGhF5SESaRGR7TN8YEVkrIrtF5CUR\nKYhZd6eI1IrIThG5yBqrRwYRmSQir4rIDhGpFpFvmf0Z5w8RcYrIJhHZavrih2Z/xvkCjPmDIrJF\nRJ41lzPSDwAickBEtpnnxjtmX+L8oZTKyBeG+O4FpgB2oAqYY7VdI3zM5wGVwPaYvvuB1Wb7duAn\nZnsesBUjTDvV9JVYfQwJ9EUZUGm2czGeFc7JYH+4zXcbsBFjukKm+uI7wKPAs+ZyRvrBPMb9wJh+\nfQnzRybfAR2fpKqUCgG9k1TTFqXUG0Bbv+4rgEfM9iPAp8325cCflVJhpdQBoJYB5lClKkqpI0qp\nKrPdDewEJpG5/ugxm06MC4giA30hIpOATwK/i+nOOD/EIJwYKUuYPzJZgAaapDrRIlusZJxSqgmM\nizIwzuzv758G0tQ/IjIV485wI1Caif4ww05bgSPAy0qpzWSmL34B/CuGAPeSiX7oRQEvi8hmEbnJ\n7EuYP9J6FJxmSGTUqBQRyQWeAr6tlOoeYF5YRvhDKRUFFopIPvB3EangxGNPa1+IyKVAk1KqSkRW\nnGTTtPZDP5YppRpFpARYKyK7SeB5kcl3QA3A5JjlSWZfptEkIqUAIlIGNJv9DUBsRba084+IZGOI\nzx+VUs+Y3RnrDwClVCfwOrCKzPPFMuByEdkPPA58TET+CBzJMD8cRynVaL63AE9jhNQSdl5ksgBt\nBmaIyBQRcQBXA89abNNoIOarl2eB68z2tcAzMf1Xi4hDRKYBMzAm8qYTvwdqlFK/jOnLOH+IyNje\nkUwikgN8AuOZWEb5Qin1b0qpyUqpMzCuB68qpb4CPEcG+aEXEXGbEQJExANcBFSTyPPC6lEWFo/w\nWIUx+qkWuMNqe0bheP+EUZYiABwCrgfGAK+YflgLFMZsfyfGSJadwEVW259gXywDIhijH7cCW8zz\noSjT/AHMN4+/CtgOfN/szzhfxBzfcvpGwWWkH4BpMd+P6t5rZCL9oSeiajQajcYSMjkEp9FoNBoL\n0QKk0Wg0GkvQAqTRaDQaS9ACpNFoNBpL0AKk0Wg0GkvQAqTRaDQaS9ACpNGkECKyRkSuNNvf5oVz\negAAAeNJREFUFhFXzLou6yzTaE4fLUAaTepyK+CJWdaT+jQphRYgjWYEEZHvmWXhEZFfiMg6s32h\niDwqIp8QkbdE5F0ReUJE3Ob6H5hF4raLyG8G2O83gQnAq737NLrlxyJSZe6zZJQOU6MZElqANJqR\nZQNwvtleDHhExGb2bQf+L7BSKfUR4D3gNnPbXyulzlFKnQW4zUzNx1FK/RojrdIKpdRKs9sDvKWU\nqjT/7v8ZwePSaIaNFiCNZmR5D1gsInkYOfjeBpZgCJAPo4rkm2Ytnq/Sl6F9pYhsFKN8+oVARZz9\nxyaWDSilXoj5u1MTeSAaTaLR9YA0mhFEKRUWkQMY2YPfxLjruRCYjlHueK1S6prYz4iIE/gvYJFS\n6rCI/BBwMTihmHYE/f3WJDn6DkijGXk2AN8D1gNvAF/DyDC8CVgmItPhePr7mRhio4BWMx3+5+Ls\ntxPIj1mWONtpNEmJFiCNZuTZAJQBbyulmjFCb+uVUkcx7oweF5FtwFvAbKVUB/A7YAfwv3y4pkrs\nSLffAi/GDELQo+A0KYUux6DRaDQaS9B3QBqNRqOxBC1AGo1Go7EELUAajUajsQQtQBqNRqOxBC1A\nGo1Go7EELUAajUajsQQtQBqNRqOxBC1AGo1Go7GE/w/2W5seaHv01wAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\ndOrUqVnLeuihh7j22mtZvXo1X//617n77rvp3Llzg2PHjRvH1KlTWbRoEddddx3jxo2rf62yspJv\nf/vbzJ07l5UrV5LL5ejTp0+zsoSgYiIi9ZpzeHtLpHkSbp2tW7fi7s0+qumFF15g8ODBXHfdddx9\n9910796d5cuXc9ddd/Haa69x4oknFrysBQsW8J3vfIfp06dz9NFHc+mll3LZZZfx29/+tsHxhxxy\nCD/72c+44447PvVaq1atGDJkCNdeey3HH398s36mkLSbKyXqmYSjnLumm2++md69e9OxY0cOP/xw\nnn32WZ566iluuOEGfve739GhQweOPvpoACZPnswRRxxBx44dOfjgg/nNb35Tv5znnnuOAw88kEmT\nJrHffvsxYsQITj/9dP7xj3/QoUMHOnbsSGVlZZN5xowZwyWXXMLVV19N9+7dAejduzfjx49vViGB\naKvkzDPPZODAgbRr147/+I//YMqUKWzcuLHB8RdeeCGDBw+mffv2n3qtR48efOc73+GLX/xiqod6\nq5iISMlZvHgxv/rVr3jllVdYv349Tz31FGVlZQwePJhrr72W8847jw0bNjBv3jwAevbsyRNPPMH6\n9eu55557+MEPfkBFRUX98iorK1m7di3Lli3jvvvuY/r06ey///5s2LCB9evX06tXL2bPnk3Xrl0b\nzPPRRx8xZ84cvvGNbzSae/bs2XTp0oWuXbvSpUuXbZ537dqVF154AYi2TD7/+c/Xv69///7sueee\nLF68OOlHlxoVk5SoZxKOcu56WrduTXV1NW+88QY1NTX06dOHfv367XD8kCFDKCsrA+CEE07g1FNP\n5fnnn99meddffz1t27Zlzz33bHAZAwcOZM2aNQ2+VlVVRW1tLb169aqfN2bMGLp06UL79u254YYb\n6pdRVVXFmjVrqKqq2ub5mjVr6ndDffjhh5/qsXTs2JENGzY0/eGUKBUTESk5Bx10ELfccgsTJkyg\nZ8+ejBgxotFdUdOnT+e4446jW7dudOnShenTp/PBB5/sSu7evTtt27ZtcZ4uXbrQqlUrVq5cWT/v\n5ptvpqqqimHDhlFTU9Os5bVv357169dvM2/dunV06NChxRnTpmKSEvVMwlHOXdPw4cN5/vnn668f\nNmbMGODTlwOprq7mnHPO4eqrr+b999+nqqqKIUOGbNM/2P49zW2+t2vXji996UtMmTKl0XGzZs2q\n78PkP+rm1R0FduSRR/Laa6/Vv+/tt99my5YtHHrooc3KVUpUTESk5CxevJhnn32W6upq9thjD/be\ne29atYp+XfXs2ZNcLldfLKqrq6murmbfffelVatWTJ8+nRkzZjS6/J49e7J69epPbR00ZtKkSdx9\n991MmjSJ999/H4Dly5fz7rvv1o8ZNGhQfR8m/1E3b+DAgQCcf/75TJs2jdmzZ7Nx40bGjRvH2Wef\nzT777NPgumtqati0aRO1tbVs2bKFzZs3U1tbW//65s2b2bRpEwCbNm1i8+bNBf9coejQ4JSoZxKO\ncobTp0/noh6+26dPw+dRbG/z5s2MHTuWN998k7Zt23L88cfXH6F17rnn8sADD9CtWzf69+/P3Llz\nufXWWzn33HOprq7mjDPOYOjQoY0u/7DDDuNb3/oW/fv3p7a2loULF/LWW29x+umn77DADBw4kJkz\nZzJhwgRuuukmIDqaa+jQoVxxxRXN+BTgiCOO4I477mDEiBGsWbOm/jyTOpdddhlmxu233w7ApZde\nyr333lu/RXXDDTdwzz33cNFFFwGw9957Y2aYGZ/5zGcwM7Zu3dqsTEnpfiYBjRo1oeBj9B944Cwu\nuGBqk+N0PxMplvj+FWnHkJ1sR3/vSe9not1cKVHPJBzlFEmfiomIiCSmYpIS9UzCUU6R9KmYiIhI\nYiomKVHPJBzlFEmfiomIiCSmYpIS9UzCUU6R9KmYiIhIYiomKVHPJBzllKZcfPHF29ydUMLT5VRE\npN64G8exbNWyoi2/T88+TLxmYtGWH0plZSXjxo3jz3/+Mxs2bKBHjx6ceOKJjB07ttkXY6yoqGD0\n6NEsWrSII444gjvvvHObe5nku/jii3nooYfYc8896+8GuW7dumZfmDINKiYpUc8kHOUMZ9mqZZSd\nVVa05eem5oq27FDq7jsycOBAZs+eTVlZGevXr+ePf/wjTz/9dLOKyZYtWzjrrLO46qqruOyyy7jj\njjsYOnQob731Fm3aNPzrd8yYMUycWPoFd3vazSUiJWnlypWcc8459OjRg4MOOojbbrut/rXrr7+e\n8847j5EjR9KxY0c++9nP8uqrr9a/Pm/ePI455hg6derE8OHD66+oW4hf/OIXdOrUifvvv7/+hlsd\nO3Zk5MiRXH755c36GcrLy9m6dStXXnklbdu25YorrsDdmTlzZrOWkwUqJilRzyQc5dz1uDtnnHEG\nRx99NCtXruSZZ57h1ltv5emnn64fM23aNEaMGMG6des444wz6n/Rb9myhWHDhjFy5EjWrFnDueee\ny6OPPrrN8rt06VJ/C93tPfPMMwwbNqzJjI3dnnfSpElAdHvez33uc9u87/Of/zwLFizY4XJvv/12\n9t13X4499tgm759SSlRMRKTkvPzyy3zwwQf8+Mc/pnXr1pSVlTF69Ggefvjh+jGDBg1i8ODBmBkX\nXngh8+fPB2DOnDnU1NRw5ZVX0rp1a84++2yOPfbYbZZfVVVVfwvd7X3wwQfb3J532rRpdOnShY4d\nO3Laaadts4wd3Z736quvBpp/e97vfe97LFmyhH/+859MnDiRUaNGMWfOnGZ8culRzyQl6pmEo5y7\nnqVLl7JixQq6du0KRFsqtbW1nHjiifVj8n/ht2vXrv7mUStXruSAAw7YZnl9+/YteN3dunXb5va8\nZ5xxBlVVVdx11108+OCDzfo5mnt73qOOOqr++ZAhQzj//POZMmUKxx13XLPWmwZtmYhIyTnwwAPp\n378/a9asqf/Gv27dOqZNm9bke/fbbz9WrFixzbxlywo/Qu2UU05h6tSm7zXU2O15626edeSRR9Zv\nMdWZP38+Rx55ZEFZsnTPGRWTlKhnEo5y7noGDBhAhw4dmDRpEps2bWLr1q0sWLCAuXPn7vA9db90\njzvuONq0acNtt91GTU0NU6ZM4aWXXip43VdddRVVVVVceOGFvPPOOwBs2LCBioqKbcY1dnvesWPH\nAtHWaOvWrbntttuorq7ml7/8Ja1ateLkk09ucN2PPvooGzduxN2ZMWMGDz74YJN3jSwV2s0lIvX6\n9OxT1MN3+/TsU9C4Vq1a8ac//YmrrrqKfv36UV1dzWGHHcZPf/rTHb6n7lyMtm3bMmXKFEaPHs1P\nfvITTj/9dM4+++xtxnbo0IEnn3yy/p7s+bp168aLL77Iddddx6BBg/jwww/p2bMngwYN4te//nUz\nftooy9SpU7nkkksYO3Yshx9+OI899lj9YcEPPfQQN954I6+//joAt956K6NHj8bd6devH3feeScn\nnHBCs9aZFt22NyDdtleyJEu7UCQc3bZXRERKlopJStQzCUc5RdKnYiIiIompmKRE55mEo5wi6VMx\nERGRxFRMUqKeSTjKKZI+nWcispvq27dvJu6TIWE159IyzaFikhL1TMJRzpbJ5XJpR5BdiHZziYhI\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def adjacent(n): return neighborhood(n, 1)\n", + " \n", + "show(population, interaction=adjacent)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is still surprising that we still have no efect from restricting trade." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# United States Distribution\n", + "\n", + "We've drawn from mathematical distributions; let's look at the actual distribution of family income in the United States. Each row in the following table is a tuple giving the lower bound and upper bound (in thousands of dollars of income), followed by the cumulative percentage of families in the row or a previous row. The table I got this from actually had \"\\$250,000 or above\" as the final row; I had to cut it off somewhere, and arbitrarily chose \\$300,000." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "USA_table = [ \n", + " (0, 10, 7.63),\n", + " (10, 20, 19.20),\n", + " (20, 30, 30.50),\n", + " (30, 40, 41.08),\n", + " (40, 50, 49.95),\n", + " (50, 60, 57.73),\n", + " (60, 70, 64.56),\n", + " (70, 80, 70.39),\n", + " (80, 90, 75.02),\n", + " (90, 100, 79.02),\n", + " (100, 110, 82.57),\n", + " (110, 120, 85.29),\n", + " (120, 130, 87.60),\n", + " (130, 140, 89.36),\n", + " (140, 150, 90.95),\n", + " (150, 160, 92.52),\n", + " (160, 170, 93.60),\n", + " (170, 180, 94.55),\n", + " (180, 190, 95.23),\n", + " (190, 200, 95.80),\n", + " (200, 250, 97.70),\n", + " (250, 300, 100.0)]\n", + "\n", + "def USA():\n", + " \"Sample from the USA distribution.\"\n", + " p = random.uniform(0, 100)\n", + " for (lo, hi, cum_pct) in USA_table:\n", + " if p <= cum_pct:\n", + " return random.uniform(lo, hi) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what it looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEPCAYAAABRHfM8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XuUVOW55/HvA/EGit0oNyFQokbBxGBOoo54PHg3ORME\nzahRHFuTrInOqIzmRHAUkBAVV7JClicu10zUBpEoSRQxywsa7JyAxlu6idpqMFrdyKHhILRR4Li4\nPPNH7e63mr7tbnZ11e7+fdaqZe1db+16+2fTT+333Rdzd0RERDrTr9gdEBGRdFDBEBGRWFQwREQk\nFhUMERGJRQVDRERiUcEQEZFYCl4wzOxQM/u1mb1tZm+Z2clmVm5mK8zsXTN71swOzWs/08zWRu3P\nLXT/REQknp7Yw/g58JS7jwO+DLwDzACed/djgZXATAAzGw9cDIwDvg7ca2bWA30UEZFOFLRgmNkg\n4B/d/UEAd9/l7h8DFwALo2YLgSnR88nAI1G7LLAWOKmQfRQRkXgKvYdxJLDZzB40sz+b2f81swHA\nMHffCODuDcDQqP1IYF3e+9dH60REpMgKXTA+B3wF+IW7fwXYRm44au/rkej6JCIiJe5zBd7+h8A6\nd38tWv4tuYKx0cyGuftGMxsObIpeXw98Pu/9o6J1LZiZCoyISDe4e7fnhQu6hxENO60zsy9Eq84C\n3gKWAxXRuiuBJ6Lny4FLzWx/MzsSOBp4pZ1t6+HO7Nmzi96HUnkoC2WhLDp+7KtC72EAXA88bGb7\nAe8DVwH9gaVmdjVQR+7IKNy91syWArXATuBaT+Kn7MWy2Wyxu1AylEWgLAJlkZyCFwx3XwN8rY2X\nzm6n/Z3AnQXtVBtmzVpAfX1jp+1Gjy5j7tzpPdAjEZHS0hN7GKlQX99IJjOn03bZbOdtelJFRUWx\nu1AylEWgLAJlkRxL44iPmcUeqYq751BdXcvUqUs7bZfNzqGyck6szxYRKSVmhu/DpHev38OIu+ew\natWUTtuUoqqqKiZNmlTsbpQEZRF0lEUmk6Gurq5nOyQ9asyYMQWZu+n1BUNEWqqrq0vkiBkpXYW6\nopKuVpty+kYdKItAWUghqGCIiEgsKhgpV1VVVewulAxlESgLKQQVDBERiUWT3imnsepAWQRdzSLu\n4efdFfeE1379+vHee+8xduzY5nW333477733Hg899BAAd9xxB7/85S/ZvHkzZWVlTJw4kV/96lct\ntlNRUcHDDz/Mhx9+yLBhw7rU19dee43bb7+d1atXA3DEEUcwdepUfvCDH3DooYd28u6WlixZwi23\n3MJHH33EOeecwwMPPEBZWVmH7/nDH/7AGWecwa233srcuXOb15155pkMHDgQd8fM+MUvfsEVV1zR\npf7sKxUMEYl9+Hl3xT3htb2je5rWL1y4kIcffpiVK1eSyWTYtGkTy5cvb9F2+/btPPbYY5SVlbF4\n8WJuuumm2P188cUXOe+887jtttt44IEHGDJkCB9++CH3338/a9as4fTTT4+9rbfeeovvf//7PP30\n05x44ol873vf45prrmlV3PLt2rWL6dOnc8opp7R6beTIkdTX18f+/ELQkFTKaaw6UBZBWrPo7HDf\n1157jfPOO49MJgPA0KFD+e53v9uizW9+8xvKy8uZNWsWlZWVXfr8m2++me985zv88Ic/ZMiQIQCM\nGjWK2bNnd6lYQG7vYvLkyUycOJEBAwbwox/9iMcee4xt27a1+56f/vSnnHfeeRx33HFd+qyeooIh\nIqlxyimnsGjRIn7yk5/w+uuvs2fPnlZtFi1axGWXXcYll1zCO++8Q3V1dfNrq1evZvDgwW1ue/v2\n7bz00ktceOGFHfZh9erVlJeXM3jwYMrLy1s8Hzx4MC+++CKQ28P48pe/3Py+sWPHcsABB/DXv/61\nze3W1dXx4IMPMmvWrDYL56ZNmxgxYgRHHXUUN954I9u3b++wn4WggpFyGrcPlEXQW7O4/PLLueee\ne1ixYgWTJk1i2LBh3H333c2v19fX88ILL3DZZZcxdOhQzj77bBYtWtT8+sSJE9myZUub2966dSt7\n9uxh+PDhzetuvvlmysvLOfjgg7njjjuat7F161a2bNnC1q1bWzzfsmULp556KgCffvppqzmPQYMG\n8cknn7T5+TfccAPz5s1jwIABrV4bN24cNTU1bNiwgZUrV/L66693aagtKSoYIlIy+vfvz86dO1us\n27lzJ/vtt1/z8re//W1WrFhBY2Mj9913H7fddhvPPfccAA899BDjx4/nS1/6UnPbJUuWsHv37k4/\nu7y8nH79+rFhw4bmdfPnz2fr1q1MnTqVXbt2delnOfjgg/n73//eYt3HH3/MIYcc0qrtk08+ySef\nfMK3vvWtNrc1dOjQ5mGqMWPGcPfdd/Pb3/62S/1JggpGyqV1rLoQlEWQ1ixGjx7d6hpIH3zwAWPG\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "hist(samples(USA), label='USA')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hey—that looks like the beta distribution. Let's compare:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nbGySAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "hist(samples(beta), label='beta')\n", + "hist(samples(USA), label='USA')" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.45 88.3 2 18 75 217 420\n", + " 20,000 0.50 100.3 1 10 69 228 451\n", + " 40,000 0.50 102.5 1 11 69 229 468\n", + " 60,000 0.50 101.6 1 11 69 231 481\n", + " 80,000 0.50 100.6 1 10 71 223 480\n", + "100,000 0.50 100.5 1 11 69 229 457\n", + "120,000 0.50 99.0 1 11 70 228 465\n", + "140,000 0.50 99.2 1 10 71 225 462\n", + "160,000 0.50 101.5 1 10 67 232 461\n", + "180,000 0.50 100.1 1 10 70 237 448\n", + "200,000 0.49 98.1 1 12 71 228 455\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEZCAYAAABSN8jfAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8VeW97/HPj0GRMUiBgAgBnMCrVds64UAdq+eIs1Ic\ngKq9R70OtQNoW0DqKcK5Hqfa9taiUatV26NRegSpxTiAigMbFFRw2MyhygwehpDf/WOtxE3IsMLO\nXnuFfN+v136x17OfvdY3Iclvr+dZg7k7IiIi2WiR7wAiItL0qZiIiEjWVExERCRrKiYiIpI1FRMR\nEcmaiomIiGRNxUQEMLMPzOykfOcQaapUTKRZMLPPzeyUam3Dzew1AHf/X+7+aj3r6GNmFWam3xuR\navRLIc1dQ87atbC/5SKImbXMxXpF4qBiIsLOey5m9h0ze9vM1pvZSjP7v2G3V8J/15nZBjM7xgK/\nMLO0mZWZWbGZdcxY75Xha1+E/TK3M9bM/mJmj5nZOmB4uO1ZZrbWzJab2f1m1ipjfRVmdq2ZLQzz\njTezfmY208zWmdmTlf3NrIuZTQnXtdrMKvOLNDoVE2nOatvDuBe4x907Af2Bp8P2yjmVju7e0d3f\nAkYCVwInA/2ADsBvAMxsIPAA8H2gB9AJ6FltW0OAp929AHgcKAduBvYFjgNOAa6r9p4zgCOBY4Gf\nAf8PGAbsDxwWbg/gx8BSoAvQDbitvm+IyO5SMZHmpMTM1lQ+CP7Q12QbcICZdXH3r9x9drXXM4vQ\nMOA/3X2xu38F3ApcGs6rXAg87+5vuHs5MKaGbb3h7lMA3H2ru89x99keWAL8gaBQZZro7pvd/UPg\nA2B6uP2NwFSCQgOwnaCI9XX3He4+s/5vkcjuUTGR5uRcd9+38sGun/grXQUcDHxkZm+Z2b/Usc6e\nwOKM5cVAK6B7+NrSyhfc/X+A1dXevzRzwcwODIemVoZDX/8OfKPae/6Z8fx/gFXVltuHz/8D+BSY\nbmafmNmoOr4OkayomEhzEmni3N0/dfdh7t4VmAT81cz2oebJ+hVAn4zlPgRDVauAlUCvqo0H6+hS\nfXPVln8HfAj0D4e+fh41dw1fxyZ3/4m79ycYTrvFzL67O+sSqY+KiUg1ZnaZmVXuDawn+INfAXwR\n/ts/o/ufgR+ZWZGZtSfYk3jS3SuAvwLnmNmxZtYaGBdh8x2ADe7+lZkdAlybxdfxL2ZWmXUjQZGr\n2N31idRFxUSai/oOAc58/XvAfDPbANwNXBrOZ/wPQbGYGc67HA08BDwGvEowpPQVcCOAuy8AbgCe\nItiD2UAwRLW1jhw/AS4Lt/3/gCfr+Trq+roOBF4ys43ATOABd9cRXZITlsubY5nZZOBfgVXufni1\n135MMKb7DXdfE7bdCvyA4BPUTe4+PWw/CigG2gAvuPvNOQstkiNm1g5YBxzg7ovr6y/SlOR6z+Rh\n4MzqjWbWCzidjIlLMxsAXAIMAM4CfmtmlWPFvwOucveDgIPMbJd1iiSRmf2rme0TFpK7gHkqJLIn\nymkxcffXgbU1vHQ38NNqbecSjDWXu3saWAQcbWaFQAd3fzvs9yhwXo4iizS2cwmGuJYRzLUMzW8c\nkdxoVX+XxmVmQ4Cl7v7+1zseAOwHvJGxvDxsKyf4Ray0LGwXSTx3vwa4Jt85RHIt1mISHhp5G8EQ\nl4iI7CHi3jPpDxQBc8P5kF7Ae+FRMcuB3hl9e4VtywkuE1G9vUZmlrsjCkRE9mDuvtsXMY3j0GAL\nH7j7B+5e6O793L0vwZDVke7+T+B5gstQ7GVmfYEDgNnuXgasN7OjwwJ0JfBcXRt090Q9xo4dm/cM\nyrRn5VImZWrsR7ZyWkzM7AlgFsERWEvMbGS1LlWX8/bgmPyngQXAC8B1/vVXeD0wGVgILHL3abnM\n3djS6XS+I+xCmaJLYi5likaZ4pPTYS53H1bP6/2qLU8AJtTQ712Cq6GKiEgC6Qz4GIwYMSLfEXah\nTNElMZcyRaNM8cnpGfD5YGa+p31NIiK5ZmZ4wifgm73S0tJ8R9iFMkWXxFyNkamoqAgz06OZPYqK\nirL+2alJ7CctikgyLF68uFGO4pGmxWy3dz7qXu+e9sOkYS6RaMJhjXzHkJjV9v8etmuYS0RE8kfF\nJAZ76ph7Y0tiJkhmriRmkuZNxURERLKmORORZqqmsfMxY+5hyZJ1Odtm794FjB+f3b3tbr/9dj79\n9FMeffTR3V7HK6+8wuWXX87SpUsb9L533nmH22+/nZkzZwLQs2dPzj//fH7yk5/QqVOnBq3riSee\n4LbbbmP16tWcfvrpPPTQQxQUFNSb+7vf/S6/+MUvGD9+fFXbKaecQrt27XB3zIwHHniAK664osZ1\n5GrOREdziUiVJUvWUVQ0LmfrT6dzt+6oduzYUfVHtyFmzZrFmWeeyS9/+UseeughunbtyrJly5g8\neTJz587lpJNOiryu+fPn82//9m9MnTqVI488kmuuuYZrr72WP//5z7W+p7y8nJtvvpljjz12l9f2\n228/lixZ0qCvp7FpmCsGSRzfVqbokpgriZka28SJE+nVqxcdO3ZkwIABvPzyy7z44ov8+te/5qmn\nnqJDhw4ceeSRABQXFzNw4EA6duzIAQccwB/+8Ieq9bzyyivsv//+TJo0iR49ejBs2DDOPvtsVqxY\nQYcOHejYsSNlZWX15hk1ahRXXXUVP/vZz+jatSsAvXr1YuzYsQ0qJBDslQwZMoRBgwbRtm1bfvWr\nX/HMM8+wefPmWt9z1113ceaZZ3LIIYc0aFtxUTERkcRZuHAhDzzwAO+++y4bNmzgxRdfpKioiDPP\nPJPbbruNSy+9lI0bNzJnzhwAunfvzgsvvMCGDRt4+OGH+dGPfkQqlapaX1lZGevWrWPJkiU8+uij\nTJ06lZ49e7Jx40Y2bNhAYWEhM2fOZN99960xz1dffcUbb7zBBRdcUGfumTNn0rlzZ/bdd186d+68\n0/N9992XWbNmAcGeyTe/+c2q9/Xr14+9996bhQsX1rjexYsX8/DDDzNmzJgah6j++c9/0qNHD/r3\n788tt9zCV199Vfc3OAdUTGIwePDgfEfYhTJFl8RcSczUmFq2bMm2bdv44IMPKC8vp3fv3vTt27fW\n/meddVbVmd0nnngiZ5xxBq+99tpO67v99ttp3bo1e++9d43rGDRoEGvWrKnxtbVr11JRUUFhYWFV\n26hRo+jcuTPt27fn17/+ddU61q5dy5o1a1i7du1Oz9esWcPxxx8PwKZNm3aZY+nYsSMbN26scfs3\n3XQTd9xxB23btt3ltQEDBpBKpVi5ciUzZszg3Xff5cc//nEt36ncUTERkcTp378/99xzD+PGjaN7\n9+4MGzaszqGoqVOnctxxx9GlSxc6d+7M1KlT+fLLL6te79q1K61bt97tPJ07d6ZFixasXLmyqm3i\nxImsXbuW888/n/Ly8gatr3379mzYsGGntvXr19OhQ4dd+k6ZMoWNGzdy0UUX1biubt26VQ199enT\nh0mTJvFf//VfDcrTGFRMYpDE8W1lii6JuZKYqbENHTqU1157jcWLFwPBngDsejmQbdu2cdFFF/Gz\nn/2ML774grVr13LWWWftNBxU/T0NnXxv27YtxxxzDM8880yd/V5//fWqeZjMR2Vb5VFghx56KHPn\nzq1636effsr27ds56KCDdlln5d5Gjx496NGjB0899RT33HMP559/fq05KioqGvT1NQYVExFJnIUL\nF/Lyyy+zbds29tprL/bZZx9atAj+XHXv3p10Ol1VLLZt28a2bdv4xje+QYsWLZg6dSrTp0+vc/3d\nu3dn9erVu+wd1GXSpEk89NBDTJo0iS+++AKAZcuW8fnnn1f1OeGEE6rmYTIflW2DBg0C4LLLLmPK\nlCnMnDmTzZs3M2bMGC688ELatWu3y3bvuOMOFi5cyNy5c5k7dy5Dhgzhmmuu4eGHHwaCDxaVR3It\nXbqU0aNHc95550X+uhqLDg2OQRLHt5UpuiTmylWm3r0Lcnr4bu/edZ9HUWnr1q2MHj2ajz76iNat\nW3P88cdXHaF18cUX86c//YkuXbrQr18/3nnnHe69914uvvhitm3bxjnnnMO5555b5/oPPvhgvv/9\n79OvXz8qKipYsGABn3zyCWeffXatBWbQoEHMmDGDcePGceeddwLB0VznnnsuN9xwQwO+CzBw4EB+\n//vfM2zYMNasWVN1nkmla6+9FjPjt7/9Le3atdupyOyzzz60a9eu6pyUOXPmcPnll7Nu3Tq6dOnC\nBRdcwB133NGgPI1BJy2KNFO60GPzpAs9NmFJHN9WpuiSmCuJmaR5UzEREZGsaZhLpJnSMFfzpGtz\nNcD69evr7dOiRYsaj+kWEZGG2yP3TH4w6gf19mtR3oLbb7mdnj175jxTaWlp4o4IUqbokpirMTJp\nz6R5apJ7JmY2GfhXYJW7Hx62TQLOAbYCnwIj3X1D+NqtwA+AcuAmd58eth8FFANtgBfcvc5rWO//\nvf3rzbb01aVs2bJl974wERHZSa4n4B8GzqzWNh041N2PABYBtwKY2UDgEmAAcBbwW/v6NNXfAVe5\n+0HAQWZWfZ2JlrRPtaBMDZHEXEnMJM1bTouJu78OrK3W9pK7V57r/ybQK3w+BHjS3cvdPU1QaI42\ns0Kgg7u/HfZ7FIj/9E4REalVvg8N/gHwQvh8PyDztmfLw7b9gGUZ7cvCtiYjiecEKFN0ScyVxExJ\nNnLkSMaMGZPvGHu0vB3NZWY/B7a7e+23FttNJXeWUFAYXGqgTfs2FB5QSNERRQCkU2kAWtIS+PqX\nsnLYIBfLqVQqp+vfneVKScmT5OU9+f+vujETxrBkVe7u2Ne7e2/G3zo+Z+tvLGVlZYwZM4b//u//\nZuPGjXTr1o2TTjqJ0aNH13gxxrqkUimuvvpqPvzwQwYOHMgf//jHne5lUpO1a9dy0EEHMWDAAF59\n9dWq9ilTpnDbbbexePFiDj/8cB588EEGDBiwW19jaWkpxcXFAFWX789Gzo/mMrM+wJTKCfiwbQRw\nDXCKu28N20YD7u4Tw+VpwFhgMfCyuw8I24cCJ7v7tbVsz8e+PLbeXEtfXcrPL/85/fr1y+bLE2my\najqqZ8TNIyg6ryhn20yXpCm+pzhn66/NyJEj2X///avum16XNWvW8O1vf5tBgwbxq1/9iqKiIjZs\n2MCzzz7Lpk2buP766yNvd/v27Rx44IHccsstXHvttfz+97/nrrvu4pNPPqFVq9o/y//whz9k4cKF\nVFRUVBWTTz75hG9961tMmzaNY445hkmTJjF58mQ+/vjjqotgRtGUL6di4SNYMPse8FNgSGUhCT0P\nDDWzvcysL3AAMNvdy4D1ZnZ0OCF/JfBcDLlFJI9WrlzJRRddRLdu3ejfvz/3339/1Wu33347l156\nKcOHD6djx44cdthhvPfee1Wvz5kzh29961t06tSJoUOHNujIzf/8z/+kU6dOPPbYY1Wf2Dt27Mjw\n4cMbVEgg+PS/Y8cObrzxRlq3bs0NN9yAuzNjxoxa3zNr1izmz5/PyJEjd2p/8cUXOfHEEznuuONo\n0aIFo0aNYvny5bzyyisNypQrOS0mZvYEMIvgCKwlZjYSuB9oD/zdzN4zs98CuPsC4GlgAcE8ynUZ\np7JfD0wGFgKL3H1aLnM3tiSObytTdEnMlcRMjcndOeecczjyyCNZuXIl//jHP7j33nv5+9//XtVn\nypQpDBs2jPXr13POOedU/aHfvn07559/PsOHD2fNmjVcfPHFu9wsqnPnzlW30K3uH//4R533Cslc\nR2235500aRIQ3J738MMP3+l93/zmN5k/f36N66yoqOCGG27gN7/5Tb3br6iowN354IMP6u0bh5zO\nmbj7sBqaH66j/wRgQg3t7wKHNWI0EUmwt99+my+//JKf//znQDCmf/XVV/Pkk09y+umnA8G9Q848\nMzhL4IorruDee+8F4I033qC8vJwbb7wRgAsvvJDvfOc7O61/7dqdDjLdyZdffrnT7XmnTJnClVde\nyY4dOzj++OOZNm1aveuo1NDb8953330cd9xxHHnkkcybN2+n10477TRGjx7Nq6++ynHHHcedd97J\n9u3b83K/95rskZdTSZoknhOgTNElMVcSMzWmxYsXs3z5cvbdd18g2FOpqKjgpJNOquqT+Qe/bdu2\nbNmyhYqKClauXMl+++18wGefPn0ib7tLly473Z73nHPOYe3atUyePJnHH3+8QV9HQ27Pu3LlSu67\n776q4brq8xoHH3wwjzzyCNdffz1lZWVcfvnlDBw4kF69eu2yrnzI96HBIiK72H///enXrx9r1qxh\nzZo1rF27lvXr1zNlypR639ujRw+WL1++U1vlnQijOPXUUykpKam3X1235628edahhx66yx7GvHnz\nOPTQQ3dZ3+zZsykrK2PgwIH06NGDm2++mbfeeouePXtWFZYLLriA999/ny+++IJx48bx+eef77LX\nlS8qJjFI4vi2MkWXxFxJzNSYjj76aDp06MCkSZPYsmULO3bsYP78+bzzzju1vqfyD+5xxx1Hq1at\nuP/++ykvL+eZZ55h9uzZkbd9yy23sHbtWq644go+++wzADZu3EgqldqpX1235x09ejQQ7EG2bNmS\n+++/n23btnHffffRokULTjnllF22e/bZZ5NOp0mlUsydO5fx48dz1FFHMXfu3Kp71r/33ntUVFTw\nxRdf8MMf/pDzzjuvwYcq54qGuUSkSu/uvUmXpHO6/ihatGjB3/72N2655Rb69u3Ltm3bOPjgg+u8\nHW3lH9zWrVvzzDPPcPXVV/OLX/yCs88+mwsvvHCnvh06dGDatGlV92TP1KVLF958801++ctfcsIJ\nJ7Bp0ya6d+/OCSecwO9+97sGfLVBlpKSEq666ipGjx7NgAEDeO6556oOC37iiSeYMGEC77//Pq1b\nt6Zbt25V7+3UqROtW7ema9euVW033XQTc+fOZa+99uKSSy7hrrvualCeXNojrxqs80xE6qerBjdP\nTfk8ExER2cOpmMQgiePbyhRdEnMlMZM0byomIiKSNc2ZaM5EminNmTRPmjMREZHEUjGJQRLHt5Up\nuiTmSmImad50nolIM9WnT5+qczOk+WjIpWUaQnMmmjMREcl6zqRZ75ncffdDbNwY7VvQu3cB48ff\nnONEIiJNU7MuJitWbOSww+6N1DedHrfb2yktLU3cVV6VKbok5lKmaJQpPpqAFxGRrDXrOZN1c9s3\naM+kuHhclulERJJJ55mIiEjeqZjEIInnBChTdEnMpUzRKFN8VExERCRrmjPRnImIiOZMREQk/1RM\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(samples(USA))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The USA distribution is indeed similar to the beta(0.9, 12) distribution, and to the stationary ending distribution." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Uri Wilensky Version\n", + "\n", + "[Another version](http://www.decisionsciencenews.com/2017/06/19/counterintuitive-problem-everyone-room-keeps-giving-dollars-random-others-youll-never-guess-happens-next/) of this simulation made the rounds in 2017. This version has these rules:\n", + "\n", + ">Imagine a room full of 100 people with 100 dollars each. With every tick of the clock, every person with money gives a dollar to one randomly chosen other person. After some time progresses, how will the money be distributed?\n", + "\n", + "To implement this all-at-once transactions rather than one-at-a-time transactions, I'll define a new `step` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.00 0.0 100 100 100 100 100\n", + " 2,000 0.24 43.4 16 48 93 165 208\n", + " 4,000 0.33 58.7 3 27 96 185 247\n", + " 6,000 0.37 66.1 2 15 99 188 326\n", + " 8,000 0.38 68.2 6 13 91 178 368\n", + " 10,000 0.40 72.5 2 15 85 200 321\n", + " 12,000 0.42 75.7 1 12 92 210 351\n", + " 14,000 0.41 74.2 3 15 79 230 295\n", + " 16,000 0.43 78.9 2 18 83 220 354\n", + " 18,000 0.45 84.9 5 16 78 227 424\n", + " 20,000 0.50 93.7 2 7 70 230 395\n" + ] + }, + { + "data": { + "image/png": "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\nTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nA2Lva/HixXzve99j3rx5jB49mrPOOouzzz6b3/zmN61uf/LJJzNmzBjmzZvHH//4R4477jhef/11\nBg8eXNL3UA5NSaUolDli9TCSpZzJueqqqxg+fDj9+/dnl1124aGHHuLee+/l8ssv54477qBfv36M\nHj0agFmzZrHrrrvSv39/dtxxR371q1817efhhx9mu+22Y/r06Wy99daMHz+eww8/nPfee49+/frR\nv39/6urqOswzadIkzjjjDC666CK22morAIYPH86ll15aUrGAwtnFkUceyZgxY+jbty///u//zuzZ\ns/nkk0822va1115j0aJFTJ06lT59+nDMMcew++67c9ddd5V0zHKpYIhILr366qv84he/4JlnnmH1\n6tXce++9VFZWcsghh3DJJZdw4oknsmbNGhYtWgTA0KFD+dOf/sTq1au58cYb+cEPfkBNTU3T/urq\n6li5ciVLly7l5ptvZt68eWyzzTasWbOG1atXM2zYMBYsWMCgQYNazfPpp5+ycOFCjjnmmHZzL1iw\ngIqKCgYNGkRFRUWzx4MGDeKxxx4DCmcYe+yxR9PrRo0aRZ8+fXj11Vc32ufixYsZNWoUm2++edO6\nPfbYg8WLF8cf0ASoYKQolLls9TCSpZzJ6NmzJw0NDbz44ousXbuWESNGsP3227e5/WGHHdb0Duf9\n99+fgw8+mEceeaTZ/qZNm0bv3r3p06dPq/sYM2YMK1asaPW5+vp61q9fz7Bhw5rWTZo0iYqKCrbY\nYgsuv/zypn3U19ezYsUK6uvrmz1esWIF++67LwAff/zxRj2P/v37s2bNmo2OXcq2aVLBEJFc2mGH\nHbj66quZOnUqQ4cOZfz48e1OG82bN4999tmHwYMHU1FRwbx58/jwww+bnt9qq63o3bv3JuepqKig\nR48eLFu2rGndVVddRX19PUcffTRr164taX9bbLEFq1evbrZu1apV9OvXr6xt06SCkaIQ5ohBPYyk\nKWdyTjrpJB555BGWLFkCFH6jh40/+qKhoYHjjjuOiy66iA8++ID6+noOO+ywZh970vI1pTa8+/bt\nyze+8Q1mz57d7naPPvpoU1+k+KtxXePVVbvtthvPPfdc0+veeOMNvvjiC/7u7/5uo33utttuvPnm\nm836G8899xy77bZbSd9DuVQwRCSXXn31VR566CEaGhr40pe+xGabbUaPHoUfWUOHDqW2trapIDQ0\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def give_dollar(population, transaction, interaction):\n", + " \"Everyone with at least a dollar gives a dollar to a random person.\"\n", + " N = len(population)\n", + " for i in range(N):\n", + " if population[i] >= 1:\n", + " population[i] -= 1\n", + " population[random.randrange(N)] += 1\n", + " return population\n", + "\n", + "show([100] * 100, k=200, step=give_dollar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So we see that inequality rises from a Gini of 0 to about 1/2 over 20,000 time steps. Let's try again starting from the first 100 actors from our initial (Gaussian) population:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " t Gini stdev 1% 10% 50% 90% 99%\n", + "------- ---- ----- ---- ---- ---- ---- ----\n", + " 0 0.12 19.4 58 71 95 119 151\n", + " 2,000 0.29 48.1 10 35 91 169 205\n", + " 4,000 0.39 66.5 3 13 88 187 329\n", + " 6,000 0.40 67.7 5 11 97 194 283\n", + " 8,000 0.39 65.8 3 13 87 179 274\n", + " 10,000 0.38 64.5 3 21 84 187 294\n", + " 12,000 0.40 71.8 5 27 78 187 376\n", + " 14,000 0.44 80.8 2 13 70 201 460\n", + " 16,000 0.47 84.3 2 11 80 193 443\n", + " 18,000 0.45 81.7 5 13 79 202 421\n", + " 20,000 0.45 80.6 0 10 79 204 400\n" + ] + }, + { + "data": { + "image/png": "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\nRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nxjHHHMPTTz/NY489xk033cQvfvELunbtyogRIwAoLS1l6NChdOvWjSOOOIK77767rp1nnnmGQw89\nlNmzZ9O/f38mTpzI2LFj+fvf/07Xrl3p1q0bVVVVLeaZMmUKl112Gddddx19+vQBYODAgcyYMaNV\nRQFSewtf+MIXGDlyJAcffDDf/va3eeSRR9i2bVujy1988cWMGTOGLl267PXahAkTOPXUUznwwAPp\n3r07V1xxRd0eTXtSYRCRvHrzzTe58847efXVV9m8eTOPPfYYiUSCMWPGMG3aNM4//3y2bNlCRUUF\nAP369eN3v/sdmzdv5t577+VrX/salZWVde1VVVWxceNGVq1axf3338+CBQsYMGAAW7ZsYfPmzZSU\nlLBw4UJ69erVaJ7333+fF154gbPPPrvZ3AsXLqRnz5706tWLnj17Zjzv1asXixYtAlJ7DB//+Mfr\n3jd48GA+/OEP8+abb+a66XjmmWcYNmxYzu20lrqSAhg9enShI2RFOcOJIWOx6NixI7t27eL111+n\nd+/eDBo0qNnlTz/99Lrnn/3sZzn11FN57rnnGD58eF17N954I506dWqyjZEjR7J+/fpGX9uwYQM1\nNTWUlHxw9f8pU6Zw9913s3v3bqZNm8a0adMYOXIkGzZsaPHzbd26da8xiW7durFly5YW39ucJ554\nggceeIDFixfn1E5bqDAUUGsGB1sz0JevdkXaYsiQIfzgBz9g5syZLF++nDFjxnDbbbdl/GGub8GC\nBcyaNYs333yTmpoatm/fzsc+9sF9vPr06dNsUWhJz5496dChA2vWrOHII48EUl1dt956KxdffDHV\n1dWtaq9Lly5s3rw5Y96mTZvo2rVrmzO++OKLXHjhhTz88MMMGTKkze20lQpDAOXl5W36BtmawcHW\nDPQ11W4yWU4iMbrN7baXtm7P9hRDxmIyYcIEJkyYwNatW/n3f/93pkyZwn333bfXoPGuXbs499xz\nmTdvHuPGjaNDhw6cddZZGUfeNHxPaweeDz74YD7zmc/wyCOPcNJJJzW53PPPP8/pp5++V/u1g90L\nFixg5MiRDBs2jCVLltS9/vbbb7N79+66otNaFRUVjB8/ntLS0oL9jmmMQUTy6s033+Tpp59m165d\nfOhDH+Kggw6iQ4fUn55+/fqRTCbr/vDv2rWLXbt28ZGPfIQOHTqwYMECHn/88Wbb79evH+vWrdvr\nW3tzZs+ezdy5c5k9ezbvvvsuAKtXr+avf/1r3TKjRo2qG7eo/6idN3LkSAAuvPBC5s+fz8KFC9m2\nbRvTp0/nnHPOafIQ0+rqanbs2EFNTQ27d+9m586d1NTUAPD6669z+umnM2fOHMaOHZv15wlNewwB\nxPLNseHeQrGKYXvGkHHQoB553SMcNKjx4/Qb2rlzJ1OnTuWNN96gU6dOnHDCCXVHGp133nnMmzeP\n3r17M3jwYF555RVuv/12zjvvPHbt2sWZZ57JuHHjmm3/qKOO4oILLmDw4MHU1NSwfPly3nrrLcaO\nHdtksRg5ciRPPfUUM2fO5JZbbgFSRyWNGzeOq666qhVbAYYOHcpdd93FxIkTWb9+fd15DLWuvPJK\nzKzukNMrrrgiY2/ppptu4t577+WLX/wit912G++99x6XXXYZX/rSl4DUlXNfe+21VmXKlU5wK6BJ\nk2a2qiuptDS7ZfPVrhQvXURv/6SL6BWxWI5pTybLCx0hKzFszxgyirSVCoOIiGRQYQgghv5m0BhD\nSDFkFGkrFQYREcmgwhBALP3NGmMIJ4aMIm2lwiAiIhlUGAKIpb9ZYwzhxJBRpK1UGEREJIMKQwCx\n9DdrjCGcGDLuqy699NKMu55JeLokhsg+avrN01m1dlXe2h/UbxCzrp+Vt/ZDqaqqYvr06fz2t79l\ny5Yt9O3blxNPPJGpU6e2+kJ3lZWVXH755axYsYKhQ4fy05/+NONeDI3ZsGEDRx55JMcccwzPPvts\n3fwOHTrUXU/JzJgwYULGTYkKSYUhgFj6mzXGEE4MGVetXUVifCJv7SfLknlrO5T169dzwgknMHLk\nSBYuXEgikWDz5s386le/4oknnmhVYdi9ezfjx4/nmmuu4corr+Suu+5i3LhxvPXWWxxwQNN/SqdM\nmcKwYcPqLpRXy8xYunQphx9+eJs/X76oK0lE8m7NmjWce+659O3blyFDhjBnzpy612688UbOP/98\nLrnkErp168axxx7LH//4x7rXKyoqOO644+jevTsTJkxgx44dWa/3tttuo3v37jzwwAMkEgkgdROd\nSy65hK985Sut+gzl5eXs2bOHq6++mk6dOnHVVVfh7jz11FNNvmfRokUsW7aMSy+9dK/X3H2vYlEs\nVBgCiKW/WWMM4cSQsVi4O2eeeSYjRoxgzZo1PPnkk9x+++088cQTdcvMnz+fiRMnsmnTJs4888y6\nP9q7d+/mrLPO4pJLLmH9+vWcd955PPzwwxnt9+zZs+42mw09+eSTnHXWWS1mbO4WnrNnzwZSt/Cs\nf8MggI9//OMsW7as0TZramq46qqr+OEPf9jkek866SQGDBjAueeey8qVK1vM2V5UGEQkr15++WXe\ne+89vvnNb9KxY0cSiQSXX345Dz30UN0yo0aNYsyYMZgZF198MUuXLgXghRdeoLq6mquvvpqOHTty\nzjnn8KlPfSqj/Q0bNnDCCSc0uu733nsv405x8+fPp2fPnnTr1o3TTjsto43169ezYcOGjOfr16/n\nuuuuA1p/C8877riD448/nhEjRjT6+rPPPksymeSNN96gf//+nHHGGUWzB6ExhgBi6G8GjTGEFEPG\nYrFy5UreeecdevXqBXzQhXLiiSfWLVP/j/fBBx9cdyObNWvWcMghh2S0d9hhh2W97t69e7NmzZq6\n6TPPPJMNGzZwzz338LOf/axVn6M1t/Bcs2YNd9xxR12XWGOXxh41ahSQKi6333473bt3Z8WKFQwb\nNqxVufJBewwikleHHnoogwcPZv369XXfxDdt2sT8+fNbfG///v155513MuatWpX9kVannHIKZWVl\nLS7XtWtXunXrlvGonVd7I59hw4bV7cnUWrp0aaN/yBcvXkxVVRVDhw6lf//+TJ48mZdeeokBAwY0\nWiRq5xXLPTVUGAKIpb9ZYwzhxJCxWHz605+ma9euzJ49mx07drBnzx6WLVvGK6+80uR7av9AHn/8\n8RxwwAHMmTOH6upqHnnkERYvXpz1uq+55ho2bNjAxRdfzF/+8hcAtmzZQmVlZcZyzd3Cc+rUqUBq\nL7Fjx47MmTOHXbt2cccdd9ChQwdOPvnkvdY7duxYkskklZWVLFmyhFmzZvGJT3yCJUuWYGYsX76c\nJUuWUFNTw9atW7nmmmsYOHAgxxxzTNafLZ/UlSSyjxrUb1BeDykd1G9QVst16NCBRx99lGuuuYbD\nDz+cXbt2cdRRR/Gd73ynyffU3vayU6dOPPLII1x++eV861vfYuzYsZxzzjkZy3bt2pXf//73dfdg\nrq937968+OKL3HDDDYwaNYqtW7fSr18/Ro0axY9//ONWfNpUlrKyMi677DKmTp3KMcccw69//eu6\nQ1UffPBBbr75Zl577TU6depE3759697bvXt3OnXqRJ8+fQBYu3YtV155Je+88w6dO3fmhBNO4NFH\n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\nAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(population[:100], k=200, step=give_dollar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Mathematician, a Statistician, and a Programmer walk into a problem ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In 2013, mathematician George Andrew's editorial *[Drowning in the Data Deluge](http://www.ams.org/notices/201207/rtx120700933p.pdf)* complains of an \"overblown enthusiasm for data analysis.\" The tone was that this new fad for \"big data\" was taking away from traditional mathematics.\n", + "\n", + "Two Stanford professors, mathematician Persi Diaconis and \n", + "statistician Susan Holmes, were more accepting of new ideas. The three of us got to discussing Andrew's editorial and the differences between mathematical, statistical, and computational thinking. At the time, I had just heard about the economics problem covered in this notebook, and I suggested the three of us work on it, and compare approaches and results.\n", + "In the end, all three of us found similar results, in that we all identified the shape of the final distribution. But there were differences in how we got there:\n", + "\n", + "**Mathematical thinking** (Persi):\n", + "\n", + "- **Tool:** Paper and pencil.\n", + "- **Notes:** The process can be modeled by a Markov chain, using the same techniques as in [this paper](http://statweb.stanford.edu/~cgates/PERSI/papers/kac10.pdf). In the limit, there is a difference between the continuous case (where money is a real number, and the distribution is stationary), and the discrete case (where money comes in integer amounts and the distribution is not ergodic as there is an absorbing state). \n", + "\n", + "**Statistical thinking** (Susan):\n", + "\n", + "- **Tool:** Simulation in `R`, with N=10 actors for T=1,000 transactions.\n", + "- **Notes**: this is extremely similar to what happens for random genetic drift in generations, that also gives clumping (and extinction of some of the alleles).\n", + "\n", + "**Computational thinking** (Peter):\n", + "\n", + "- **Tool:** Simulation in `IPython`, with N=5000 actors for T=200,000 transactions.\n", + "- **Notes**: Results are very similar to Susan's, but with more variations explored and more pretty pictures." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Fred Buns.ipynb b/pytudes/ipynb/Fred Buns.ipynb new file mode 100644 index 0000000..72e4948 --- /dev/null +++ b/pytudes/ipynb/Fred Buns.ipynb @@ -0,0 +1,1475 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
Peter Norvig, 15 June 2015
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Let's Code About Bike Locks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The [June 15, 2015 post on Bike Snob NYC](http://bikesnobnyc.blogspot.com/2015/06/lets-get-this-show-on-road-once-we-all.html) leads with \"*Let's talk about bike locks.*\" Here's what I want to talk about: in my local bike shop, I saw a combination lock called *WordLock®*,\n", + "which replaces digits with letters. I classified this as a Fred lock,\n", + "\"[Fred](http://bikesnobnyc.blogspot.com/2014/06/a-fred-too-far.html)\" being the term for an amateurish cyclist with the wrong equipment.\n", + "I tried the combination \"FRED,\" and was amused with the result:\n", + "\n", + "![](http://norvig.com/ipython/fredbuns.jpg)\n", + "\n", + "FRED BUNS! Naturally I set all the other locks on the rack to FRED BUNS as well. But my curiosity was raised ... \n", + "\n", + "# Questions\n", + "\n", + "1. How many words can the WordLock® make?\n", + "3. Can a lock with different letters on the tumblers make more words? \n", + "4. How many words can be made simultaneously? For example, with the tumbler set to \"FRED\", the lock\n", + "above also makes \"BUNS\" in the next line, but with \"SOMN\", fails to make a word in the third line.\n", + "Could different letters make words in every horizontal line?\n", + "5. Is it a coincidence that the phrase \"FRED BUNS\" appears, or was it planted there by mischievous WordLock® designers? \n", + "\n", + "Vocabulary\n", + "===\n", + "\n", + "Before we can answer the questions, we'll need to be clear about the vocabulary of the problem and how to represent concepts in code:\n", + "\n", + "* **Lock**: For our purposes a lock can be modeled as a `list` of 4 **tumblers**. \n", + "* **Tumbler:** Each tumbler has 10 distinct letters. I will represent a tumbler as a `str` of 10 letters.\n", + "* **Combination**: Choosing a letter from each tumbler gives a combination, such as \"FRED\" or \"BUNS\". There are 104 = 10,000 combinations.\n", + "* **Word**: Some combinations (such as \"BUNS\") are *words*; others (such as \"SOMN\") are not words. We'll need a collection of dictionary words.\n", + "\n", + "Now on to the code! First the imports I will need and the vocabulary concepts:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from __future__ import division, print_function # To work in Python 2.x or 3.x\n", + "from collections import Counter, defaultdict\n", + "import itertools\n", + "import random \n", + "\n", + "Lock = list # A Lock is a list of tumblers\n", + "Tumbler = ''.join # A Tumbler is 10 characters joined into a str\n", + "Word = ''.join # A word is 4 letters joined into a str" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The only remaining vocabulary concept is `combinations`. I will define `fredbuns` to be a lock with four tumblers, but with each tumbler consisting of not all ten letters, but only the two letters that spell \"FRED BUNS\": " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fredbuns = ['FB', 'RU', 'EN', 'DS'] # A lock with two letters on each of four tumblers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need a way to get the combinations that can be made from this lock. It turns out that the built-in function `itertools.product` does most of the job; it generates the product of all 2 × 2 × 2 × 2 = 16 combinations of letters:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('F', 'R', 'E', 'D'),\n", + " ('F', 'R', 'E', 'S'),\n", + " ('F', 'R', 'N', 'D'),\n", + " ('F', 'R', 'N', 'S'),\n", + " ('F', 'U', 'E', 'D'),\n", + " ('F', 'U', 'E', 'S'),\n", + " ('F', 'U', 'N', 'D'),\n", + " ('F', 'U', 'N', 'S'),\n", + " ('B', 'R', 'E', 'D'),\n", + " ('B', 'R', 'E', 'S'),\n", + " ('B', 'R', 'N', 'D'),\n", + " ('B', 'R', 'N', 'S'),\n", + " ('B', 'U', 'E', 'D'),\n", + " ('B', 'U', 'E', 'S'),\n", + " ('B', 'U', 'N', 'D'),\n", + " ('B', 'U', 'N', 'S')]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(itertools.product(*fredbuns))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I would prefer to deal with the string `'BUNS'` rather than the tuple `('B', 'U', 'N', 'S')`, so I will define a function, `combinations`, that takes a lock as input and returns a list of strings representing the combinations:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def combinations(lock):\n", + " \"Return a list of all combinations that can be made by this lock.\"\n", + " return [Word(combo) for combo in itertools.product(*lock)]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['FRED',\n", + " 'FRES',\n", + " 'FRND',\n", + " 'FRNS',\n", + " 'FUED',\n", + " 'FUES',\n", + " 'FUND',\n", + " 'FUNS',\n", + " 'BRED',\n", + " 'BRES',\n", + " 'BRND',\n", + " 'BRNS',\n", + " 'BUED',\n", + " 'BUES',\n", + " 'BUND',\n", + " 'BUNS']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "combinations(fredbuns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dictionary Words\n", + "===\n", + "\n", + "I happen to have handy a file of four-letter words (no, not *[that](http://en.wikipedia.org/wiki/Four-letter_word)* kind of four-letter word). It is the union of an official Scrabble® word list and a list of proper names. The following shell command tests if the file has already been downloaded to our local directory and if not, fetches it from the web:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "! [ -e words4.txt ] || curl -O http://norvig.com/ngrams/words4.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are the first few lines of the file:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AADI\r\n", + "AAHS\r\n", + "AALS\r\n", + "ABAS\r\n", + "ABBA\r\n", + "ABBE\r\n", + "ABBY\r\n", + "ABED\r\n", + "ABEL\r\n", + "ABET\r\n" + ] + } + ], + "source": [ + "! head words4.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python can make a set of words:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "WORDS = set(open('words4.txt').read().split())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4360" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(WORDS)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So that means that no lock could ever make more than 4,360 words. Let's define `words_from(lock)`:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def words_from(lock): \n", + " \"A list of words that can be made by lock.\"\n", + " return [c for c in combinations(lock) if c in WORDS]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['FRED', 'FUND', 'FUNS', 'BRED', 'BUND', 'BUNS']" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "words_from(fredbuns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Note*: An alternative is to represent a collection of words as a `set`; then `words_from` could do `return combinations(lock) & WORDS`. \n", + "\n", + "I will also introduce the function `show` to print out a lock and its words:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def show(lock):\n", + " \"Show a lock and the words it makes.\"\n", + " words = words_from(lock)\n", + " print('Lock: {}\\nCount: {}\\nWords: {}'\n", + " .format(space(lock), len(words), space(sorted(words))))\n", + " \n", + "space = ' '.join # Function to concatenate strings with a space between each one." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: FB RU EN DS\n", + "Count: 6\n", + "Words: BRED BUND BUNS FRED FUND FUNS\n" + ] + } + ], + "source": [ + "show(fredbuns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For this tiny lock with just two letters on each tumbler, we find that 6 out of the 16 possible combinations are words. We're now ready to answer the real questions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Question 1: How Many Words?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is the answer:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "wordlock = ['SPHMTWDLFB', 'LEYHNRUOAI', 'ENMLRTAOSK', 'DSNMPYLKTE']" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: SPHMTWDLFB LEYHNRUOAI ENMLRTAOSK DSNMPYLKTE\n", + "Count: 1118\n", + "Words: BAAL BAAS BAKE BALD BALE BALK BALL BALM BALS BAMS BAND BANE BANK BANS BARD BARE BARK BARM BARN BARS BASE BASK BASS BAST BATE BATS BATT BEAD BEAK BEAM BEAN BEAT BEEN BEEP BEES BEET BELL BELS BELT BEND BENE BENS BENT BERK BERM BEST BETS BIAS BIKE BILE BILK BILL BIND BINE BINS BINT BIOS BIRD BIRK BIRL BISE BISK BITE BITS BITT BLAE BLAM BLAT BLED BLET BLOT BOAS BOAT BOLD BOLE BOLL BOLT BOND BONE BONK BONY BOOK BOOM BOON BOOS BOOT BORE BORK BORN BORT BOSK BOSS BOTS BOTT BRAD BRAE BRAN BRAS BRAT BRAY BRED BREE BREN BROS BULK BULL BUMP BUMS BUND BUNK BUNN BUNS BUNT BUOY BURD BURL BURN BURP BURS BURY BUSK BUSS BUST BUSY BUTE BUTS BUTT BYES BYRE BYRL BYTE DAKS DALE DALS DAME DAMN DAMP DAMS DANE DANK DANS DARE DARK DARN DART DATE DEAD DEAL DEAN DEED DEEM DEEP DEES DEET DEKE DELE DELL DELS DELT DEME DEMY DENE DENS DENT DENY DEON DERE DERM DESK DHAK DHAL DIAL DIED DIEL DIES DIET DIKE DILL DIME DIMS DINE DINK DINS DINT DIOL DION DIRE DIRK DIRL DIRT DISK DISS DITE DITS DOAT DOES DOLE DOLL DOLS DOLT DOME DOMS DONE DONS DOOM DORE DORK DORM DORP DORS DORY DOSE DOSS DOST DOTE DOTS DOTY DRAM DRAT DRAY DREE DREK DROP DUAD DUAL DUEL DUES DUET DUKE DULL DULY DUMP DUNE DUNK DUNS DUNT DUOS DURE DURN DUSK DUST DUTY DYAD DYED DYES DYKE DYNE FAKE FALL FAME FANE FANS FARD FARE FARL FARM FART FAST FATE FATS FEAL FEAT FEED FEEL FEES FEET FELL FELT FEME FEMS FEND FENS FEOD FERE FERN FESS FEST FETE FETS FIAT FILE FILL FILM FILS FIND FINE FINK FINN FINS FIRE FIRM FIRN FIRS FIST FITS FLAK FLAM FLAN FLAP FLAT FLAY FLED FLEE FLEY FLOE FLOP FOAL FOAM FOES FOLD FOLK FOND FONS FONT FOOD FOOL FOOT FORD FORE FORK FORM FORT FOSS FRAE FRAP FRAT FRAY FRED FREE FRET FROE FROM FUEL FULL FUME FUMY FUND FUNK FUNS FURL FURS FURY FUSE FUSS FYKE HAED HAEM HAEN HAES HAET HAKE HALE HALL HALM HALT HAME HAMS HAND HANK HANS HANT HARD HARE HARK HARL HARM HARP HART HASP HAST HATE HATS HEAD HEAL HEAP HEAT HEED HEEL HELD HELL HELM HELP HEME HEMP HEMS HENS HENT HERD HERE HERL HERM HERN HERS HEST HETS HIED HIES HIKE HILL HILT HIMS HIND HINS HINT HIRE HISN HISS HIST HITS HOED HOES HOKE HOLD HOLE HOLK HOLM HOLP HOLS HOLT HOLY HOME HOMY HONE HONK HONS HOOD HOOK HOOP HOOT HORN HOSE HOST HOTS HUED HUES HULK HULL HUMP HUMS HUNK HUNS HUNT HURL HURT HUSK HUTS HYMN HYTE LAKE LAKY LALL LAME LAMP LAMS LAND LANE LANK LARD LARK LARS LASE LASS LAST LATE LATS LEAD LEAK LEAL LEAN LEAP LEAS LEEK LEES LEET LEKE LEKS LEND LENS LENT LEON LESS LEST LETS LIAM LIAN LIED LIEN LIES LIKE LILT LILY LIME LIMN LIMP LIMY LINE LINK LINN LINS LINT LINY LION LIRE LISP LIST LITE LITS LOAD LOAM LOAN LOLL LONE LOOK LOOM LOON LOOP LOOS LOOT LORD LORE LORN LORY LOSE LOSS LOST LOTS LUES LUKE LULL LUMP LUMS LUNE LUNK LUNT LUNY LURE LURK LUST LUTE LYAM LYES LYLE LYRE LYSE MAES MAKE MALE MALL MALM MALT MANE MANS MANY MARE MARK MARL MARS MART MARY MASK MASS MAST MATE MATS MATT MEAD MEAL MEAN MEAT MEED MEEK MEET MELD MELL MELS MELT MEME MEMS MEND MERE MERK MERL MESS METE MHOS MIEN MIKE MILD MILE MILK MILL MILS MILT MIME MIND MINE MINK MINT MIRE MIRK MIRS MIRY MISE MISS MIST MITE MITT MITY MOAN MOAS MOAT MOKE MOLD MOLE MOLL MOLS MOLT MOLY MOME MOMS MONK MONS MONY MOOD MOOL MOON MOOS MOOT MORE MORN MORS MORT MOSK MOSS MOST MOTE MOTS MOTT MULE MULL MUMM MUMP MUMS MUNS MUON MURE MURK MUSE MUSK MUSS MUST MUTE MUTS MUTT PALE PALL PALM PALP PALS PALY PAMS PANE PANS PANT PARD PARE PARK PARS PART PASE PASS PAST PATE PATS PATY PEAK PEAL PEAN PEAS PEAT PEED PEEK PEEL PEEN PEEP PEES PEKE PELE PELT PEND PENS PENT PEON PERE PERK PERM PERP PERT PEST PETS PHAT PHON PHOT PIAL PIAN PIAS PIED PIES PIKE PILE PILL PILY PIMP PINE PINK PINS PINT PINY PION PIRN PISS PITS PITY PLAN PLAT PLAY PLED PLOD PLOP PLOT PLOY POEM POET POKE POKY POLE POLL POLS POLY POME POMP POMS POND PONE PONS PONY POOD POOL POON POOP POOS PORE PORK PORN PORT POSE POST POSY POTS PRAM PRAT PRAY PREE PREP PREY PROD PROM PROP PROS PUKE PULE PULL PULP PULS PUMP PUNK PUNS PUNT PUNY PURE PURL PURS PUSS PUTS PUTT PYAS PYES PYRE SAAD SAKE SALE SALL SALP SALS SALT SAME SAMP SAND SANE SANK SANS SARD SARK SASS SATE SEAL SEAM SEAN SEAS SEAT SEED SEEK SEEL SEEM SEEN SEEP SEES SELL SELS SEME SEND SENE SENT SERE SERS SETS SETT SHAD SHAE SHAM SHAT SHAY SHED SHES SHOD SHOE SHOP SHOT SIAL SIKE SILD SILK SILL SILT SIMP SIMS SINE SINK SINS SIRE SIRS SITE SITS SLAM SLAP SLAT SLAY SLED SLOE SLOP SLOT SNAP SNED SNOT SOAK SOAP SOKE SOLD SOLE SOLS SOME SOMS SONE SONS SOOK SOON SOOT SORD SORE SORN SORT SOTS SUED SUES SUET SUKS SULK SUMP SUMS SUNK SUNN SUNS SURD SURE SUSS SYED SYKE SYNE TAEL TAKE TALE TALK TALL TAME TAMP TAMS TANK TANS TAOS TARE TARN TARP TARS TART TASK TASS TATE TATS TEAK TEAL TEAM TEAS TEAT TEED TEEL TEEM TEEN TEES TELE TELL TELS TEMP TEND TENS TENT TERM TERN TESS TEST TETS THAE THAN THAT THEE THEM THEN THEY TIED TIES TIKE TILE TILL TILS TILT TIME TINE TINS TINT TINY TIRE TIRL TITS TOAD TOED TOES TOKE TOLD TOLE TOLL TOME TOMS TONE TONS TONY TOOK TOOL TOOM TOON TOOT TORE TORN TORS TORT TORY TOSS TOST TOTE TOTS TRAD TRAE TRAM TRAP TRAY TREE TREK TRES TRET TREY TROD TROP TROT TROY TULE TUMP TUNE TUNS TURD TURK TURN TUSK TUTS TYEE TYES TYKE TYNE TYRE WAES WAKE WALE WALK WALL WALY WAME WAND WANE WANK WANS WANT WANY WARD WARE WARK WARM WARN WARP WARS WART WARY WASP WAST WATS WATT WEAK WEAL WEAN WEED WEEK WEEL WEEN WEEP WEES WEET WELD WELL WELT WEND WENS WENT WERE WERT WEST WETS WHAM WHAP WHAT WHEE WHEN WHET WHEY WHOM WHOP WILD WILE WILL WILT WILY WIMP WIND WINE WINK WINS WINY WIRE WIRY WISE WISP WISS WIST WITE WITS WOAD WOES WOKE WOKS WOLD WONK WONS WONT WOOD WOOL WOOS WORD WORE WORK WORM WORN WORT WOST WOTS WRAP WREN WUSS WYES WYLE WYND WYNN WYNS WYTE\n" + ] + } + ], + "source": [ + "show(wordlock)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# How Secure is WordLock?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The lock makes 1118 words (according to my word list). You might say that an attacker who knows the combination is a word would find this lock to be only 11.18% as secure as a 4-digit lock with 10,000 combinations. But in reality, every cable lock is [vulnerable](https://www.sfbike.org/news/video-how-to-lock-your-bike/) to an attacker with wire cutters, or with a knowledge of lock-picking, so security is equally poor for WordLock® and for an equivalent lock with numbers. (You should use a hardened steel U-lock instead.)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Random Locks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 2 asks if a different lock can make more words. As a baseline, before we get to improved locks, I will start with completely random locks, as produced by the function `random_lock`. I use `t=4` to say that by default there are 4 tumblers, and `c=10` to indicate 10 letters on each tumbler (\"c\" for \"circumference\"). I give `random_lock` an argument to seed the random number generator; that makes calls repeatable if desired." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def random_lock(t=4, c=10, seed='seed'):\n", + " \"Make a lock by sampling randomly and uniformly from the alphabet.\"\n", + " random.seed(seed)\n", + " return Lock(Tumbler(random.sample(alphabet, c))\n", + " for i in range(t))\n", + "\n", + "alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: EBHLJPYKQR VNSYPCWBGR BJOHSCFMRP XCSLUNMQJI\n", + "Count: 15\n", + "Words: BROS BYRL EBBS EBON ECRU EGOS ENOL EPOS EROS ERRS HYMN HYPS KNOX PROM PROS\n" + ] + } + ], + "source": [ + "show(random_lock())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wow, that's not very many words. Let's repeat 100 times and take the best one, with \"best\" determined by the function `word_count`:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def word_count(lock): return len(words_from(lock))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: IDQPSFOJCW MQYGODAINT NLRZPXWFBI STGWCOLJEH\n", + "Count: 259\n", + "Words: CABS CAFE CALE CALL CALO CANE CANS CANT CAPE CAPH CAPO CAPS CARE CARL CARS CART CAWS CINE CIRE COBS COFT COIL COLE COLS COLT CONE CONS COPE COPS CORE CORS COWL COWS DABS DAFT DAIS DALE DALS DANE DANG DANS DAPS DARE DART DAWS DAWT DAZE DIBS DIFS DILL DINE DING DINO DINS DINT DIPS DIPT DIRE DIRL DIRT DOIT DOLE DOLL DOLS DOLT DONE DONG DONS DOPE DORE DORS DOWS DOZE DYNE FABS FAIL FALL FANE FANG FANO FANS FARE FARL FARO FART FAZE FIBS FIFE FILE FILL FILO FILS FINE FINO FINS FIRE FIRS FIXT FOBS FOIL FONS FONT FOPS FORE FORT FOWL IDLE IMPS INFO INNS INRO IONS JABS JAIL JANE JAPE JARL JARS JAWS JIBE JIBS JILL JILT JINS JOBS JOLE JOLT JOWL JOWS OAFS OARS ODIC OGLE OGRE OILS OMIT OOPS OOZE OTIC OTIS PAIL PALE PALL PALS PANE PANG PANS PANT PAPS PARE PARS PART PAWL PAWS PILE PILL PINE PING PINS PINT PIPE PIPS POIS POLE POLL POLO POLS PONE PONG PONS POPE POPS PORE PORT POWS PYIC PYRE PYRO QOPH SABE SABS SAFE SAIL SALE SALL SALS SALT SANE SANG SANS SAPS SAWS SIBS SIFT SILL SILO SILT SINE SING SINH SINS SIPE SIPS SIRE SIRS SIZE SMIT SNIT SOBS SOFT SOIL SOLE SOLO SOLS SONE SONG SONS SOPH SOPS SORE SORT SOWS SYBO SYNC SYNE SYPH WABS WAFT WAIL WAIT WALE WALL WANE WANS WANT WAPS WARE WARS WART WAWL WAWS WIFE WILE WILL WILT WINE WING WINO WINS WIPE WIRE WONS WONT WOPS WORE WORT WOWS WYLE WYNS\n" + ] + } + ], + "source": [ + "random_locks = [random_lock(seed=i) for i in range(100)]\n", + "\n", + "show(max(random_locks, key=word_count))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Still not very good. We will need a more systematic approach." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Question 2: More Words (via Greedy Locks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "My first idea for a lock with more words is this: consider each tumbler, one at a time, and fill the tumbler with the letters that make the most words. How do I determine what letters make the most words? A `Counter` does most of the work; we feed it a list of the first letter of each word, and then ask it for the ten most common letters (and their counts): " + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('S', 373),\n", + " ('T', 268),\n", + " ('P', 268),\n", + " ('B', 267),\n", + " ('D', 251),\n", + " ('C', 248),\n", + " ('L', 246),\n", + " ('M', 239),\n", + " ('A', 236),\n", + " ('R', 203)]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "first_letters = [w[0] for w in WORDS]\n", + "\n", + "Counter(first_letters).most_common(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In other words, the letters SPTBDCLMAR are the most common ways to start a word. Let's add up those counts:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2599" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def n_most_common(counter, n): return sum(n for (_, n) in counter.most_common(n))\n", + "\n", + "n_most_common(Counter(first_letters), 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This means that SPTBDCLMAR covers 2,599 words. We don't know for sure that these are the best 10 letters to put on the first tumbler, but we do know that whatever letters are best, they can't form more than 2,599 words, so we have an upper bound on the number of words in a lock (and the 1,118 from `wordlock` is a lower bound).\n", + "\n", + "What letters should we put on the second tumbler? We will do the same thing, but this time don't consider *all* the words in the dictionary; just consider the 2,599 words that start with one of the ten letters on the first tumbler. Continue this way until we fill in all four tumblers. This is called a *greedy* approach, because when we consider each tumbler, we pick the solution that looks best right then, for that tumbler, without consideration for future tumblers." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def greedy_lock(t=4, c=10, words=WORDS):\n", + " \"Make a lock with t tumblers, each consisting of the c letters that cover the most words at that position.\"\n", + " lock = Lock()\n", + " for i in range(t):\n", + " # Make a tumbler of c letters, such that the tumbler covers the most words.\n", + " # Then update words to only include the ones that can be made with this tumbler\n", + " counter = Counter(word[i] for word in words)\n", + " tumbler = Tumbler(L for (L, _) in counter.most_common(c))\n", + " words = [w for w in words if w[i] in tumbler]\n", + " lock.append(tumbler)\n", + " return lock" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: STPBDCLMAR OAIEURLHYN RNALEOTISM SETADNLKPY\n", + "Count: 1177\n", + "Words: AALS AEON AERY AHED AHIS AHOY AILA AILS AIMS AINS AIRN AIRS AIRT AIRY AITS ALAE ALAN ALAS ALEA ALEE ALEK ALES ALIA ALIT ALLS ALLY ALMA ALME ALMS ALOE ALTS ANAL ANAS ANAY ANES ANIL ANIS ANNA ANNE ANOA ANON ANSA ANTA ANTE ANTS ARAK AREA ARES ARIA ARID ARIE ARIL ARMS ARMY ARON ARSE ARTS ARTY AULD AUNT AURA AYAN AYES AYIN AYLA BAAL BAAS BAIL BAIT BALD BALE BALK BALL BALS BAMS BAND BANE BANK BANS BARD BARE BARK BARN BARS BASE BASK BASS BAST BATE BATS BATT BEAD BEAK BEAN BEAT BEEN BEEP BEES BEET BELL BELS BELT BEMA BEND BENE BENS BENT BERK BEST BETA BETS BIAS BILE BILK BILL BIMA BIND BINE BINS BINT BIOS BIRD BIRK BIRL BISE BISK BITE BITS BITT BLAE BLAT BLED BLET BLIN BLIP BLOT BOAS BOAT BOIL BOLA BOLD BOLE BOLL BOLT BOND BONE BONK BONY BOOK BOON BOOS BOOT BORA BORE BORK BORN BORT BOSK BOSS BOTA BOTS BOTT BRAD BRAE BRAN BRAS BRAT BRAY BREA BRED BREE BREN BRIA BRIE BRIN BRIS BRIT BROS BULK BULL BUMP BUMS BUNA BUND BUNK BUNN BUNS BUNT BUOY BURA BURD BURL BURN BURP BURS BURY BUSK BUSS BUST BUSY BUTE BUTS BUTT BYES BYRE BYRL BYTE CAEL CAID CAIN CALE CALK CALL CAME CAMP CAMS CANE CANS CANT CARA CARD CARE CARK CARL CARN CARP CARS CART CASA CASE CASK CAST CATE CATS CEES CEIL CELL CELS CELT CENT CERE CESS CETE CHAD CHAP CHAT CHAY CHIA CHID CHIN CHIP CHIS CHIT CHON CHOP CIAN CINE CION CIRE CIST CITE CITY CLAD CLAN CLAP CLAY CLIP CLOD CLON CLOP CLOT CLOY COAL COAT COED COEN COIL COIN COLA COLD COLE COLS COLT COLY COMA COME COMP CONE CONK CONN CONS CONY COOK COOL COON COOP COOS COOT CORA CORD CORE CORK CORN CORS CORY COSS COST COSY COTE COTS CRAP CRED CRIS CRIT CROP CUED CUES CULL CULT CUNT CURD CURE CURL CURN CURS CURT CUSK CUSP CUSS CUTE CUTS CYAN CYMA CYME CYST DAIS DALE DALS DAME DAMN DAMP DAMS DANA DANE DANK DANS DARE DARK DARN DART DATA DATE DEAD DEAL DEAN DEED DEEP DEES DEET DEIL DELE DELL DELS DELT DEME DEMY DENE DENS DENT DENY DEON DERE DESK DHAK DHAL DIAL DIED DIEL DIES DIET DILL DIME DIMS DINA DINE DINK DINS DINT DIOL DION DIRE DIRK DIRL DIRT DISK DISS DITA DITE DITS DOAT DOES DOIT DOLE DOLL DOLS DOLT DOME DOMS DONA DONE DONS DORE DORK DORP DORS DORY DOSE DOSS DOST DOTE DOTS DOTY DRAT DRAY DREE DREK DRIP DROP DUAD DUAL DUEL DUES DUET DUIT DULL DULY DUMA DUMP DUNE DUNK DUNS DUNT DUOS DURA DURE DURN DUSK DUST DUTY DYAD DYED DYES DYNE LAID LAIN LALL LAMA LAME LAMP LAMS LANA LAND LANE LANK LARA LARD LARK LARS LASE LASS LAST LATE LATS LEAD LEAK LEAL LEAN LEAP LEAS LEEK LEES LEET LEIA LEIS LELA LENA LEND LENS LENT LEON LESS LEST LETS LIAN LIED LIEN LIES LILA LILT LILY LIMA LIME LIMN LIMP LIMY LINA LINE LINK LINN LINS LINT LINY LION LIRA LIRE LISA LISP LIST LITE LITS LOAD LOAN LOID LOIN LOLA LOLL LONE LOOK LOON LOOP LOOS LOOT LORD LORE LORN LORY LOSE LOSS LOST LOTA LOTS LUES LUIS LULL LUMA LUMP LUMS LUNA LUNE LUNK LUNT LUNY LURE LURK LUST LUTE LYES LYLA LYLE LYRA LYRE LYSE MAES MAIA MAID MAIL MAIN MALE MALL MALT MAMA MANA MANE MANS MANY MARA MARE MARK MARL MARS MART MARY MASA MASK MASS MAST MATE MATS MATT MEAD MEAL MEAN MEAT MEED MEEK MEET MELD MELL MELS MELT MEME MEMS MEND MERE MERK MERL MESA MESS META METE MHOS MIEN MILA MILD MILE MILK MILL MILS MILT MIME MINA MIND MINE MINK MINT MIRA MIRE MIRK MIRS MIRY MISE MISS MIST MITE MITT MITY MOAN MOAS MOAT MOIL MOLA MOLD MOLE MOLL MOLS MOLT MOLY MOME MOMS MONA MONK MONS MONY MOOD MOOL MOON MOOS MOOT MORA MORE MORN MORS MORT MOSK MOSS MOST MOTE MOTS MOTT MULE MULL MUMP MUMS MUNS MUON MURA MURE MURK MUSA MUSE MUSK MUSS MUST MUTE MUTS MUTT MYLA MYNA MYRA PAID PAIK PAIL PAIN PALE PALL PALP PALS PALY PAMS PANE PANS PANT PARA PARD PARE PARK PARS PART PASE PASS PAST PATE PATS PATY PEAK PEAL PEAN PEAS PEAT PEED PEEK PEEL PEEN PEEP PEES PEIN PELE PELT PEND PENS PENT PEON PERE PERK PERP PERT PEST PETS PHAT PHIS PHON PHOT PIAL PIAN PIAS PIED PIES PILE PILL PILY PIMA PIMP PINA PINE PINK PINS PINT PINY PION PIRN PISS PITA PITS PITY PLAN PLAT PLAY PLEA PLED PLIE PLOD PLOP PLOT PLOY POET POIS POLE POLL POLS POLY POME POMP POMS POND PONE PONS PONY POOD POOL POON POOP POOS PORE PORK PORN PORT POSE POST POSY POTS PRAT PRAY PREE PREP PREY PROA PROD PROP PROS PULA PULE PULL PULP PULS PUMA PUMP PUNA PUNK PUNS PUNT PUNY PURE PURL PURS PUSS PUTS PUTT PYAS PYES PYIN PYRE RAIA RAID RAIL RAIN RAIS RALE RAMP RAMS RAND RANK RANT RARE RASE RASP RATE RATS READ REAL REAP REED REEK REEL REES REID REIN REIS RELY REMS REMY REND RENE RENT REST RETE RETS RHEA RHOS RIAL RIAN RIAS RIEL RILE RILL RIME RIMS RIMY RIND RINK RINS RIOT RISE RISK RITA RITE ROAD ROAN ROES ROIL ROLE ROLL ROME ROMP ROMS ROOD ROOK ROOT RORY ROSA ROSE ROSS ROSY ROTA ROTE ROTL ROTS RUED RUES RUIN RULE RULY RUMP RUMS RUNE RUNS RUNT RUSE RUSK RUST RUTS RYAN RYAS RYES RYND RYOT SAAD SAID SAIL SAIN SALE SALL SALP SALS SALT SAME SAMP SANA SAND SANE SANK SANS SARA SARD SARK SASS SATE SEAL SEAN SEAS SEAT SEED SEEK SEEL SEEN SEEP SEES SEIS SELL SELS SEME SEND SENE SENT SERA SERE SERS SETA SETS SETT SHAD SHAE SHAT SHAY SHEA SHED SHES SHIN SHIP SHIT SHOD SHOE SHOP SHOT SIAL SILD SILK SILL SILT SIMA SIMP SIMS SINE SINK SINS SIRE SIRS SITE SITS SLAP SLAT SLAY SLED SLID SLIP SLIT SLOE SLOP SLOT SNAP SNED SNIP SNIT SNOT SOAK SOAP SOIL SOLA SOLD SOLE SOLS SOMA SOME SOMS SONE SONS SOOK SOON SOOT SORA SORD SORE SORN SORT SOTS SRIS SUED SUES SUET SUIT SULK SUMP SUMS SUNK SUNN SUNS SURA SURD SURE SUSS SYED SYNE TAEL TAIL TAIN TALA TALE TALK TALL TAME TAMP TAMS TANK TANS TAOS TARA TARE TARN TARP TARS TART TASK TASS TATE TATS TEAK TEAL TEAS TEAT TEED TEEL TEEN TEES TELA TELE TELL TELS TEMP TEND TENS TENT TERN TESS TEST TETS THAE THAN THAT THEA THEE THEN THEY THIN THIS TIED TIES TILE TILL TILS TILT TIME TINA TINE TINS TINT TINY TIRE TIRL TITS TOAD TOEA TOED TOES TOIL TOIT TOLA TOLD TOLE TOLL TOME TOMS TONE TONS TONY TOOK TOOL TOON TOOT TORA TORE TORN TORS TORT TORY TOSS TOST TOTE TOTS TRAD TRAE TRAP TRAY TREE TREK TRES TRET TREY TRIP TROD TROP TROT TROY TUIS TULE TUMP TUNA TUNE TUNS TURD TURK TURN TUSK TUTS TYEE TYES TYIN TYNE TYRE\n" + ] + } + ], + "source": [ + "show(greedy_lock())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Remember that the `wordlock` gave 1118 words, so the greedy lock with 1177 is better, but only by 5%. Is it possible to do better still? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Question 2: More Words (via Improved Locks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's another idea to get more words from a lock:\n", + "\n", + "1. Start with some lock.\n", + "2. Pick, at random, one letter on one tumbler and change it to a new letter.\n", + "3. If the change yields more words, keep the change; otherwise discard the change.\n", + "4. Repeat.\n", + "\n", + "We can implement this strategy with the function `improved_lock`, which calls `changed_lock` to make a random change:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def improved_lock(lock, steps=3000):\n", + " \"Randomly change letters in lock, keeping changes that improve the score.\"\n", + " score = word_count(lock)\n", + " for i in range(steps):\n", + " lock2 = changed_lock(lock)\n", + " score2 = word_count(lock2)\n", + " if score2 >= score: \n", + " lock, score = lock2, score2\n", + " return lock\n", + "\n", + "def changed_lock(lock): \n", + " \"Change one letter in one tumbler.\"\n", + " lock2 = Lock(lock)\n", + " i = random.randrange(len(lock))\n", + " old = random.choice(lock[i])\n", + " new = random.choice([L for L in alphabet if L not in lock[i]])\n", + " lock2[i] = lock2[i].replace(old, new)\n", + " return lock2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how this does to improve the best lock we've seen so far, the greedy lock:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: STPBDCLMWF OAIEURLHYP RNALEOTISC SETADNLKHY\n", + "Count: 1240\n", + "Words: BAAL BAAS BACH BACK BAIL BAIT BALD BALE BALK BALL BALS BAND BANE BANK BANS BARD BARE BARK BARN BARS BASE BASH BASK BASS BAST BATE BATH BATS BATT BEAD BEAK BEAN BEAT BECK BEEN BEES BEET BELL BELS BELT BEND BENE BENS BENT BERK BEST BETA BETH BETS BIAS BICE BILE BILK BILL BIND BINE BINS BINT BIOS BIRD BIRK BIRL BISE BISK BITE BITS BITT BLAE BLAH BLAT BLED BLET BLIN BLOT BOAS BOAT BOCK BOIL BOLA BOLD BOLE BOLL BOLT BOND BONE BONK BONY BOOK BOON BOOS BOOT BORA BORE BORK BORN BORT BOSH BOSK BOSS BOTA BOTH BOTS BOTT BRAD BRAE BRAN BRAS BRAT BRAY BREA BRED BREE BREN BRIA BRIE BRIN BRIS BRIT BROS BUCK BULK BULL BUNA BUND BUNK BUNN BUNS BUNT BUOY BURA BURD BURL BURN BURS BURY BUSH BUSK BUSS BUST BUSY BUTE BUTS BUTT BYES BYRE BYRL BYTE CACA CAEL CAID CAIN CALE CALK CALL CANE CANS CANT CARA CARD CARE CARK CARL CARN CARS CART CASA CASE CASH CASK CAST CATE CATS CECA CEES CEIL CELL CELS CELT CENT CERE CESS CETE CHAD CHAT CHAY CHIA CHID CHIN CHIS CHIT CHON CIAN CINE CION CIRE CIST CITE CITY CLAD CLAN CLAY CLOD CLON CLOT CLOY COAL COAT COCA COCK COED COEN COIL COIN COLA COLD COLE COLS COLT COLY CONE CONK CONN CONS CONY COOK COOL COON COOS COOT CORA CORD CORE CORK CORN CORS CORY COSH COSS COST COSY COTE COTS CRED CRIS CRIT CUED CUES CULL CULT CUNT CURD CURE CURL CURN CURS CURT CUSK CUSS CUTE CUTS CYAN CYST DACE DAIS DALE DALS DANA DANE DANK DANS DARE DARK DARN DART DASH DATA DATE DEAD DEAL DEAN DECK DEED DEES DEET DEIL DELE DELL DELS DELT DENE DENS DENT DENY DEON DERE DESK DHAK DHAL DIAL DICE DICK DIED DIEL DIES DIET DILL DINA DINE DINK DINS DINT DIOL DION DIRE DIRK DIRL DIRT DISH DISK DISS DITA DITE DITS DOAT DOCK DOCS DOES DOIT DOLE DOLL DOLS DOLT DONA DONE DONS DORE DORK DORS DORY DOSE DOSS DOST DOTE DOTH DOTS DOTY DRAT DRAY DREE DREK DUAD DUAL DUCE DUCK DUCT DUEL DUES DUET DUIT DULL DULY DUNE DUNK DUNS DUNT DUOS DURA DURE DURN DUSK DUST DUTY DYAD DYED DYES DYNE FACE FACT FAIL FAIN FALL FANE FANS FARD FARE FARL FART FASH FAST FATE FATS FEAL FEAT FECK FEED FEEL FEES FEET FELL FELT FEND FENS FEOD FERE FERN FESS FEST FETA FETE FETS FIAT FICE FILA FILE FILL FILS FIND FINE FINK FINN FINS FIRE FIRN FIRS FISH FIST FITS FLAK FLAN FLAT FLAY FLEA FLED FLEE FLEY FLIT FLOE FOAL FOES FOIL FOIN FOLD FOLK FOND FONS FONT FOOD FOOL FOOT FORA FORD FORE FORK FORT FOSS FRAE FRAT FRAY FRED FREE FRET FRIT FROE FUCK FUEL FULL FUND FUNK FUNS FURL FURS FURY FUSE FUSS FYCE LACE LACK LACS LACY LAID LAIN LALL LANA LAND LANE LANK LARA LARD LARK LARS LASE LASH LASS LAST LATE LATH LATS LEAD LEAH LEAK LEAL LEAN LEAS LECH LEEK LEES LEET LEIA LEIS LELA LENA LEND LENS LENT LEON LESS LEST LETS LIAN LICE LICH LICK LIED LIEN LIES LILA LILT LILY LINA LINE LINK LINN LINS LINT LINY LION LIRA LIRE LISA LIST LITE LITS LOAD LOAN LOCA LOCH LOCK LOID LOIN LOLA LOLL LONE LOOK LOON LOOS LOOT LORD LORE LORN LORY LOSE LOSS LOST LOTA LOTH LOTS LUCA LUCE LUCK LUCY LUES LUIS LULL LUNA LUNE LUNK LUNT LUNY LURE LURK LUSH LUST LUTE LYCH LYES LYLA LYLE LYRA LYRE LYSE MACE MACH MACK MACS MACY MAES MAIA MAID MAIL MAIN MALE MALL MALT MANA MANE MANS MANY MARA MARE MARK MARL MARS MART MARY MASA MASH MASK MASS MAST MATE MATH MATS MATT MEAD MEAL MEAN MEAT MEED MEEK MEET MELD MELL MELS MELT MEND MERE MERK MERL MESA MESH MESS META METE METH MHOS MIAH MICA MICE MICK MICS MIEN MILA MILD MILE MILK MILL MILS MILT MINA MIND MINE MINK MINT MIRA MIRE MIRK MIRS MIRY MISE MISS MIST MITE MITT MITY MOAN MOAS MOAT MOCK MOCS MOIL MOLA MOLD MOLE MOLL MOLS MOLT MOLY MONA MONK MONS MONY MOOD MOOL MOON MOOS MOOT MORA MORE MORN MORS MORT MOSH MOSK MOSS MOST MOTE MOTH MOTS MOTT MUCH MUCK MULE MULL MUNS MUON MURA MURE MURK MUSA MUSE MUSH MUSK MUSS MUST MUTE MUTS MUTT MYAH MYCS MYLA MYNA MYRA MYTH PACA PACE PACK PACS PACT PACY PAID PAIK PAIL PAIN PALE PALL PALS PALY PANE PANS PANT PARA PARD PARE PARK PARS PART PASE PASH PASS PAST PATE PATH PATS PATY PEAK PEAL PEAN PEAS PEAT PECH PECK PECS PEED PEEK PEEL PEEN PEES PEIN PELE PELT PEND PENS PENT PEON PERE PERK PERT PEST PETS PHAT PHIS PHON PHOT PIAL PIAN PIAS PICA PICE PICK PICS PIED PIES PILE PILL PILY PINA PINE PINK PINS PINT PINY PION PIRN PISH PISS PITA PITH PITS PITY PLAN PLAT PLAY PLEA PLED PLIE PLOD PLOT PLOY POCK POET POIS POLE POLL POLS POLY POND PONE PONS PONY POOD POOH POOL POON POOS PORE PORK PORN PORT POSE POSH POST POSY POTS PRAT PRAY PREE PREY PROA PROD PROS PUCE PUCK PULA PULE PULL PULS PUNA PUNK PUNS PUNT PUNY PURE PURL PURS PUSH PUSS PUTS PUTT PYAS PYES PYIN PYRE SAAD SACK SACS SAID SAIL SAIN SALE SALL SALS SALT SANA SAND SANE SANK SANS SARA SARD SARK SASH SASS SATE SEAL SEAN SEAS SEAT SECS SECT SEED SEEK SEEL SEEN SEES SEIS SELL SELS SEND SENE SENT SERA SERE SERS SETA SETH SETS SETT SHAD SHAE SHAH SHAT SHAY SHEA SHED SHES SHIN SHIT SHOD SHOE SHOT SIAL SICE SICK SICS SILD SILK SILL SILT SINE SINH SINK SINS SIRE SIRS SITE SITH SITS SLAT SLAY SLED SLID SLIT SLOE SLOT SOAK SOCA SOCK SOIL SOLA SOLD SOLE SOLS SONE SONS SOOK SOON SOOT SORA SORD SORE SORN SORT SOTH SOTS SPAE SPAN SPAS SPAT SPAY SPED SPIK SPIN SPIT SPOT SPRY SRIS SUCH SUCK SUED SUES SUET SUIT SULK SUNK SUNN SUNS SURA SURD SURE SUSS SYCE SYED SYNE TACE TACH TACK TACT TAEL TAIL TAIN TALA TALE TALK TALL TANK TANS TAOS TARA TARE TARN TARS TART TASK TASS TATE TATS TEAK TEAL TEAS TEAT TECH TEED TEEL TEEN TEES TELA TELE TELL TELS TEND TENS TENT TERN TESS TEST TETH TETS THAE THAN THAT THEA THEE THEN THEY THIN THIS TICK TICS TIED TIES TILE TILL TILS TILT TINA TINE TINS TINT TINY TIRE TIRL TITS TOAD TOEA TOED TOES TOIL TOIT TOLA TOLD TOLE TOLL TONE TONS TONY TOOK TOOL TOON TOOT TORA TORE TORN TORS TORT TORY TOSH TOSS TOST TOTE TOTS TRAD TRAE TRAY TREE TREK TRES TRET TREY TROD TROT TROY TUCK TUIS TULE TUNA TUNE TUNS TURD TURK TURN TUSH TUSK TUTS TYCE TYEE TYES TYIN TYNE TYRE WACK WAES WAIL WAIN WAIT WALE WALK WALL WALY WAND WANE WANK WANS WANT WANY WARD WARE WARK WARN WARS WART WARY WASH WAST WATS WATT WEAK WEAL WEAN WEED WEEK WEEL WEEN WEES WEET WELD WELL WELT WEND WENS WENT WERE WERT WEST WETS WHAT WHEE WHEN WHET WHEY WHID WHIN WHIT WHOA WICH WICK WILD WILE WILL WILT WILY WIND WINE WINK WINS WINY WIRE WIRY WISE WISH WISS WIST WITE WITH WITS WOAD WOES WOLD WONK WONS WONT WOOD WOOL WOOS WORD WORE WORK WORN WORT WOST WOTS WREN WRIT WUSS WYCH WYES WYLE WYND WYNN WYNS WYTE\n" + ] + } + ], + "source": [ + "show(improved_lock(greedy_lock()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How about starting from a random lock? " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: TMSLBPFWCD AEHYLORIWU CNATELISRO LDSYANKETH\n", + "Count: 1240\n", + "Words: BAAL BAAS BACH BACK BAIL BAIT BALD BALE BALK BALL BALS BAND BANE BANK BANS BARD BARE BARK BARN BARS BASE BASH BASK BASS BAST BATE BATH BATS BATT BEAD BEAK BEAN BEAT BECK BEEN BEES BEET BELL BELS BELT BEND BENE BENS BENT BERK BEST BETA BETH BETS BIAS BICE BILE BILK BILL BIND BINE BINS BINT BIOS BIRD BIRK BIRL BISE BISK BITE BITS BITT BLAE BLAH BLAT BLED BLET BLIN BLOT BOAS BOAT BOCK BOIL BOLA BOLD BOLE BOLL BOLT BOND BONE BONK BONY BOOK BOON BOOS BOOT BORA BORE BORK BORN BORT BOSH BOSK BOSS BOTA BOTH BOTS BOTT BRAD BRAE BRAN BRAS BRAT BRAY BREA BRED BREE BREN BRIA BRIE BRIN BRIS BRIT BROS BUCK BULK BULL BUNA BUND BUNK BUNN BUNS BUNT BUOY BURA BURD BURL BURN BURS BURY BUSH BUSK BUSS BUST BUSY BUTE BUTS BUTT BYES BYRE BYRL BYTE CACA CAEL CAID CAIN CALE CALK CALL CANE CANS CANT CARA CARD CARE CARK CARL CARN CARS CART CASA CASE CASH CASK CAST CATE CATS CECA CEES CEIL CELL CELS CELT CENT CERE CESS CETE CHAD CHAT CHAY CHIA CHID CHIN CHIS CHIT CHON CIAN CINE CION CIRE CIST CITE CITY CLAD CLAN CLAY CLOD CLON CLOT CLOY COAL COAT COCA COCK COED COEN COIL COIN COLA COLD COLE COLS COLT COLY CONE CONK CONN CONS CONY COOK COOL COON COOS COOT CORA CORD CORE CORK CORN CORS CORY COSH COSS COST COSY COTE COTS CRED CRIS CRIT CUED CUES CULL CULT CUNT CURD CURE CURL CURN CURS CURT CUSK CUSS CUTE CUTS CYAN CYST DACE DAIS DALE DALS DANA DANE DANK DANS DARE DARK DARN DART DASH DATA DATE DEAD DEAL DEAN DECK DEED DEES DEET DEIL DELE DELL DELS DELT DENE DENS DENT DENY DEON DERE DESK DHAK DHAL DIAL DICE DICK DIED DIEL DIES DIET DILL DINA DINE DINK DINS DINT DIOL DION DIRE DIRK DIRL DIRT DISH DISK DISS DITA DITE DITS DOAT DOCK DOCS DOES DOIT DOLE DOLL DOLS DOLT DONA DONE DONS DORE DORK DORS DORY DOSE DOSS DOST DOTE DOTH DOTS DOTY DRAT DRAY DREE DREK DUAD DUAL DUCE DUCK DUCT DUEL DUES DUET DUIT DULL DULY DUNE DUNK DUNS DUNT DUOS DURA DURE DURN DUSK DUST DUTY DYAD DYED DYES DYNE FACE FACT FAIL FAIN FALL FANE FANS FARD FARE FARL FART FASH FAST FATE FATS FEAL FEAT FECK FEED FEEL FEES FEET FELL FELT FEND FENS FEOD FERE FERN FESS FEST FETA FETE FETS FIAT FICE FILA FILE FILL FILS FIND FINE FINK FINN FINS FIRE FIRN FIRS FISH FIST FITS FLAK FLAN FLAT FLAY FLEA FLED FLEE FLEY FLIT FLOE FOAL FOES FOIL FOIN FOLD FOLK FOND FONS FONT FOOD FOOL FOOT FORA FORD FORE FORK FORT FOSS FRAE FRAT FRAY FRED FREE FRET FRIT FROE FUCK FUEL FULL FUND FUNK FUNS FURL FURS FURY FUSE FUSS FYCE LACE LACK LACS LACY LAID LAIN LALL LANA LAND LANE LANK LARA LARD LARK LARS LASE LASH LASS LAST LATE LATH LATS LEAD LEAH LEAK LEAL LEAN LEAS LECH LEEK LEES LEET LEIA LEIS LELA LENA LEND LENS LENT LEON LESS LEST LETS LIAN LICE LICH LICK LIED LIEN LIES LILA LILT LILY LINA LINE LINK LINN LINS LINT LINY LION LIRA LIRE LISA LIST LITE LITS LOAD LOAN LOCA LOCH LOCK LOID LOIN LOLA LOLL LONE LOOK LOON LOOS LOOT LORD LORE LORN LORY LOSE LOSS LOST LOTA LOTH LOTS LUCA LUCE LUCK LUCY LUES LUIS LULL LUNA LUNE LUNK LUNT LUNY LURE LURK LUSH LUST LUTE LYCH LYES LYLA LYLE LYRA LYRE LYSE MACE MACH MACK MACS MACY MAES MAIA MAID MAIL MAIN MALE MALL MALT MANA MANE MANS MANY MARA MARE MARK MARL MARS MART MARY MASA MASH MASK MASS MAST MATE MATH MATS MATT MEAD MEAL MEAN MEAT MEED MEEK MEET MELD MELL MELS MELT MEND MERE MERK MERL MESA MESH MESS META METE METH MHOS MIAH MICA MICE MICK MICS MIEN MILA MILD MILE MILK MILL MILS MILT MINA MIND MINE MINK MINT MIRA MIRE MIRK MIRS MIRY MISE MISS MIST MITE MITT MITY MOAN MOAS MOAT MOCK MOCS MOIL MOLA MOLD MOLE MOLL MOLS MOLT MOLY MONA MONK MONS MONY MOOD MOOL MOON MOOS MOOT MORA MORE MORN MORS MORT MOSH MOSK MOSS MOST MOTE MOTH MOTS MOTT MUCH MUCK MULE MULL MUNS MUON MURA MURE MURK MUSA MUSE MUSH MUSK MUSS MUST MUTE MUTS MUTT MYAH MYCS MYLA MYNA MYRA MYTH PACA PACE PACK PACS PACT PACY PAID PAIK PAIL PAIN PALE PALL PALS PALY PANE PANS PANT PARA PARD PARE PARK PARS PART PASE PASH PASS PAST PATE PATH PATS PATY PEAK PEAL PEAN PEAS PEAT PECH PECK PECS PEED PEEK PEEL PEEN PEES PEIN PELE PELT PEND PENS PENT PEON PERE PERK PERT PEST PETS PHAT PHIS PHON PHOT PIAL PIAN PIAS PICA PICE PICK PICS PIED PIES PILE PILL PILY PINA PINE PINK PINS PINT PINY PION PIRN PISH PISS PITA PITH PITS PITY PLAN PLAT PLAY PLEA PLED PLIE PLOD PLOT PLOY POCK POET POIS POLE POLL POLS POLY POND PONE PONS PONY POOD POOH POOL POON POOS PORE PORK PORN PORT POSE POSH POST POSY POTS PRAT PRAY PREE PREY PROA PROD PROS PUCE PUCK PULA PULE PULL PULS PUNA PUNK PUNS PUNT PUNY PURE PURL PURS PUSH PUSS PUTS PUTT PYAS PYES PYIN PYRE SAAD SACK SACS SAID SAIL SAIN SALE SALL SALS SALT SANA SAND SANE SANK SANS SARA SARD SARK SASH SASS SATE SEAL SEAN SEAS SEAT SECS SECT SEED SEEK SEEL SEEN SEES SEIS SELL SELS SEND SENE SENT SERA SERE SERS SETA SETH SETS SETT SHAD SHAE SHAH SHAT SHAY SHEA SHED SHES SHIN SHIT SHOD SHOE SHOT SIAL SICE SICK SICS SILD SILK SILL SILT SINE SINH SINK SINS SIRE SIRS SITE SITH SITS SLAT SLAY SLED SLID SLIT SLOE SLOT SOAK SOCA SOCK SOIL SOLA SOLD SOLE SOLS SONE SONS SOOK SOON SOOT SORA SORD SORE SORN SORT SOTH SOTS SRIS SUCH SUCK SUED SUES SUET SUIT SULK SUNK SUNN SUNS SURA SURD SURE SUSS SWAN SWAT SWAY SWOT SYCE SYED SYNE TACE TACH TACK TACT TAEL TAIL TAIN TALA TALE TALK TALL TANK TANS TAOS TARA TARE TARN TARS TART TASK TASS TATE TATS TEAK TEAL TEAS TEAT TECH TEED TEEL TEEN TEES TELA TELE TELL TELS TEND TENS TENT TERN TESS TEST TETH TETS THAE THAN THAT THEA THEE THEN THEY THIN THIS TICK TICS TIED TIES TILE TILL TILS TILT TINA TINE TINS TINT TINY TIRE TIRL TITS TOAD TOEA TOED TOES TOIL TOIT TOLA TOLD TOLE TOLL TONE TONS TONY TOOK TOOL TOON TOOT TORA TORE TORN TORS TORT TORY TOSH TOSS TOST TOTE TOTS TRAD TRAE TRAY TREE TREK TRES TRET TREY TROD TROT TROY TUCK TUIS TULE TUNA TUNE TUNS TURD TURK TURN TUSH TUSK TUTS TWAE TWAS TWAT TWEE TWIN TWIT TWOS TYCE TYEE TYES TYIN TYNE TYRE WACK WAES WAIL WAIN WAIT WALE WALK WALL WALY WAND WANE WANK WANS WANT WANY WARD WARE WARK WARN WARS WART WARY WASH WAST WATS WATT WEAK WEAL WEAN WEED WEEK WEEL WEEN WEES WEET WELD WELL WELT WEND WENS WENT WERE WERT WEST WETS WHAT WHEE WHEN WHET WHEY WHID WHIN WHIT WHOA WICH WICK WILD WILE WILL WILT WILY WIND WINE WINK WINS WINY WIRE WIRY WISE WISH WISS WIST WITE WITH WITS WOAD WOES WOLD WONK WONS WONT WOOD WOOL WOOS WORD WORE WORK WORN WORT WOST WOTS WREN WRIT WUSS WYCH WYES WYLE WYND WYNN WYNS WYTE\n" + ] + } + ], + "source": [ + "show(improved_lock(random_lock()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We got up to 1240 words, but can we go beyond? I'll improve 50 random locks, taking 6000 steps each rather than just 3000 (this will take around 15 minutes):" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15min 48s, sys: 9.03 s, total: 15min 57s\n", + "Wall time: 19min 40s\n" + ] + } + ], + "source": [ + "%time improved_locks = [improved_lock(random_lock(seed=i), 6000) for i in range(50)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what we got:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({1232: 3, 1235: 5, 1240: 42})" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Counter(map(word_count, improved_locks))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So 42/50 locks got a score of 1240.\n", + "My first reaction to this was that if I discovered 42 different locks with score 1240, then probably there is at least one undiscovered lock with a score above 1240. But a discussion with [Matt Chisholm](https://blog.glyphobet.net/faq) changed my thinking. The key is to realize that some locks that look different are actually the same; they just have the letters in a different order. I define the function `alock` to put each tumbler into alphabetical order (and make the lock be a tuple rather than a list, so that it can be an entry in a `dict` or `set`):" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def alock(lock):\n", + " \"Canonicalize lock by alphabetizing the letters in each tumbler.\"\n", + " return tuple(Tumbler(sorted(tumbler)) for tumbler in lock)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we can find the unique locks:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{('BCDFHLMPST', 'AEHILORUWY', 'ACELMNORST', 'ADEKLNPSTY'): 1232,\n", + " ('BCDFLMPSTW', 'AEHILOPRUY', 'ACEILNORST', 'ADEHKLNSTY'): 1240,\n", + " ('BCDFLMPSTW', 'AEHILORUWY', 'ACEILNORST', 'ADEHKLNSTY'): 1240,\n", + " ('BCDGLMPSTW', 'AEHILORUWY', 'AEILMNORST', 'ADEKLNPSTY'): 1235}" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def unique_locks(locks):\n", + " \"Return a dict of {lock: word_count} for the distinct locks.\"\n", + " return {alock(lock): word_count(lock) \n", + " for lock in locks}\n", + "\n", + "unique_locks(improved_locks)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So out of the 50 `improved_locks` there are actually only 4 distinct ones. And only two have a score of 1240:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{('BCDFLMPSTW', 'AEHILOPRUY', 'ACEILNORST', 'ADEHKLNSTY'),\n", + " ('BCDFLMPSTW', 'AEHILORUWY', 'ACEILNORST', 'ADEHKLNSTY')}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "peaks = {alock(lock) for lock in improved_locks if word_count(lock) == 1240}\n", + "peaks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These two differ in just one letter (a `P` or a `W` in the second tumbler). \n", + "\n", + "This discovery changes my whole thinking about the space of scores for locks. Previously I imagined a spiky \"porcupine-shaped\" landscape, with 42 different peaks hitting a height of 1240. But now I have a different picture of the landscape: a single peak containing the two locks (one with a `P` and one with a `W`), surrounded by rolling hills. To verify this picture, I'll look at all the neighbors of the two peak locks, and see which ones are at least 1240:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{('BCDFLMPSTW', 'AEHILOPRUY', 'ACEILNORST', 'ADEHKLNSTY'): 1240,\n", + " ('BCDFLMPSTW', 'AEHILORUWY', 'ACEILNORST', 'ADEHKLNSTY'): 1240}" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alphabetset = set(alphabet)\n", + "\n", + "def neighborhood(lock): \n", + " \"Yield all locks resulting from a change of one letter in one tumbler.\"\n", + " for i in range(len(lock)):\n", + " for new in alphabetset - set(lock[i]):\n", + " for old in lock[i]:\n", + " lock2 = Lock(lock)\n", + " lock2[i] = lock2[i].replace(old, new)\n", + " yield lock2\n", + " \n", + "unique_locks(lock for peak in peaks for lock in neighborhood(peak) if word_count(lock) >= 1240)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nothing new. This doesn't prove there is no lock with score over 1240, but it does mean we have looked hard to find one and failed.\n", + "\n", + "# Question 3: Simultaneous Words" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Can we make a lock that spells 10 words simultaneously? One possible approach would be to start with any lock and randomly change it (just as we did with `improved_lock`), but measure improvements by the number of words formed. My intuition is that this approach would work, eventually, but that progress would be very slow, because most random changes to a letter would not make a word.\n", + "\n", + "An alternative approach is to think of the lock not as a list of 4 vertical tumblers (each with 10 letters), but rather as a list of 10 horizontal words (each with 4 letters). I'll call this the *word list* representation, and note that a lock and a word list are *[matrix transposes](http://en.wikipedia.org/wiki/Transpose)* of each other—they swap rows for columns. There is an [old trick](https://books.google.com/books?id=eH6jBQAAQBAJ&pg=PA574&lpg=PA574&dq=lisp+transpose+matrix&source=bl&ots=Yixwj8m3k4&sig=KoeuJnFhRnJsiD06_Cx56rUOetQ&hl=en&sa=X&ved=0CB4Q6AEwAGoVChMIyM-WiriLxgIVD6OICh2QcwBK#v=onepage&q=transpose%20matrix&f=false) to compute the transpose of a matrix `M` with the expression `zip(*M)`. But `zip` returns tuples; we want strings, so we can define `transpose` as:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def transpose(strings): return [Word(letters) for letters in zip(*strings)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can see the transpose of the `wordlock` is a list of words:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['SLED',\n", + " 'PENS',\n", + " 'HYMN',\n", + " 'MHLM',\n", + " 'TNRP',\n", + " 'WRTY',\n", + " 'DUAL',\n", + " 'LOOK',\n", + " 'FAST',\n", + " 'BIKE']" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transpose(['SPHMTWDLFB', \n", + " 'LEYHNRUOAI', \n", + " 'ENMLRTAOSK', \n", + " 'DSNMPYLKTE'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first row of the word list has the letters SLED, because those are the letters in the first column of the lock. You can see that the WordLock® is designed to spell out LOOK FAST BIKE, among other words.\n", + "\n", + "Now we're ready to find a good word list with this strategy:\n", + "\n", + "1. Start with some word list (e.g., a random sample of 10 words from `WORDS`).\n", + "2. Pick, at random, one word and change it to a new word.\n", + "3. If the change is an improvement, keep the change; otherwise discard the change.\n", + "4. Repeat.\n", + "\n", + "But what counts as an improvement? We can't improve the number of words, because we start with 10 words, and every change also gives us 10 words. Rather, we will try to improve the number of duplicate letters on any tumbler (of the lock that corresponds to the word list). We improve by reducing the number of duplicate letters, and stop when there are no duplicates.\n", + "\n", + "The following code implements this approach:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def improved_wordlist(wordlist):\n", + " \"Find a wordlist that has no duplicate letters, via random changes to wordlist.\"\n", + " score = duplicates(wordlist)\n", + " while score > 0:\n", + " wordlist2 = changed_wordlist(wordlist)\n", + " score2 = duplicates(wordlist2)\n", + " if score2 < score: \n", + " wordlist, score = wordlist2, score2\n", + " return wordlist\n", + " \n", + "def duplicates(wordlist):\n", + " \"The number of duplicate letters across all the tumblers of the lock that corresponds to this wordlist.\"\n", + " lock = transpose(wordlist) \n", + " def duplicates(tumbler): return len(tumbler) - len(set(tumbler))\n", + " return sum(duplicates(tumbler) for tumbler in lock)\n", + "\n", + "def changed_wordlist(wordlist, words=list(WORDS)):\n", + " \"Make a copy of wordlist and replace one of the words.\"\n", + " copy = list(wordlist)\n", + " i = random.randrange(len(wordlist))\n", + " copy[i] = random.choice(words)\n", + " return copy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The structure of `improved_wordlist` is similar to `improved_lock`, with a few differences:\n", + "1. We are minimizing duplicates, not maximizing word count. \n", + "2. We stop when the score is 0, rather than continuing for a given number of iterations.\n", + "3. We want to make a `random.choice` from `WORDS`. But `random.choice` can't operate on a `set`, so we\n", + "have to introduce `words=list(WORDS)`.\n", + "\n", + "Now we can find some wordlists:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['KNUR',\n", + " 'FLAG',\n", + " 'APES',\n", + " 'EVIL',\n", + " 'COZY',\n", + " 'TICK',\n", + " 'PHON',\n", + " 'LATU',\n", + " 'DUPE',\n", + " 'REFT']" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "improved_wordlist(random.sample(WORDS, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was easy! Can we go to 11?" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['BRAS',\n", + " 'EMIR',\n", + " 'NIPA',\n", + " 'PESO',\n", + " 'ONYX',\n", + " 'WYNN',\n", + " 'CUKE',\n", + " 'MOLY',\n", + " 'FLOC',\n", + " 'THEM',\n", + " 'HARL']" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "improved_wordlist(random.sample(WORDS, 11))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Improving Anything" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now have two similar functions, `improved_lock` and `improved_wordlist`. Could (and should?) we replace them by a single function, say, `improved`, that could improve locks, wordlists, and anything else?\n", + "\n", + "The answer is: *yes* we could, and *maybe* we should.\n", + "\n", + "It is nice to form an abstraction for the idea of *improvement*. (Traditionally, the method we have used for improvement has been called *hill-climbing*, because of the analogy that the score is like the elevation on a topological map, and we are trying to find our way to a peak.)\n", + "\n", + "However, there are many variations on the theme of *improvement*: maximizing or minimizing? Repeat for a given number of iterations, or continue until we meet a goal? I don't want `improved` to have an argument list a mile long, and I felt that five arguments is right on the border of acceptable. The arguments are:\n", + "1. `item`: The object to start with; this is what we will try to improve.\n", + "2. `changed`: a function that generates a new item.\n", + "3. `scorer`: a function that evaluates the quality of an item.\n", + "4. `extremum`: should be `max` if we are maximizing scores, or `min` if we are minimizing scores.\n", + "5. `stop`: a predicate with args `(i, score, item)`, where `i` is the iteration number, and `score` is `scorer(item)`. Return `True` to stop.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def improved(item, changed, scorer, extremum, stop):\n", + " \"\"\"Apply the function `changed` to `item` and evaluate with the function `scorer`;\n", + " When `stop(i, score)` is true, return `item`.\"\"\"\n", + " score = scorer(item)\n", + " for i in itertools.count(0):\n", + " if stop(i, score):\n", + " return item\n", + " item2 = changed(item)\n", + " score2 = scorer(item2)\n", + " if score2 == extremum(score, score2):\n", + " item, score = item2, score2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can re-implement `improved_lock` and `improved_wordlist` using `improved`:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def improved_lock(lock, steps=3000):\n", + " \"Randomly change letters in lock, keeping changes that improve the score.\"\n", + " return improved(lock, changed_lock, word_count, max,\n", + " lambda i, _: i == steps)\n", + "\n", + "def improved_wordlist(wordlist):\n", + " \"Find a wordlist that has no duplicate letters, via random changes to wordlist.\"\n", + " return improved(wordlist, changed_wordlist, duplicates, min,\n", + " lambda _, score: score == 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lock: TMSLBPFWCD AEHYLORIWU CNATELISRO LDSYANKETH\n", + "Count: 1240\n", + "Words: BAAL BAAS BACH BACK BAIL BAIT BALD BALE BALK BALL BALS BAND BANE BANK BANS BARD BARE BARK BARN BARS BASE BASH BASK BASS BAST BATE BATH BATS BATT BEAD BEAK BEAN BEAT BECK BEEN BEES BEET BELL BELS BELT BEND BENE BENS BENT BERK BEST BETA BETH BETS BIAS BICE BILE BILK BILL BIND BINE BINS BINT BIOS BIRD BIRK BIRL BISE BISK BITE BITS BITT BLAE BLAH BLAT BLED BLET BLIN BLOT BOAS BOAT BOCK BOIL BOLA BOLD BOLE BOLL BOLT BOND BONE BONK BONY BOOK BOON BOOS BOOT BORA BORE BORK BORN BORT BOSH BOSK BOSS BOTA BOTH BOTS BOTT BRAD BRAE BRAN BRAS BRAT BRAY BREA BRED BREE BREN BRIA BRIE BRIN BRIS BRIT BROS BUCK BULK BULL BUNA BUND BUNK BUNN BUNS BUNT BUOY BURA BURD BURL BURN BURS BURY BUSH BUSK BUSS BUST BUSY BUTE BUTS BUTT BYES BYRE BYRL BYTE CACA CAEL CAID CAIN CALE CALK CALL CANE CANS CANT CARA CARD CARE CARK CARL CARN CARS CART CASA CASE CASH CASK CAST CATE CATS CECA CEES CEIL CELL CELS CELT CENT CERE CESS CETE CHAD CHAT CHAY CHIA CHID CHIN CHIS CHIT CHON CIAN CINE CION CIRE CIST CITE CITY CLAD CLAN CLAY CLOD CLON CLOT CLOY COAL COAT COCA COCK COED COEN COIL COIN COLA COLD COLE COLS COLT COLY CONE CONK CONN CONS CONY COOK COOL COON COOS COOT CORA CORD CORE CORK CORN CORS CORY COSH COSS COST COSY COTE COTS CRED CRIS CRIT CUED CUES CULL CULT CUNT CURD CURE CURL CURN CURS CURT CUSK CUSS CUTE CUTS CYAN CYST DACE DAIS DALE DALS DANA DANE DANK DANS DARE DARK DARN DART DASH DATA DATE DEAD DEAL DEAN DECK DEED DEES DEET DEIL DELE DELL DELS DELT DENE DENS DENT DENY DEON DERE DESK DHAK DHAL DIAL DICE DICK DIED DIEL DIES DIET DILL DINA DINE DINK DINS DINT DIOL DION DIRE DIRK DIRL DIRT DISH DISK DISS DITA DITE DITS DOAT DOCK DOCS DOES DOIT DOLE DOLL DOLS DOLT DONA DONE DONS DORE DORK DORS DORY DOSE DOSS DOST DOTE DOTH DOTS DOTY DRAT DRAY DREE DREK DUAD DUAL DUCE DUCK DUCT DUEL DUES DUET DUIT DULL DULY DUNE DUNK DUNS DUNT DUOS DURA DURE DURN DUSK DUST DUTY DYAD DYED DYES DYNE FACE FACT FAIL FAIN FALL FANE FANS FARD FARE FARL FART FASH FAST FATE FATS FEAL FEAT FECK FEED FEEL FEES FEET FELL FELT FEND FENS FEOD FERE FERN FESS FEST FETA FETE FETS FIAT FICE FILA FILE FILL FILS FIND FINE FINK FINN FINS FIRE FIRN FIRS FISH FIST FITS FLAK FLAN FLAT FLAY FLEA FLED FLEE FLEY FLIT FLOE FOAL FOES FOIL FOIN FOLD FOLK FOND FONS FONT FOOD FOOL FOOT FORA FORD FORE FORK FORT FOSS FRAE FRAT FRAY FRED FREE FRET FRIT FROE FUCK FUEL FULL FUND FUNK FUNS FURL FURS FURY FUSE FUSS FYCE LACE LACK LACS LACY LAID LAIN LALL LANA LAND LANE LANK LARA LARD LARK LARS LASE LASH LASS LAST LATE LATH LATS LEAD LEAH LEAK LEAL LEAN LEAS LECH LEEK LEES LEET LEIA LEIS LELA LENA LEND LENS LENT LEON LESS LEST LETS LIAN LICE LICH LICK LIED LIEN LIES LILA LILT LILY LINA LINE LINK LINN LINS LINT LINY LION LIRA LIRE LISA LIST LITE LITS LOAD LOAN LOCA LOCH LOCK LOID LOIN LOLA LOLL LONE LOOK LOON LOOS LOOT LORD LORE LORN LORY LOSE LOSS LOST LOTA LOTH LOTS LUCA LUCE LUCK LUCY LUES LUIS LULL LUNA LUNE LUNK LUNT LUNY LURE LURK LUSH LUST LUTE LYCH LYES LYLA LYLE LYRA LYRE LYSE MACE MACH MACK MACS MACY MAES MAIA MAID MAIL MAIN MALE MALL MALT MANA MANE MANS MANY MARA MARE MARK MARL MARS MART MARY MASA MASH MASK MASS MAST MATE MATH MATS MATT MEAD MEAL MEAN MEAT MEED MEEK MEET MELD MELL MELS MELT MEND MERE MERK MERL MESA MESH MESS META METE METH MHOS MIAH MICA MICE MICK MICS MIEN MILA MILD MILE MILK MILL MILS MILT MINA MIND MINE MINK MINT MIRA MIRE MIRK MIRS MIRY MISE MISS MIST MITE MITT MITY MOAN MOAS MOAT MOCK MOCS MOIL MOLA MOLD MOLE MOLL MOLS MOLT MOLY MONA MONK MONS MONY MOOD MOOL MOON MOOS MOOT MORA MORE MORN MORS MORT MOSH MOSK MOSS MOST MOTE MOTH MOTS MOTT MUCH MUCK MULE MULL MUNS MUON MURA MURE MURK MUSA MUSE MUSH MUSK MUSS MUST MUTE MUTS MUTT MYAH MYCS MYLA MYNA MYRA MYTH PACA PACE PACK PACS PACT PACY PAID PAIK PAIL PAIN PALE PALL PALS PALY PANE PANS PANT PARA PARD PARE PARK PARS PART PASE PASH PASS PAST PATE PATH PATS PATY PEAK PEAL PEAN PEAS PEAT PECH PECK PECS PEED PEEK PEEL PEEN PEES PEIN PELE PELT PEND PENS PENT PEON PERE PERK PERT PEST PETS PHAT PHIS PHON PHOT PIAL PIAN PIAS PICA PICE PICK PICS PIED PIES PILE PILL PILY PINA PINE PINK PINS PINT PINY PION PIRN PISH PISS PITA PITH PITS PITY PLAN PLAT PLAY PLEA PLED PLIE PLOD PLOT PLOY POCK POET POIS POLE POLL POLS POLY POND PONE PONS PONY POOD POOH POOL POON POOS PORE PORK PORN PORT POSE POSH POST POSY POTS PRAT PRAY PREE PREY PROA PROD PROS PUCE PUCK PULA PULE PULL PULS PUNA PUNK PUNS PUNT PUNY PURE PURL PURS PUSH PUSS PUTS PUTT PYAS PYES PYIN PYRE SAAD SACK SACS SAID SAIL SAIN SALE SALL SALS SALT SANA SAND SANE SANK SANS SARA SARD SARK SASH SASS SATE SEAL SEAN SEAS SEAT SECS SECT SEED SEEK SEEL SEEN SEES SEIS SELL SELS SEND SENE SENT SERA SERE SERS SETA SETH SETS SETT SHAD SHAE SHAH SHAT SHAY SHEA SHED SHES SHIN SHIT SHOD SHOE SHOT SIAL SICE SICK SICS SILD SILK SILL SILT SINE SINH SINK SINS SIRE SIRS SITE SITH SITS SLAT SLAY SLED SLID SLIT SLOE SLOT SOAK SOCA SOCK SOIL SOLA SOLD SOLE SOLS SONE SONS SOOK SOON SOOT SORA SORD SORE SORN SORT SOTH SOTS SRIS SUCH SUCK SUED SUES SUET SUIT SULK SUNK SUNN SUNS SURA SURD SURE SUSS SWAN SWAT SWAY SWOT SYCE SYED SYNE TACE TACH TACK TACT TAEL TAIL TAIN TALA TALE TALK TALL TANK TANS TAOS TARA TARE TARN TARS TART TASK TASS TATE TATS TEAK TEAL TEAS TEAT TECH TEED TEEL TEEN TEES TELA TELE TELL TELS TEND TENS TENT TERN TESS TEST TETH TETS THAE THAN THAT THEA THEE THEN THEY THIN THIS TICK TICS TIED TIES TILE TILL TILS TILT TINA TINE TINS TINT TINY TIRE TIRL TITS TOAD TOEA TOED TOES TOIL TOIT TOLA TOLD TOLE TOLL TONE TONS TONY TOOK TOOL TOON TOOT TORA TORE TORN TORS TORT TORY TOSH TOSS TOST TOTE TOTS TRAD TRAE TRAY TREE TREK TRES TRET TREY TROD TROT TROY TUCK TUIS TULE TUNA TUNE TUNS TURD TURK TURN TUSH TUSK TUTS TWAE TWAS TWAT TWEE TWIN TWIT TWOS TYCE TYEE TYES TYIN TYNE TYRE WACK WAES WAIL WAIN WAIT WALE WALK WALL WALY WAND WANE WANK WANS WANT WANY WARD WARE WARK WARN WARS WART WARY WASH WAST WATS WATT WEAK WEAL WEAN WEED WEEK WEEL WEEN WEES WEET WELD WELL WELT WEND WENS WENT WERE WERT WEST WETS WHAT WHEE WHEN WHET WHEY WHID WHIN WHIT WHOA WICH WICK WILD WILE WILL WILT WILY WIND WINE WINK WINS WINY WIRE WIRY WISE WISH WISS WIST WITE WITH WITS WOAD WOES WOLD WONK WONS WONT WOOD WOOL WOOS WORD WORE WORK WORN WORT WOST WOTS WREN WRIT WUSS WYCH WYES WYLE WYND WYNN WYNS WYTE\n" + ] + } + ], + "source": [ + "show(improved_lock(random_lock()))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['UMAR',\n", + " 'DISH',\n", + " 'TEMP',\n", + " 'JUDE',\n", + " 'WORM',\n", + " 'STOW',\n", + " 'BHUT',\n", + " 'YAGI',\n", + " 'ACTA',\n", + " 'GYPS']" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "improved_wordlist(random.sample(WORDS, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Question 4: Coincidence?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is still one unanswered question: did the designers of WordLock® deliberately put \"FRED BUNS\" in, or was it a coincidence? Hacker News reader [emhart](https://news.ycombinator.com/user?id=emhart) (aka the competitive lockpicker Schyler Towne) astutely commented that he had found the [patent](https://www.google.com/patents/US6621405) assigned to WordLock; it describes an algorithm similar to my `greedy_lock`.\n", + "After seeing that, I'm inclined to believe that \"FRED BUNS\" is the coincidental result of running the algorithm. On\n", + "the other hand, there is a [followup patent](https://www.google.com/patents/US20080053167) that discusses a refinement\n", + "\"wherein the letters on the wheels are configured to spell a first word displayed on a first row of letters and a second word displayed on a second row of letters.\" So the possibility of a two-word phrase was somthing that Wordlock LLc. was aware of.\n", + "\n", + "We see below that the procedure described in the [patent](https://www.google.com/patents/US6621405) is not quite as good as `greedy_lock`, because the patent states that at each tumbler position \"*the entire word list is scanned*\" to produce the letter frequencies, whereas `greedy_lock` scans only the words that are consistent with the previous tumblers. Because of that difference, `greedy_lock` produces more words, 1177 to 1161:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1177, 1161)" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def greedy_lock_patented(t=4, c=10, words=WORDS):\n", + " \"Make a lock with t tumblers, each consisting of the c letters that cover the most words at that position.\"\n", + " lock = Lock()\n", + " for i in range(t):\n", + " # Make a tumbler of c letters, such that the tumbler covers the most words.\n", + " # Then update words to only include the ones that can be made with this tumbler\n", + " counter = Counter(word[i] for word in words)\n", + " tumbler = Tumbler(L for (L, _) in counter.most_common(c))\n", + " # words = [w for w in words if w[i] in tumbler] # <<<< The patent does not update the word list\n", + " lock.append(tumbler)\n", + " return lock\n", + "\n", + "word_count(greedy_lock()), word_count(greedy_lock_patented())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tests" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is a \n", + "good idea to have some tests, in case you want to change some code and see if you have introduced an error. Also, tests serve as examples of usage of functions. The following tests have poor coverage, because it is hard to test non-deterministic functions, and I didn't attempt that here." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'pass'" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " assert 'WORD' in WORDS\n", + " assert 'FRED' in WORDS\n", + " assert 'BUNS' in WORDS\n", + " assert 'XYZZ' not in WORDS\n", + " assert 'word' not in WORDS\n", + " assert 'FIVE' in WORDS\n", + " assert 'FIVER' not in WORDS\n", + " assert len(WORDS) == 4360\n", + " \n", + " assert fredbuns == ['FB', 'RU', 'EN', 'DS']\n", + " assert combinations(fredbuns) == ['FRED','FRES','FRND','FRNS','FUED','FUES','FUND','FUNS',\n", + " 'BRED','BRES','BRND','BRNS','BUED','BUES','BUND','BUNS']\n", + " assert words_from(fredbuns) == ['FRED', 'FUND', 'FUNS', 'BRED', 'BUND', 'BUNS']\n", + " assert \"FRED\" in words_from(wordlock) and \"BUNS\" in words_from(wordlock)\n", + "\n", + " assert wordlock == ['SPHMTWDLFB', 'LEYHNRUOAI', 'ENMLRTAOSK', 'DSNMPYLKTE']\n", + " assert len(combinations(wordlock)) == 10000\n", + " assert word_count(wordlock) == 1118\n", + " \n", + " assert transpose(['HIE', 'BYE']) == ['HB', 'IY', 'EE']\n", + " assert transpose(transpose(wordlock)) == wordlock\n", + " \n", + " return 'pass'\n", + " \n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# One More Question" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I wonder if [@BIKESNOBNYC](https://twitter.com/bikesnobnyc) would appreciate this notebook? On the one hand, he is the kind of guy who, in discussing the fact that bicycling is the seventh most popular recreational activity, [wrote]() \"*the number seven is itself a highly significant number. It is the lowest number that cannot be represented as the sum of the square of three integers*,\" so it seems he has some interest in mathematical oddities. On the other hand, he followed that up by writing \"*I have no idea what that means, but it's true*,\" so maybe not." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{7, 15, 23, 28, 31, 39, 47, 55, 60, 63, 71, 79, 87, 92, 95}" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Numbers up to 100 that are not the sum of 3 squares\n", + "nums = range(11)\n", + "sums = {A**2 + B**2 + C**2 for A in nums for B in nums for C in nums}\n", + "set(range(max(nums)**2)) - sums" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Gesture Typing.ipynb b/pytudes/ipynb/Gesture Typing.ipynb new file mode 100644 index 0000000..1ec2c2d --- /dev/null +++ b/pytudes/ipynb/Gesture Typing.ipynb @@ -0,0 +1,2111 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Gesture Typing \n", + "===\n", + "\n", + "Typing quickly and accurately on a smartphone screen is hard! One invention to make it easier is **gesture typing**, in which your finger can trace a **path** consisting of letter-to-letter **segments**. When you lift your finger the path (and the word) is complete. Below we see the path for the word \"hello.\" Note that the path is imprecise; it didn't quite hit the \"L\", but the word was recognized anyways, because \"Hello\" is a known word, whereas \"Hekko\", \"Hwerklo\", etc., are not.\n", + "\n", + "\n", + "\n", + "Questions About Gesture Typing\n", + "===\n", + "\n", + "My colleague Nicolas Schank examined (and answered) the question of what word has the longest path length. I mentioned this to [Shumin Zhai](http://www.shuminzhai.com/), the pioneer of gesture typing, and between the three of us we expanded the list of questions:\n", + "\n", + " 1. What words have the longest path length?\n", + " 2. What words have the highest ratio of path length to word length? \n", + " 3. What is the average segment length, over a typical typing work load?\n", + " 3. Is there a better keyboard layout to minimize the average segment length over a work load?\n", + " 4. How often are two words confused because they have similar paths?\n", + " 5. Is there a better keyboard layout to minimize confusion? \n", + " 6. Is there a better keyboard layout to maximize overall user satisfaction?\n", + "\n", + "Let's look at each of these questions, but first, let's get a rough idea for of the concepts we will need to model.\n", + "\n", + "Vocabulary\n", + "===\n", + "\n", + "We will need to talk about the following concepts:\n", + "\n", + "* **Keyboard**: We'll need to know the **location** of each letter on the keyboard (we consider only letters, not the other symbols).\n", + "* **Location**: A location is a **point** in two-dimensional space (we assume keyboards are flat).\n", + "* **Path**: A path connects the letters in a word. In the picture above the path is curved, but a shortest path is formed by connecting straight line **segments**, so maybe we need only deal with straight lines.\n", + "* **Segment**: A line segment is a straight line between two points.\n", + "* **Length**: Paths and Segments have lengths; the distance traveled along them.\n", + "* **Words**: We will need a list of allowable words (in order to find the one with the longest path).\n", + "* **Work Load**: If we want to find the average path length over a typical work load, we'll have to represent a work load: not\n", + "just a list of words, but a measure of how frequent each word (or each segment) is.\n", + "* **Confusion**: We need some measure of *whether* (or perhaps *to what degree*) the paths for two words can be confused with each other.\n", + "* **Satisfaction**: This is a very difficult concept to define. A user will be more satisfied with a keyboard if it allows for fast, accurate typing, and if it gives the user a feeling of mastery, not frustration.\n", + "\n", + "**Note**: Before we get started writing any real code, I've taken all the `import`s I will need throughout this notebook and gathered them together here:\n", + "\n", + "\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from collections import Counter\n", + "from statistics import mean\n", + "import matplotlib.pyplot as plt\n", + "import urllib\n", + "import itertools\n", + "import random \n", + "import re" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Representing Keyboards and Points\n", + "===\n", + "\n", + "The representation for a keyboard needs to describe the location of each of the letters. Using the principle of *\"Do the simplest thing that could possibly work,\"* I represent a keyboard as a `dict` of `{letter: point}` pairs, where there will be 26 letters, A-Z,\n", + "and each point will mark the x-y coordinates of the center of the corresponding key. In a standard keyboard the letters are not all on a strict rectangular grid; the **A** key is half way between the **Q** and **W** in the horizontal direction. I would like to have a programmer-friendly way of defining keyboard layouts. For example, a programmer should be able to write:\n", + "\n", + " Keyboard(('Q W E R T Y U I O P',\n", + " ' A S D F G H J K L ',\n", + " ' Z X C V B N M '))\n", + " \n", + "and this would be equivalent to the `dict`:\n", + "\n", + " {'Q': Point(0, 0), 'W': Point(1, 0), ...\n", + " 'A': Point(0.5, 1), 'S': Point(1.5, 1), ...\n", + " 'Z': Point(1.5, 2), 'X': Point(2.5, 2), ...}\n", + " \n", + "Note that one key width is two characters in the input to `Keyboard`. Here is the implementation:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Keyboard(rows):\n", + " \"A keyboard is a {letter: location} map, e.g. {'Q':Point(0, 0), 'A': Point(0.5, 1)}.\"\n", + " return {ch: Point(x/2, y) \n", + " for (y, row) in enumerate(rows)\n", + " for (x, ch) in enumerate(row)\n", + " if ch != ' '}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What about `Point`? At first glance, Python does not appear to have a two-dimensional point as a builtin data type, but\n", + "on second thought, it does: `complex`. A complex number is a point in the two-dimensional complex plane;\n", + "we can use that to model the two-dimensional (x, y) plane. Because complex numbers are built in, manipulating them will be efficient. A bonus is that the distance between points `A` and `B` is simply `abs(A-B)`; easier than the usual formula involving squares and a square root. Thus, the simplest possible thing I could do to represent points is\n", + "\n", + "
\n",
+    "Point = complex\n",
+    "
\n", + "\n", + "That would work fine. However, I would like to refer to the x coordinate of point `p` as `p.x` rather than `p.real`, and I would like points to display nicely, so I will do the second-simplest thing: make `Point` be a subclass of `complex` with `x` and `y` properties and a `__repr__` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Point(complex):\n", + " \"A point in the (x, y) plane.\"\n", + " def __repr__(self): return 'Point({}, {})'.format(self.x, self.y)\n", + " x = property(lambda p: p.real)\n", + " y = property(lambda p: p.imag)\n", + " \n", + "def distance(A, B):\n", + " \"The distance between two points.\"\n", + " return abs(A - B)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternative representations for points include an `(x, y)` tuple or namedtuple, or a NumPy two-element array, or a class. \n", + "\n", + "Alternatives for `Keyboard` include a subclass of `dict`, or a class that contains a `dict`. \n", + "\n", + "\n", + "Now we can check that `Keyboard` works:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'A': Point(0.5, 1.0),\n", + " 'B': Point(5.5, 2.0),\n", + " 'C': Point(3.5, 2.0),\n", + " 'D': Point(2.5, 1.0),\n", + " 'E': Point(2.0, 0.0),\n", + " 'F': Point(3.5, 1.0),\n", + " 'G': Point(4.5, 1.0),\n", + " 'H': Point(5.5, 1.0),\n", + " 'I': Point(7.0, 0.0),\n", + " 'J': Point(6.5, 1.0),\n", + " 'K': Point(7.5, 1.0),\n", + " 'L': Point(8.5, 1.0),\n", + " 'M': Point(7.5, 2.0),\n", + " 'N': Point(6.5, 2.0),\n", + " 'O': Point(8.0, 0.0),\n", + " 'P': Point(9.0, 0.0),\n", + " 'Q': Point(0.0, 0.0),\n", + " 'R': Point(3.0, 0.0),\n", + " 'S': Point(1.5, 1.0),\n", + " 'T': Point(4.0, 0.0),\n", + " 'U': Point(6.0, 0.0),\n", + " 'V': Point(4.5, 2.0),\n", + " 'W': Point(1.0, 0.0),\n", + " 'X': Point(2.5, 2.0),\n", + " 'Y': Point(5.0, 0.0),\n", + " 'Z': Point(1.5, 2.0)}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "qwerty = Keyboard(('Q W E R T Y U I O P',\n", + " ' A S D F G H J K L ',\n", + " ' Z X C V B N M '))\n", + "qwerty" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Computing Path Length\n", + "===\n", + "\n", + "Now let's figure out the path length for a word: the sum of the lengths of segments between letters. So the path length for `'WORD'` would be the sum of the segment lengths for `'WO'` plus `'OR'` plus `'RD'`:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13.118033988749895" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "W, O, R, D = qwerty['W'], qwerty['O'], qwerty['R'], qwerty['D'], \n", + "distance(W, O) + distance(O, R) + distance(R, D)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's make a function to compute this:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def path_length(word, kbd=qwerty):\n", + " \"The total path length for a word on this keyboard: the sum of the segment lengths.\"\n", + " return sum(distance(kbd[word[i]], kbd[word[i+1]])\n", + " for i in range(len(word)-1))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13.118033988749895" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path_length('WORD')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's check with a simpler example that we know the answer to:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4.0" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path_length('TO')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That makes it clearer—the **O** is four keys to the right of the **T**, on the same row, so the distance between them is 4.\n", + "\n", + "Here's another one that you can verify on your own:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path_length('TYPEWRITER') == 1 + 4 + 7 + 1 + 2 + 4 + 3 + 2 + 1 == 25" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 1: Longest Path Length?\n", + "===\n", + "\n", + "To know what the longest word is, we'll have to know what the allowable words are. The so-called TWL06 word list gives all the words that are legal in the game of Scrabble; that seems like a reasonable list (although it omits proper nouns). Here's how to load a copy:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "! [ -e TWL06.txt ] || curl -O http://norvig.com/ngrams/TWL06.txt\n", + " \n", + "WORDS = set(open('TWL06.txt').read().split())" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "178691" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(WORDS)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's a lot of words; which one has the longest path?" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'PALEOMAGNETISMS'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(WORDS, key=path_length)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the ten longest paths? Including the lengths? We'll use a helper function, `print_top`, which prints the top *n* items in a seqence according to some key function:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "72.2 PALEOMAGNETISMS\n", + "70.0 ANTIQUARIANISMS\n", + "69.9 ELECTROANALYSIS\n", + "69.9 ANTIAPHRODISIAC\n", + "69.3 PARLIAMENTARIAN\n", + "68.9 BLEPHAROSPASMS\n", + "68.6 BIDIALECTALISMS\n", + "67.6 PALEOGEOGRAPHIC\n", + "67.6 SPERMATOZOANS\n", + "67.1 APOCALYPTICISMS\n" + ] + } + ], + "source": [ + "def print_top(n, sequence, key=None, formatter='{:.1f} {}'.format):\n", + " \"Find the top n elements of sequence as ranked by key function, and print them.\"\n", + " for x in sorted(sequence, key=key, reverse=True)[:n]:\n", + " print(formatter(key(x), x))\n", + " \n", + "print_top(10, WORDS, path_length)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 2: Highest Path Length to Word Length Ratio?\n", + "===\n", + "\n", + "Very long words tend to have long path lengths. But what words have the highest *ratio*\n", + "of path length to word length? (I decided to measure word length by number of letters; an alternative is number of segments.) " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def path_length_ratio(word, kbd=qwerty): return path_length(word, kbd) / len(word)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6.9 PALAPA\n", + "6.7 PAPAL\n", + "6.4 PAPA\n", + "6.4 JALAPS\n", + "6.2 SLAPS\n", + "6.2 KAMALA\n", + "6.2 LAPELS\n", + "6.2 PAPS\n", + "6.2 HALALA\n", + "6.1 SPALE\n" + ] + } + ], + "source": [ + "print_top(10, WORDS, path_length_ratio)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 3: Average Segment Length on Work Load?\n", + "===\n", + "\n", + "What is the average segment length for a typical typing work load? To answer that, we need to know what a typical work load is. We will read a file of \"typical\" text, and count how many times each segment is used. A `Workload` is a `dict` of the form `{segment: proportion, ...},` e.g. `{'AB': 0.02}`, where each key is a two-letter string (or *bigram*) representing a segment, and each value is the proportion of time that segment appears in the workload. Since the distance from `A` to `B` on a keyboard is the same as the distance from `B` to `A`, we can combine them together into one count;\n", + "I'll arbitrarily choose count them both under the alphabetically first one. I make a `Counter` of all two-letter segments, and `normalize` it so that the counts sum to 1 (and are thus probabilities)." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Workload(text):\n", + " \"\"\"Create a Workload--a dict of the form {'AB': 1000, ...} \n", + " saying how often each letter pair occurs in text.\"\"\"\n", + " segments = (min(AB, AB[::-1]) for AB in bigrams(text))\n", + " return normalize(Counter(segments))\n", + "\n", + "def bigrams(text): return re.findall(r'(?=([A-Z][A-Z]))', text)\n", + "\n", + "def normalize(dictionary):\n", + " \"Normalize a {key: val} dict so that the sum of the vals is 1.0.\"\n", + " total = sum(dictionary.values())\n", + " for k in dictionary:\n", + " dictionary[k] /= total\n", + " return dictionary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Note:* Some `re` trickiness here: `([A-Z][A-Z])` means a group of two consecutive letters. But if I only looked for that, then in the text `'FOUR'` I would find `['FO', 'UR']`. So I use the `?=` operator, which says to check for a match, but don't consume the matched characters. So I can find `['FO', 'OU', 'UR']`, which is what I want.\n", + "\n", + "Let's see what a workload looks like for a tiny text:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({'AL': 0.05,\n", + " 'AO': 0.05,\n", + " 'DO': 0.05,\n", + " 'GO': 0.1,\n", + " 'HO': 0.05,\n", + " 'HS': 0.05,\n", + " 'IS': 0.05,\n", + " 'OO': 0.55,\n", + " 'OT': 0.05})" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Workload('SHOT IS GOOD -- GOOOOOOOOOOOAL!')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I happened to have a file of about a megabyte of random text, `smaller.txt`; that should work fine as a typical work load:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "! [ -e smaller.txt ] || curl -O http://norvig.com/ngrams/smaller.txt\n", + " \n", + "WORKLOAD = Workload(open('smaller.txt').read().upper())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's peek at the most common segments:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('HT', 0.04144819308354474),\n", + " ('ER', 0.04050225926898767),\n", + " ('EH', 0.03576926529702987),\n", + " ('IN', 0.02699818128015268),\n", + " ('AN', 0.02320447132440709),\n", + " ('NO', 0.022344984888333263),\n", + " ('EN', 0.021994208025641622),\n", + " ('IT', 0.021467211506811055),\n", + " ('ES', 0.020667573255841017),\n", + " ('DE', 0.020619362217840744)]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "WORKLOAD.most_common(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The most popular segments, at about 4% each are `HT/TH` and `ER/RE`. Now we can compute the workload average:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def workload_average(kbd, workload=WORKLOAD):\n", + " \"The average segment length over a workload of segments.\"\n", + " return sum(distance(kbd[A], kbd[B]) * workload[A+B]\n", + " for (A, B) in workload)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.2333097802127653" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "workload_average(qwerty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, on average, your finger has to travel a little over 3 keys from one letter to the next over a typical workload." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Aside: Visualizing a Keyboard\n", + "---\n", + "\n", + "We'll need a way of visualizing what a keyboard looks like. I could just `print` letters, but I think it is more compelling to use IPython's `matplotlib` module. In the function `show_kbd` we'll draw a square around the center point of each key, and annotate the square with the key letter. " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_kbd(kbd, name='keyboard', K=20):\n", + " \"Plot the keyboard with square keys, K units on a side.\"\n", + " H = K / 2 # (K is Key width/height; H is half K)\n", + " for L in kbd:\n", + " x, y = K * kbd[L].x, -K * kbd[L].y\n", + " plot_square(x, y, H, label=L)\n", + " plt.axis('equal'); plt.axis('off')\n", + " plt.title(title(kbd, name));\n", + " plt.show()\n", + "\n", + "def plot_square(x, y, H, label='', style='k-'):\n", + " \"Plot a square with center (x, y), half-width H, and optional label.\"\n", + " plt.plot([x-H, x+H, x+H, x-H, x-H], \n", + " [y-H, y-H, y+H, y+H, y-H], style) \n", + " plt.annotate(label, (x-H/4, y-H/4)) # H/4 seems to place label well.\n", + " \n", + "def title(kbd, name): return '{}: path length = {:.1f}'.format(name, workload_average(kbd))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n+DNG2sdQVZcAOyd54dxpSR6b5OgRsjYAl9Jdj2M/qN3/TDrJo+nu/98eK6efKrsQeOGWL77tWXTX\n3xur6toRs7YbFoO2xYuAA4BzBi9XXZXklGkHJflPwI39gzbAOcCjkzx52lm9k4HjkqxJshp4M/DN\nkbLOp5sbH7sYdpn7P/VZp9U4n7s/XOY7gP0mTpt6VlV9o6r+fKSM7Y7fx6DGcv0sfLOWRs5yzlpK\n3GKQJDUsBklSw2KQJDUsBklSw2KQJDUsBklSw2KQJDUsBklSwze4qZHEG4S2J+uqahbfG7GkWAyS\npIZTSZKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpY\nDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKk\nhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUg\nSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpY\nDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKk\nhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUg\nSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpYDJKkhsUgSWpY\nDJKkhsUgSWpYDJKkxv8HwqVDBjxNM0gAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(qwerty, 'qwerty')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 4: Keyboard with Minimal Workload Average?\n", + "===\n", + "\n", + "Now for a much harder question: can we find a different keyboard layout that has a smaller average segment length over the workload? First, let's note that there are two ways to modify a keyboard: \n", + "\n", + "* Keep the keys in the same locations but swap letters. (This is an operation you can do on a physical keyboard just by prying off the key caps and swapping them.) \n", + "* Change the locations of keys. (On a physical keyboard you'd need a saw and glue to do this, but it is easier on a virtual keyboard.) \n", + "\n", + "Let's start by limiting ourselves to just swapping letters. \n", + "\n", + "This is an **optimization** problem. There are many permutations of letters; too many to try them all. To be precise, there are 26! (26 factorial) permutations, which is about 1026 (fun fact: 25 and 26 are the only integers for which n! ≈ 10n). If we can't try them all, we need some way to sample the configurations, trying to make progress towards a better one. Again, we'll try the simplest thing that could possibly work: \n", + "\n", + " 1. Pick two keys at random.\n", + " 2. Swap them.\n", + " 3. If that gives a better (lower) workload total, keep them that way.\n", + " 4. If not, swap back.\n", + " 5. Repeat this for a given number of times, say 1000." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def improved(kbd, swaps=1000, scorer=workload_average):\n", + " \"Minimize scorer(kbd) by swapping keys and keeping improvements.\"\n", + " kbd = kbd.copy()\n", + " score = scorer(kbd)\n", + " letters = list(kbd)\n", + " for _ in range(swaps):\n", + " A, B = random.sample(letters, 2) # Step 1: pick two keys\n", + " swap(kbd, A, B) # Step 2: swap them\n", + " score2 = scorer(kbd)\n", + " if score2 < score: # Step 3: If better, keep them\n", + " score = score2 # (and record the new best total)\n", + " else:\n", + " swap(kbd, B, A) # Step 4: swap back if not better\n", + " return kbd\n", + "\n", + "def swap(kbd, A, B): kbd[A], kbd[B] = kbd[B], kbd[A]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note 1:** This strategy is called **hillclimbing**, drawing on the metaphor of getting to a high peak by trying to take a step, and continuing if the step is uphill, and returning if it is not. This technique often finds a local maximum—a solution that is better than all its neighbors, but not as good as another solution that is many steps away.\n", + "\n", + "**Note 2:** I make `scorer` be a parameter, in case we later decide we want to minimize something else other than `workload_average`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how well we can do:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(improved(qwerty, 3000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's a pretty good improvement! We decreased the workload average by about a third. (If you are reading this in an active IPython notebook, you can re-run the cell above and see a different result each time.) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Visualizing `improved`\n", + "---\n", + "\n", + "Let's get a better feeling for what `improved` does. We will keep track of the workload average after each swap, and plot that as a curve. We will repeat that 10 times (because each run has random variation).\n", + "\n", + "I'll add another parameter, `scores`, to `improved`, If it is not `None`, then it should be a list into which we can accumulate all the scores (after each time step). Then I'll add a new function, `plot_improvements`, that plots the scores that `improved` accumulates." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "def improved(kbd, swaps=1000, scorer=workload_average, scores=[]):\n", + " \"Minimize scorer(kbd) by swapping keys and keeping improvements.\"\n", + " kbd = kbd.copy()\n", + " score = scorer(kbd)\n", + " letters = list(kbd)\n", + " for _ in range(swaps):\n", + " A, B = random.sample(letters, 2) # Step 1: pick two keys\n", + " swap(kbd, A, B) # Step 2: swap them\n", + " score2 = scorer(kbd)\n", + " if score2 < score: # Step 3: If better, keep them\n", + " score = score2 # (and record the new best total)\n", + " else:\n", + " swap(kbd, B, A) # Step 4: swap back if not better\n", + " scores.append(score) # <<< NEW\n", + " return kbd" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_improvements(kbd, swaps, scorer=workload_average, repeats=10):\n", + " plt.ylabel('Workload average segment length') \n", + " plt.xlabel('Number of swaps'); \n", + " for _ in range(repeats):\n", + " scores = []\n", + " improved(kbd.copy(), swaps, scorer, scores)\n", + " plt.plot(scores)\n", + " plt.show()\n", + " \n", + "plot_improvements(qwerty, 2500)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This plot is interesting. I note the following:\n", + "\n", + "* Each curve follows a slightly different path (because the swaps are random).\n", + "* The curves are grouped very tightly together; the variance is small. Almost everywhere, the difference between the best and the worst is about 0.2 or less. By the end, almost all the curves are between 1.9 and 2.0.\n", + "* We make rapid progress, decreasing from 3.2 to around 2.2 in about 200 swaps, and to around 2.0 in about 500 swaps.\n", + "* After 1000 swaps, progress is slow, and after 2000, even slower." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I can't say we've found the best possible keyboard, but it looks like progress will be slow in improving over about 1.9. \n", + "\n", + "Keys in Different Physical Locations\n", + "---\n", + "\n", + "Now let's allow keys to be in different physical locations. Rather than allowing complete freedom of movement, we'll start from a few different fixed key layouts and swap keys from there. I'll define three layouts and gather them into a `dict`:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "keyboards = {\n", + " 'qwerty': Keyboard(('Q W E R T Y U I O P',\n", + " ' A S D F G H J K L ', \n", + " ' Z X C V B N M ')),\n", + "\n", + " '4-by-7': Keyboard((' A B C D E F ',\n", + " 'G H I J K L M',\n", + " ' N O P Q R S ',\n", + " 'T U V W X Y Z')),\n", + "\n", + " '5-by-6': Keyboard((' A B C D E ',\n", + " 'F G H I J K',\n", + " 'L M N O P Q',\n", + " ' R S T U V',\n", + " ' W X Y Z '))\n", + " }" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a function to report on a collection of keyboards such as this (after improving them):" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nGhaDJKnxH5X1NnZZb1gBAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\npetOpHpPa06nOa3i8s/nlR5lNV/+fKoSe4DqzbjD2102Iu4EDqA6xfIRquL654h4vnaxC4HdqY5i\n6yan7d9G9ebdpUDjJfb3gaup3jj8A/CTtuEjno2IhxtfVG+YPhsRi5bxM19I9QQ0l+pN6q/Vt5lu\n8010dtR3ADA9IuY1r1B1JtSkFtdpeJDqjcsHqPb9oRFxV1r3CeCrkh6nen/l4lrGZ1Lm6WmoZpsB\nftZ26uu+AVwJXJNubwbVm5/ttlOfP4Hq1d48qn16KdV7RQ0nA8emnEd0sL1u+QjV0OaZwI5UQ0vf\na6xMQ3g7AETEFKoDgF+nn/8Mqved7hyEXMOaouWreetlkq6jOrvnnNxZcpN0LNVZN5MH8TZ2ptrf\nzcMkfU3VOfIfjohdc2exoecjf+tbaSjoYKqhEFsGSa+TtH0avnsL8Hk8Tl4sl39/Kv7lWjrr417g\n5xExPXeePrES1RPlE8CvqP6G46ysiSwbD/uYmRXIR/5mZgVy+ZuZFcjlb2ZWIJe/mVmBXP5mZgVy\n+ZuZFcjlb2ZWIJe/mVmBXP5mZgVy+ZuZFcjlb2ZWIJe/mVmBXP5mZgVy+ZuZFcjlb2ZWIJe/mVmB\nXP5mZgVy+ZuZFcjlb2ZWIJe/mVmBXP5mZgVy+ZuZFcjlb2ZWIJe/mVmBXP5mZgVy+ZuZFcjlb2ZW\nIJe/mVmBRuYO0C8kLQLG5M7RgQCUO0QHnLO7+iFnP2QEWBwRY3OHGGyKiNwZ+oKkiIief+A6Z3c5\nZ/f0Q0bon5zLy8M+ZmYFcvmbmRXI5W9mViCXv5lZgVz+ZmYFcvmbmRXI5W9mViCXv5lZgVz+ZmYF\ncvmbmRXI5W9mViCXv5lZgVz+ZmYFcvmbmRXI5W9mViCXv5lZgVz+ZmYFcvkPEUlfl/SZ2vwvJX2v\nNn+qpM/mSfdSkl4r6QJJcyXdJGm6pPfnztVM0guSTqnNf17Sl3NmaiZpqaSZkuZImiXpCEk99ylR\ntZyz0vdxuTO1I+nJ3BmGA5f/0JkObA+QfvnXBDatrd8emJEhVytXAL+OiA0i4u3AfsB6mTO18hzw\nL5J6+fNWn4qICRGxGTAR2BM4LnOmVho5t0rf780daAD+7NkucPkPnRmk8qcq/TnAk5JeLWklYGNg\nZq5wDZJ2A56LiO83lkXEgog4M2Osdp4HvgcckTtIJyJiIfAx4FO5s7TQc69GbHC5/IdIRDwILJG0\n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\nDNV9Pjm9UimCy78FSR8F5kfEtLToLGBjSe/MGGsgF1GNT/dk+QOrAeelUz1vBjYBvpI3UksBEBH3\nR8S3c4cZQOQOMMwcCqwFnFU71XOmpH1zBxtMql6NDy+SIiJ6/ujIObvLOburH3L2Q0bozZw+8jcz\nK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzN\nzArk8jczK5DL38ysQMP2XzrnzmBmVrM4IsbmDlE3LMvfzMwG5mEfM7MCufzNzArk8jczK5DL38ys\nQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jcz\nK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzN\nzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/\nM7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK5DL38ysQC5/M7MCufzNzArk8jczK9D/\nA0XbOuVPdisIAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nSY3/D8A5ahkgRRcLAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def report(keyboards=keyboards, swaps=3000, scorer=workload_average):\n", + " \"Iterate through a dict of {name: kbd} pairs, showing kbd before and after repeated_improved(kbd).\"\n", + " for (name, kbd) in keyboards.items():\n", + " show_kbd(improved(kbd, swaps=swaps, scorer=scorer), \n", + " ('improved ' if swaps else '') + name)\n", + " \n", + "report()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(**Note:** The plots of different-shaped keyboards have different-sized squares around the keys. Some of the plots have a lot of whitespace around them. If anyone knows an easy way to tell `plot` to display them better, let me know.)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "So the more compact keyboards with a smaller diameter (`4-by-7` and `5-by-6`) seem to perform slightly better than `qwerty`. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 5: How often are two words confused because of similar paths?\n", + "===\n", + "\n", + "When can one word be confused with another? When their paths are similar (which means that their corresponding letters are in similar locations). For example, on a Qwerty keyboard, the paths for \"HELLO\" and \"JELLO\" are similar, because **H** and **J** are adjacent, and the other letters are the same.\n", + "\n", + "\n", + "\n", + "We'd like to know, for a given keyboard, how confusing is it? How many words have paths on the keyboard that can be confused for other words? We have our work cut out for us:\n", + "\n", + "1. Determine what letters could be confused for each other.\n", + "2. Determine what words/paths can be confused.\n", + "3. Invent some metric for the overall confusingness of a keyboard. \n", + "4. Try to find less-confusing keyboards.\n", + "\n", + "Letter Confusions\n", + "---\n", + "\n", + "So, as a first step, we will make a mapping from each key to the keys that it can be confused with. I'll say that any key within a distance of 1.5 units on the keyboard is a **neighboring** key, and thus a potential confusion:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def neighboring_keys(kbd, radius=1.5):\n", + " \"Build a dict of {Letter:NeighboringLetters}, e.g. {'Q':'AQW', ...}.\"\n", + " return {A: cat(sorted(B for B in kbd if distance(kbd[A], kbd[B]) <= radius))\n", + " for A in kbd}\n", + "\n", + "cat = ''.join ## Function to join letters (or strings) into one string" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'A': 'AQSWZ',\n", + " 'B': 'BGHJNV',\n", + " 'C': 'CDFGVX',\n", + " 'D': 'CDEFRSXZ',\n", + " 'E': 'DERSW',\n", + " 'F': 'CDFGRTVX',\n", + " 'G': 'BCFGHTVY',\n", + " 'H': 'BGHJNUVY',\n", + " 'I': 'IJKOU',\n", + " 'J': 'BHIJKMNU',\n", + " 'K': 'IJKLMNO',\n", + " 'L': 'KLMOP',\n", + " 'M': 'JKLMN',\n", + " 'N': 'BHJKMN',\n", + " 'O': 'IKLOP',\n", + " 'P': 'LOP',\n", + " 'Q': 'AQW',\n", + " 'R': 'DEFRT',\n", + " 'S': 'ADESWXZ',\n", + " 'T': 'FGRTY',\n", + " 'U': 'HIJUY',\n", + " 'V': 'BCFGHV',\n", + " 'W': 'AEQSW',\n", + " 'X': 'CDFSXZ',\n", + " 'Y': 'GHTUY',\n", + " 'Z': 'ADSXZ'}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "qwerty_neighbors = neighboring_keys(qwerty) \n", + "qwerty_neighbors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see, for example, that **Q**, off in the corner, has only **A**, **W**, and itself as neighbors, while **G**, in the middle of the keyboard, has 8 neighbors. \n", + "\n", + "Word Confusions\n", + "---\n", + "\n", + "Consider each of the letters in the word \"HELLO,\" and all the possible choices for neighbors of each letter:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['BGHJNUVY', 'DERSW', 'KLMOP', 'KLMOP', 'IKLOP']" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "columns = [qwerty_neighbors[L] for L in 'HELLO']\n", + "columns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These are five columns of letters, and if we pick one letter from each column, we get a path that is formed by letters that are each confusions of letters in the original word, and so the whole path is a confusion for the original word. So \"JELLO\" is a confusion for \"HELLO\", as would be \"BDKKI\" and \"YWPPP\", except those are not words.\n", + "\n", + "It turns out that there is a library function, `itertools.product`, that will take alternative choices, and generate all possible ways of assembling a sequence consisting of one selection (letter) from each alternative choice." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "paths = {cat(picks) for picks in itertools.product(*columns)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How many paths are there?" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5000" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(paths)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's look at a few of them:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['NWPOO', 'HEOOP', 'JRMLI', 'HWPKL', 'VEMKO', 'UWOPI', 'VDOMK', 'HELLI']" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.sample(paths, 8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And let's see all the paths that are also words:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BROMO', 'BROOK', 'HELLO', 'JELLO'}" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "WORDS & paths" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Only 4 out of 5000; That's pretty good, but it means \"HELLO\" is still a confusing word. We can package this as the function `confusions`:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def confusions(word, neighbors=neighboring_keys(qwerty)):\n", + " \"All valid words whose paths could be confused with the path for the given word.\"\n", + " columns = [neighbors[L] for L in word]\n", + " return {cat(picks) for picks in itertools.product(*columns)} & WORDS" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BROMO', 'BROOK', 'HELLO', 'JELLO'}" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "confusions('HELLO')" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ALTOS', 'EIDOS', 'SIDLE', 'SKEPS', 'WIELD', 'WORKS', 'WORLD', 'WORMS'}" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "confusions('WORLD')" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'FEARING',\n", + " 'FRAYING',\n", + " 'GEARING',\n", + " 'GRATING',\n", + " 'GRAYING',\n", + " 'GREYING',\n", + " 'REARING',\n", + " 'REEFING',\n", + " 'RESTING',\n", + " 'TEARING',\n", + " 'TESTING'}" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "confusions('TESTING')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So far, so good. But I'm worried about the efficiency of `confusions`.\n", + "\n", + "My first concern is that `WORDS` has 178,691 words, including many unusual words, so there might be too many confusions. I will read in a smaller word set, with only common words:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "! [ -e words.js ] || curl -O https://xkcd.com/simplewriter/words.js\n", + " \n", + "COMMON = set(re.findall('[A-Z]+', open('words.js').read().upper()))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(3614, 'SPECIALS', 'UNDERSTANDINGS')" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(COMMON), max(COMMON, key=path_length), max(COMMON, key=len)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More Efficient `confusions`\n", + "---\n", + "\n", + "Another issue is that `confusions` is really slow:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3.14 s, sys: 306 ms, total: 3.44 s\n", + "Wall time: 3.45 s\n" + ] + }, + { + "data": { + "text/plain": [ + "{'SOMETHING'}" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time confusions('SOMETHING')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It took (on my computer) 3 seconds to compute this. Why so long? Let's count:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[7, 5, 5, 5, 5, 8, 5, 6, 8]" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[len(neighboring_keys(qwerty)[L]) for L in 'SOMETHING']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are 7 × 5 × 5 × 5 × 5 × 8 × 5 × 6 × 8 = 8,400,000 paths for `confusions` to consider. `'PALEOMAGNETISMS'` would have about 10,000 times more paths. Looking at every path is slow, but for most paths, we're wasting our time. For example, one choice for the first two neighboring letters of 'SO' is 'XP', but 'XP' does not start any word in the dictionary. Nevertheless, `itertools.product` will generate 240,000 combinations that start with 'XP', and will then rule them out one at a time. It would be better to stop as soon as we see 'XP', and never consider continuations of this path.\n", + "\n", + "So that gives us the key idea for a more efficient version of `confusions`: *only follow paths that form a prefix of some word.* I'll make a set of all the prefixes of the `COMMON` words:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def prefixes(words):\n", + " \"Return a set of prefixes (1 to N characters) of this collection of words.\"\n", + " return {word[:i] for word in words for i in range(1, len(word)+1)}\n", + "\n", + "PREFIXES = prefixes(COMMON)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'T', 'TH', 'THE', 'THES', 'THESE', 'THEY', 'THO', 'THOS', 'THOSE'}" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "prefixes(['THESE', 'THEY', 'THOSE'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can describe the more efficient version of the `confusions` algorithm:\n", + "\n", + "1. Maintain a queue of partial paths, where a partial path is a string representing choices for neighboring letters for a prefix of the word. For example, 'HE' and 'JE' are both partial paths for the word 'HELLO'. Initialize the queue to have just one partial path, the empty string.\n", + "2. Remove a partial path from the queue. Find all possible ways to extend the path by adding a neighboring letter, but only if doing so creates a path that is a prefix of some word in the dictionary. For example, given the word 'HELLO', and the partial path 'JE', consider all the neighbors of 'L' (namely, 'K', 'M', 'L', 'O', or 'P'), but only 'JEM', 'JEL', and 'JEO' are prefixes of words, so add just those to the queue.\n", + "3. When a partial path reaches the same length as the word ('HELLO' in this example), then don't extend it any farther; instead check to see if the path is a word. If it is, yield it as a result.\n", + "\n", + "A word is `confusable` if it has a confusion word (other than itself)." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def confusions(word, neighbors=neighboring_keys(qwerty)):\n", + " \"All valid words whose paths could be confused with the path for this word.\"\n", + " Q = [''] # A queue of partial paths \n", + " while Q:\n", + " path = Q.pop()\n", + " if len(path) < len(word):\n", + " for L in neighbors[word[len(path)]]:\n", + " if path + L in PREFIXES:\n", + " Q.append(path + L)\n", + " elif path in COMMON:\n", + " yield path\n", + "\n", + "def confusable(word, neighbors=neighboring_keys(qwerty)) -> bool: \n", + " \"Is this word confusable with another, given this keyboard's neighboring keys?\"\n", + " return any(c != word for c in confusions(word, neighbors))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's check the speed (remember the old version took over 3 seconds):" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 94 µs, sys: 0 ns, total: 94 µs\n", + "Wall time: 95.8 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "{'SOMETHING'}" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time set(confusions('SOMETHING'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We went from about 3 seconds to about 100 microseconds: that's 30,000 times faster! We can look at some more confusions:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BELIEVED': 'BELIEVES BELIEVER BELIEVED',\n", + " 'BENDS': 'BENDS',\n", + " 'BITEY': 'HURRY BITEY',\n", + " 'CEILINGS': 'CEILINGS',\n", + " 'COATING': 'COATING',\n", + " 'COLORERS': 'COLORERS',\n", + " 'COUPLES': 'COUPLES',\n", + " 'DUSTING': 'SHARING DUSTING',\n", + " 'DYING': 'EYING DYING',\n", + " 'ENJOYS': 'ENJOYS',\n", + " 'FREED': 'TREES TREED FREES FREER FREED FEWER FEEDS DRESS',\n", + " 'GET': 'YET TRY HEY HER GET CRY',\n", + " 'GUESSES': 'GUESSES GUESSED',\n", + " 'HOSPITAL': 'HOSPITAL',\n", + " 'IMAGING': 'OKAYING IMAGING',\n", + " 'LETTER': 'LETTER',\n", + " 'LUCKY': 'LUCKY',\n", + " 'MAY': 'MAY LAY',\n", + " 'ONCE': 'ONCE',\n", + " 'PALE': 'PALE',\n", + " 'PARTIES': 'PARTIES PARTIED',\n", + " 'PLAYER': 'PLAYER PLAYED PLATED OKAYED',\n", + " 'REPEAT': 'REPEAT',\n", + " 'RUSHES': 'RUSHES RUSHED FISHES FISHED',\n", + " 'SAMES': 'WAKES WAKED SANDS SAMES ASKED',\n", + " 'SHARP': 'SHARP',\n", + " 'SINGE': 'WINGS SONGS SINGS SINGE SINCE AUNTS',\n", + " 'SPEND': 'WORKS SPEND DOWNS',\n", + " 'TAUGHT': 'TAUGHT',\n", + " 'WALLED': 'WALLED WALKER WALKED'}" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{w: ' '.join(confusions(w))\n", + " for w in random.sample(COMMON, 30)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Visualizing Paths on a Keyboard\n", + "----\n", + "\n", + "It would be nice to see potentially confusable word paths on a keyboard.\n", + "I'll add functionality to `show_kbd` to call the new function `plot_paths` if any `words` are passed to `show_kbd`:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_kbd(kbd, name='keyboard', K=20, words=()):\n", + " \"Plot the keyboard with square keys, K units on a side.\"\n", + " H = K / 2 # (K is Key width/height; H is half K)\n", + " for L in kbd:\n", + " x, y = K * kbd[L].x, -K * kbd[L].y\n", + " plot_square(x, y, H, label=L)\n", + " plot_paths(kbd, K, words)\n", + " plt.axis('equal'); plt.axis('off')\n", + " plt.title(title(kbd, name));\n", + " plt.show()\n", + " \n", + "def plot_paths(kbd, K, words):\n", + " \"Plot paths for each word.\"\n", + " for (i, word) in enumerate(words):\n", + " Xs = [+K * kbd[L].x for L in word]\n", + " Ys = [-K * kbd[L].y for L in word]\n", + " plt.plot(Xs, Ys, '-o')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how it works on three similar paths:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n1bj7RX1QDFcBT7v7bDP7DbAAOFTF0HsqBgn05oUS77AfAf7b3X9X4KyjgXuAo9z9/tSy4pI4B361\nE+y6Arg8vqkRmAY3zXM/I9+soCgW37sHbzQb+wG7AHOBt4BFtYt99ZsTU1mv8L6twD+AIcDWwFR3\nf6YAOQ3AtkR/9mpP4DMUrhgagIOJDmmeATwKzAQuUDH0XkV/L4CUhO8AC3IphTwcR3SYYg8g62LI\nKHqH9Pgas1W7wa7Jm6qBraMdXf4x9313IfAV4Cs2YUQ9+zSPYAFRMSwAPgysLKtLI6sLG9x9HwAz\nOxC4Adi9EEHu/lb87n0msLEQGYmsBWY2HjgNuJvoXJfkoay/F0CKm5kdAZwIZHWyNM+svYEjgQOB\nL8UniFO1ApZPJDpe1aERWBmVUboa29cxEXglCqYFGBVfX2DxSeetzGyrAsZcBXwKGFrAjA5/AC4D\nbu6DrJKnYpBeiz8Z9Etgurtv6IPInwIz3X0Z8AM2H+1JzQK46BZYtAm4js3nGJ6AG8zsvamG1W+c\nzl3VLewIzCEap8yubqF+4/RUczZ7+520mU0hev2/Uagcd19LdGL/7AJkBFlE2+El7v7PAmZtMVQM\nko8ZwGjgGjN72syeib+fknZQ/ImnfyfOK1wDTDGzQ9PMaXBfMgeOaoE7LoTVI+CtG6G1FT5P9DHI\n1Hhr81xeap7KsiGrWAksqF7GS81Tsz3x3AuDO54nonfW070wJxmT87ycaBxUqJOZDuDur7n7jwuU\nscXRyWcJlOovFymrOHJKOauYaMQgIiIBFYOIiARUDCIiElAxiIhIQMUgIiIBFYOIiARUDCIiElAx\niIhIQL/gJgEz0wYhW5K17j6yvxdioFExiIhIQIeSREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQ\nEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagY\nREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIq\nBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGA\nikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQk\noGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhER\nCagYRERKp2HJAAAApUlEQVQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagY\nREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIq\nBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGAikFERAIqBhERCagYREQkoGIQEZGA\nikFERAL/D9dUkOSX0vFjAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(qwerty, words=['VALUE', 'VALOR', 'CAKE'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OK, we're on the right track, but I see three problems, which I think I can solve: \n", + "\n", + "- The letters are obscured by the circles. Solution: offset paths away from the center.\n", + "- When the paths are the same, they overwrite each other. Solution: offset each path towards a different corner.\n", + "- There is no indication what direction the path is going in. Solution: put a diamond on the start position.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def plot_paths(kbd, K, words):\n", + " \"Plot paths for each word, each with a different offset (and color).\"\n", + " Q = K / 5 # Q originally meant a quarter of a key width; but 1/5 looks nicer.\n", + " offsets = [Point(-Q, -Q), Point(-Q, +Q), Point(Q, +Q), Point(Q, -Q)]\n", + " for (i, word) in enumerate(words):\n", + " Xs = [+K * kbd[L].x + offsets[i % 4].x for L in word]\n", + " Ys = [-K * kbd[L].y + offsets[i % 4].y for L in word]\n", + " plt.plot(Xs, Ys, '-o')\n", + " plt.plot(Xs[:1], Ys[:1], 'kd')" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nATWc5UXqYBs1AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(qwerty, words=['VALUE', 'VALOR', 'CAKE'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks busier, but it is easier to follow the paths. Another example:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEKCAYAAAAW8vJGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmcHFXV//HPSUImIWQhZIEQkmE1SIKQsAUCKosiuIA+\ngsqmCIIgD4LI70F5TCIoKogrIIJbANk3BZ4oEmQLhF0IBAMJAULIIgkJSSCT5fz+uNUzdXt6Znqp\nnp6ZfN+vV79murq6TlUvdfrce6vK3B0REZGcbrVeARER6ViUGEREJKLEICIiESUGERGJKDGIiEhE\niUFERCJKDBsJM3vVzA7MeJknmNlDWS6zxPj3m9mJNYr9BzP7fpHzjjSzDWbW7t+3Wr9H0jkpMUil\nuvyBMBntXKv+OrWSgNoj9jQzW2xm75jZM2b26VbmPcfMnjezFWY2x8zOqfb6SWl61HoFRNpiZt3d\nfX0tV4HOkQBz62k1iH0m8JK7rzWzvYB/mNmO7r6ohfmPA54DdgD+bmavu/tN7bWy0jpVDBshM9vZ\nzOaa2dHJ/a3M7JbkF98cMzsjmT7UzFaZ2eap545N5uueTOpmZr9Kfim+mG6uSpZ7p5m9bWazzeyk\n1GN7mtl0M1tmZm8my+iRenyDmZ1mZrOB2cm0Q8xsVvKcX1HCDtDMJprZzWZ2Q/JL9Ukz2zX1+P8z\ns1eSx2aa2RHJ9FHAFcB4M3vXzJamFjvQzO5KnvOomW1b5Lr0M7OrzWyBmb1hZheYmSWPnWBmD5nZ\nxWa2NHk/Dk09t97MHjCz5Wb2dzP7tZlNSR5+IPn7TrJOezc9rfDysuLuz7v72tSkHsA2Lcx7ibs/\n6+4b3H02cCewX9brJOVTYtjImNlYYCpwurvfmOyQ/go8A2wFHAScaWaHJL/27geOSi3iWOD61C/4\nvYGXgS2AScBtZjYgeexG4HVgS+DzwA/N7CPJY+uBbwIDgfHAgcBpeav7GWBP4INmtgVwK/AdYBAw\nh9TOxMy2SXZ8w1vZ/E8n67Q5cD1wRyrBvQLs5+79gMnAtWY21N1fAk4FHnX3vu4+MLW8o4GJwIBk\nfX7QSuy0PwENwHbA7sAhwEmpx/cCZhFe04uB36Ue+zPwWPLYZMIv75wDkr/93L2fu89I7u/dyvIi\nZvbXJPEuLfD3L61tVPLc95L1u9/dn2xt/pT9gReKnFfag7vrthHcgFcJO+43gP1T0/cC5uXN+z/A\n75L/jwIeTv7vBrwFjEvunwDMz3vuDOAYYDiwFtg09dgPgd+3sH5nArem7m8APpy6fxwwPe85bwAn\nFrn9E9PPJ1QbCwjJoND8zwCfSm3ng3mP/wH4ber+J4AXW1jWSEIi7AYMBd4H6lKPfwGYloo1O/VY\n7+S1GEL4Bd4A9Eo9fg0wJT9O6vFCy1sPDKnS56w78HHgm0XOPzl5rTep9XdEt6ab+hg2LqcAD7h7\nuiN1JLB1qonECDuwB5P7dwJXmNlIYGfgHXd/KvX8N/NivAYMS25L3X113mPjAMxsR+BSYA/CzqoH\n8FS8KOan/h9GSARp+ffb0ji/u7uZzU+Wi5kdD5wF1Cez9CFUJq1ZmPp/NbBZEeswAtgEeCvXepTc\nXi+0XHd/L5lvM2Aw4TV9P2+bWquSCi3PkuUtLmJ9S+KhkvybmX3TzF5x97tamtfMvkGoQCd43Awl\nNaampI3LqcAIM7s0Ne0NYK67D0xum7t7f3f/FIC7rwFuIvxiP5bwCzVt67z7Iwi/xBcQ2uD75D2W\nSyRXEJo3tnf3AcB3ad5nkO7wfSt5flrBNuxWNM6f7ByHAwvMbATwW+C0ZPs3JzRt5NYny47nNwgV\nwxap13uAu+/a1hMJr8FAM+uVmpZ+DSpeTzO7J+lLWVHgdncJi+oBbN9KnBOBc4ED3f2tStdbsqXE\nsHF5FzgUOMDMLkqmPQ68a2bnmlkvM+tuZruY2R6p510DfBn4FM0Tw1AzO8PMepjZ54FRwN3uPh+Y\nDlxkZnVJR+9XU8/vC6xw99VJB+/X21j3uwl9DUck63gmoVmmFONyzydUB+8T2sP7EJpr/mNm3czs\nK8Do1PMWAcPNbJMS46UZgLsvBP4O/MzM+lqwnZkd0PrTwd1fB54EJpnZJmY2nvCe5CxJtqPFHXIR\nMQ7z0JfSr8Dt8IIbZvYBMzs0+fz0MLNjCf0GD7Qw/zGE/phD3P21ctdVqkeJYePhAO6+gtDZeaiZ\nTXb3DcAngd0I/RCLgauAfo1PdJ9O2OE87e75zTePATsC/wEuAD7n7u8kj30R2JZQPdwK/K+73588\ndg5wjJmtAK4Ebii0vql1eJvQgf3jJNb2wCO5x5PO5xVtdD7fSegwXkboBznS3de7+yzgp8m2LAR2\nAR5OPW8aoYJYaGblNr+kt+d4oCfwIrAUuJnQQV/Mc48B9iW8Bt8nvG5rIDQTEXa4jySdxXsVsbws\nGKH/ahHh83MGcJS7PwtgZhOS9znnAsKggydS1cnlGa+TVMDcO8PwbKk1M7sPuM7df1/rdSmHmU0k\nNFsdX+t1yZKZ3QDMcvfJtV4X6TpUMUibzGxPwrDKG2u9Lhs7M9sjaXqy5HiETwN31Hq9pGvRqCRp\nlZn9kXA8wX+7+6oar46EJqfbCE0x84FT3f1ftV0l6WrUlCQiIhE1JYmISESJQUREIkoMIiISUWIQ\nEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhERCSi\nxCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQYREQkosQgIiIRJQYREYkoMYiI\nSESJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFi\nEBGRiBKDiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQYREQk\nosQgIiIRJQYREYkoMYiISESJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGI\niEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJR\nYhARkYgSg4iIRJQYREQkosQgIiIRJQYREYn0qPUKbGzMbCmweTuFc8AUq8PHUazOFas9t2mZuw9s\np1iNzN3bO+ZGzczc3dvlQ6VYnSOOYnWuWF1xm/KpKUlERCJKDCIiElFiEBGRiDqfpaqszuoZyoVs\nxjBWsoBFnO9rfF6hefuZ1Y+GC7eCYW/Bgplw/govPK9kr5T3qj1V+rkodrv0+WuixCBVY3VWzyj+\nwSfZnp5AA3AX+1idHZz/xexnVv8Z+MdvYPs+wCrgVNinn9nBG+uXsz2V8l61p0o/F8Vulz5/MY1K\namdddURDoVg2wq7lOI6hZ2piA3AN1/nrfmx63n3Nrr0XjumTmrYKOASum+7xvBp9kn2sFt+re3iK\nI7iu7GBTuZRDObvcp+91GSdMW8KH8j8XJ27G/E9ty1PpeZ9awWfG9ePO9LSXlzB2xWi2oXtq4noY\n/hhPfWtl03Z9BY75NYzrSJ+/9o6VpopBqmczhkU7GoCeyfQ8W8GwPnnT+gBb0nxeqZxNtt7AOGA8\nMJ56Di/4XtUxBBhRdqD+UMzzN22g2/6vMXD8fAaPWcSgHZcyeOQ7DPpxA70KfS4GrGNA34Z4uSOA\n9LQlmzJ8QHcGD1jZPN7A7vF29YUh+vw1UWLo4Mxsa+Ay4IOEwQL3AN9y97UZxrgUmOfuv0zuTwVe\nd/evJfcvAea7+89LWvBKFtAAzX6FzuIjZvY04SAhB24YDwtWEb6MOauAhbCgzM0iWff1wL+ATYC5\nwHHuvqKSZRaIMRC4j7AtWwHrgSXJ/b3cfV3G8R4CfuDuU5P7nwe+4u6HFZx/shlhJxiSwMkA/Ad4\nEXgUuIUFGA0c0ey9msdTTOJgdx+Tij8ReNfdLy1iXb/pU/2svIlDgV2BD6X+7tQHek6Fm4EHCe/Z\nc/fDRasKVJLPv8+dV77U/Jc8k/gY8GXga8Bibuc1DmSPAtv1xJeXsy3he2VbwKoLyOWxpjgZf/5e\nBE5w9/crWWZ7UGLo+G4DLnP3I8zMgKuAi4FvZhjjEeDzwC+TGIOAvqnH9y0rXm9+xP0cw0ch1b47\nBxjq7mPTs04zO28iMJmQHJI23jkz4fwytidtVS6Wmf0ROB24qMJlRtx9KbB7EuN7wMpidpoVOBW4\n2cymEV7ZHwAfyz3YrBqAfQg/Kh4FHuVvwIkM9om+uvE5P7Tp3MWYvLb4OSzhEuCKstbSrOeY8Pc4\n4kTQE3iOsMN8APgl8MJqWIT7F9KLmGl2/qmwT17bf/S5SBLfR/gcAK8AdxCSw6PMYiTerI9hDgvZ\nDvhZ7nu1CUw9CD7wAFgVP3/XhsVS2g+sGlAfQzsrpc3QzA4EvufuH0lN6wu8Bgx3b/piVxLLzLYC\nZrj7CDMbDZwDbAkcDbwHLASGtPbLt2C79WR7jncYw61clx4RQgPPu3vfvAX4KzDneHhsSxi2sJVR\nISW+hivcvV/y/ynAGHf/RpHPLbl9t5Rf05XEMrMfAauBPvSjG2fzFE2JYBeaqoHHkr/zfGL4srcU\nq9DoHRpw4K/uvmur29hCFTALeu0MN9KUCJ4D5lNgx5N+r9Jyo4XyPxc22QbRVB00cA+7cBgDfaIv\na3W75nM3zimN3yuz/svhmSEwZDf4y9awZUf4/JUaK0uqGDq2XSDuYHP3d83sVWAHwpesYu7+lpmt\nNbPhhOpgOrA1YSezAni+1OYQm2z9gDEM4Ax/3X8dPWbWO92UdBY8cSmwA+wx3f2dLLYpHS6J2R04\nCLg64+W3q8Zq4Nus4ErOo45enMrbhM/Do8C3gKfS1UCxklE6+c0zI+MVsJ4fgKGjYCfMLqaNKuCD\nsNrzqoBSJTvnY6GpOrDJdhHwCdLVweNs8BlxUii0XWZ2BrnvVaiQr+4P/9cA+zwOP3T3mZWsb57c\n569Hsr7/l+Gyq0aJoXOqxi+I6cB+hMTwU2B4cn85oampVA8D+MQ4KSRWR01JZg78m+yTAkAuCQ0n\n/Iq+twoxqqJZ30C6GujDowzk7yzn33Tnu7lqINsVsKE3wX5nwCDMppBUAZ+GlRvgDeAF4Be0UgVg\n2XxUm1UHcCVwWro6sEllxToN2B44jvAdyFru8wfwEPC7KsTInBJDx/Yi8F/pCWbWDxgK/DvjWNMJ\nSWE0MBOYT/j1uRz4QykLaqwW4Iy2Z7avJf/tU0qMEqx297Fm1gv4G/AN4FdVilWRNvsG8qoBm5Q0\n6VSaFMx6AqOIm4F2BXp+DGauCf1NjVXAxfAj4MlL3K+pKG5bq5XrOwjJIKoOKtzm8L0yGwdMAsZb\nqHi2IfRRZCn+EdRJKDF0YO5+n5ldZGbHuvu1SXPIJcCv3H1NxuGmE/oW5nj45bfMzAYQRm2cXOKy\nWqsWIK54rqR61UJjLHd/38zOBO4ws8vcfUOV4hW3UsWMFAqJYF6m1YDZ0IPD33NI9QUA82jqA2is\nAvq7+ztmjxvMdfcnkxFYH6c6Haih2aWI6qAS7n5fD7OfXAX3nAynG7xK6GD/QxVGDLV7/0AWlBg6\nviOBy5PRLoOBG9z9R1WI8zywBXBt3rRNk1E3RcmvFsz61cPoC2GrYfDWAph5PtDLzJ4eDIOGA6/A\n3ZmOH4017lTd/Vkz+xfwRajgoK0ylDNSqLKALVcB3w1zbEOqCsD9vdR7dXDuvfKQMI4nfAYvJbye\nk9z91UzWM7e6k80wutlku55sq4Nmn8E6nj//BVhwDAz8GlxIGNV1D/DdCjejkE45ukejktpZJaMM\nzGwf4HrgSHd/tpqxSpWLZZPtOWCMT3QLX8jP/AN+s31qEOocuPNg9xXzUn0Lo8qJVYXNyCROq30D\nJY4UKnJFC44IIq4CGkcEGWxoNoKsrfeqTG1tVwvVwbXlVAcFR8YV2K5zOOA/F/D0ol6wB2VUCDry\nWToUd38M2LbW69GS5n0Loy9s+kJC+Pub7WHOhZg9mEysVt9Cuym1b6D8QC1WAXWEHX96RNCLtDSc\nOa9D2Iwe8OHLCr9XQ6abUcEonb9hxt/jaRtg1B2bs8dvhzOizyBePXAxT5w6n1cOXQ7dPgV8yiZl\nFevk0fD9rXLbNZaXOJfXBk1gzCNP+nMd/kCzWlFikCzl9S1sNSw+lhmSEw0Mo/p9C1VRRDWQTd9A\n61VArgJofURQi7bAjE+m1n8PGNO98Hu1dBGhX6tMlxwCHwvPH/FQPw78348x7MnD8G7rmL/3bfzx\n/vtYsGeBk1ZUGAt2BE6CzRqTQj+WcxNHcTqX8xQ3NDteQpooMUg26oBmI5HeWhCaJOITGkzmiU2T\nOx2+WkhVA/vQtCPNrhpIqoAwSD86LqC0KqDFxdODMNIstf5zAM5M1v9iYAb885ew6pjmJyX59wvu\n+b/CS4l/L0yytcQji44CHvUp92bajm32TwjXU/8a4bP4J3j8dVj1adiUqzmJqRzKzRwO/LyiU110\ndepjaGddtX3STjNnKPjEpnhmp+0BvWfA97ul262da7enjL6FpuVWZ7uaVQNv8t9szWpCNZDrF4j6\nBkoL0HIVcCOMOjp0frZ6dHDbIRhEnMT2IJzv59GmW/fn3NdXtY+hse/gbS5mC16ggr6DNmMZOwIn\nw6Jvw9D7k1h3uLMmt12nsfv2X+Va9uVe1vDNivpOuup3OIqrxNC+uuKHKulbWA6ckR6iasZP4akB\ncEZdaFbacfcpPHbncTxwArB5uc1IWW1Xm9XA7/kxJ9Kn5GqguL6AXHPQi7ivLu/0G4WqAYYCj9OU\nCGa4szR+XgunxGgcvbPlMFgYRiWVsPNMEuuHgVPIVQe/4wS+SresD8AzoydhxF6qOtjpHPfZzbbr\nJtvkk4fit+zPh595jvfmlLpdzWN3ve9ws7hKDO2rK36o0iORmmKzJeHI2NHuvJVM+5xjtzj828qs\nFsJyytiJttw3MIvo13SJI4WK6wtoswooJlZx1QAvurO+9eVk+7lIqoMTCDvptaSqg8xjNVYHnACN\nlUhSHRSIZdYfeBo4D/ebslmHrvcdzqc+BqlI40ike4CJ0UPfBq7JJQWAdXQfBLA7z3yvzbG2la9X\ntn0DWY0IKnb9m6qB3Cin/GrgYgpUA+2lYHUAXyGD4w6axSpYHbC/O7PbeKIRzo01NauksLFQYpBK\nPQyE3VUiqRa+TNixNerOht8sp9+b/2K3b5txs3s2B/8UUQ3cSjiqu7i+gaQK+Fb4v/EcQWQyIqgl\nhUYKNVYDjxBGBrVZDVRbC9VBZkclR7FaqQ6KXET6PEhSAiUGKVvecQvp8w81qxZy50RayWZjCL+s\nDwPuLitwD7DJNoFKq4E2qoBtwlyZVQFNYaNqIKkImo8UqlU1kK9TVAfNF9R4HqRyDmLb2KmPoZ1Z\nONq3a/g6oXFjUnriUJKuBcJlHAIHXgJ2BuCzwP8AexUXpz/hBA7Dk7+DCWcVeoNwqr83gDa6sYdQ\nSkdA1ragedfAm8QHQb8I1PT0Tc1tSnihxhFW7UnCC1SV3ewOFCgOCAdDl6YfuU6FcDm4Tm6Zuw9s\n76BKDJ1ERzsNROsjkejunrriW6gWriQZiWRGN+BZOHyM+935F/fpDYwlbhZKVwOP0lo10EIVsAyG\nbh5+/TcbEdT2q1K8UA3sthaePY2m/oE2RwqVHy/zjuRC1cFvmcQjWX/+WqgOrgL7dwWnBzHgJmAx\n7qcXMXuX70guhxJDJ9EBE0NRI5GSB5qdE8mMz8Hjt3D+AfX0WFP0SKG8lS16RJCFa1hnf+xDwZFC\ns/rCzn8gVQ5Uq28gw6G7LY4syjJOWFbrfQcVnjfqdOCrwL7FNCEpMRSmxNBJdKTEUG61YJN4n9w5\nhZzxrBz8WXqveIcea/5Ja9VAGccFlLNdbSncN9C8GgB7uzPsbFqsDgr0HVT6+rVUHRTqOyg7VuhX\nmEroVyjqugpKDIUpMXQSHSwxtFkt5EYK+STmvbUZy4adwyvkVwM///h1vHPPk9Btr8YRShkdF1DO\ndjV/TsHjBpp1DuRXAx1lZ2MhoV4OnObujY31bVUHpcZpff1KH1lUVqwyj1foKO9VR6PE0EnUOjFY\nnU1gCFPoy+bAALbjZ36Xn934eK/lv2DHe7bkv770RLcXOHy3vzFh21V09/XY9AO5euEBTCFdDZj1\n3BXW7Mflb5zE1U+M4+m+lFgFZLFdTY8XVw0U0zfQEXY2Vmf1GPexhm2p41Wcg/gO9RRRHZQSp/C8\nUXUwmlAdXF3syKKSX78S+xUqilUBJQbJXC0Tg9XZBEYxjU+yCT0JA0XuYh1DuJAJDGRdzwPY0GM3\nuq17rscLDbOPvp0jr4TujWfcgXUj4dsXhuHRjVXALOjVgx2m38ZnR57DJad0Z0OGxwW0vl3lVgPl\nxKqmFt6vegYxg7cZwhpCqt2adRzOXLbg15RxzqIij8xOVwczCYmnlOMOio6V94SS+hUqilUBJQbJ\nXE0TwzY2l+PZlp6piQ3AzaziGL7PbdeMY/ZhS/y9gd/Y12zuvbBt/jk6vwDv/RWuIlUFGKwC7w48\nC5znXuZxDW1uU+ceKVRqLBtqt7OGI1iemtgfqOMOX+RHZhUnTK+sOiglVgszl9yvUHasCnWmxKAD\n3KRtmzEgSgoQLp3enQYm+RTCQQm7AGwJAwqd1X8TeB/3M6MHzHBngxmTgUlm3JPF0dCFq4HrAfYE\nHgJ+Asyq9VHEVfMuE3gvb9pyoDcTsgqRVXVQ4Ur0JzQhnV5OUpCWdav1Ckh1mNkRZrbBzHaqeGEr\neafZcUYNyXS+fAtsvQFsqpk9PRveW5U36ypgYeuHoN1OaPA4rKUZzGy9mT1tZjPN7BkzO9vMzIwe\nZuxmxtfNmGLGbMJhxGcC6wlHEdfDB3HnRHeucmdma0khFeuZ5O+IVta9ImY2xMyuM7NXzOwJM3vE\nzD5T0UL78jD986b1B95jQF7sE8zsVxTJjDozjjbjPnKnQglHJR/kzo3ppGBm75a7+kWujAFX94Jt\ncp3NZnaYmb1kZttUKWR1t6kjcXfdOsEtvFUlzX8D4YCuiZXGoScT2JUGvoMzCec7OLvSQLfh58De\na+Hl4clzB/aGTx8LDSvBHXwl+LHQ0BcmtBYL/HPgT4BbC+u1IplvEEz/Euw8F77xKvgK8Fngvwc/\nGXw0ePdKXr9crPZ4r4DpwMmp+9sAp1f4ftUzjEXU4YBThzOMRcC7ec89Afhl2zF8R/ixgy8Cvw/8\naPC6ar2GRb1+cLqHUUjJ54KDgNlAfRXfq3b7XNT6VvMV0K3IN6q0D3AfwokidgBeyiIOPZnAcOYy\niqUMZy49mQAX/wXGzcmfty9MGA9zj4Sl42FuoaSQHwu8G/hz4IenpvUA3w3869C7Afxl8OXg98Ij\nv4Sey8EHVuH1e7fYeSuJBRwI3F+NWPSknjrmABuoYw49qc/fsbWWGMDrkgRwH/jiJDHsVMJ6VS8x\nwDiHJR4+3+8C+wOvADtW672qdJtKjVXrW81XQLci36jSPsBfAq5K/n8Y2D3rOOBbwrtLYZPnCadB\nugw4oJJtAj8lKTR+AD4trgY2eS+/GgCWAoOr8PqtI/wafQa4tVrvFeHkgz+t1ueC0BN0NdAzb7ty\n2zYvPzGE6sB/kl8dlLpTq1pigP4OcxyOSuZtIJw5a3TmsTLcplJj1fqmPoau6YuEpiSAGwmJImvn\nwmZTYO2uhBEpS4AbzOz4Yp4cRgp9iFTfwMuE/gCAQ5P/693Z2Z0TYe1ab943UK0RHqvdfay77+7u\nn6tSjGbM7Ndm9qyZzchiee7e4O4nedPBbbntGuvuu5NcQSOv7+CRZN6CfQc1Vfj6CmsJzXEn1Wy9\nuiCNSupizGxzQhPF6ORMrt0JJzf9dnYxGq+3sIuHn0IPAg+a2fPA8cCUAs8paqQQcARhlNPU8AOx\npXWw7YB17r4kq+2qgReAxsTj7t8wsy2AJ9on/NihMHQ/4HVqNbKoNIWur7AeOAqYZmbnuftFNVmz\nLkYVQ9fzeWCKu2/r7tu5+0jgVTPLbKgicC4wBayvme2Qmr4b8FqBkUIvE0YK/TdtjxRqaYRS6uA0\nGwxcQXwNiCy1y1hzd58G1JnZKanJ+aN9y2ZmPc3s6uTUGMmkdHVw6vnJ9I5XHeRrur7CUcQHsZmH\n+4cDXzKzE6u5FlVcdoeiiqHrORr4cd602wjNSw83n704TReKH1EPO+0JyyYAmwG/MttkIGxWB+PW\nwF1LCG3/uaOIWzxuwAp8zdzZYHbX5fDQn8xeeQ7eWgAzzwd6mdnThHbztYTk97Nyt6cN7XnU5xHA\nz83sXEJz3CpC4q1IeL/63wfLt4X+HzX7wVehridRdXDWn2HVh7yCg9EKx7bukGGCaf14hVzj/TIz\n+wTwgJktdve7MovfpLeZvU5IEA5c6u4/r0KcmtORz51ETY98tn718Jl/wG+2Dz9oVwFnL4HTH4Jd\ndyVcB2cGTaeSKPucQoVjnToH7jzYfcW8LLerWmodK7yGo2bA7CHhyLb+wF4b4IdXwR6XlpMISjtX\nkn0IuNLd9yk1TrNYFZwHqeRYVdaZjnyuee+3bsXdaKcRDYXiwPhrYaUnI4aS20qH4x5r6biB7GON\nv7YzvH4dIRaMuR1GhmMYGm8jHcbcXu1tIpykbyZwUCaxkuMVHHp1xfeqo97UlCRF2GpY86bvPsDK\n1e7MbJ9YWw7LNk5XtmACvJ037TVgiyz7mQpy9ysJp9aunK7bXDPqfJYivLUgNOmkrQIWLujcsbqq\nYQ/DyLxpI5PpnYTOg1RTSgxShJnnh3b+3A471+4/8/zWntXxY3VV886CIYtpPGFSf8L9eWfVcq1K\nlH+8grQjdT53EjW/UE/jqKQth4Vf7zPPr6QzuKPEqoaOECu8ht1yo5JehQ0HdZbO+9PN/LJwZHbJ\n11coVUd4rzoiJYZOotaJQbE6X6yWLu2ZdZxMmY1bAk8Ohh3bowmpo7xXHY0SQyehxKBYtYzVLnGS\n6zYfBdsYeDQwAAAGJklEQVTd1MVev/aOVSn1MYhI7aXOg3RzrddFlBhEpEPInQfpW7VeEVFTUqeR\nnBBPpMsZS+6izeGEWl3YMncfWOuVKIYSg0S6apurYnXQOEm/AnAeTZfo7HKvX2ejpiQRqY3C11eQ\nDkCnxBCRWil0fQXpAFQxiEi7yV0jYr7Z3hS+voJ0AEoMItIu+pnV9w9X6TvxUHjoHpik8yB1TOp8\nlkhX7fhTrNrG6WdWPwpmzIYhuStE7ASLX4K9V7jPyzJWKdT5XJgqBhGpunr42eIkKUC4fNBiGFIP\n1boKn1RAnc8iUnULYELBK0RA1a8RIaVTxSBlM7MjzOwZM3s6uT1jZuvN7ONViDXczOaa2YDk/ubJ\n/RFZx0qWP9TMrjezl83sCTO7y8x2yDjGNDM7JG/amWZ2WZZxUsten7xPz5rZk2ZW1qU3i4izwcwu\nTt3/lsOSgleIqOA65KlYU1L3u5vZEjP7SyXL3dgpMUjZ3P0Od9/d3ce6+1jCmTwfdPe/VSHW/GT5\nP04m/Qj4jbu/nnWsxO3ANHff0d33BM4DhmYc48/AF/OmfSGZXg2rkvdqN+A7hNewGtYAnzWzxqN8\nl8HUIbA4ukIELJ4HlV4jYhUw2szqkvuHAG9UuMyNnhKDZMLMdgK+BxxbxTA/B/Y2szOBfYGfViOI\nmX0UaHD3q3LT3P15d38k41C3AoeZWY8k7khgqyrEyUl3svYHllYpzjrgt8DZuQkO77wEewNzw13m\nFup4LtM9wOHJ/18Ers9gmRs1JQapWLJjuw44y93frFYcd18HnEvosDzT3ddXKdRo4KkqLbuRuy8D\nHgc+kUz6AuFyltXSO2lKmkXYcV9QpTgOXAYcY2Z9cxNXuM9bDjsDv18OO2eUFBy4AfhiUjXsCszI\nYLkbNSUGycKFwEx3v6UdYh0GLADGtEOs9nADISGQ/K3mr93VSVPSzoRkdE21Arn7SuBPwJl50xvc\n/aRKLxyUt8yZQD2hWribuDKSMigxSEXM7CPAkcDp7RBrN+AgYB/gbDPLus0/5wVgjyotO9+dwEFm\ntjvQ292faY+g7v4YMMjMBlUxzC+ArwKbVjFGzl+Ai1EzUiaUGKRsZrY58HvgeHdf3Q4hLyc0Ic0H\nfkKV+hjcfRrQ08xOyk0zszFmtl8VYq0C/kl4Hau9U2v8JW1mowjf//xRpJnFSZrKbgJOan32ymMR\nXr/J7v5CFWNtNJQYpBKnAIOBK1LDVZ82s89nHcjMTgZeS3baAFcAo8xs/6xjJY4EDjGzV8zseeCH\nwMIqxbqe0DZe7cTQK/c+JbGO9+qc+iC9zJ8CW+RNyzyWu7/p7r+uUoyNjk6JIZGuejoCxeoccbpy\nrM5EFYOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGRiA5wk4iZ6QMhG5Nl\n7j6w7dk2LkoMIiISUVOSiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgS\ng4iIRJQYREQkosQgIiIRJQYREYkoMYiISESJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIi\nESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlB\nREQiSgwiIhJRYhARkYgSg4iIRJQYREQkosQgIiIRJQYREYkoMYiISESJQUREIkoMIiISUWIQEZGI\nEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhERCSixCAi\nIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQYREQkosQgIiIRJQYREYkoMYiISESJ\nQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGR\niBKDiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQYREQkosQg\nIiIRJQYREYkoMYiISESJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIikf8P3Lvmwv17SsgA\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(qwerty, words={'HOUSED', 'HOUSES', 'NOISES'})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Average Confusions of a Keyboard\n", + "===\n", + "\n", + "The question is: how confusing is a keyboard? One metric for confusingness is the percentage of words that are confused with other words:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def confusingness(kbd):\n", + " \"The proportion of words in COMMON that are confused with other words on this keyboard.\"\n", + " neighbors = neighboring_keys(kbd)\n", + " return mean([confusable(w, neighbors) for w in COMMON])\n", + "\n", + "def title(kbd, name): \n", + " return ('{}: path length = {:.1f}, confuse = {:.0%}'\n", + " .format(name, workload_average(kbd), confusingness(kbd)))" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'4-by-7': 0.4571112340896514,\n", + " '5-by-6': 0.5282235749861649,\n", + " 'qwerty': 0.5398450470392916}" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{name: confusingness(kbd) for (name, kbd) in keyboards.items()}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "About half the common words are confusable, with a little bit of variation between keyboards." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 6: Is there a Keyboard that Minimizes Confusion?\n", + "===\n", + "\n", + "Consider this:" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 112 ms, sys: 990 µs, total: 113 ms\n", + "Wall time: 112 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "0.5398450470392916" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time confusingness(qwerty)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 168 µs, sys: 0 ns, total: 168 µs\n", + "Wall time: 171 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "3.2333097802127653" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time workload_average(qwerty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Computing `confusingness` takes about 500 times longer than computing `workload_average`, so if we want to use `confusingness` as a scoring function, we will have to settle for fewer swaps:" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEKCAYAAAAW8vJGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAF/NJREFUeJzt3Xm4JGWZpvH7oUoBNwQXtNncGwUUSrQVl0YcRkRtRQVB\nbZh2aR1HRdHpjVFEW23brbtdcGcE2VxQbHTUUVQUxFYLbBYdRFCWQgWrkJJNqHrnj4iD+R3qVJ2i\nMvJUnbp/15XXyYjIiDe2zCfii8g8qSokSZqyyVzPgCRp/WIwSJIaBoMkqWEwSJIaBoMkqWEwSJIa\nBsMaJLkkyV5jnuYhSb4zzmmuZf1vJnnRHNU+OsmbZ/naHZKsTDLx/XSut9GGIskeSS5Mcm2Sv5jr\n+dF4GAxzZ95/gWRMH66Dr6fVBNAkap+W5DdJrkly9uo+XJO8JsnPk/wuyeVJ3j0XoTnNm4F/q6q7\nVdUX53heVivJnv36vibJxasY/ogkp/fDL03yv0aGPTzJef22eu1I/4VJzkqyzaSWYxLmeqfSgJIs\nmOtZYMMIwKn5zBzUPhTYpqruDrwM+FSSrWd47SnA7lW1BbAzsCvw6snM5ox2AC6Y43mYreuAjwOv\nn2H48cC3+m2xJ/CKJE/vh70dOAx4BHB4knv3/Q8DPltVVww213PAYFgLSR6a5OIkz+u775vks/1R\nxM+TvKrvv3WS65JsOTLuov51Ux/WmyR5X390csFoc1U/3VOS/LY/TX/JyLBHJTkzybIkV/TTWDgy\nfGWSVyS5ELiw77d3kp/047yPtfgATHJEks8kObFvLvhhkoePDP/bJBf1w85L8qy+/47AUcBjkyxP\nsnRkslslObUf53tJ7j/Leblbko8lWZLksiRvSZJ+2CFJvpPknUmW9ttjn5Fx75fk2/3R9teSvD/J\nMf3gb/d/r+nn6c/+ONqqpzcuVXVuVd080mshsN0Mr72kqpb1nQuAlcCDZlsryUv7fW1qW+3a998x\nXfPisiTnJnnGyDhH9+vqNtsryUXA/YGpYXfMtKbXfv85tn++aZJjk1zd1/p+knv1w2bctuNSVT+o\nquOAS2Z4yQ504UBVXQx8F9ipH3Z/4JtVdSXwM2D7JDsAzwbeO875XC9UlY/VPOh2or2ARcAvgaf2\n/QP8EDic7k16P+AiYO9++KnAy0am8x7gX/vnhwA30x3tLQAOAK4B7t4PPx14H3AHuiOU3wB79sMW\n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\nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 10.4 s, sys: 19.7 ms, total: 10.4 s\n", + "Wall time: 10.4 s\n" + ] + } + ], + "source": [ + "%time show_kbd(improved(qwerty, swaps=100, scorer=confusingness))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This did indeed reduce confusingness (which was 54%); not bad for only 100 swaps." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Question 7: Is there a Keyboard that Maximizes User Satisfaction?\n", + "===\n", + "\n", + "What is user satisfaction? I don't know, but for now I'll approximate satisfaction (or rather, *dissatisfaction*, since lower scores are better) with a combined score that is the product of workload average and confusingness. Then I (rather arbitrarily) scale the result by 5, just because I think a number like \"2.1\" looks better than \"0.42\".\n", + "\n", + "First we'll define the combined scorer function and incorporate it into `title`:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def dissatisfaction(kbd):\n", + " \"The product of workload average and confusingness, scaled by 5.\"\n", + " return 5 * workload_average(kbd) * confusingness(kbd)\n", + "\n", + "def title(kbd, name): \n", + " return ('{}: path length = {:.1f}, confuse = {:.0%}, overall = {:.1f}'\n", + " .format(name, workload_average(kbd), confusingness(kbd), \n", + " dissatisfaction(kbd)))" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYz\nMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPB\nzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBg\nMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4\nGMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwK\nDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOz\ngoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzM\nrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYzMys4GMzMrOBgMDOzgoPBzMwKDgYz\nMys4GMzMrOBgMDOzwv8HncS9VgcZunsAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(qwerty)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let'stry to minimize confusion. This should take around 2 minutes:" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\nyVbnVgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2min 30s, sys: 482 ms, total: 2min 31s\n", + "Wall time: 2min 31s\n" + ] + } + ], + "source": [ + "%time report(swaps=500, scorer=dissatisfaction)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Success! We were in fact able to make progress on the combined metric. If we could run 50,000 swaps instead of just 500, we could probably do even better. To do so would require either (1) more computers, (2) more patience, or (3) more efficient algorithms. I'll leave it up to you to make more progress.\n", + "\n", + "**Note**: Each time this notebook is run, different random results can occur. I'll record a keyboard found by one\n", + "of the good runs (only 11% confusingness) here, just in case another run is not as good:" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nP/K3c1luY46PAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(Keyboard((' U D J K N W ',\n", + " 'T V H E B Q R',\n", + " ' Z I M X A C ',\n", + " 'S P G O F Y L')))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Summary\n", + "=====\n", + " \n", + " So where are we? Let's revisit our initial questions and see what answers we have:\n", + " \n", + " 1. What words have the longest path length?
**Answered**: \"PALEOMAGNETISMS\" etc.\n", + " 2. What words have the highest ratio of path length to word length?
**Answered**: \"PALAPA\" etc.\n", + " 3. What is the average segment length, over a typical typing work load?
**Answered**: 3.23 keys, for Qwerty keyboard, on our sample workload.\n", + " 4. Is there a better keyboard layout to minimize the average segment length over a work load?
**Answered**: Yes, many layouts at around 1.9 on Qwerty; or 1.7 or 1.8 on more square keyboards.\n", + " 5. How often are two words confused because they have similar paths?
**Answered**: On Qwerty, 26% of the words in a small dictionary, and 55% of the words in running text have at least one possible confusion. Other layouts are worse.\n", + " 6. Is there a better keyboard layout to minimize confusion?
**Partially Answered**: We found a keyboard with less confusingness than Qwerty. The computation of confusingness takes too long to do very much hillclimbing search. \n", + " 7. Is there a better keyboard layout to maximize overall user satisfaction?
**Partially Answered**: We defined a combined metric, and found\n", + "a keyboard with a better score. There are no doubt better metrics, and better keyboards to be found.\n", + " \n", + "\n", + "\n", + "\n", + "Going Beyond\n", + "===\n", + "\n", + "Now it is your turn to answer the open questions, or make up some questions of your own. Good luck! Here are a few ideas to get you started:\n", + "\n", + "* Hillclimbing just keeps the one best keyboard it has found so far. Other optimization techniques such as\n", + "[beam search](http://en.wikipedia.org/wiki/Beam_search) or [genetic algorithms](http://en.wikipedia.org/wiki/Genetic_algorithm) or [ant colony optimization](http://en.wikipedia.org/wiki/Ant_colony_optimization_algorithms) maintain several candidates at a time. Is that a good idea?\n", + "\n", + "* The code in this notebook emphasizes clarity, not efficiency. Can you modify the code (or perhaps port it to another language) and make it twice as efficient? 10 times? 100 times?\n", + "\n", + "* What other factors do you think are important to user satisfaction with a keyboard. Can you measure them?\n", + "\n", + "* Consider the 5 paths below. They all start at 'P', move in a straight line to 'T', and then go to 'S', but they all make different stops along the top row. In other words, the 5 paths all trace exacty the same lines, so they are very confusing, but our definition of `confusions` makes most of them different. Can you think\n", + "of a better way to handle confusions for paths like this?" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nfLXp0dsei7D9fuTurxcx1seGEoO0xVnAVsCtqe6qL5nZsYUOZGZnAG8nF22AW4FxZvaZQsdKHA1M\nNLO5ZvYacDWwrEixfkmoGy92YuiT2U9JrMlenOfup+f5U2CLrGEFj+Xui9395iLF+NjR7zFIpLs+\nC1+xukac7hyrK1GJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEX3CT\niJnpgJCPk2p3b4/fjehSlBhERCSiqiQREYkoMYiISESJQUREIkoMIiISUWIQEZGIEoOIiESUGERE\nJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhERCSixCAiIhElBhERiSgx\niIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQYREQkosQgIiIRJQYREYkoMYiISESJQUREIkoMIiIS\nUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhE\nRCSixCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQYREQkosQgIiIRJQYREYko\nMYiISESJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJKDGIiEhEiUFERCJKDCIi\nElFiEBGRiBKDiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlBREQiSgwiIhJRYhARkYgSg4iIRJQY\nREQkosQgIiIRJQYREYkoMYiISESJQUREIkoMIiISUWIQEZGIEoOIiESUGEREJKLEICIiESUGERGJ\nKDGIiEhEiUFERCJKDCIiElFiEBGRiBKDiIhElBhERCSixCAiIhElBhERiSgxiIhIRIlBREQi/x8t\nGVDmodqb0gAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_kbd(qwerty, words=['POUTS', 'POIUYTS', 'PUTTS', 'PUTS', 'POTS', 'PITS'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Ghost.ipynb b/pytudes/ipynb/Ghost.ipynb new file mode 100644 index 0000000..de05e0c --- /dev/null +++ b/pytudes/ipynb/Ghost.ipynb @@ -0,0 +1,1231 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Ghost\n", + "\n", + "According to [Wikipedia](https://en.wikipedia.org/wiki/Ghost_(game)):\n", + "\n", + "> **Ghost** *is a written or spoken word game in which players take turns adding letters to a growing word fragment, trying not to be the one to complete a valid word. Each fragment must be the beginning of an actual word, and usually some minimum is set on the length of a word that counts, such as three or four letters. The player who completes a word loses.*\n", + "\n", + "I'd like to create a program to allow any two players (human or computer) to play the game, and I'd like to figure out who wins if both players play optimally. The concepts I will need to define, and my implementation choices, are as follows:\n", + "\n", + "- **Words**: I will read a standard online word list, `enable1`, and make a set of all the words of sufficient length.\n", + "- **Fragment**: a fragment is a `str` of letters, such as `'gho'`.\n", + "- **Beginning**: each word has a set of valid beginnings: for `ghost` it is `{'', g, gh, gho, ghos, ghost}`. \"Prefix\" is a synonym of \"beginning\".\n", + "- **Vocabulary**: A `Vocabulary` object holds a set of all the `words` in a dictionary, as well as all the valid `fragments` (beginnings) of the words.\n", + "- **Player**: The first player will be called player `0`; the second player `1`. \n", + "- **Play**: A play is a new fragment formed by adding one letter to the end of the existing fragment.\n", + "- **Legal Play**: A play that is a valid prefix of some word. `enable1.legal_plays('gho') = {'ghos, 'ghou'}`.\n", + "- **Strategy**: A strategy is a function with signature `strategy(vocab, fragment) -> play`.\n", + "- **Game**: `play_game(vocab, *strategies)` plays a game between two (or more) player strategies.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Vocabulary: Words, Fragments, Legal Plays, and `enable1`\n", + "\n", + "`Vocabulary(words)` takes a collection of words as input, stores the words as a set, and also stores all the legal fragments of those words. `legal_plays(fragments)` gives a set of all plays that can be formed by adding a letter to create a legal word fragment. I also define the function `words` to split any string into component words." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Vocabulary:\n", + " \"Holds a set of legal words and a set of legal prefix fragments of those words.\"\n", + " def __init__(self, words, minlength=3):\n", + " self.words = {word for word in words if len(word) >= minlength}\n", + " self.fragments = {word[:i] for word in self.words for i in range(len(word) + 1)}\n", + " \n", + " def legal_plays(self, fragment): \n", + " return {fragment + L for L in alphabet} & self.fragments \n", + " \n", + "alphabet = 'abcdefghijklmnopqrstuvwxyz'\n", + " \n", + "words = str.split # Function to split a str into words" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a small example with a vocabulary of just three words:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'game', 'ghost', 'ghoul'}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v = Vocabulary(words('game ghost ghoul'))\n", + "\n", + "v.words" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'', 'g', 'ga', 'gam', 'game', 'gh', 'gho', 'ghos', 'ghost', 'ghou', 'ghoul'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v.fragments" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here is a large vocabulary, from a standard online Scrabble™ word list known as `enable1`:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "! [ -e enable1.txt ] || curl -O http://norvig.com/ngrams/enable1.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "enable1 = Vocabulary(words(open('enable1.txt').read()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's explore `enable1`:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(172724, 387878, 'ethylenediaminetetraacetates')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(enable1.words), len(enable1.fragments), max(enable1.words, key=len)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ghos', 'ghou'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enable1.legal_plays('gho')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ewe'}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enable1.legal_plays('ew')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'tha', 'the', 'thi', 'tho', 'thr', 'thu', 'thw', 'thy'}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enable1.legal_plays('th')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Players and Winners\n", + "\n", + "The first player is `0` and the second player is `1`. These names are convenient because:\n", + "- During the course of the game, the player whose turn it is to play next is always the length of the current fragment mod 2.\n", + "- When the game ends, the winning player is the length of the current fragment mod 2.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "to_play = winner = lambda fragment: len(fragment) % 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Who Wins?\n", + "\n", + "Who wins a game if both players play rationally? To answer that, consider the general situation at some point\n", + "during the game where\n", + "a player is presented with a fragment. That player can win if either:\n", + "- The fragment is a complete word (meaning the other player just formed the word, and thereby lost).\n", + "- The fragment is not a legal fragment (meaning the other player made a mistake, and thereby lost).\n", + "- At least one of the legal plays in this position puts the opponent in a position from which they *cannot* win.\n", + "\n", + "The function `win(vocab, fragment)` implements this. It returns a winning fragment if there is one, otherwise `False`. In particular, it returns `fragment` if the current player has already won (because `fragment` is\n", + "a word or illegal fragment), and it returns one of the legal plays if that play leads to a position from\n", + "which the opponent *cannot* `win`." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def win(vocab, fragment=''):\n", + " \"\"\"Does the current player have a forced win? \n", + " If so, return a play (or the current fragment) that leads to a win.\"\"\"\n", + " if fragment in vocab.words or fragment not in vocab.fragments:\n", + " return fragment\n", + " for play in vocab.legal_plays(fragment):\n", + " if not win(vocab, play):\n", + " return play \n", + " return False" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's test `win` to gain some confidence that we got it right:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# No winning play because all words have odd number of letters.\n", + "win(Vocabulary(words('cat camel gecko'))) " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'g'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 'g' is a winning play (but 'c' would be a loser)\n", + "win(Vocabulary(words('cat camel goat gerbil'))) " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# No winning play; doomed to 'camel' or 'gar'\n", + "win(Vocabulary(words('cat camel goat gecko gerbil gar'))) " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'g'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 'g' wins because 'ga' can be answered with 'gan' and 'ge' with 'ge'\n", + "win(Vocabulary(words('cat camel goat gecko gerbil gar gannet'))) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# TL;DR: The Answer\n", + "\n", + "Can the first player win with the `enable1` vocabulary?" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "win(enable1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**No.** The game is a win for the second player, not the first.\n", + "This agrees with [xkcd](https://xkcd.com/)'s Randall Monroe, who [says](https://blog.xkcd.com/2007/12/31/ghost/) *\"I hear if you use the Scrabble wordlist, it’s always a win for the second player.\"*\n", + "\n", + "But ... Wikipedia says that the minimum word length can be \"three or four letters.\" In `enable1` the limit was three; let's try again with a limit of four:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'n'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enable1_4 = Vocabulary(enable1.words, 4)\n", + "\n", + "win(enable1_4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Yes.** The first player can win with this vocabulary, by playing `'n'` first (and there might be other first plays that also force a win). It makes sense that it is easier for the first player to win, because we've eliminated a bunch of three-letter words from the vocabulary, all of which are losers for the first player. So here's a good meta-strategy: Say \"*Hey, let's play a game of Ghost. We can use the `enable1` word list. Would you like the limit to be 3 or 4 letters?*\" Then if your opponent says three (or four) you can say \"*OK, since you decided that, I'll decide to go second (or first).*\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Playing the Game: Strategies\n", + "\n", + "We define a *strategy* as a function that is given a vocabulary and a fragment as arguments, and returns a legal play. Below we define `rational`, a strategy that wins whenever it is possible to do so and plays randomly otherwise, and `ask` (a strategy factory that returns a strategy that, when called, will ask the named person to input a fragment)." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "\n", + "def rational(vocab, fragment): \n", + " \"Select a play that makes opponent not win (if possible), otherwise a random play.\"\n", + " return win(vocab, fragment) or random.choice(list(vocab.legal_plays(fragment)))\n", + "\n", + "def ask(name):\n", + " \"Return a strategy that asks for the next letter.\"\n", + " return lambda _, fragment: input('Player ' + name + ' given \"' + fragment + '\" plays? ')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a function to play a game. You give it a vocabulary, two (or possibly more) strategies, and optionally a `verbose` keyword to say if you want a line printed for each play or not." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import cycle\n", + "\n", + "def play(vocab, *strategies, verbose=False):\n", + " \"Return (winner, final_fragment) for a game of Ghost between these strategies.\"\n", + " fragment = ''\n", + " for (p, strategy) in cycle(enumerate(strategies)): # p is the player number\n", + " play = strategy(vocab, fragment)\n", + " if verbose:\n", + " print('Player {}, given \"{}\", plays \"{}\".'.format(p, fragment, play))\n", + " if play not in vocab.legal_plays(fragment):\n", + " return (winner(fragment + '?'), play) # Player loses for making an illegal play\n", + " elif play in vocab.words:\n", + " return (winner(play), play) # Player loses for making a word\n", + " else:\n", + " fragment = play # Keep playing" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, 'odyssey')" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "play(enable1, rational, rational) " + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 'truancies'),\n", + " (1, 'xebec'),\n", + " (1, 'ods'),\n", + " (1, 'vying'),\n", + " (1, 'ewe'),\n", + " (1, 'bwana'),\n", + " (1, 'vying'),\n", + " (1, 'knell'),\n", + " (1, 'zloty'),\n", + " (1, 'flirt'),\n", + " (1, 'zlote'),\n", + " (1, 'bwana'),\n", + " (1, 'gjetost'),\n", + " (1, 'pliancies'),\n", + " (1, 'flounce'),\n", + " (1, 'ufologist'),\n", + " (1, 'flour'),\n", + " (1, 'dweeb'),\n", + " (1, 'flirt'),\n", + " (1, 'ignatia')]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Does player 1 win every time?\n", + "\n", + "[play(enable1, rational, rational, verbose=False) for _ in range(20)]" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0, 'nyctalopia')" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "play(enable1_4, rational, rational)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Player P given \"\" plays? d\n", + "Player P given \"dw\" plays? dwa\n", + "Player P given \"dwar\" plays? dwarv\n", + "Player P given \"dwarve\" plays? dwarves\n" + ] + }, + { + "data": { + "text/plain": [ + "(1, 'dwarves')" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "play(enable1, ask('P'), rational)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Minimizing Possible Outcomes\n", + "\n", + "Now we know how to play perfectly, if we have a computer handy to execute the strategy.\n", + "But can we summarize the strategy into a form that is small enough that a human can memorize it? I will define the function `outcomes(vocab, fragment, player)` to return a set of all the words that are possible outcomes of a game, where the opponent can use any strategy whatsoever, but `player` uses a strategy that is:\n", + "\n", + "- *Rational*: plays towards a forced win whenever there is one.\n", + "- *Exploitive*: otherwise tries to give the opponent an opportunity to make a mistake that can be exploited.\n", + "- *Minimizing*: within the above constraints, returns the smallest possible set of words." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import textwrap \n", + "\n", + "def outcomes(vocab, fragment, player):\n", + " \"The smallest set of outcome words, if player tries to win, and make the set small.\"\n", + " if fragment in vocab.words:\n", + " return {fragment}\n", + " else:\n", + " cases = [outcomes(vocab, play, player) for play in vocab.legal_plays(fragment)]\n", + " if to_play(fragment) == player: # Player picks the top priority case\n", + " return min(cases, key=lambda words: priority(words, player))\n", + " else: # Oher player could pick anything\n", + " return set.union(*cases)\n", + " \n", + "def priority(words, player):\n", + " \"\"\"Return (lossiness, number_of_words, total_number_of_letters),\n", + " where lossiness is 0 if no losses, 1 if mixed losses/wins, 2 if all losses.\n", + " The idea is to find the list of outcome words that minimizes this triple.\"\"\"\n", + " lossiness = (0 if all(winner(word) == player for word in words) else\n", + " 1 if any(winner(word) == player for word in words) else\n", + " 2) \n", + " return (lossiness, len(words), sum(map(len, words)))\n", + "\n", + "def report_outcomes(vocab, player):\n", + " \"Find minimal outcomes for player; print info.\"\n", + " oc = outcomes(vocab, '', player)\n", + " winners = {w for w in oc if winner(w) == player}\n", + " def fill(label, words): \n", + " if words:\n", + " text = '{} ({}): {}'.format(label, len(words), ' '.join(sorted(words)))\n", + " print(textwrap.fill(text))\n", + " print('Outcomes ({}) for player {}:'.format(len(oc), player))\n", + " fill('Losers', oc - winners)\n", + " fill('Winners', winners)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Minimizing Outcomes for Player 0\n", + "\n", + "Let's see what minimal set of words player 0 can force the game into (with both vocabularies):" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Outcomes (6) for player 0:\n", + "Losers (1): qursh\n", + "Winners (5): qaid qiviut qoph qurush qwerty\n" + ] + } + ], + "source": [ + "report_outcomes(enable1, 0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Interesting!** There are only 6 words; it wouldn't be hard for a human to memorize these. Then, when you are playing as player 0, pick `'q'` first, and then try to steer the game to one of the 5 words with an even number of letters. Unfortunately, one word, `'qursh'` (a monetary unit of Saudi Arabia), has an odd number of letters, which means that if the opponent replies to `'q'` with `'qu'` and to `'qur'` with `'qurs'`, then player 0 will lose. But if the opponent makes any other responses, player 0 will win." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Outcomes (7) for player 0:\n", + "Winners (7): naan nene ngultrum nirvanic nolo null nyctalopia\n" + ] + } + ], + "source": [ + "report_outcomes(enable1_4, 0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Neat!** Only 7 words, and the first player can always win by forcing the opponent to one of these words.\n", + "\n", + "## Minimizing Outcomes for Player 1\n", + "\n", + "Since player 0 can pick any letter, the minimal `outcomes` set for player 1 must be at least 26 words. Let's see how much bigger it turns out to be. \n", + "\n", + "With `enable1` we already know that player 1 can force a win, so all the words in the `outcomes` set will have odd length:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Outcomes (55) for player 1:\n", + "Winners (55): aah aal aargh aas bwana cwm drave dreck drink droit\n", + "druid dry ewe fjeld fjord gjetost hmm ihram jnana kwashiorkor llano\n", + "mho nth oquassa prawn prequel prill pro prurigo pry qua quell quiff\n", + "quomodo qursh rhamnus rheum rhizoid rho rhumb rhyolitic squoosh\n", + "tchotchke uhlan vying wrath wrest wrist wrong wrung wry xanthic\n", + "xanthin yttrium zucchetto\n" + ] + } + ], + "source": [ + "report_outcomes(enable1, 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Memorize this list and you will never lose as player 1.\n", + "\n", + "How about with the other vocabulary?" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Outcomes (85) for player 1:\n", + "Losers (4): hybris hyphen hyte ngultrum\n", + "Winners (81): aquiculture aquifer aquilegia aquiver bwana cnidarian\n", + "drave dreck drink droit druid dryness eschatologies eschatology\n", + "escheat eserine esker esophagus esplanade esquire esquiring essay\n", + "estuarine estuary esurience fjeld fjord gjetost hyaenic hydatid hyena\n", + "hyenine hyenoid hygeist hying hylozoism hylozoist hymen hyoid hypha\n", + "hyraces hyrax hyson ihram jnana kwashiorkor llano mbira ngwee oquassa\n", + "plaza plethoric plica plonk pluck plyer quaff quell quiff quomodo\n", + "qursh rhamnus rheum rhizoid rhomb rhumb rhyolitic squoosh tchotchke\n", + "uhlan vying wrath wrest wrist wrong wrung wryly xanthic xanthin\n", + "yttrium zucchetto\n" + ] + } + ], + "source": [ + "report_outcomes(enable1_4, 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case there are 85 words, four of which are losses for player 1. But the other 81 words are wins, so with this strategy you'd have a good chance against an imperfect opponent." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SuperGhost\n", + "\n", + "In the variant *SuperGhost*, players can add a letter to either the beginning or the end of a fragment, as long as this forms a fragment that is part of some word. As Wikipedia says, given the fragment `era`, a player might play `bera` or `erad`. I was thinking of SuperGhost when I made the design decision to encapsulate `legal_plays` as a method of `Vocabulary`, rather than as a separate function. Because I did that, I should be able to use all the existing code if I just make a new class, `SuperVocabulary`, that finds *all* fragments (i.e. infixes) rather than just the beginning fragments (i.e. prefixes), and if I change `legal_plays` to add letters to both ends." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "class SuperVocabulary(Vocabulary):\n", + " \"Holds a set of legal words and a set of legal infix fragments of those words.\"\n", + " def __init__(self, words, minlength=3):\n", + " self.words = {word for word in words if len(word) >= minlength}\n", + " self.fragments = {word[i:j] for word in self.words \n", + " for i in range(len(word)) \n", + " for j in range(i, len(word) + 1)}\n", + " \n", + " def legal_plays(self, fragment):\n", + " \"All plays (adding a letter to fragment) that form a valid infix.\"\n", + " return {p for L in alphabet for p in (fragment + L, L + fragment)} & self.fragments" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I will create `SuperVocabulary` objects for 3- and 4-letter versions of `enable1`, and check out how many fragments there are in each variant:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "enable1_3super = SuperVocabulary(enable1.words, 3)\n", + "enable1_4super = SuperVocabulary(enable1.words, 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'acrop',\n", + " 'cropa',\n", + " 'crope',\n", + " 'croph',\n", + " 'cropi',\n", + " 'cropl',\n", + " 'cropo',\n", + " 'cropp',\n", + " 'cropr',\n", + " 'crops',\n", + " 'cropt',\n", + " 'cropu',\n", + " 'cropy',\n", + " 'ecrop',\n", + " 'icrop',\n", + " 'ncrop',\n", + " 'rcrop',\n", + " 'tcrop'}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example legal plays\n", + "enable1_3super.legal_plays('crop')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'u'" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Can the first player win in SuperGhost with 3-letter words?\n", + "\n", + "win(enable1_3super)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'u'" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# How about with a 4-letter limit?\n", + "\n", + "win(enable1_4super)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first player can win with or without three-letter words. And unless the first player is perfect, the rational strategy can do pretty well as seond player as well. Here is a sample game:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Player P given \"\" plays? q\n", + "Player P given \"cq\" plays? cqu\n", + "Player P given \"cque\" plays? acque\n", + "Player P given \"acques\" plays? acquest\n" + ] + }, + { + "data": { + "text/plain": [ + "(1, 'acquest')" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "play(enable1_3super, ask('P'), rational)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I would like to give a concise summary of the strategy for SuperGhost, but my existing `outcomes` function won't do it. That's because it is not enough to know that a particular word results in a win; we have to know in what order the letters of the word are added. I'll leave it as an exercise to find a good way to summarize SuperGhost strategies.\n", + "\n", + "# SuperDuperGhost\n", + "\n", + "In the variant *SuperDuperGhost*, players have an option to reverse the fragment before adding a letter to the beginning or end. As Wikipedia says, given the fragment `era`, a player might play `bera, erad, nare,` or `aren`.\n", + "Wikipedia is not clear, but I interpret this as meaning that the fragment played must still be a fragment of a word (not a reversed fragment of a word). Again, all we need is a new subclass:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class SuperDuperVocabulary(SuperVocabulary):\n", + " \"Holds a set of legal words and a set of legal infix fragments of those words.\"\n", + " \n", + " def legal_plays(self, fragment):\n", + " \"All plays that form a valid infix; optionally reverse fragment first.\"\n", + " def all4(f, L): return (f + L, f[::-1] + L, L + f, L + f[::-1])\n", + " return {p for L in alphabet for p in all4(fragment, L)} & self.fragments" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enable1_3duper = SuperDuperVocabulary(enable1.words)\n", + "enable1_4duper = SuperDuperVocabulary(enable1.words, 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'acrop',\n", + " 'cropa',\n", + " 'crope',\n", + " 'croph',\n", + " 'cropi',\n", + " 'cropl',\n", + " 'cropo',\n", + " 'cropp',\n", + " 'cropr',\n", + " 'crops',\n", + " 'cropt',\n", + " 'cropu',\n", + " 'cropy',\n", + " 'ecrop',\n", + " 'icrop',\n", + " 'iporc',\n", + " 'ncrop',\n", + " 'nporc',\n", + " 'porce',\n", + " 'porch',\n", + " 'porci',\n", + " 'porcu',\n", + " 'rcrop',\n", + " 'tcrop'}" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example legal plays\n", + "enable1_3duper.legal_plays('crop')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we should check who wins. But I'm impateint: I tried `win(enable1_3duper)`, waited a minute, and it still hadn't returned, so I interrupted that computation and threw in a `lru_cache` decorator; which stops `win` from wasting time repeating the same computation over and over. This brings the time down to about 2 seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "from functools import lru_cache\n", + "\n", + "@lru_cache(None)\n", + "def win(vocab, fragment=''):\n", + " \"\"\"Does the current player have a forced win? \n", + " Return fragment if the player has already won, or return a play that forces a win.\"\"\"\n", + " if fragment in vocab.words or fragment not in vocab.fragments:\n", + " return fragment\n", + " for play in vocab.legal_plays(fragment):\n", + " if not win(vocab, play):\n", + " return play \n", + " return False" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'p'" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "win(enable1_3duper)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'p'" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "win(enable1_4duper)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first player can win with either vocabulary. Here's a sample game." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Player 0, given \"\", plays \"p\".\n", + "Player 1, given \"p\", plays \"pr\".\n", + "Player 0, given \"pr\", plays \"lpr\".\n", + "Player 1, given \"lpr\", plays \"rple\".\n", + "Player 0, given \"rple\", plays \"rplex\".\n", + "Player 1, given \"rplex\", plays \"rplexe\".\n", + "Player 0, given \"rplexe\", plays \"urplexe\".\n", + "Player 1, given \"urplexe\", plays \"urplexes\".\n", + "Player 0, given \"urplexes\", plays \"ourplexes\".\n", + "Player 1, given \"ourplexes\", plays \"fourplexes\".\n" + ] + }, + { + "data": { + "text/plain": [ + "(0, 'fourplexes')" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "play(enable1_3duper, rational, rational, verbose=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how many fragments each vocabulary takes:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[387878, 387844, 1076434, 1076431, 1076434, 1076431]" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[len(v.fragments) \n", + " for v in [enable1, enable1_4, enable1_3super, enable1_4super, enable1_3duper, enable1_4duper]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Summary\n", + "\n", + "Here's a summary of what we have learned. (*Note:* the bold **qursh** means it is a losing word):\n", + "\n", + "| Variant \t| Shortest \t| Winner \t| First Player Forced Outcomes | 2nd Outcomes | Fragments\n", + "|:----:\t|:---:\t |:---:\t |:---: |:---: |---:\n", + "| Ghost | 3 \t | Second \t| qaid qiviut qoph **qursh** qurush qwerty | 55 words | 387,878\n", + "| Ghost | 4 \t | First \t| naan nene ngultrum nirvanic nolo null nyctalopia | 85 words | 387,844\n", + "| Super | 3\t| First \t| ? | ? | 1,076,434\n", + "| Super | 4 \t| First \t| ? | ? | 1,076,431\n", + "| SuperDuper | 3 | First| ? | ? | 1,076,434\n", + "| SuperDuper | 4 | First| ? | ? | 1,076,431\n", + "\n", + "# Further Work\n", + "\n", + "Here are some additional ideas to play with:\n", + "\n", + "- **Exploitation:** What are some good strategies when you are not guaranteed to win, to exploit an imperfect human opponent? Can you steer the game so that you win if the opponent is unfamiliar with some obscure word(s)? You might need a file of [word frequencies](http://norvig.com/ngrams/count_1w.txt).\n", + "- **Security:** A strategy function could *cheat*, and modify `vocab.words`, inserting or deleting some crucial words to ensure victory. Can you harden `play` (and/or change `Vocabulary`) to protect against that?\n", + "- **Pruning:** Currently `Vocabulary` saves words and fragments that could never be reached in a game. For example, because `'the'` is a word that ends the game, we could never reach `'them'` or `'theme'` or `'thermoluminescences'`. Can you prune away these redundant words/fragments?\n", + "- **Multi-player:** `play(enable1, ask('A'), ask('B'), ask('C'))` will play a three-player game. But `rational` (along with `win` and `winner`) would no longer work, since they assume there are exactly two players. Can you alter them to allow *n* players?\n", + "- **SuperGhost Summary:** Can you summarize a SuperGhost or SuperDuperGhost strategy in a way that a human can memorize?\n", + "- **Xghost:** In *Xghost*, a letter can be added anywhere, so from the fragment `'era'` you could play `'erba'`.\n", + "- **Spook:** In *Spook*, letters can be rearranged before adding one, so from the fragment `'era'` you could play `'bear'`." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Golomb-Puzzle.ipynb b/pytudes/ipynb/Golomb-Puzzle.ipynb new file mode 100644 index 0000000..f7480ea --- /dev/null +++ b/pytudes/ipynb/Golomb-Puzzle.ipynb @@ -0,0 +1,1326 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Sol Golomb’s Rectangle Puzzle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This problem by Solomon Golomb was presented by Gary Antonik in his 14/4/14 New York Times [Numberplay column](http://wordplay.blogs.nytimes.com/2014/04/14/rectangle):\n", + "\n", + ">Say you’re given the following challenge: create a set of five rectangles that have sides of length 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10 units. You can combine sides in a variety of ways: for example, you could create a set of rectangles with dimensions 1 x 3, 2 x 4, 5 x 7, 6 x 8 and 9 x 10.\n", + ">\n", + ">1. How many different sets of five rectangles are possible?\n", + ">\n", + ">2. What are the maximum and minimum values for the total areas of the five rectangles?\n", + ">\n", + ">3. What other values for the total areas of the five rectangles are possible?\n", + ">\n", + ">4. Which sets of rectangles may be assembled to form a square?\n", + "\n", + "To me, these are interesting questions because, first, I have a (slight) personal connection to Solomon Golomb (my former colleague at USC) and to Nelson Blachman (the father of my colleague Nancy Blachman), who presented the problem to Antonik, and second, I find it interesting that the problems span the range from mathematical to computational. Let's answer them." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. How many different sets of five rectangles are possible?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a basic [combinatorics](http://en.wikipedia.org/wiki/Combinatorics) or counting problem. I will present *three* methods to count the sets. If all goes well they will give the same answer. The example set of rectangles given in the problem was\n", + "\n", + "> {1 × 3, 2 × 4, 5 × 7, 6 × 8, 9 × 10}\n", + " \n", + "and in general it would be\n", + "\n", + "> {A × B, C × D, E × F, G × H, I × J}\n", + "\n", + "The question is: how many distinct ways can we assign the integers 1 through 10 to the variables A through J?\n", + " \n", + "**Method 1: Count all permutations and divide by repetitions:** There are 10 variables to be filled, so there are 10! = 3,628,800 permutations. But if we fill the first two variables with 1 × 3, that is the same rectangle as 3 × 1. So divide 10! by 25 to account for the fact that each of 5 rectangles can appear 2 ways. Similarly, if we fill A and B with 1 × 3, that yields the same set as if we filled C and D with 1 × 3. So divide again by 5! (the number of permutations of 5 things) to account for this.\n", + "That gives us:\n", + "\n", + ">
10! / 25 / 5! = 945. \n", + "\n", + "(It is always a relief when this \"count and divide\" method comes out to a whole number.)\n", + "\n", + "**Method 2: Count without repetitions**: in each rectangle of the example set the smaller component is listed first, and in each set, the rectangles with smaller first components are listed first. An alternate to \"count and divide\" is to count directly how many sets there are that respect this ordering. We'll work from left to right. How many choices are there for variable A? Only one: A must always be 1, because we agreed that the smallest number comes first. Then, given A, there are 9 remaining choices for B. For C, given A and B, there is again only one choice: C must be the smallest of the remaining 8 numbers (it will be 3 if the first rectangle was 1 × 2; otherwise it will be 2, but either way there is only one choice). That leaves 7 choices for D, 5 for F, 3 for H and 1 for J. So:\n", + "\n", + "> 9 × 7 × 5 × 3 × 1 = 945.\n", + "\n", + "(It is always a relief when two methods give the same answer.)\n", + " \n", + "**Method 3: Write a program to enumerate the sets:** We'll represent the 1 × 3 rectangle as the tuple `(1, 3)` and the example set of rectangles as the set\n", + "\n", + " {(1, 3), (2, 4), (5, 7), (6, 8), (9, 10)}\n", + "\n", + "We'll write a program to generate all possible sets of rectangles, following method 2, and then just count how many there are. To implement method 2, the minimum side will always be the first element, A, in an (A, B) pair. We iterate through all possible values for B, and then join that pair with all possible rectangles made from the remaining sides. We also have to handle the case when there are no sides; then there is one possible set of rectangles: the empty set." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "def rectangle_sets(sides):\n", + " \"Given a set of sides, list all distinct sets of rectangles that can be made.\"\n", + " if not sides:\n", + " return [ set() ]\n", + " else:\n", + " A = min(sides)\n", + " return [ {(A, B)} | other_rects\n", + " for B in sides if B is not A\n", + " for other_rects in rectangle_sets(sides - {A, B}) ]" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{(1, 2), (3, 4)}, {(1, 3), (2, 4)}, {(1, 4), (2, 3)}]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rectangle_sets({1, 2, 3, 4})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see above that there are three possible rectangle sets for 4 sides (the 1 can pair with any other side, and then a second rectangle can only be made one way from the remaining 2 sides). Below we count how many can be made with 10 sides:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "945" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sides = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n", + "\n", + "all_sets = rectangle_sets(sides)\n", + "\n", + "len(all_sets)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(It is a relief that once again we get the same answer, 945.) \n", + "\n", + "I don't want to print all 945 sets, but let's peek at every 100th one:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)},\n", + " {(1, 2), (3, 10), (4, 8), (5, 6), (7, 9)},\n", + " {(1, 3), (2, 10), (4, 6), (5, 7), (8, 9)},\n", + " {(1, 4), (2, 10), (3, 5), (6, 8), (7, 9)},\n", + " {(1, 5), (2, 9), (3, 8), (4, 6), (7, 10)},\n", + " {(1, 6), (2, 9), (3, 5), (4, 7), (8, 10)},\n", + " {(1, 7), (2, 9), (3, 4), (5, 8), (6, 10)},\n", + " {(1, 8), (2, 7), (3, 9), (4, 5), (6, 10)},\n", + " {(1, 9), (2, 7), (3, 5), (4, 6), (8, 10)},\n", + " {(1, 10), (2, 7), (3, 4), (5, 8), (6, 9)}]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_sets[::100]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. What are the maximum and minimum values for the total areas of the five rectangles?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "I think I know this one, but I'm not completely sure. I know that a rectangle with a fixed perimeter has maximum area when it is a square. My guess is that the maximum total area occurs when each rectangle is *almost* square: a 9 × 10 rectangle; 7 × 8; and so on. So that would give us a maximum area of:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "190" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(1 * 2) + (3 * 4) + (5 * 6) + (7 * 8) + (9 * 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the minimum area should be when the rectangles deviate the most from squares: a 1 × 10, and so on:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "110" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(1 * 10) + (2 * 9) + (3 * 8) + (4 * 7) + (5 * 6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since I am not sure, I will double check by finding the rectangle sets with the min and max total areas:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def total_area(rectangles): return sum(w * h for (w, h) in rectangles)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(all_sets, key=total_area)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 10), (2, 9), (3, 8), (4, 7), (5, 6)}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "min(all_sets, key=total_area)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This verifies my intuitions. But I still don't completely understand the situation. Suppose there are *N* sides that are not consecutive integers. Will the maximum total area always be formed by combining the two biggest sides, and so on?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. What other values for the total areas of the five rectangles are possible?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I have no idea how to figure this out mathematically from first principles, but it is easy to compute with the code we already have:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 183, 184, 186, 187, 190]\n" + ] + } + ], + "source": [ + "areas = {total_area(s) for s in all_sets}\n", + "print(sorted(areas))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Is there a more succint way to describe these values? Let's see ..." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{176, 185, 188, 189}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(range(110, 191)) - areas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The answer is: \"All the integers between 110 and 190 inclusive, except 176, 185, 188, and 189.\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Which sets of rectangles may be assembled to form a square?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The only way I can think about this is to write a program; I don't see any way to work it out by hand. I do know that the total area will have to be a perfect square, and since the total area is between 110 and 191, that means either 121, 144, or 169:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(121, {(1, 6), (2, 9), (3, 10), (4, 8), (5, 7)}),\n", + " (121, {(1, 6), (2, 10), (3, 8), (4, 9), (5, 7)}),\n", + " (121, {(1, 6), (2, 10), (3, 9), (4, 7), (5, 8)}),\n", + " (121, {(1, 7), (2, 10), (3, 6), (4, 9), (5, 8)}),\n", + " (121, {(1, 8), (2, 6), (3, 10), (4, 9), (5, 7)}),\n", + " (121, {(1, 8), (2, 7), (3, 10), (4, 6), (5, 9)}),\n", + " (121, {(1, 8), (2, 9), (3, 7), (4, 6), (5, 10)}),\n", + " (121, {(1, 8), (2, 10), (3, 5), (4, 9), (6, 7)}),\n", + " (121, {(1, 9), (2, 7), (3, 6), (4, 10), (5, 8)}),\n", + " (121, {(1, 9), (2, 7), (3, 8), (4, 6), (5, 10)}),\n", + " (121, {(1, 9), (2, 7), (3, 10), (4, 5), (6, 8)}),\n", + " (121, {(1, 9), (2, 8), (3, 6), (4, 7), (5, 10)}),\n", + " (121, {(1, 10), (2, 5), (3, 9), (4, 8), (6, 7)}),\n", + " (121, {(1, 10), (2, 8), (3, 7), (4, 5), (6, 9)}),\n", + " (144, {(1, 3), (2, 9), (4, 10), (5, 7), (6, 8)}),\n", + " (144, {(1, 3), (2, 10), (4, 7), (5, 9), (6, 8)}),\n", + " (144, {(1, 3), (2, 10), (4, 8), (5, 7), (6, 9)}),\n", + " (144, {(1, 5), (2, 6), (3, 8), (4, 10), (7, 9)}),\n", + " (144, {(1, 7), (2, 4), (3, 8), (5, 9), (6, 10)}),\n", + " (144, {(1, 7), (2, 9), (3, 5), (4, 6), (8, 10)}),\n", + " (144, {(1, 9), (2, 5), (3, 7), (4, 6), (8, 10)}),\n", + " (144, {(1, 9), (2, 6), (3, 5), (4, 7), (8, 10)}),\n", + " (144, {(1, 10), (2, 4), (3, 5), (6, 8), (7, 9)}),\n", + " (169, {(1, 2), (3, 5), (4, 9), (6, 10), (7, 8)}),\n", + " (169, {(1, 2), (3, 7), (4, 6), (5, 10), (8, 9)}),\n", + " (169, {(1, 2), (3, 7), (4, 9), (5, 6), (8, 10)}),\n", + " (169, {(1, 2), (3, 8), (4, 5), (6, 10), (7, 9)}),\n", + " (169, {(1, 3), (2, 5), (4, 8), (6, 9), (7, 10)}),\n", + " (169, {(1, 3), (2, 7), (4, 5), (6, 10), (8, 9)}),\n", + " (169, {(1, 3), (2, 7), (4, 8), (5, 6), (9, 10)}),\n", + " (169, {(1, 4), (2, 5), (3, 7), (6, 9), (8, 10)}),\n", + " (169, {(1, 5), (2, 3), (4, 9), (6, 7), (8, 10)}),\n", + " (169, {(1, 5), (2, 4), (3, 8), (6, 7), (9, 10)}),\n", + " (169, {(1, 5), (2, 7), (3, 4), (6, 8), (9, 10)}),\n", + " (169, {(1, 6), (2, 3), (4, 8), (5, 7), (9, 10)})]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "perfect_squares = {i ** 2 for i in range(100)}\n", + "\n", + "sorted((total_area(s), s) \n", + " for s in all_sets if total_area(s) in perfect_squares)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So 35 out of 945 rectangle sets *might* be assembled into a square; we don't know yet if they *can* be. \n", + "\n", + "# Packing Rectangles into a Square\n", + "\n", + "I would like to see *how* the rectangles are packed into the square, not just *which* sets can be packed, so I'll need a data structure to hold information on which rectangle goes where, and a way to visually display the results.\n", + "I'll represent a *Grid* as a two-dimensional array: a list of rows, each of which is a list of cells, with the idea that each cell will be covered by a rectangle by assigning `grid[y][x] = rect` (and the special rectangle `empty` will be used to mark a cell as uncovered). I only need to deal with square grids:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "empty = (0, 0)\n", + "\n", + "def Square(n):\n", + " \"Create an [n x n] grid of empty cells.\"\n", + " return [[empty for col in range(n)] \n", + " for row in range(n)]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],\n", + " [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],\n", + " [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],\n", + " [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],\n", + " [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Square(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's make a function to place a single rectangle onto a grid: `place_rectangle_at((w, h), grid, (x0, y0))` places a rectangle of width *w* and height *h* onto a grid at position (x0, y0). If the rectangle overlaps a non-empty cell, or goes off the grid, we return `None` to indicate that this is not a legal placement. If the rectangle does fit, we return a new grid with the new rectangle placed on it (we do not modify the original grid):" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def place_rectangle_at(rect, grid, pos):\n", + " \"\"\"Place the rectangle of size (w, h) onto grid at position (x0, y0).\n", + " Return a new grid, or None if the rectangle cannot be placed.\"\"\"\n", + " (w, h) = rect\n", + " (x0, y0) = pos\n", + " newgrid = [row.copy() for row in grid] \n", + " for x in range(x0, x0+w):\n", + " for y in range(y0, y0+h):\n", + " if y >= len(grid) or x >= len(grid[y]) or newgrid[y][x] is not empty:\n", + " return None \n", + " newgrid[y][x] = rect\n", + " return newgrid" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)],\n", + " [(0, 0), (0, 0), (3, 4), (3, 4), (3, 4)],\n", + " [(0, 0), (0, 0), (3, 4), (3, 4), (3, 4)],\n", + " [(0, 0), (0, 0), (3, 4), (3, 4), (3, 4)],\n", + " [(0, 0), (0, 0), (3, 4), (3, 4), (3, 4)]]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Place a 3 x 4 rectangle on a 5 x 5 square grid, 2 cells over and 1 down:\n", + "place_rectangle_at((3, 4), Square(5), (2, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[(2, 5), (2, 5), (0, 0), (0, 0), (0, 0)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)]]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Place two rectangles on a grid\n", + "grid0 = Square(5)\n", + "grid1 = place_rectangle_at((3, 4), grid0, (2, 1))\n", + "grid2 = place_rectangle_at((2, 5), grid1, (0, 0))\n", + "grid2" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[(2, 5), (2, 5), (3, 1), (3, 1), (3, 1)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)]]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Place a third rectangle that just barely fits\n", + "place_rectangle_at((3, 1), grid2, (2, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n" + ] + } + ], + "source": [ + "# Alternatively, try to place a third rectangle that does not fit\n", + "print(place_rectangle_at((4, 1), grid2, (2, 0)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need a strategy for packing a set of rectangles onto a grid. I know that many variants of [bin packing problems](http://en.wikipedia.org/wiki/Bin_packing_problem) are NP-hard, but we only have 5 rectangles, so it should be easy: just exhaustively try each rectangle in each possible position, and in both possible orientations (horizontal and vertical). But placing rectangles is commutative, so we can do this two ways:\n", + "\n", + "> Way 1: Considering the *rectangles* in a fixed order, try every possible *position* for each *rectangle*.\n", + "\n", + "or\n", + "\n", + "> Way 2: Considering the *positions* in a fixed order, try every possible *rectangle* for each *position*.\n", + "\n", + "In Way 1, we could pre-sort the rectangles (say, biggest first). Then we try to put the biggest rectangle in all possible positions on the grid, and for each position that fits, try putting the second biggest rectangle in all remaining positions, and so on. As a rough estimate, assume there are on average about 10 ways to place a rectangle. Then this way will look at about 105 = 100,000 combinations.\n", + "\n", + "In Way 2, we consider the positions in some fixed order; say top-to-bottom, left-to right. Take the first empty position (say, the upper left corner). Try putting each of the rectangles there, and for each one that fits, try all possible rectangles in the next empty position, and so on. There are only 5! permutations of rectangles, and each rectangle can go either horizontally or vertically, so we would have to consider 5! × 25 = 3840 combinations. Since 3840 < 100,000, I'll go with Way 2. Here is a more precise description:\n", + "\n", + "> Way 2: To `pack` a set of rectangles onto a grid, find the first empty cell on the grid. Try in turn all possible placements of any rectangle (in either orientation) at that position. For each one that fits, try to `pack` the remaining rectangles, and return the resulting grid if one of these packings succeeds. " + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "def pack(rectangles, grid):\n", + " \"\"\"Find a way to pack all rectangles onto grid and return the packed grid,\n", + " or return None if not possible.\"\"\"\n", + " if not rectangles:\n", + " return grid \n", + " pos = first_empty_cell(grid)\n", + " if grid and pos:\n", + " for (rectangles2, grid2) in rectangle_placements(rectangles, grid, pos):\n", + " solution = pack(rectangles2, grid2)\n", + " if solution:\n", + " return solution\n", + "\n", + "def rectangle_placements(rectangles, grid, pos):\n", + " \"Yield all (rectangles2, grid2) pairs that are the result of placing any rectangle at pos on grid.\"\n", + " for (w, h) in rectangles:\n", + " for rect in [(w, h), (h, w)]:\n", + " grid2 = place_rectangle_at(rect, grid, pos)\n", + " if grid2: \n", + " yield rectangles - {(w, h)}, grid2 \n", + " \n", + "def first_empty_cell(grid):\n", + " \"The uppermost, leftmost empty cell.\"\n", + " for (y, row) in enumerate(grid):\n", + " for (x, cell) in enumerate(row):\n", + " if cell is empty:\n", + " return (x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try a simple example that I know will fit:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[(2, 5), (2, 5), (3, 1), (3, 1), (3, 1)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)],\n", + " [(2, 5), (2, 5), (3, 4), (3, 4), (3, 4)]]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pack({(1, 3), (2, 5), (3, 4)}, Square(5))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It works! But it is not pretty.\n", + "\n", + "# Colored Rectangles" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It would be nicer to have a graphical display of colored rectangles. I will define the function `show` which displays a grid as colored rectangles, by calling upon `html_table`, which formats any grid into HTML text." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import HTML, display, clear_output\n", + "\n", + "def show(grid):\n", + " \"Display a colored HTML representation of this grid, unless it is None.\"\n", + " if grid:\n", + " display(html_table(grid, colored_cell))\n", + " \n", + "def html_table(grid, cell_function='{}'.format):\n", + " \"Return an HTML , where each cell's contents comes from calling cell_function(grid[y][x])\"\n", + " return HTML('
{}
'\n", + " .format(cat('\\n' + cat(map(cell_function, row)) \n", + " for row in grid)))\n", + "\n", + "def colored_cell(rect): \n", + " x, y = sorted(rect)\n", + " return '{}{}'.format(colors[x], x%10, y%10)\n", + "\n", + "colors = 'lightgrey yellow plum chartreuse cyan coral red olive slateblue lightgrey wheat'.split()\n", + "\n", + "cat = ''.join" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
2525131313\n", + "
2525343434\n", + "
2525343434\n", + "
2525343434\n", + "
2525343434
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# For example:\n", + "show(pack({(1, 3), (2, 5), (3, 4)}, Square(5)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's much nicer to look at! Now we can show all the rectangles that are packable into a square:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373712898989898989898989\n", + "
37373712898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
79797979797979606060606060\n", + "
45454545451212606060606060\n", + "
45454545453838383838383838\n", + "
45454545453838383838383838\n", + "
45454545453838383838383838
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
3939395858585858585858\n", + "
3939395858585858585858\n", + "
3939395858585858585858\n", + "
3939395858585858585858\n", + "
3939395858585858585858\n", + "
3939394747474747474716\n", + "
3939394747474747474716\n", + "
3939394747474747474716\n", + "
3939394747474747474716\n", + "
2020202020202020202016\n", + "
2020202020202020202016
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "
2828191919191919191919\n", + "
2828474747475050505050\n", + "
2828474747475050505050\n", + "
2828474747475050505050\n", + "
2828474747475050505050\n", + "
2828474747475050505050\n", + "
2828474747475050505050\n", + "
2828474747475050505050\n", + "
3636363636365050505050\n", + "
3636363636365050505050\n", + "
3636363636365050505050
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def pack_square(rectangles):\n", + " \"Pack rectangles into a square of appropriate size, if possible.\"\n", + " A = total_area(rectangles)\n", + " if A in perfect_squares:\n", + " return pack(rectangles, Square(int(A ** 0.5)))\n", + "\n", + "for s in all_sets:\n", + " show(pack_square(s))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So there are 4 sets of rectangles that work." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Animated Colored Rectangles" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is gratifying to see the final results, and have the computation be so fast, but I'd like to get a better understanding of the process of finding the results. I can try to visualize the process by *animating* the search that `pack` does: every time we successfully call `place_rectangle_at`, I can show the new grid, and then pause for a short period. I accomplish this by modifying `pack` to take an optional argument, `animation`, which when false gives the same behavior as before, but when it is a number, pauses for that number of seconds in between displaying each step of the packing." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import time\n", + "\n", + "def pack(rectangles, grid, animation=False): \n", + " \"\"\"Find a way to pack all rectangles onto grid and return the packed grid,\n", + " or return None if not possible. \n", + " Pause `animation` seconds between displaying each rectangle placement if `animation` is not false.\"\"\"\n", + " if animation: \n", + " clear_output()\n", + " show(grid)\n", + " time.sleep(animation) \n", + " if not rectangles:\n", + " return grid \n", + " pos = first_empty_cell(grid)\n", + " if grid and pos:\n", + " for (rectangles2, grid2) in rectangle_placements(rectangles, grid, pos): \n", + " solution = pack(rectangles2, grid2, animation)\n", + " if solution:\n", + " return solution" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you are running this in a live IPython notebook (not in nbviewer), you can see for yourself by re-running this cell:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373750505050505050505050\n", + "
37373712898989898989898989\n", + "
37373712898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989\n", + "
46464646898989898989898989
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pack({(1, 2), (3, 7), (4, 6), (5, 10), (8, 9)}, Square(13), 1);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Now For Something Completely Different: Cryptarithmetic" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On April 28, Gary Antonik had another [Numberplay column](http://wordplay.blogs.nytimes.com/2014/04/28/num/) that quotes my friend Bill Gosper. (Gosper often presents more advanced puzzles in the [math-fun](http://mailman.xmission.com/cgi-bin/mailman/listinfo/math-fun) mailing list.) This puzzle was:\n", + "\n", + ">For the expression N U M + B E R = P L A Y,\n", + "\n", + "> Which distinct numerals (each different) can be substituted for letters to make a valid expression?\n", + "\n", + "> How many solutions are there?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I tackled this type of problem (known as a [cryptarithmetic](http://mathworld.wolfram.com/Cryptarithmetic.html) or [alphametic](http://mathworld.wolfram.com/Alphametic.html) problem) in my Udacity class [CS 212](https://www.udacity.com/wiki/cs212/unit-2#cryptarithmetic). My approach was simple: try all permutations of digits replacing letters (that should be quick and easy—there can be at most 10 factorial or 3.6 million permutations), then for each one, use Python's `eval` function to see if the resulting string is a true expression. The basic idea is simple, but there are complications to worry about:\n", + "\n", + "1. Math uses `=` and Python uses `==` for equality; we'll allow either one.\n", + "2. The more detailed rules for these problems say that a number with a leading zero (like `012`) is illegal (but `0` itself is ok).\n", + "3. By default, Python thinks that 3/2 is 1, because integer division rounds down. But we can import \"proper\" division from the future.\n", + "4. If we try to eval an expression like 1/0, Python raises an error; we'll have to handle it." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import division\n", + "import itertools\n", + "import re\n", + "\n", + "def solve_all(formula):\n", + " \"\"\"Given a formula like 'NUM + BER = PLAY', fill in digits to solve it.\n", + " Input formula is a string; generate each digit-filled-in string.\"\"\"\n", + " formula = formula.replace(' = ', ' == ')\n", + " for exp in replace_letters(formula):\n", + " if valid(exp):\n", + " yield exp\n", + "\n", + "def replace_letters(formula):\n", + " \"Generate all possible replacements of letters with digits in formula.\"\n", + " letters = ''.join(set(re.findall('[A-Z]', formula)))\n", + " for digits in itertools.permutations('1234567890', len(letters)):\n", + " trans = str.maketrans(letters, ''.join(digits))\n", + " yield formula.translate(trans)\n", + "\n", + "def valid(exp):\n", + " \"Expression is valid iff it has no numbers with leading zero, and evals true.\"\n", + " try:\n", + " return not leading_zero(exp) and eval(exp)\n", + " except ArithmeticError:\n", + " return False\n", + " \n", + "leading_zero = re.compile(r'\\b0[0-9]').search" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'857 + 349 == 1206'" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "next(solve_all('NUM + BER = PLAY'))" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 29 s, sys: 42.2 ms, total: 29.1 s\n", + "Wall time: 29.1 s\n" + ] + }, + { + "data": { + "text/plain": [ + "96" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time len(list(solve_all('NUM + BER = PLAY')))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So there are 96 solutions, but it is a bit slow to find them all. For each of the permutations of digits, we substitute the digits for letters, and then call `eval(exp)` on the resulting string. The majority of time is spent inside `eval`. But the expression is basically the same each time; we could save a lot of work if we eval the expression just once, yielding a Python function, and then call that function once for each permutation of digits. In other words, we want to take an expression such as\n", + "\n", + " \"NUM + BER == PLAY\"\n", + " \n", + "and transform it into the Python function\n", + "\n", + "\n", + " lambda A,B,E,M,L,N,P,R,U,Y: (100*N+10*U+M) + (100*B+10*E+R) == (1000*P+100*L+10*A+Y)\n", + " \n", + "Actually that's not quite right. The rules are that the first letter of each multi-letter word (the \"N\" in \"NEW\"; the \"B\" in \"BER\"; and the \"P\" in \"PLAY\") cannot be a zero. So the function should be:\n", + "\n", + " lambda A,B,E,M,L,N,P,R,U,Y: N and B and P and (100*N+10*U+M) + (100*B+10*E+R) == (1000*P+100*L+10*A+Y)\n", + "\n", + "In my Udacity class I show a solution to this problem; you can [go there](https://www.udacity.com/wiki/cs212/unit-2#rethinking-eval) or see it here. Here is the code to compile a formula (or expression) into a Python function: " + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def compile_formula(formula, verbose=False):\n", + " \"\"\"Compile formula into a function. Also return letters found, as a str,\n", + " in same order as parms of function. For example, 'YOU == ME**2' returns\n", + " (lambda Y,M,E,U,O: Y and M and ((100*Y+10*O+U) == (10*M+E)**2)), 'YMEUO'\"\"\"\n", + " formula = formula.replace(' = ', ' == ')\n", + " letters = ''.join(set(re.findall('[A-Z]', formula)))\n", + " firstletters = set(re.findall(r'\\b([A-Z])[A-Z]', formula))\n", + " body = re.sub('[A-Z]+', compile_word, formula)\n", + " if firstletters:\n", + " body = '{} and ({})'.format(' and '.join(firstletters), body)\n", + " fn = 'lambda {}: {}'.format(','.join(letters), body)\n", + " if verbose: print(fn)\n", + " return eval(fn), letters\n", + "\n", + "def compile_word(matchobj):\n", + " \"Compile the word 'YOU' as '(100*Y + 10*O + U)'.\"\n", + " word = matchobj.group()\n", + " terms = reversed([mult(10**i, L) for (i, L) in enumerate(reversed(word))])\n", + " return '(' + '+'.join(terms) + ')'\n", + "\n", + "def mult(factor, var): return var if factor == 1 else str(factor) + '*' + var" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "lambda Y,M,E,O,U: Y and M and ((100*Y+10*O+U) == (10*M+E)**2)\n" + ] + }, + { + "data": { + "text/plain": [ + "(>, 'YMEOU')" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "compile_formula(\"YOU == ME**2\", verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "lambda L,A,Y,P,M,E,R,U,B,N: P and B and N and ((100*N+10*U+M) + (100*B+10*E+R) == (1000*P+100*L+10*A+Y))\n" + ] + }, + { + "data": { + "text/plain": [ + "(>, 'LAYPMERUBN')" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "compile_formula(\"NUM + BER == PLAY\", verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def faster_solve_all(formula):\n", + " \"\"\"Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it.\n", + " Input formula is a string; output is a digit-filled-in string or None.\n", + " Capital letters are variables. This version precompiles the formula; only one eval per formula.\"\"\"\n", + " fn, letters = compile_formula(formula)\n", + " for digits in itertools.permutations((1,2,3,4,5,6,7,8,9,0), len(letters)):\n", + " try:\n", + " if fn(*digits):\n", + " yield replace_all(formula, letters, digits)\n", + " except ZeroDivisionError: \n", + " pass\n", + " \n", + "def replace_all(text, olds, news):\n", + " \"Replace each occurrence of each old in text with the corresponding new.\"\n", + " # E.g. replace_all('A + B', ['A', 'B'], [1, 2]) == '1 + 2'\n", + " for (old, new) in zip(olds, news):\n", + " text = text.replace(str(old), str(new))\n", + " return text" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'857 + 349 = 1206'" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "next(faster_solve_all('NUM + BER = PLAY'))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.75 s, sys: 3.29 ms, total: 1.76 s\n", + "Wall time: 1.76 s\n" + ] + }, + { + "data": { + "text/plain": [ + "96" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time len(list(faster_solve_all('NUM + BER = PLAY')))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We get the same answer, but 15 times faster." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/How To Count Things.ipynb b/pytudes/ipynb/How To Count Things.ipynb new file mode 100644 index 0000000..2edcae5 --- /dev/null +++ b/pytudes/ipynb/How To Count Things.ipynb @@ -0,0 +1,1196 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import re\n", + "from itertools import product, chain, permutations\n", + "from collections import defaultdict\n", + "from functools import lru_cache as cache\n", + "from math import factorial" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# How to Count Things\n", + "\n", + "This notebook contains problems designed to show how to count things. So far there are five example problems.\n", + "\n", + "# (1) Student Records: Late, Absent, Present\n", + "\n", + "Consider this problem:\n", + "\n", + "> (1) Students at a school must meet with the guidance counselor if they have two total absences, or three consecutive late days. Each student's attendance record consists of a string of 'A' for absent, 'L' for late, or 'P' for present. For example: \"LAPLPA\" requires a meeting (because there are two absences), and \"LAPLPL\" is OK (there are three late days, but they are not consecutive). Write a function that takes such a string as input and returns `True` if the student's record is OK. \n", + "\n", + "> (2) Write a function to calculate the number of attendance records of length N that are OK.\n", + "\n", + "For part (1), the simplest approach is to use `re.search`:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def ok(record: str) -> bool: return not re.search(r'LLL|A.*A', record)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'pass'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_ok():\n", + " assert ok(\"LAPLLP\")\n", + " assert not ok(\"LAPLLL\") # 3 Ls in a row\n", + " assert not ok(\"LAPLLA\") # 2 As overall\n", + " assert ok(\"APLLPLLP\")\n", + " assert not ok(\"APLLPLLL\") # 3 Ls in a row\n", + " assert not ok(\"APLLPLLA\") # 2 As overall\n", + " return 'pass'\n", + " \n", + "test_ok() " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For part (2), I'll start with a simple (but slow) solution called `total_ok_slow` that enumerates `all_strings` (using `itertools.product`) and counts how many are `ok`. I use the `quantify` recipe ([from `itertools`](https://docs.python.org/3.6/library/itertools.html#itertools-recipes)) to count them:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def total_ok_slow(N: int) -> int:\n", + " \"How many strings over 'LAP' of length N are ok?\"\n", + " return quantify(all_strings('LAP', N), ok)\n", + "\n", + "def all_strings(alphabet, N): \n", + " \"All length-N strings over the given alphabet.\"\n", + " return map(cat, product(alphabet, repeat=N))\n", + "\n", + "def quantify(iterable, pred=bool) -> int:\n", + " \"Count how many times the predicate is true of items in iterable.\"\n", + " return sum(map(pred, iterable))\n", + "\n", + "cat = ''.join" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: 1,\n", + " 1: 3,\n", + " 2: 8,\n", + " 3: 19,\n", + " 4: 43,\n", + " 5: 94,\n", + " 6: 200,\n", + " 7: 418,\n", + " 8: 861,\n", + " 9: 1753,\n", + " 10: 3536}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{N: total_ok_slow(N) for N in range(11)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This looks good, but\n", + "I will need a more efficient algorithm to handle large values of *N*. Here's how I think about it:\n", + "\n", + "* I can't enumerate all the strings; there are too many of them, 3N. \n", + "* Even if I only enumerate the ok strings, there are still too many, O(2N).\n", + "* Instead, I'll want to keep track of a *summary* of all the ok strings of length *N*, and use that to quickly compute a summary of the ok strings of length *N*+1. I recognize this as a *[dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming)* approach.\n", + "\n", + "* What is in the summary? A list of all ok strings is too much. A count of the number of ok strings is not enough. Instead, I will group together the strings that have the same number of `'A'` characters in them, and the same number of consecutive `'L'` characters at the end of the string, and count them. I don't need to count strings that have two or more `'A'` characters, or 3 consecutive `'L'` characters anywhere in the string. And I don't need to worry about runs of 1 or 2 `'L'` characters embedded in the middle of the string. So the summary is a mapping of the form `{(A, L): count, ...}`. \n", + "\n", + "Here is a function to create the summary for `N+1`, given the summary for `N`:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def next_summary(prev_summary: dict) -> dict:\n", + " \"Given a summary of the form {(A, L): count}, return summary for one char more.\"\n", + " summary = defaultdict(int)\n", + " for (A, L), c in prev_summary.items():\n", + " if A < 1: summary[A+1, 0] += c # transition with 'A'\n", + " if L < 2: summary[A, L+1] += c # transition with 'L'\n", + " summary[A, 0] += c # transition with 'P'\n", + " return summary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For `N = 0`, the summary is `{(0, 0): 1}`, because there is one string, the empty string, which has no `'A'` nor `'L'`. From there we can proceed in a \"bottom-up\" fashion to compute the total number of OK strings for any value of `N`:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "defaultdict(int, {(0, 0): 1, (0, 1): 1, (1, 0): 1})" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "next_summary({(0, 0): 1})" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "defaultdict(int, {(0, 0): 2, (0, 1): 1, (0, 2): 1, (1, 0): 3, (1, 1): 1})" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "next_summary(_)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I can annotate that result with the two-letter strings that form each count:\n", + "\n", + " {(0, 0): 2, # LP, PP\n", + " (0, 1): 1, # PL\n", + " (0, 2): 1, # LL\n", + " (1, 0): 1, # AP, LA, PA\n", + " (1, 1): 1} # AL\n", + "\n", + "\n", + "Here's an implementation of `total_ok`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def total_ok(N) -> int:\n", + " \"How many strings of length N are ok?\"\n", + " summary = {(0, 0): 1}\n", + " for _ in range(N):\n", + " summary = next_summary(summary)\n", + " return sum(summary.values()) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can use this to go way beyond what we could do with `total_ok_slow`:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.21 ms, sys: 111 µs, total: 1.32 ms\n", + "Wall time: 1.35 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "5261545087067582125179062608958232695543100705754634272071166414871321070487675367" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time total_ok(300)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.3689147905858837e+143" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "3. ** 300" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are over 1080 ok strings of length 300; more than the number of atoms in the universe. But it only took around a millisecond to count them (while ignoring the 3300 = 10143 not-ok strings of length 300).\n", + "\n", + "Dynamic programming can also be done top-down (where we start at `N` and work down to `0`):" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def total_ok(N) -> int:\n", + " \"How many strings of length N are ok?\"\n", + " return sum(summary_for(N).values())\n", + " \n", + "def summary_for(N) -> dict: \n", + " \"The {(A, L): count} summary for strings of length N.\"\n", + " return ({(0, 0): 1} if N == 0 else next_summary(summary_for(N - 1)))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.82 ms, sys: 46 µs, total: 1.87 ms\n", + "Wall time: 1.88 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "5261545087067582125179062608958232695543100705754634272071166414871321070487675367" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time total_ok(300)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We get the same answer in about the same amount of time.\n", + "\n", + "Let's verify our results against the slow, reliable `total_ok_slow`, and look at the summaries for the first few values of `N`:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " N ok summary(N)\n", + "-- ---- ----------\n", + " 0 1 {(0, 0): 1}\n", + " 1 3 {(0, 1): 1, (1, 0): 1, (0, 0): 1}\n", + " 2 8 {(0, 1): 1, (1, 0): 3, (0, 0): 2, (0, 2): 1, (1, 1): 1}\n", + " 3 19 {(0, 1): 2, (1, 2): 1, (0, 0): 4, (1, 0): 8, (0, 2): 1, (1, 1): 3}\n", + " 4 43 {(0, 1): 4, (1, 2): 3, (0, 0): 7, (1, 0): 19, (0, 2): 2, (1, 1): 8}\n", + " 5 94 {(0, 1): 7, (1, 2): 8, (0, 0): 13, (1, 0): 43, (0, 2): 4, (1, 1): 19}\n", + " 6 200 {(0, 1): 13, (1, 2): 19, (0, 0): 24, (1, 0): 94, (0, 2): 7, (1, 1): 43}\n", + " 7 418 {(0, 1): 24, (1, 2): 43, (0, 0): 44, (1, 0): 200, (0, 2): 13, (1, 1): 94}\n", + " 8 861 {(0, 1): 44, (1, 2): 94, (0, 0): 81, (1, 0): 418, (0, 2): 24, (1, 1): 200}\n", + " 9 1753 {(0, 1): 81, (1, 2): 200, (0, 0): 149, (1, 0): 861, (0, 2): 44, (1, 1): 418}\n", + "10 3536 {(0, 1): 149, (1, 2): 418, (0, 0): 274, (1, 0): 1753, (0, 2): 81, (1, 1): 861}\n" + ] + } + ], + "source": [ + "print(' N ok summary(N)')\n", + "print('-- ---- ----------')\n", + "for N in range(11): \n", + " assert total_ok(N) == total_ok_slow(N)\n", + " print('{:2} {:4} {}'.format(N, total_ok(N), dict(summary_for(N))))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# (2) Count Strings with Alphabetic First Occurrences\n", + "\n", + "Here's another problem:\n", + "\n", + "> Given an alphabet of length k, how many strings of length k can be formed such that the first occurrences of each character in the string are a prefix of the alphabet?\n", + "\n", + "Let's first make sure we understand the problem. Since *k* could go well beyond 26, I will choose as my alphabet the integers, not the letters `'abc...'`. An alphabet of length *k* is `range(k)`, and a valid string of length 3 could be\n", + "`[0, 1, 2]` or `[0, 0, 1]` (or other possibilities). These are valid because the first occurrence of each character for these strings are `[0, 1, 2]` and `[0, 1]`, respectively, and these are prefixes of `range(3)`. But `[0, 0, 2]` is not valid, because the first occurrences are `[0, 2]`, and this is not a prefix (because it is missing the `1`). \n", + "\n", + "I'll define four key concepts:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def valid(s) -> bool: \n", + " \"A string is valid if its first occurrences are a prefix of the alphabet.\"\n", + " return is_prefix(first_occurrences(s))\n", + "\n", + "def is_prefix(s) -> bool: \n", + " \"A string is a valid prefix if it is consecutive integers starting from 0.\"\n", + " return s == list(range(len(s)))\n", + "\n", + "def first_occurrences(s) -> list:\n", + " \"The unique elements of s, in the order they first appear.\" \n", + " firsts = []\n", + " for x in s:\n", + " if x not in firsts: firsts.append(x)\n", + " return firsts \n", + "\n", + "def all_strings(k): \n", + " \"All strings of length k over an alphabet of k ints.\"\n", + " return product(range(k), repeat=k)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ok'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test(): \n", + " assert valid([0, 1, 2]) and valid([0, 0, 1])\n", + " assert not valid([0, 0, 2])\n", + " assert is_prefix([0, 1, 2])\n", + " assert first_occurrences([0, 0, 2]) == [0, 2]\n", + " assert set(all_strings(2)) == {(0, 0), (0, 1), (1, 0), (1, 1)}\n", + " # s first_occurrences(s) valid(s)\n", + " assert test1([0, 1, 2], [0, 1, 2], True) \n", + " assert test1([0, 0, 0], [0], True) \n", + " assert test1([1], [1], False) \n", + " assert test1([0, 1, 3], [0, 1, 3], False)\n", + " assert test1([0, 1, 3, 2], [0, 1, 3, 2], False)\n", + " assert test1([0, 1, 0, 1, 0, 2, 1], [0, 1, 2], True)\n", + " assert test1([0, 1, 0, 2, 1, 3, 1, 2, 5, 4, 3], [0, 1, 2, 3, 5, 4], False)\n", + " assert test1([0, 1, 0, 2, 1, 3, 1, 2, 4, 5, 3], [0, 1, 2, 3, 4, 5], True)\n", + " return 'ok'\n", + "\n", + "def test1(s, firsts, is_valid):\n", + " return first_occurrences(s) == firsts and valid(s) == is_valid\n", + " \n", + "test()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, I will solve the problem in a slow but sure way: generate all possible strings, then count the number that are valid. The complexity of this algorithm is $O(k^{k+1})$, because there are $k^k$ strings, and to validate a string requires looking at all $k$ characters." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 1, 2, 5, 15, 52, 203]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def how_many_slow(k) -> int: \n", + " \"\"\"Count the number of valid strings. (Try all possible strings.)\"\"\"\n", + " return quantify(all_strings(k), valid)\n", + "\n", + "[how_many_slow(k) for k in range(7)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's think about how to speed that up. I don't want to have to consider every possible string, because there are too many ($k^k$) of them. Can I group together many strings and just count the number of them, without enumerating each one? For example, if I knew there were 52 valid strings of length $k-1$ (and didn't know anything else about them), can I tell how many valid strings of length $k$ there are? I don't see a way to do this directly, because the number of ways to extend a valid string is dependent on the number of distinct characters in the string. If a string has $m$ distinct characters, then I can extend it in $m$ waysby repeating any of those $m$ characters, or I can introduce a first occurrence of character number $m+1$ in just 1 way.\n", + "\n", + "So I need to keep track of the number of valid strings of length $k$ that have exactly $m$ distinct characters (those characters must be exactly `range(m)`). I'll call that number `C(k, m)`. Because I can reach a recursive call to `C(k, m)` by many paths, I will use the `cache` decorator to keep track of the computations that I have already done. Then I can define `how_many(k)` as the sum over all values of `m` of `C(k, m)`:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "@cache()\n", + "def C(k, m) -> int:\n", + " \"Count the number of valid strings of length k, that use m distinct characters.\"\n", + " return (1 if k == 0 == m else\n", + " 0 if k == 0 != m else\n", + " C(k-1, m) * m + C(k-1, m-1)) # m ways to add an old character; 1 way to add new\n", + "\n", + "def how_many(k): return sum(C(k, m) for m in range(k+1))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "47585391276764833658790768841387207826363669686825611466616334637559114497892442622672724044217756306953557882560751" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "how_many(100)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert all(how_many(k) == how_many_slow(k) for k in range(7))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0 1\n", + " 1 1\n", + " 2 2\n", + " 3 5\n", + " 4 15\n", + " 5 52\n", + " 6 203\n", + " 7 877\n", + " 8 4140\n", + " 9 21147\n", + " 10 115975\n", + " 20 5.17242e+13\n", + " 30 8.46749e+23\n", + " 40 1.57451e+35\n", + " 50 1.85724e+47\n", + " 60 9.76939e+59\n", + " 70 1.8075e+73\n", + " 80 9.91268e+86\n", + " 90 1.4158e+101\n", + "100 4.75854e+115\n", + "110 3.46846e+130\n", + "120 5.1263e+145\n" + ] + } + ], + "source": [ + "for k in chain(range(10), range(10, 121, 10)):\n", + " print('{:3} {:12g}'.format(k, how_many(k)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# (3) Sol Golomb’s Rectangle Puzzle\n", + "\n", + "This problem is covered in depth in [another notebook](Golomb-puzzle.ipynb), so here I present just the part that has to do with counting things:\n", + "\n", + "> *Say you’re given the following challenge: create a set of five rectangles that have sides of length 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10 units. You can combine sides in a variety of ways: for example, you could create a set of rectangles with dimensions 1 x 3, 2 x 4, 5 x 7, 6 x 8 and 9 x 10. How many different sets of five rectangles are possible?*\n", + "\n", + "This is a basic [combinatorics](http://en.wikipedia.org/wiki/Combinatorics) or counting problem. I will present *three* methods to count the sets. If all goes well they will give the same answer. The example set of rectangles given in the problem was\n", + "\n", + "> {1 × 3, 2 × 4, 5 × 7, 6 × 8, 9 × 10}\n", + " \n", + "and in general it would be\n", + "\n", + "> {A × B, C × D, E × F, G × H, I × J}\n", + "\n", + "The question is: how many distinct ways can we assign the integers 1 through 10 to the variables A through J?\n", + " \n", + "**Method 1: Count all permutations and divide by repetitions:** There are 10 variables to be filled, so there are 10! = 3,628,800 permutations. But if we fill the first two variables with 1 × 3, that is the same rectangle as 3 × 1. So divide 10! by 25 to account for the fact that each of 5 rectangles can appear 2 ways. Similarly, if we fill A and B with 1 × 3, that yields the same set as if we filled C and D with 1 × 3. So divide again by 5! (the number of permutations of 5 things) to account for this.\n", + "That gives us:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "945.0" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "factorial(10) / 2 ** 5 / factorial(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(It is always a relief when this \"count and divide\" method comes out to a whole number.)\n", + "\n", + "**Method 2: Count without repetitions**: in each rectangle of the example set the smaller component is listed first, and in each set, the rectangles with smaller first components are listed first. An alternate to \"count and divide\" is to count directly how many sets there are that respect this ordering. We'll work from left to right. How many choices are there for variable A? Only one: A must always be 1, because we agreed that the smallest number comes first. Then, given A, there are 9 remaining choices for B. For C, given A and B, there is again only one choice: C must be the smallest of the remaining 8 numbers (it will be 3 if the first rectangle was 1 × 2; otherwise it will be 2, but either way there is only one choice). That leaves 7 choices for D, 5 for F, 3 for H and 1 for J. So:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "945" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "9 * 7 * 5 * 3 * 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(It is always a relief when two methods give the same answer.)\n", + " \n", + "**Method 3: Write a program to enumerate the sets:** We'll represent the 1 × 3 rectangle as the tuple `(1, 3)` and the example set of rectangles as the set\n", + "\n", + " {(1, 3), (2, 4), (5, 7), (6, 8), (9, 10)}\n", + "\n", + "We'll write a program to generate all possible sets of rectangles, following method 2, and then just count how many there are. To implement method 2, the minimum side will always be the first element, A, in an (A, B) pair. We iterate through all possible values for B, and then join that pair with all possible rectangles made from the remaining sides. We also have to handle the case when there are no sides; then there is one possible set of rectangles: the empty set." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "945" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def rectangle_sets(sides):\n", + " \"Given a set of sides, list all distinct sets of rectangles that can be made.\"\n", + " if not sides:\n", + " return [ set() ]\n", + " else:\n", + " A = min(sides)\n", + " return [ {(A, B)} | other_rects\n", + " for B in sides if B is not A\n", + " for other_rects in rectangle_sets(sides - {A, B}) ]\n", + " \n", + "len(rectangle_sets({1, 2, 3, 4, 5, 6, 7, 8, 9, 0}))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(It is a relief that once again we get the same answer, 945.) \n", + "\n", + "Here is a list of the rectangle sets with just 6 sides:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{(1, 2), (3, 4), (5, 6)},\n", + " {(1, 2), (3, 5), (4, 6)},\n", + " {(1, 2), (3, 6), (4, 5)},\n", + " {(1, 3), (2, 4), (5, 6)},\n", + " {(1, 3), (2, 5), (4, 6)},\n", + " {(1, 3), (2, 6), (4, 5)},\n", + " {(1, 4), (2, 3), (5, 6)},\n", + " {(1, 4), (2, 5), (3, 6)},\n", + " {(1, 4), (2, 6), (3, 5)},\n", + " {(1, 5), (2, 3), (4, 6)},\n", + " {(1, 5), (2, 4), (3, 6)},\n", + " {(1, 5), (2, 6), (3, 4)},\n", + " {(1, 6), (2, 3), (4, 5)},\n", + " {(1, 6), (2, 4), (3, 5)},\n", + " {(1, 6), (2, 5), (3, 4)}]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rectangle_sets({1, 2, 3, 4, 5, 6})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# (4) Counting Positions in Fischerandom Chess\n", + "\n", + "In this [variant](https://en.wikipedia.org/wiki/Chess960) of chess, the pieces are set up in a random but restricted fashion. The pawns are in their regular positions, and the major white pieces are placed randomly on the first rank, with two restrictions: the bishops must be placed on opposite-color squares, and the king must be placed between the rooks. The black pieces are set up to mirror the white pieces. How many starting positions are there?\n", + "\n", + "We can answer by generating all distinct permutations of the eight pieces and quantifying (counting) the number of permutations that are legal according to the two restrictions:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "960" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from statistics import median\n", + "\n", + "def legal(pieces):\n", + " B, R, K = map(pieces.index, 'BRK')\n", + " b, r = map(cat(pieces).rindex, 'BR')\n", + " return (B % 2 != b % 2) and median([R, K, r]) == K\n", + "\n", + "quantify(set(permutations('RNBKQBNR')), legal)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Note:* initially I wrote `pieces.rindex`, because I forgot that while tuples, lists and strings all have an `index` method, only strings have `rindex`. How annoying! In Ruby, both strings and arrays have `index` and `rindex`. In Java and Javascript, both strings and lists/arrays have both `indexOf` and `lastIndexOf`. What's wrong with Python?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# (5) Counting Paths on a Grid\n", + "\n", + "Consider the following grid, where the goal is to find a path from `S` to `G`, making only \"right\" or \"down\" moves:\n", + "\n", + " S..........\n", + " ...........\n", + " ...........\n", + " ...........\n", + " ...........\n", + " ..........G\n", + " \n", + "One solution path would be to go right 10 times, then go down 5 times. But you could also go down 3 times, then right 10 times, then down 2 times; or take many other paths. How many paths are there? We can use the same three methods we used for the previous puzzle:\n", + "\n", + "**Method 1: Count all permutations and divide by repetitions:** Any path must consist of 10 right and 5 down moves, but they can appear in any order. Arranging 15 things in any order gives 15! = 1,307,674,368,000 possible paths. But that counts all the moves as being distinct, when actually the 10 right moves are indistinguishable, as are the 5 down moves, so we need to divide by the number of ways that they can be arranged. That gives us:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3003.0" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "factorial(15) / factorial(10) / factorial(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Method 2: Count without repetitions**: Another way to look at it is that there will be 15 total moves, so start with all 15 being \"right\" moves and then choose 5 of them to become \"down\" moves. So the answer is (15 choose 5), which leads to the same formula we just used.\n", + "\n", + "**Method 3: Write a program to count the paths:** We can define the function `paths(start, goal)` to count the number of paths from start location to goal location, where a location is a `(column, row)` pair of integers.\n", + "In general, the number of paths to the goal is the number of paths to the location just to the left of the goal, plus the number of paths to the location just above the goal. But there are two special cases: there is only one path (the empty path) when the start is equal to the goal, and there are zero paths when the goal is off the board." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3003" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@cache()\n", + "def paths(start, goal):\n", + " \"Number of paths to goal, using only 'right' and 'down' moves.\"\n", + " (col, row) = goal\n", + " return (1 if goal == start else\n", + " 0 if col < 0 or row < 0 else\n", + " paths(start, (col - 1, row)) + paths(start, (col, row - 1)))\n", + " \n", + "paths((0, 0), (5, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can handle much larger grids (while checking the time taken, and then verifying that the answer agrees with the factorial formula):" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 222 ms, sys: 2.81 ms, total: 225 ms\n", + "Wall time: 225 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "4158251463258564744783383526326405580280466005743648708663033657304756328324008620" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "goal = (C, R) = (100, 200)\n", + "\n", + "%time paths((0, 0), goal)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "_ == factorial(C + R) // factorial(C) // factorial(R)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Why bother with the recursive function when the formula works so well? Good question. One reason is that the two different approaches validate each other by giving the same answer. Another reason is that we can modify the `paths` function to handle grids that have obstacles in them. I'll define a `Grid` constructor, and any cell in the grid that is not a `'.'` will be considered an impassible barrier." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Grid(text): return tuple(text.split())\n", + "\n", + "@cache()\n", + "def paths2(grid, start=(0, 0), goal=None):\n", + " \"Number of paths to goal, using only 'right' and 'down' moves.\"\n", + " goal = goal or bottom_right(grid)\n", + " (col, row) = goal\n", + " return (1 if goal == start else\n", + " 0 if col < 0 or row < 0 or grid[col][row] != '.' else\n", + " paths2(grid, start, (col - 1, row)) + \n", + " paths2(grid, start, (col, row - 1)))\n", + "\n", + "def bottom_right(grid): return (len(grid) - 1, len(grid[0]) - 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can verify that we get the same answer on the 11 by 6 empty grid:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3003" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "paths2(Grid(\"\"\"\n", + "...........\n", + "...........\n", + "...........\n", + "...........\n", + "...........\n", + "...........\n", + "\"\"\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's a grid where there should be only two paths:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "paths2(Grid(\"\"\"\n", + "...........\n", + ".........|.\n", + ".........|.\n", + ".........|.\n", + ".--------+.\n", + "...........\n", + "\"\"\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we tear down that wall, there should be many paths (but less than 3003 because some of the wall remains):" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "992" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "paths2(Grid(\"\"\"\n", + "...........\n", + ".........|.\n", + ".........|.\n", + "...........\n", + ".-------...\n", + "...........\n", + "\"\"\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's a bigger, and a much bigger example:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "58975" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "paths2(Grid(r\"\"\"\n", + "................\\---\n", + "../......|..........\n", + "./..()...|.().|...\\.\n", + ".\\............|.....\n", + "..\\----....|..|.....\n", + ".......\\...|........\n", + "\\.......\\...........\n", + "-\\.............()...\n", + "--\\.................\n", + "---\\....../\\........\n", + "\"\"\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "121480689204" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "paths2(Grid(r\"\"\"\n", + "....................http://www.ascii-art-generator.org/.................\n", + "........................................................................\n", + ".......................WWNK0OkxdoooolooddxkO0KXW........................\n", + ".................WX0kdolc::::::::::cc::::::::::clodk0XW.................\n", + "............WXOdl::::cldxkO0KKKKKKXXXXKKKKKK0Okxdlc:;;:ldOXW............\n", + ".........N0dc;;coxkxxdxKXXXXXXXKddKXXKxdKXXXXXXXKxdxxxxoc;;cd0N.........\n", + "........d:,:oxkdl:,..'xXXXXXXXX0:.,;;;.:0XXXXXXXXx'..':ldkxo:,:d0W......\n", + "....W0l.;okxl;.......cKXXXXXXXXO,......,kXXXXXXXXKc.......;lxko;,l0W....\n", + "...Xo';.Od;..........;OXXXXXXXKl........lKXXXXXXXO:..........;dkd;,oX...\n", + "..K:'lO.,.............;dOKKK0x:..........:x0KKKOd;.............,xOl':K..\n", + ".Xc.o0o..................,,,'...............,,,..................o0o.cX.\n", + ".k';0k'..........................................................'k0;'k.\n", + ".d.cKd............................................................dKc.d.\n", + ".k';Ok,...........................................................kO;'k.\n", + ".Xl.l0d'.........''..................................''...........0l.cX.\n", + "..Kc'cOk;......;x000ko;..,okOOd;........;dOOko,..;ok000x;......;x..'cK..\n", + "...Xd,,dkd:....oXXXXXXKkx0XXXXXKd'....'dKXXXXX0xkKXXXXXXo....;dkd;.dX...\n", + "....WKo,;lxxo;':OXXXXXXXXXXXXXXXXx,..'xXNXXXXXXXXXXXXXXO:'.oxxl;,l.W....\n", + "......WKx:,:lxxxOXXXXXXXXXXXXXXXXXx::xXXXXXXXXXXXXXXXXXOxx..:,:dKW......\n", + ".........WKxl;;:ldk0KXXXXNNXXXXXXXXKKXXXXXXXXXXXXXXK0kdl:;.cxKW.........\n", + "............WN0xoc:;:clodxkO00KKKXXXXXXKKK00Okxdol::;:cox0.W............\n", + ".................WNKOxdlcc::::::::::::::::::::ccldxOKNW.................\n", + "........................WWXK0OkkxxddddxxkkO0KXNW........................\n", + "........................................................................\n", + "\"\"\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Can you verify that these last three answers are correct?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/How to Do Things with Words.ipynb b/pytudes/ipynb/How to Do Things with Words.ipynb new file mode 100644 index 0000000..e3c68a3 --- /dev/null +++ b/pytudes/ipynb/How to Do Things with Words.ipynb @@ -0,0 +1,2307 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Boring preliminaries\n", + "import re\n", + "import math\n", + "import string\n", + "from collections import Counter\n", + "from __future__ import division" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "

Statistical Natural Language Processing in Python.\n", + "
or\n", + "
How To Do Things With Words. And Counters.\n", + "
or\n", + "
Everything I Needed to Know About NLP I learned From Sesame Street.\n", + "
Except Kneser-Ney Smoothing.\n", + "
The Count Didn't Cover That.\n", + "
\n", + "
\n", + "
*One, two, three, ah, ah, ah!* — The Count\n", + "

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(1) Data: Text and Words\n", + "========\n", + "\n", + "Before we can do things with words, we need some words. First we need some *text*, possibly from a *file*. Then we can break the text into words. I happen to have a big text called [big.txt](file:///Users/pnorvig/Documents/ipynb/big.txt). We can read it, and see how big it is (in characters):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "6488409" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TEXT = file('big.txt').read()\n", + "len(TEXT)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, six million characters.\n", + "\n", + "Now let's break the text up into words (or more formal-sounding, *tokens*). For now we'll ignore all the punctuation and numbers, and anything that is not a letter." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def tokens(text):\n", + " \"List all the word tokens (consecutive letters) in a text. Normalize to lowercase.\"\n", + " return re.findall('[a-z]+', text.lower()) " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['this', 'is', 'a', 'test', 'this', 'is']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tokens('This is: A test, 1, 2, 3, this is.')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1105211" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "WORDS = tokens(TEXT)\n", + "len(WORDS)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, a million words. Here are the first 10:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['the', 'project', 'gutenberg', 'ebook', 'of', 'the', 'adventures', 'of', 'sherlock', 'holmes']\n" + ] + } + ], + "source": [ + "print(WORDS[:10])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(2) Models: Bag of Words\n", + "====\n", + "\n", + "The list `WORDS` is a list of the words in the `TEXT`, but it can also serve as a *generative model* of text. We know that language is very complicated, but we can create a simplified model of language that captures part of the complexity. In the *bag of words* model, we ignore the order of words, but maintain their frequency. Think of it this way: take all the words from the text, and throw them into a bag. Shake the bag, and then generating a sentence consists of pulling words out of the bag one at a time. Chances are it won't be grammatical or sensible, but it will have words in roughly the right proportions. Here's a function to sample an *n* word sentence from a bag of words:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def sample(bag, n=10):\n", + " \"Sample a random n-word sentence from the model described by the bag of words.\"\n", + " return ' '.join(random.choice(bag) for _ in range(n))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'the mucous acute ordered inevitability collision collection a attained august'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sample(WORDS)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another representation for a bag of words is a `Counter`, which is a dictionary of `{'word': count}` pairs. For example," + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({'a': 2, 'is': 2, 'test': 2, 'this': 1, 'it': 1})" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Counter(tokens('Is this a test? It is a test!'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A `Counter` is like a `dict`, but with a few extra methods. Let's make a `Counter` for the big list of `WORDS` and get a feel for what's there:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[('the', 80029), ('of', 40025), ('and', 38312), ('to', 28766), ('in', 22047), ('a', 21155), ('that', 12512), ('he', 12401), ('was', 11410), ('it', 10681)]\n" + ] + } + ], + "source": [ + "COUNTS = Counter(WORDS)\n", + "\n", + "print COUNTS.most_common(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80029 the\n", + "83 rare\n", + "38312 and\n", + "0 neverbeforeseen\n", + "460 words\n" + ] + } + ], + "source": [ + "for w in tokens('the rare and neverbeforeseen words'):\n", + " print COUNTS[w], w" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In 1935, linguist George Zipf noted that in any big text, the *n*th most frequent word appears with a frequency of about 1/*n* of the most frequent word. He get's credit for *Zipf's Law*, even though Felix Auerbach made the same observation in 1913. If we plot the frequency of words, most common first, on a log-log plot, they should come out as a straight line if Zipf's Law holds. Here we see that it is a fairly close fit:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "M = COUNTS['the']\n", + "yscale('log'); xscale('log'); title('Frequency of n-th most frequent word and 1/n line.')\n", + "plot([c for (w, c) in COUNTS.most_common()])\n", + "plot([M/i for i in range(1, len(COUNTS)+1)]);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(3) Task: Spelling Correction\n", + "========\n", + "\n", + "Given a word *w*, find the most likely correction *c* = `correct(`*w*`)`.\n", + "\n", + "**Approach:** Try all candidate words *c* that are known words that are near *w*. Choose the most likely one.\n", + "\n", + "How to balance *near* and *likely*?\n", + "\n", + "For now, in a trivial way: always prefer nearer, but when there is a tie on nearness, use the word with the highest `WORDS` count. Measure nearness by *edit distance*: the minimum number of deletions, transpositions, insertions, or replacements of characters. By trial and error, we determine that going out to edit distance 2 will give us reasonable results. Then we can define `correct(`*w*`)`:\n", + " \n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def correct(word):\n", + " \"Find the best spelling correction for this word.\"\n", + " # Prefer edit distance 0, then 1, then 2; otherwise default to word itself.\n", + " candidates = (known(edits0(word)) or \n", + " known(edits1(word)) or \n", + " known(edits2(word)) or \n", + " [word])\n", + " return max(candidates, key=COUNTS.get)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The functions `known` and `edits0` are easy; and `edits2` is easy if we assume we have `edits1`:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def known(words):\n", + " \"Return the subset of words that are actually in the dictionary.\"\n", + " return {w for w in words if w in COUNTS}\n", + "\n", + "def edits0(word): \n", + " \"Return all strings that are zero edits away from word (i.e., just word itself).\"\n", + " return {word}\n", + "\n", + "def edits2(word):\n", + " \"Return all strings that are two edits away from this word.\"\n", + " return {e2 for e1 in edits1(word) for e2 in edits1(e1)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now for `edits1(word)`: the set of candidate words that are one edit away. For example, given `\"wird\"`, this would include `\"weird\"` (inserting an `e`) and `\"word\"` (replacing a `i` with a `o`), and also `\"iwrd\"` (transposing `w` and `i`; then `known` can be used to filter this out of the set of final candidates). How could we get them? One way is to *split* the original word in all possible places, each split forming a *pair* of words, `(a, b)`, before and after the place, and at each place, either delete, transpose, replace, or insert a letter:\n", + "\n", + "\n", + "
pairs: Ø+wird w+ird wi+rd wir+dwird+ØNotes: (a, b) pair\n", + "
deletions: Ø+ird w+rd wi+d wir+ØDelete first char of b\n", + "
transpositions: Ø+iwrd w+rid wi+drSwap first two chars of b\n", + "
replacements: Ø+?ird w+?rd wi+?d wir+?Replace char at start of b\n", + "
insertions: Ø+?+wird w+?+ird wi+?+rd wir+?+d wird+?+ØInsert char between a and b\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def edits1(word):\n", + " \"Return all strings that are one edit away from this word.\"\n", + " pairs = splits(word)\n", + " deletes = [a+b[1:] for (a, b) in pairs if b]\n", + " transposes = [a+b[1]+b[0]+b[2:] for (a, b) in pairs if len(b) > 1]\n", + " replaces = [a+c+b[1:] for (a, b) in pairs for c in alphabet if b]\n", + " inserts = [a+c+b for (a, b) in pairs for c in alphabet]\n", + " return set(deletes + transposes + replaces + inserts)\n", + "\n", + "def splits(word):\n", + " \"Return a list of all possible (first, rest) pairs that comprise word.\"\n", + " return [(word[:i], word[i:]) \n", + " for i in range(len(word)+1)]\n", + "\n", + "alphabet = 'abcdefghijklmnopqrstuvwxyz'" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('', 'wird'), ('w', 'ird'), ('wi', 'rd'), ('wir', 'd'), ('wird', '')]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "splits('wird')" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "set(['wird'])\n" + ] + } + ], + "source": [ + "print edits0('wird')" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "set(['wirdh', 'wirdw', 'jird', 'wiid', 'wirj', 'wiprd', 'rird', 'wkird', 'wiqrd', 'wrird', 'wisrd', 'zwird', 'wiqd', 'wizrd', 'wirs', 'wrd', 'wqird', 'tird', 'wirdp', 'wrrd', 'wzrd', 'wiad', 'nird', 'wirsd', 'wixd', 'wxird', 'lird', 'eird', 'wmird', 'wihd', 'wirp', 'lwird', 'wirzd', 'widrd', 'wxrd', 'ewird', 'wirdx', 'wirkd', 'hwird', 'wipd', 'wirnd', 'uwird', 'wirz', 'mwird', 'wjrd', 'wirjd', 'wirrd', 'wirdd', 'wsird', 'bwird', 'wcrd', 'xwird', 'wdird', 'wibrd', 'wikd', 'wiryd', 'wiord', 'gird', 'wtird', 'wbrd', 'nwird', 'wlrd', 'wgird', 'wmrd', 'wirf', 'wirg', 'wird', 'wire', 'wirb', 'wirc', 'wira', 'wkrd', 'wiro', 'wirl', 'wirm', 'iird', 'wirk', 'wirh', 'wiri', 'wirv', 'wirw', 'wirt', 'wiru', 'wirr', 'wicd', 'cird', 'wirq', 'wirqd', 'wizd', 'wirhd', 'ird', 'bird', 'wirx', 'wiry', 'wvrd', 'widr', 'wprd', 'wirad', 'wijd', 'wirxd', 'uird', 'wirdb', 'qwird', 'dird', 'wnrd', 'wjird', 'gwird', 'whrd', 'wtrd', 'woird', 'rwird', 'wurd', 'wijrd', 'witrd', 'wwrd', 'dwird', 'vwird', 'wibd', 'wiyd', 'wicrd', 'weird', 'yird', 'wiwrd', 'wirdv', 'wirdu', 'wid', 'wirds', 'wirdr', 'sird', 'wirbd', 'wirdq', 'wirdy', 'wivrd', 'wirdg', 'wirdf', 'wirde', 'wiud', 'wirdc', 'wir', 'wirda', 'wfird', 'kwird', 'wirdn', 'wirdm', 'wirdl', 'wirdk', 'wirdj', 'wiird', 'wnird', 'wiurd', 'wied', 'aird', 'wirod', 'wpird', 'wcird', 'wzird', 'jwird', 'wirdo', 'wsrd', 'wimd', 'wirwd', 'mird', 'fird', 'wuird', 'wirdt', 'wired', 'wirgd', 'wirfd', 'witd', 'wfrd', 'wyrd', 'wihrd', 'zird', 'ward', 'wilrd', 'widd', 'iwrd', 'hird', 'word', 'wisd', 'wvird', 'pird', 'wlird', 'wyird', 'wdrd', 'werd', 'wild', 'oird', 'wirid', 'wgrd', 'wirvd', 'wiod', 'wirud', 'wircd', 'wiyrd', 'wigrd', 'wixrd', 'wiard', 'vird', 'wiwd', 'wigd', 'wirmd', 'swird', 'wierd', 'xird', 'qird', 'waird', 'wqrd', 'kird', 'cwird', 'wirtd', 'wirdz', 'awird', 'fwird', 'wirpd', 'wifrd', 'pwird', 'owird', 'wivd', 'wimrd', 'iwird', 'winrd', 'wirdi', 'wrid', 'wifd', 'wirld', 'wwird', 'ywird', 'wirn', 'wbird', 'whird', 'wikrd', 'wind', 'twird'])\n" + ] + } + ], + "source": [ + "print edits1('wird')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "24254\n" + ] + } + ], + "source": [ + "print len(edits2('wird'))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['spelling',\n", + " 'errors',\n", + " 'in',\n", + " 'something',\n", + " 'whatever',\n", + " 'unusual',\n", + " 'mistakes',\n", + " 'everywhere']" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "map(correct, tokens('Speling errurs in somethink. Whutever; unusuel misteakes everyware?'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Can we make the output prettier than that?" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def correct_text(text):\n", + " \"Correct all the words within a text, returning the corrected text.\"\n", + " return re.sub('[a-zA-Z]+', correct_match, text)\n", + "\n", + "def correct_match(match):\n", + " \"Spell-correct word in match, and preserve proper upper/lower/title case.\"\n", + " word = match.group()\n", + " return case_of(word)(correct(word.lower()))\n", + "\n", + "def case_of(text):\n", + " \"Return the case-function appropriate for text: upper, lower, title, or just str.\"\n", + " return (str.upper if text.isupper() else\n", + " str.lower if text.islower() else\n", + " str.title if text.istitle() else\n", + " str)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " str]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "map(case_of, ['UPPER', 'lower', 'Title', 'CamelCase'])" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Spelling Errors IN something. Whatever; unusual mistakes?'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "correct_text('Speling Errurs IN somethink. Whutever; unusuel misteakes?')" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Audience says: tumbler ...'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "correct_text('Audiance sayzs: tumblr ...')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So far so good. You can probably think of a dozen ways to make this better. Here's one: in the text \"three, too, one, blastoff!\" we might want to correct \"too\" with \"two\", even though \"too\" is in the dictionary. We can do better if we look at a *sequence* of words, not just an individual word one at a time. But how can we choose the best corrections of a sequence? The ad-hoc approach worked pretty well for single words, but now we could use some real theory ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(4) Models: Word and Sequence Probabilities\n", + "===\n", + "\n", + "If we have a bag of words, what's the probability of picking a particular word out of the bag? We'll denote that probability as $P(w)$. To create the function `P` that computes this probability, we define a function, `pdist`, that takes as input a `Counter` (that is, a bag of words) and returns a function that acts as a probability distribution over all possible words. In a probability distribution the probability of each word is between 0 and 1, and the sum of the probabilities is 1." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def pdist(counter):\n", + " \"Make a probability distribution, given evidence from a Counter.\"\n", + " N = sum(counter.values())\n", + " return lambda x: counter[x]/N\n", + "\n", + "Pword = pdist(COUNTS)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0724106075672 the\n", + "0.00884356018896 is\n", + "0.000821562579453 most\n", + "0.000259678921039 common\n", + "0.000269631771671 word\n", + "0.0199482270806 in\n", + "0.000190913771217 english\n" + ] + } + ], + "source": [ + "# Print probabilities of some words\n", + "for w in tokens('\"The\" is most common word in English'):\n", + " print Pword(w), w" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, what is the probability of a *sequence* of words? Use the definition of a joint probability:\n", + "\n", + "$P(w_1 \\ldots w_n) = P(w_1) \\times P(w_2 \\mid w_1) \\times P(w_3 \\mid w_1 w_2) \\ldots \\times \\ldots P(w_n \\mid w_1 \\ldots w_{n-1})$\n", + "\n", + "In the bag of words model, each word is drawn from the bag *independently* of the others. So $P(w_2 \\mid w_1) = P(w_2)$, and we have:\n", + " \n", + "$P(w_1 \\ldots w_n) = P(w_1) \\times P(w_2) \\times P(w_3) \\ldots \\times \\ldots P(w_n)$\n", + "\n", + " \n", + " \n", + "\n", + "Now clearly this model is wrong; the probability of a sequence depends on the order of the words. But, as the statistician George Box said, *All models are wrong, but some are useful.* The bag of words model, wrong as it is, has many useful applications.\n", + " \n", + "How can we compute $P(w_1 \\ldots w_n)$? We'll use a different function name, `Pwords`, rather than `P`, and we compute the product of the individual probabilities:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def Pwords(words):\n", + " \"Probability of words, assuming each word is independent of others.\"\n", + " return product(Pword(w) for w in words)\n", + "\n", + "def product(nums):\n", + " \"Multiply the numbers together. (Like `sum`, but with multiplication.)\"\n", + " result = 1\n", + " for x in nums:\n", + " result *= x\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.98419543271e-11 this is a test\n", + "8.64036404331e-16 this is a unusual test\n", + "0.0 this is a neverbeforeseen test\n" + ] + } + ], + "source": [ + "tests = ['this is a test', \n", + " 'this is a unusual test',\n", + " 'this is a neverbeforeseen test']\n", + "\n", + "for test in tests:\n", + " print Pwords(tokens(test)), test" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Yikes—it seems wrong to give a probability of 0 to the last one; it should just be very small. We'll come back to that later. The other probabilities seem reasonable." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(5) Task: Word Segmentation\n", + "====\n", + "\n", + "**Task**: *given a sequence of characters with no spaces separating words, recover the sequence of words.*\n", + " \n", + "\n", + "Why? Languages with no word delimiters: [不带空格的词](http://translate.google.com/#auto/en/%E4%B8%8D%E5%B8%A6%E7%A9%BA%E6%A0%BC%E7%9A%84%E8%AF%8D)\n", + "\n", + "In English, sub-genres with no word delimiters ([spelling errors](https://www.google.com/search?q=wordstogether), [URLs](http://speedofart.com)).\n", + "\n", + "**Approach 1:** Enumerate all candidate segementations and choose the one with highest Pwords\n", + "\n", + "Problem: how many segmentations are there for an *n*-character text?\n", + "\n", + "**Approach 2:** Make one segmentation, into a first word and remaining characters. If we assume words are independent \n", + "then we can maximize the probability of the first word adjoined to the best segmentation of the remaining characters.\n", + " \n", + " assert segment('choosespain') == ['choose', 'spain']\n", + "\n", + " segment('choosespain') ==\n", + " max(Pwords(['c'] + segment('hoosespain')),\n", + " Pwords(['ch'] + segment('oosespain')),\n", + " Pwords(['cho'] + segment('osespain')),\n", + " Pwords(['choo'] + segment('sespain')),\n", + " ...\n", + " Pwords(['choosespain'] + segment('')))\n", + " \n", + " \n", + " \n", + "To make this somewhat efficient, we need to avoid re-computing the segmentations of the remaining characters. This can be done explicitly by *dynamic programming* or implicitly with *memoization*. Also, we shouldn't consider all possible lengths for the first word; we can impose a maximum length. What should it be? A little more than the longest word seen so far." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def memo(f):\n", + " \"Memoize function f, whose args must all be hashable.\"\n", + " cache = {}\n", + " def fmemo(*args):\n", + " if args not in cache:\n", + " cache[args] = f(*args)\n", + " return cache[args]\n", + " fmemo.cache = cache\n", + " return fmemo" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "18" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(len(w) for w in COUNTS)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def splits(text, start=0, L=20):\n", + " \"Return a list of all (first, rest) pairs; start <= len(first) <= L.\"\n", + " return [(text[:i], text[i:]) \n", + " for i in range(start, min(len(text), L)+1)]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[('', 'word'), ('w', 'ord'), ('wo', 'rd'), ('wor', 'd'), ('word', '')]\n", + "[('r', 'eallylongtext'), ('re', 'allylongtext'), ('rea', 'llylongtext'), ('real', 'lylongtext')]\n" + ] + } + ], + "source": [ + "print splits('word')\n", + "print splits('reallylongtext', 1, 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "@memo\n", + "def segment(text):\n", + " \"Return a list of words that is the most probable segmentation of text.\"\n", + " if not text: \n", + " return []\n", + " else:\n", + " candidates = ([first] + segment(rest) \n", + " for (first, rest) in splits(text, 1))\n", + " return max(candidates, key=Pwords)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['choose', 'spain']" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "segment('choosespain')" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['speed', 'of', 'art']" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "segment('speedofart')" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "decl = ('wheninthecourseofhumaneventsitbecomesnecessaryforonepeople' +\n", + " 'todissolvethepoliticalbandswhichhaveconnectedthemwithanother' +\n", + " 'andtoassumeamongthepowersoftheearththeseparateandequalstation' +\n", + " 'towhichthelawsofnatureandofnaturesgodentitlethem')" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "when in the course of human events it becomes necessary for one people to dissolve the political bands which have connected them with another and to assume among the powers of the earth the separate and equal station to which the laws of nature and of natures god entitle them\n" + ] + } + ], + "source": [ + "print(' '.join(segment(decl)))" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3.613815636889254e-141" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Pwords(segment(decl))" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1.305966345742529e-281" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Pwords(segment(decl+decl))" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Pwords(segment(decl+decl+decl))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's a problem. We'll come back to it later." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['small', 'and', 'insignificant']" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "segment('smallandinsignificant')" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['large', 'and', 'insignificant']" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "segment('largeandinsignificant')" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4.1121373609e-10\n", + "1.06638804821e-11\n" + ] + } + ], + "source": [ + "print(Pwords(['large', 'and', 'insignificant']))\n", + "print(Pwords(['large', 'and', 'in', 'significant']))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Summary:\n", + " \n", + "- Looks pretty good!\n", + "- The bag-of-words assumption is a limitation.\n", + "- Recomputing Pwords on each recursive call is somewhat inefficient.\n", + "- Numeric underflow for texts longer than 100 or so words; we'll need to use logarithms, or other tricks.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# (6) Data: Mo' Data, Mo' Better" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's move up from millions to *billions and billions* of words. Once we have that amount of data, we can start to look at two word sequences, without them being too sparse. I happen to have data files available in the format of `\"word \\t count\"`, and bigram data in the form of `\"word1 word2 \\t count\"`. Let's arrange to read them in:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def load_counts(filename, sep='\\t'):\n", + " \"\"\"Return a Counter initialized from key-value pairs, \n", + " one on each line of filename.\"\"\"\n", + " C = Counter()\n", + " for line in open(filename):\n", + " key, count = line.split(sep)\n", + " C[key] = int(count)\n", + " return C" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "COUNTS1 = load_counts('count_1w.txt')\n", + "COUNTS2 = load_counts('count_2w.txt')\n", + "\n", + "P1w = pdist(COUNTS1)\n", + "P2w = pdist(COUNTS2)" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "333333 588.124220187\n", + "286358 225.955251755\n" + ] + } + ], + "source": [ + "print len(COUNTS1), sum(COUNTS1.values())/1e9\n", + "print len(COUNTS2), sum(COUNTS2.values())/1e9" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('of the', 2766332391),\n", + " ('in the', 1628795324),\n", + " ('to the', 1139248999),\n", + " ('on the', 800328815),\n", + " ('for the', 692874802),\n", + " ('and the', 629726893),\n", + " ('to be', 505148997),\n", + " ('is a', 476718990),\n", + " ('with the', 461331348),\n", + " ('from the', 428303219),\n", + " ('by the', 417106045),\n", + " ('at the', 416201497),\n", + " ('of a', 387060526),\n", + " ('in a', 364730082),\n", + " ('will be', 356175009),\n", + " ('that the', 333393891),\n", + " ('do not', 326267941),\n", + " ('is the', 306482559),\n", + " ('to a', 279146624),\n", + " ('is not', 276753375),\n", + " ('for a', 274112498),\n", + " ('with a', 271525283),\n", + " ('as a', 270401798),\n", + " (' and', 261891475),\n", + " ('of this', 258707741),\n", + " (' the', 258483382),\n", + " ('it is', 245002494),\n", + " ('can be', 230215143),\n", + " ('If you', 210252670),\n", + " ('has been', 196769958)]" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "COUNTS2.most_common(30)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(7) Theory and Practice: Segmentation With Bigram Data\n", + "===\n", + "\n", + "A less-wrong approximation:\n", + " \n", + "$P(w_1 \\ldots w_n) = P(w_1 \\mid start) \\times P(w_2 \\mid w_1) \\times P(w_3 \\mid w_2) \\ldots \\times \\ldots P(w_n \\mid w_{n-1})$\n", + "\n", + "This is called the *bigram* model, and is equivalent to taking a text, cutting it up into slips of paper with two words on them, and having multiple bags, and putting each slip into a bag labeled with the first word on the slip. Then, to generate language, we choose the first word from the original single bag of words, and chose all subsequent words from the bag with the label of the previously-chosen word. To determine the probability of a word sequence, we multiply together the conditional probabilities of each word given the previous word. We'll do this with a function, `cPword` for \"conditional probability of a word.\"\n", + "\n", + "$P(w_n \\mid w_{n-1}) = P(w_{n-1}w_n) / P(w_{n-1}) $" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def Pwords2(words, prev=''):\n", + " \"The probability of a sequence of words, using bigram data, given prev word.\"\n", + " return product(cPword(w, (prev if (i == 0) else words[i-1]) )\n", + " for (i, w) in enumerate(words))\n", + "\n", + "P = P1w # Use the big dictionary for the probability of a word\n", + "\n", + "def cPword(word, prev):\n", + " \"Conditional probability of word, given previous word.\"\n", + " bigram = prev + ' ' + word\n", + " if P2w(bigram) > 0 and P(prev) > 0:\n", + " return P2w(bigram) / P(prev)\n", + " else: # Average the back-off value and zero.\n", + " return P(word) / 2" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.98419543271e-11\n", + "6.41367629438e-08\n", + "1.18028600367e-11\n" + ] + } + ], + "source": [ + "print Pwords(tokens('this is a test'))\n", + "print Pwords2(tokens('this is a test'))\n", + "print Pwords2(tokens('is test a this'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To make `segment2`, we copy `segment`, and make sure to pass around the previous token, and to evaluate probabilities with `Pwords2` instead of `Pwords`." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "@memo \n", + "def segment2(text, prev=''): \n", + " \"Return best segmentation of text; use bigram data.\" \n", + " if not text: \n", + " return []\n", + " else:\n", + " candidates = ([first] + segment2(rest, first) \n", + " for (first, rest) in splits(text, 1))\n", + " return max(candidates, key=lambda words: Pwords2(words, prev))" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['choose', 'spain']\n", + "['speed', 'of', 'art']\n", + "['small', 'and', 'in', 'significant']\n", + "['large', 'and', 'in', 'significant']\n" + ] + } + ], + "source": [ + "print segment2('choosespain')\n", + "print segment2('speedofart')\n", + "print segment2('smallandinsignificant')\n", + "print segment2('largeandinsignificant')" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['far', 'out', 'in', 'the', 'un', 'chart', 'ed', 'back', 'waters', 'of', 'the', 'un', 'fashionable', 'end', 'of', 'the', 'western', 'spiral', 'arm', 'of', 'the', 'galaxy', 'lies', 'a', 'small', 'un', 'regarded', 'yellow', 'sun']\n", + "['far', 'out', 'in', 'the', 'uncharted', 'backwaters', 'of', 'the', 'unfashionable', 'end', 'of', 'the', 'western', 'spiral', 'arm', 'of', 'the', 'galaxy', 'lies', 'a', 'small', 'un', 'regarded', 'yellow', 'sun']\n" + ] + } + ], + "source": [ + "adams = ('faroutintheunchartedbackwatersoftheunfashionableendofthewesternspiral' +\n", + " 'armofthegalaxyliesasmallunregardedyellowsun')\n", + "print segment(adams)\n", + "print segment2(adams)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P1w('unregarded')" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'dry', 'bare', 'sandy', 'hole', 'with', 'nothing', 'in', 'it', 'to', 'sit', 'down', 'on', 'or', 'to', 'eat']\n", + "['a', 'dry', 'bare', 'sandy', 'hole', 'with', 'nothing', 'in', 'it', 'to', 'sit', 'down', 'on', 'or', 'to', 'eat']\n" + ] + } + ], + "source": [ + "tolkien = 'adrybaresandyholewithnothinginittositdownonortoeat'\n", + "print segment(tolkien)\n", + "print segment2(tolkien)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Conclusion? Bigram model is a little better, but not much. Hundreds of billions of words still not enough. (Why not trillions?) Could be made more efficient." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(8) Theory: Evaluation\n", + "===\n", + "\n", + "So far, we've got an intuitive feel for how this all works. But we don't have any solid metrics that quantify the results. Without metrics, we can't say if we are doing well, nor if a change is an improvement. In general,\n", + "when developing a program that relies on data to help make\n", + "predictions, it is good practice to divide your data into three sets:\n", + "
    \n", + "
  1. Training set: the data used to create our spelling\n", + " model; this was the big.txt file.\n", + "
  2. Development set: a set of input/output pairs that we can\n", + " use to rank the performance of our program as we are developing it.\n", + "
  3. Test set: another set of input/output pairs that we use\n", + " to rank our program after we are done developing it. The\n", + " development set can't be used for this purpose—once the\n", + " programmer has looked at the development test it is tainted, because\n", + " the programmer might modify the program just to pass the development\n", + " test. That's why we need a separate test set that is only looked at\n", + " after development is done.\n", + "
\n", + "\n", + "For this program, the training data is the word frequency counts, the development set is the examples like `\"choosespain\"` that we have been playing with, and now we need a test set." + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def test_segmenter(segmenter, tests):\n", + " \"Try segmenter on tests; report failures; return fraction correct.\"\n", + " return sum([test_one_segment(segmenter, test) \n", + " for test in tests]), len(tests)\n", + "\n", + "def test_one_segment(segmenter, test):\n", + " words = tokens(test)\n", + " result = segmenter(cat(words))\n", + " correct = (result == words)\n", + " if not correct:\n", + " print 'expected', words\n", + " print ' got', result\n", + " return correct\n", + "\n", + "cat = ''.join\n", + "\n", + "proverbs = (\"\"\"A little knowledge is a dangerous thing\n", + " A man who is his own lawyer has a fool for his client\n", + " All work and no play makes Jack a dull boy\n", + " Better to remain silent and be thought a fool that to speak and remove all doubt;\n", + " Do unto others as you would have them do to you\n", + " Early to bed and early to rise, makes a man healthy, wealthy and wise\n", + " Fools rush in where angels fear to tread\n", + " Genius is one percent inspiration, ninety-nine percent perspiration\n", + " If you lie down with dogs, you will get up with fleas\n", + " Lightning never strikes twice in the same place\n", + " Power corrupts; absolute power corrupts absolutely\n", + " Here today, gone tomorrow\n", + " See no evil, hear no evil, speak no evil\n", + " Sticks and stones may break my bones, but words will never hurt me\n", + " Take care of the pence and the pounds will take care of themselves\n", + " Take care of the sense and the sounds will take care of themselves\n", + " The bigger they are, the harder they fall\n", + " The grass is always greener on the other side of the fence\n", + " The more things change, the more they stay the same\n", + " Those who do not learn from history are doomed to repeat it\"\"\"\n", + " .splitlines())" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "expected ['power', 'corrupts', 'absolute', 'power', 'corrupts', 'absolutely']\n", + " got ['power', 'corrupt', 's', 'absolute', 'power', 'corrupt', 's', 'absolutely']\n", + "expected ['the', 'grass', 'is', 'always', 'greener', 'on', 'the', 'other', 'side', 'of', 'the', 'fence']\n", + " got ['the', 'grass', 'is', 'always', 'green', 'er', 'on', 'the', 'other', 'side', 'of', 'the', 'fence']\n" + ] + }, + { + "data": { + "text/plain": [ + "(18, 20)" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_segmenter(segment, proverbs)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(20, 20)" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_segmenter(segment2, proverbs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This confirms that both segmenters are very good, and that `segment2` is slightly better. There is much more that can be done in terms of the variety of tests, and in measuring statistical significance." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(9) Theory and Practice: Smoothing\n", + "======\n", + "\n", + "Let's go back to a test we did before, and add some more test cases:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.98419543271e-11 this is a test\n", + "8.64036404331e-16 this is a unusual test\n", + "0.0 this is a nongovernmental test\n", + "0.0 this is a neverbeforeseen test\n", + "0.0 this is a zqbhjhsyefvvjqc test\n" + ] + } + ], + "source": [ + "tests = ['this is a test', \n", + " 'this is a unusual test',\n", + " 'this is a nongovernmental test',\n", + " 'this is a neverbeforeseen test',\n", + " 'this is a zqbhjhsyefvvjqc test']\n", + "\n", + "for test in tests:\n", + " print Pwords(tokens(test)), test" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The issue here is the finality of a probability of zero. Out of the three 15-letter words, it turns out that \"nongovernmental\" is in the dictionary, but if it hadn't been, if somehow our corpus of words had missed it, then the probability of that whole phrase would have been zero. It seems that is too strict; there must be some \"real\" words that are not in our dictionary, so we shouldn't give them probability zero. There is also a question of likelihood of being a \"real\" word. It does seem that \"neverbeforeseen\" is more English-like than \"zqbhjhsyefvvjqc\", and so perhaps should have a higher probability.\n", + "\n", + "We can address this by assigning a non-zero probability to words that are not in the dictionary. This is even more important when it comes to multi-word phrases (such as bigrams), because it is more likely that a legitimate one will appear that has not been observed before.\n", + "\n", + "We can think of our model as being overly spiky; it has a spike of probability mass wherever a word or phrase occurs in the corpus. What we would like to do is *smooth* over those spikes so that we get a model that does not depend on the details of our corpus. The process of \"fixing\" the model is called *smoothing*.\n", + "\n", + "For example, Laplace was asked what's the probability of the sun rising tomorrow. From data that it has risen $n/n$ times for the last *n* days, the maximum liklihood estimator is 1. But Laplace wanted to balance the data with the possibility that tomorrow, either it will rise or it won't, so he came up with $(n + 1) / (n + 2)$.\n", + "\n", + "\n", + " \n", + " \n", + "\n", + "
What we know is little, and what we are ignorant of is immense.
— Pierre Simon Laplace, 1749-1827" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def pdist_additive_smoothed(counter, c=1):\n", + " \"\"\"The probability of word, given evidence from the counter.\n", + " Add c to the count for each item, plus the 'unknown' item.\"\"\"\n", + " N = sum(counter.values()) # Amount of evidence\n", + " Nplus = N + c * (len(counter) + 1) # Evidence plus fake observations\n", + " return lambda word: (counter[word] + c) / Nplus \n", + "\n", + "P1w = pdist_additive_smoothed(COUNTS1)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1.7003201005861308e-12" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P1w('neverbeforeseen')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But now there's a problem ... we now have previously-unseen words with non-zero probabilities. And maybe 10-12 is about right for words that are observed in text: that is, if I'm *reading* a new text, the probability that the next word is unknown might be around 10-12. But if I'm *manufacturing* 20-letter sequences at random, the probability that one will be a word is much, much lower than 10-12. \n", + "\n", + "Look what happens:" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['this',\n", + " 'is',\n", + " 'a',\n", + " 'test',\n", + " 'of',\n", + " 'segment',\n", + " 'at',\n", + " 'i',\n", + " 'on',\n", + " 'of',\n", + " 'along',\n", + " 'sequence',\n", + " 'of',\n", + " 'words']" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "segment.cache.clear()\n", + "segment('thisisatestofsegmentationofalongsequenceofwords')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are two problems:\n", + " \n", + "First, we don't have a clear model of the unknown words. We just say \"unknown\" but\n", + "we don't distinguish likely unknown from unlikely unknown. For example, is a 8-character unknown more likely than a 20-character unknown?\n", + "\n", + "Second, we don't take into account evidence from *parts* of the unknown. For example, \n", + "\"unglobulate\" versus \"zxfkogultae\".\n", + "\n", + "For our next approach, *Good - Turing* smoothing re-estimates the probability of zero-count words, based on the probability of one-count words (and can also re-estimate for higher-number counts, but that is less interesting).\n", + "\n", + "\n", + "\n", + "
I. J. Good (1916 - 2009)             Alan Turing (1812 - 1954)\n", + "\n", + "So, how many one-count words are there in `COUNTS`? (There aren't any in `COUNTS1`.) And what are the word lengths of them? Let's find out:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(7, 1357),\n", + " (8, 1356),\n", + " (9, 1176),\n", + " (6, 1113),\n", + " (10, 938),\n", + " (5, 747),\n", + " (11, 627),\n", + " (12, 398),\n", + " (4, 367),\n", + " (13, 215),\n", + " (3, 161),\n", + " (14, 112),\n", + " (2, 51),\n", + " (15, 37),\n", + " (16, 10),\n", + " (17, 7)]" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "singletons = (w for w in COUNTS if COUNTS[w] == 1)\n", + "\n", + "lengths = map(len, singletons)\n", + "\n", + "Counter(lengths).most_common()" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0012278198461651215" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1357 / sum(COUNTS.values())" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "hist(lengths, bins=len(set(lengths)));" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def pdist_good_turing_hack(counter, onecounter, base=1/26., prior=1e-8):\n", + " \"\"\"The probability of word, given evidence from the counter.\n", + " For unknown words, look at the one-counts from onecounter, based on length.\n", + " This gets ideas from Good-Turing, but doesn't implement all of it.\n", + " prior is an additional factor to make unknowns less likely.\n", + " base is how much we attenuate probability for each letter beyond longest.\"\"\"\n", + " N = sum(counter.values())\n", + " N2 = sum(onecounter.values())\n", + " lengths = map(len, [w for w in onecounter if onecounter[w] == 1])\n", + " ones = Counter(lengths)\n", + " longest = max(ones)\n", + " return (lambda word: \n", + " counter[word] / N if (word in counter) \n", + " else prior * (ones[len(word)] / N2 or \n", + " ones[longest] / N2 * base ** (len(word)-longest)))\n", + "\n", + "# Redefine P1w\n", + "P1w = pdist_good_turing_hack(COUNTS1, COUNTS)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['this',\n", + " 'is',\n", + " 'a',\n", + " 'test',\n", + " 'of',\n", + " 'segment',\n", + " 'at',\n", + " 'i',\n", + " 'on',\n", + " 'of',\n", + " 'a',\n", + " 'very',\n", + " 'long',\n", + " 'sequence',\n", + " 'of',\n", + " 'words']" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "segment.cache.clear()\n", + "segment('thisisatestofsegmentationofaverylongsequenceofwords')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was somewhat unsatisfactory. We really had to crank up the prior, specifically because the process of running `segment` generates so many non-word candidates (and also because there will be fewer unknowns with respect to the billion-word `WORDS1` than with respect to the million-word `WORDS`). It would be better to separate out the prior from the word distribution, so that the same distribution could be used for multiple tasks, not just for this one.\n", + "\n", + "Now let's think for a short while about smoothing **bigram** counts. Specifically, what if we haven't seen a bigram sequence, but we've seen both words individually? For example, to evaluate P(\"Greenland\") in the phrase \"turn left at Greenland\", we might have three pieces of evidence:\n", + "\n", + " P(\"Greenland\")\n", + " P(\"Greenland\" | \"at\")\n", + " P(\"Greenland\" | \"left\", \"at\")\n", + " \n", + "Presumably, the first would have a relatively large count, and thus large reliability, while the second and third would have decreasing counts and reliability. With *interpolation smoothing* we combine all three pieces of evidence, with a linear combination:\n", + " \n", + "$P(w_3 \\mid w_1w_2) = c_1 P(w_3) + c_2 P(w_3 \\mid w_2) + c_3 P(w_3 \\mid w_1w_2)$\n", + "\n", + "How do we choose $c_1, c_2, c_3$? By experiment: train on training data, maximize $c$ values on development data, then evaluate on test data.\n", + " \n", + "However, when we do this, we are saying, with probability $c_1$, that a word can appear anywhere, regardless of previous words. But some words are more free to do that than other words. Consider two words with similar probability:" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7.73314623661e-05\n", + "7.72494966889e-05\n" + ] + } + ], + "source": [ + "print P1w('francisco')\n", + "print P1w('individuals')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "They have similar unigram probabilities but differ in their freedom to be the second word of a bigram:" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['San francisco', 'san francisco']\n" + ] + } + ], + "source": [ + "print [bigram for bigram in COUNTS2 if bigram.endswith('francisco')]" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['are individuals', 'other individuals', 'on individuals', 'infected individuals', 'in individuals', 'where individuals', 'or individuals', 'which individuals', 'to individuals', 'both individuals', 'help individuals', 'more individuals', 'interested individuals', 'from individuals', ' individuals', 'income individuals', 'these individuals', 'about individuals', 'the individuals', 'among individuals', 'some individuals', 'those individuals', 'by individuals', 'minded individuals', 'These individuals', 'qualified individuals', 'certain individuals', 'different individuals', 'For individuals', 'few individuals', 'and individuals', 'two individuals', 'for individuals', 'between individuals', 'affected individuals', 'healthy individuals', 'private individuals', 'with individuals', 'following individuals', 'as individuals', 'such individuals', 'that individuals', 'all individuals', 'of individuals', 'many individuals']\n" + ] + } + ], + "source": [ + "print [bigram for bigram in COUNTS2 if bigram.endswith('individuals')]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Intuitively, words that appear in many bigrams before are more likely to appear in a new, previously unseen bigram. In *Kneser-Ney* smoothing (Reinhard Kneser, Hermann Ney) we multiply the bigram counts by this ratio. But I won't implement that here, because The Count never covered it.\n", + "\n", + "(10) One More Task: Secret Codes\n", + "===\n", + "\n", + "Let's tackle one more task: decoding secret codes. We'll start with the simplest of codes, a rotation cipher, sometimes called a shift cipher or a Caesar cipher (because this was state-of-the-art crypotgraphy in 100 BC). First, a method to encode:" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def rot(msg, n=13): \n", + " \"Encode a message with a rotation (Caesar) cipher.\" \n", + " return encode(msg, alphabet[n:]+alphabet[:n])\n", + "\n", + "def encode(msg, key): \n", + " \"Encode a message with a substitution cipher.\" \n", + " table = string.maketrans(upperlower(alphabet), upperlower(key))\n", + " return msg.translate(table) \n", + "\n", + "def upperlower(text): return text.upper() + text.lower() " + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Uijt jt b tfdsfu nfttbhf.'" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rot('This is a secret message.', 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Guvf vf n frperg zrffntr.'" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rot('This is a secret message.', 13)" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'This is a secret message.'" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rot(rot('This is a secret message.'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now decoding is easy: try all 26 candidates, and find the one with the maximum Pwords:" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def decode_rot(secret):\n", + " \"Decode a secret message that has been encoded with a rotation cipher.\"\n", + " candidates = [rot(secret, i) for i in range(len(alphabet))]\n", + " return max(candidates, key=lambda msg: Pwords(tokens(msg)))" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Nyf befnj kyv rejnvi?\n", + "Who knows the answer?\n" + ] + } + ], + "source": [ + "msg = 'Who knows the answer?'\n", + "secret = rot(msg, 17)\n", + "\n", + "print(secret)\n", + "print(decode_rot(secret))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's make it a tiny bit harder. When the secret message contains separate words, it is too easy to decode by guessing that the one-letter words are most likely \"I\" or \"a\". So what if the encode routine mushed all the letters together:" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def encode(msg, key): \n", + " \"Encode a message with a substitution cipher; remove non-letters.\" \n", + " msg = cat(tokens(msg)) ## Change here\n", + " table = string.maketrans(upperlower(alphabet), upperlower(key))\n", + " return msg.translate(table) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can decode by segmenting. We change candidates to be a list of segmentations, and still choose the candidate with the best Pwords: " + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def decode_rot(secret):\n", + " \"\"\"Decode a secret message that has been encoded with a rotation cipher,\n", + " and which has had all the non-letters squeezed out.\"\"\"\n", + " candidates = [segment(rot(secret, i)) for i in range(len(alphabet))]\n", + " return max(candidates, key=lambda msg: Pwords(msg))" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pahdghplmaxtglpxkmablmbfxtgrhgxunxeexk\n", + "['who', 'knows', 'the', 'answer', 'this', 'time', 'anyone', 'bu', 'e', 'll', 'er']\n" + ] + } + ], + "source": [ + "msg = 'Who knows the answer this time? Anyone? Bueller?'\n", + "secret = rot(msg, 19)\n", + "\n", + "print(secret)\n", + "print(decode_rot(secret))" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-123 p ah d g h p l max t g l p x km a bl mb f x t gr h g x un x e ex k\n", + "-133 q b i eh i q m n by u hm q y l n b cm n c g y u h s i h y vo y ff y l\n", + "-128 r c j f i jr no c z v in r z mo c d nod h z v it j i z w p z g g z m\n", + "-115 sd k g j k so p da w j os an p de op e i a w j u k j ax q ah h an\n", + "-144 t el h k l t p q e b x k p t b o q e f p q f j b x k v l k by r b ii b o\n", + "-145 u f m il m u q r f cy l qu c p r f g q r g k cy l wm l c z s c j j c p\n", + "-141 v g n j m n v r sg d z mr v d q sg h r s h l d z m x nm dat d k k d q\n", + "-39 who knows the answer this time anyone bu e ll er\n", + "-119 xi p l op x tu if b o t x f s u i j tu j n f b oz p of c v f mm f s\n", + "-151 y j q m p q y u v j g c p u y g t v j ku v k o g c pa q pg d w g n n g t\n", + "-151 z k r n q r z v w k h d q v z h u w k l v w l p h d q br q he x ho oh u\n", + "-97 also r saw x lie r w a iv x l m w x m q i er c s r if y i pp iv\n", + "-146 b mt p st b x y m j f s x b j w y m n x y n r j f sd t s j g z j q q j w\n", + "-137 c n u q tu cy z n k g ty c k x z no y z os k g t eut k ha k r r k x\n", + "-124 do v r u v d z a o l h u z d ly a op z apt l h u f v u li bl s sly\n", + "-121 e p w s v we ab pm iv a em z b p q ab qu m iv g w v m j cm t tm z\n", + "-142 f q x t w x f bc q n j w b fn a c q r bc r v n j wh x w n k d n u un a\n", + "-119 gr y u x y g c dr ok x c go b dr s c d s w ok xi y x o leo v vo b\n", + "-119 h s z vy z h des ply d h p c est de t x ply j z y pm f p w w p c\n", + "-137 it a w z a i e ft q m ze i q d f tu e f u y q m z ka z q n g q xx q d\n", + "-130 j u b x ab j f g u r na f jr eg u v f g v z r n alba r oh r y y re\n", + "-125 k v cy bc k g h v sob g k s f h v w g h was o b m c b s p is z z s f\n", + "-130 l w d z c d l hi w t p ch l t g i w x h ix b t p c nd c t q j t a at g\n", + "-123 m x e a dem i j x u q dim u h j x y i j y c u q doe du r ku b bu h\n", + "-124 ny f be fn j k y v re j n vi k y z j k z d v rep fe vs l v c c vi\n", + "-134 oz g cf go k l z w s f k o w j l z ak la e w s f q g f w tm w d d w j\n" + ] + } + ], + "source": [ + "candidates = [segment(rot(secret, i)) for i in range(len(alphabet))]\n", + "\n", + "for c in candidates:\n", + " print int(log10(Pwords(c))), ' '.join(c)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What about a general substitution cipher? The problem is that there are 26! substitution ciphers, and we can't enumerate all of them. We would need to search through this space. Initially make some guess at a substitution, then swap two letters; if that looks better keep going, if not try something else. This approach solves most substitution cipher problems, although it can take a few minutes on a message of length 100 words or so.\n", + "\n", + "(∞ and beyond) Where To Go Next\n", + "===\n", + "\n", + "What to do next? Here are some options:\n", + " \n", + "- **Spelling correction**: Use bigram or trigram context; make a model of spelling errors/edit distance; go beyond edit distance 2; make it more efficient\n", + "- **Evaluation**: Make a serious test suite; search for best parameters (e.g. $c_1, c_2, c_3$)\n", + "- **Smoothing**: Implement Kneser-Ney and/or Interpolation; do letter *n*-gram-based smoothing\n", + "- **Secret Codes**: Implement a search over substitution ciphers\n", + "- **Classification**: Given a corpus of texts, each with a classification label, write a classifier that will take a new text and return a label. Examples: spam/no-spam; favorable/unfavorable; what author am I most like; reading level.\n", + "- **Clustering**: Group data by similarity. Find synonyms/related words.\n", + "- **Parsing**: Representing nested structures rather than linear sequences of words. relations between parts of the structure. Implicit missing bits. Inducing a grammar.\n", + "- **Meaning**: What semantic relations are meant by the syntactic relations?\n", + "- **Translation**: Using examples to transform one language into another.\n", + "- **Question Answering**: Using examples to transfer a question into an answer, either by retrieving a passage, or by synthesizing one.\n", + "- **Speech**: Dealing with analog audio signals rather than discrete sequences of characters." + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'congratulations'" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "correct('cpgratulations')" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Life.ipynb b/pytudes/ipynb/Life.ipynb new file mode 100644 index 0000000..060437f --- /dev/null +++ b/pytudes/ipynb/Life.ipynb @@ -0,0 +1,836 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# John Conway's Game of Life\n", + "\n", + "The cellular automata game *Life*, invented by the mathematician [John Conway](https://en.wikipedia.org/wiki/John_Horton_Conway), makes a fun programming exercise. Let's review the [rules](http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life):\n", + "\n", + "The *world* of the Game of Life is an infinite two-dimensional orthogonal grid of *cells*, each of which is in one of two possible states, *live* or *empty*. Each cell has eight *neighbors*, the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following rules are applied to create the next *generation*:\n", + "\n", + "+ Any live cell with two or three live neighbors lives on to the next generation.\n", + "+ Any empty cell with exactly three live neighbors becomes a live cell in the next generation.\n", + "+ All other cells are empty in the next generation.\n", + "\n", + "For example, in the diagram below, \"`@`\" cells are live. In the transition from Generation 0 to 1, the cell marked \"`,`\" becomes empty (dies off) because it has zero live neighbors. In the next transition, a fourth `@` becomes live, because it has 3 live neighbors. All other cells stay the same. \n", + "\n", + " . . . . . . . . . . . . . . .\n", + " . . . @ . . . . , . . . . . .\n", + " . @ . . . . @ . . . . @ @ . .\n", + " . @ @ . . . @ @ . . . @ @ . .\n", + " . . . . . . . . . . . . . . .\n", + " Gen 0 Gen 1 Gen 2\n", + " \n", + "\n", + "\n", + "The world continues to evolve by these rules for as long as you care to observe. \n", + "\n", + "# Developing a Life Program\n", + "\n", + "\n", + "To create a program to play Life, start with the vocabulary of concepts:\n", + "\n", + "+ **World**\n", + "+ **Cell**\n", + "+ **Live/Empty**\n", + "+ **Neighbors**\n", + "+ **Next Generation**\n", + "+ **Display**\n", + "+ **Live Neighbor Counts**\n", + "\n", + "and consider how to implement them:\n", + "\n", + "+ **World**: The state of the world must represent which cells are empty and which are live. The tricky part is that the number of cells is infinite, and we can't store an infinite array in a finite computer. I can think of three ways to deal with this problem:\n", + " 1. **Change the rules**; make the world finite instead of infinite. (Cells at the edge of the world have fewer neighbors, or perhaps they wrap around to the other side of the world.)\n", + " 2. Use a **finite rectangular window** that covers all the live cells in the infinite grid. As the world\n", + " evolves, this window may have to grow or shift.\n", + "
Example: `world = [[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 1, 0, 0, 0], [0, 1, 1, 0, 0], [0, 0, 0, 0, 0]]` \n", + "\n", + " 3. Represent a world as a **set of live cells.** This set will grow and shrink in size from one generation to the next, but we don't have to worry about overflowing the edges of an array.\n", + "
Example: `world = {(3, 1), (1, 2), (1, 3), (2, 3)}` \n", + "
I will go with this choice.\n", + "\n", + "\n", + "+ **Cell**: Each cell will be represented as an (x, y) pair of integer coordinates.
Example: `cell = (1, 2)`.\n", + "+ **Live/Empty**: \n", + "A cell is live if it is a member of the set of live cells. \n", + "
Example: \"`cell in world`\" is True, given the definition of `cell` and `world` above, so `cell` is live.\n", + "+ **Neighbors**: The cell `(x, y)` has eight neighbors, formed by adding or subtracting 1 from `x` or `y` or both. We can define\n", + "a function `neighbors(cell)` to return this set.\n", + "
Example: `neighbors((8, 8)) == [(7, 7), (8, 7), (9, 7), (7, 8), (9, 8), (7, 9), (8, 9), (9, 9)]`\n", + "\n", + "+ **Display**: We will need some way to display the state of the world. Let's defer that for now.\n", + "\n", + "+ **Next Generation**: We can define a function, `next_generation(world)`, that takes a world as input and returns\n", + "a new world with the new set of live cells according to the rules.\n", + "Example: `next_generation({(3, 1), (1, 2), (1, 3), (2, 3)}) == {(1, 2), (1, 3), (2, 3)}`\n", + "\n", + "+ **Live Neighbor Counts**: I need to know how many live neighbors each cell has. A good way to represent this is a dict of `{(x, y): count}`. But which cells need to be the keys of this dict? We can start with the live cells, and also add any cells neighboring the live cells. An easy way to generate this dict is to create a `Counter` and pass it every neighbor of every live cell. This may feel like we're doing the counting \"backwards.\" Instead of asking \"for each cell, how many live neighbors does it have?\" we are saying \"for each live cell, increment the count of each of its neighbors.\" The two amount to the same thing because *neighbor* is symmetric—if P is a neighbor of Q, then Q is a neighbor of P. Below we see the neighbor counts for each of the three generations; in each generation the top diagram gives the neighbor counts for the empty cells, and the bottom diagram gives the counts for the live cells. This is just to make the diagram easier to read; in the code these are combined into one `Counter`. Here are the counts:\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " . . 1 1 1 . . . . . . . . . .\n", + " 1 1 2 @ 1 1 1 1 , . 1 2 2 1 .\n", + " 2 @ 4 2 1 2 @ 3 1 . 2 @ @ 2 .\n", + " 2 @ @ 1 . 2 @ @ 1 . 2 @ @ 2 .\n", + " 1 2 2 1 . 1 2 2 1 . 1 2 2 1 .\n", + " Gen 0 Gen 1 Gen 2\n", + " . . . . . . . . . . . . . . .\n", + " . . . 0 . . . . , . . . . . .\n", + " . 2 . . . . 2 . . . . 3 3 . .\n", + " . 2 2 . . . 2 2 . . . 3 3 . .\n", + " . . . . . . . . . . . . . . .\n", + " \n", + "\n", + "Here is the implementation. Note that in `next_generation` the `neighbor_counts` is used two ways so I decided to use two different names for clarity: `possible_cells` is used to iterate over all cells that might be live, and `counts` is used to check if a cell has the right number of neighbors." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import Counter\n", + "\n", + "def next_generation(world):\n", + " \"The set of live cells in the next generation.\"\n", + " possible_cells = counts = neighbor_counts(world)\n", + " return {cell for cell in possible_cells\n", + " if (counts[cell] == 3) \n", + " or (counts[cell] == 2 and cell in world)}\n", + "\n", + "def neighbor_counts(world):\n", + " \"A {cell: int} counter of the number of live neighbors for each cell that has neighbors.\"\n", + " return Counter(nb for cell in world \n", + " for nb in neighbors(cell))\n", + "\n", + "def neighbors(cell):\n", + " \"All 8 adjacent neighbors of cell.\"\n", + " (x, y) = cell\n", + " return [(x-1, y-1), (x, y-1), (x+1, y-1), \n", + " (x-1, y), (x+1, y), \n", + " (x-1, y+1), (x, y+1), (x+1, y+1)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see how this works:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 2), (1, 3), (2, 3)}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "world = {(3, 1), (1, 2), (1, 3), (2, 3)}\n", + "next_generation(world)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 2), (1, 3), (2, 2), (2, 3)}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "next_generation(next_generation(world))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 3), (2, 3), (3, 3), (1, 4), (3, 4), (1, 5), (2, 5), (3, 5)]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "neighbors((2, 4))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({(0, 1): 1,\n", + " (0, 2): 2,\n", + " (0, 3): 2,\n", + " (0, 4): 1,\n", + " (1, 1): 1,\n", + " (1, 2): 2,\n", + " (1, 3): 2,\n", + " (1, 4): 2,\n", + " (2, 0): 1,\n", + " (2, 1): 2,\n", + " (2, 2): 4,\n", + " (2, 3): 2,\n", + " (2, 4): 2,\n", + " (3, 0): 1,\n", + " (3, 2): 2,\n", + " (3, 3): 1,\n", + " (3, 4): 1,\n", + " (4, 0): 1,\n", + " (4, 1): 1,\n", + " (4, 2): 1})" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "neighbor_counts(world)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`run` is a function to play n generations of Life:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def run(world, n):\n", + " \"Run the world for n generations. No display; just return the nth generation.\"\n", + " for g in range(n):\n", + " world = next_generation(world)\n", + " return world" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 2), (1, 3), (2, 2), (2, 3)}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "run(world, 100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Display\n", + "\n", + "Now let's see how to display worlds. We'll consider a rectangular window on the infinite plane, specified as ranges of `Xs` and `Ys` coordinates. The function `picture` turns a world into a string showing what the world looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "from IPython.display import clear_output, display_html\n", + "\n", + "LIVE = '@'\n", + "EMPTY = '.'\n", + "PAD = ' '\n", + " \n", + "def picture(world, Xs, Ys):\n", + " \"Return a picture: a grid of characters representing the cells in this window.\"\n", + " def row(y): return PAD.join(LIVE if (x, y) in world else EMPTY for x in Xs)\n", + " return '\\n'.join(row(y) for y in Ys)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ". . . . .\n", + ". . . @ .\n", + ". @ . . .\n", + ". @ @ . .\n", + ". . . . .\n" + ] + } + ], + "source": [ + "print(picture(world, range(5), range(5)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The function `display_run` runs the world for `n` steps, displaying the picture at each step:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def display_run(world, n=10, Xs=range(10), Ys=range(10), pause=0.2):\n", + " \"Step and display the world for the given number of generations.\"\n", + " for g in range(n + 1):\n", + " html = ('Generation {}, Population {}\\n{}'\n", + " .format(g, len(world), pre(picture(world, Xs, Ys))))\n", + " clear_output()\n", + " display_html(html, raw=True)\n", + " time.sleep(pause)\n", + " world = next_generation(world)\n", + " \n", + "def pre(text): return '
' + text + '
'" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 5, Population 4\n", + "
. . . . .\n",
+       ". . . . .\n",
+       ". @ @ . .\n",
+       ". @ @ . .\n",
+       ". . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(world, 5, range(5), range(5))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Interesting Worlds\n", + "\n", + "Now let's take a look at some initial worlds that *Life* enthusiasts have discovered. It would be tedious to enumerate these with an explicit set of `(x, y)` coordinates, so we will define the function `shape` that takes a picture as input and returns a world; `shape` and `picture` are more-or-less inverses. " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def shape(picture, offset=(3, 3)):\n", + " \"Convert a graphical picture (e.g. '@ @ .\\n. @ @') into a world (set of cells).\"\n", + " cells = {(x, y) \n", + " for (y, row) in enumerate(picture.splitlines())\n", + " for (x, c) in enumerate(row.replace(PAD, ''))\n", + " if c == LIVE}\n", + " return move(cells, offset)\n", + "\n", + "def move(cells, offset):\n", + " \"Move/Translate/slide a set of cells by a (dx, dy) displacement/offset.\"\n", + " (dx, dy) = offset\n", + " return {(x+dx, y+dy) for (x, y) in cells}\n", + "\n", + "blinker = shape(\"@@@\")\n", + "block = shape(\"@@\\n@@\")\n", + "beacon = block | move(block, (2, 2))\n", + "toad = shape(\".@@@\\n@@@.\")\n", + "glider = shape(\".@.\\n..@\\n@@@\")\n", + "rpentomino = shape(\".@@\\n@@.\\n.@.\", (36, 20))\n", + "line = shape(\".@@@@@@@@.@@@@@...@@@......@@@@@@@.@@@@@\", (10, 10))\n", + "growth = shape(\"@@@.@\\n@\\n...@@\\n.@@.@\\n@.@.@\", (10, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is how `shape` and `move` work:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(3, 3), (4, 3), (4, 4), (5, 4)}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "shape(\"\"\"@ @ .\n", + " . @ @\"\"\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(3, 3), (3, 4), (4, 3), (4, 4)}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "block" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(103, 203), (103, 204), (104, 203), (104, 204)}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "move(block, (100, 200))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's run some examples. If you are viewing a static notebook, you will only see the last generation; rerun each cell to see all the generations." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 10, Population 3\n", + "
. . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . @ @ @ . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(blinker)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 10, Population 8\n", + "
. . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . @ @ . . . . .\n",
+       ". . . @ @ . . . . .\n",
+       ". . . . . @ @ . . .\n",
+       ". . . . . @ @ . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(beacon)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 10, Population 6\n", + "
. . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . @ @ @ . . .\n",
+       ". . . @ @ @ . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(toad)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 15, Population 5\n", + "
. . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . . . .\n",
+       ". . . . . . . @ . .\n",
+       ". . . . . . . . @ @\n",
+       ". . . . . . . @ @ .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(glider, 15)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 130, Population 178\n", + "
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . @\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . @ . . . . . . . . . . . . . @\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @\n",
+       ". . . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . @ @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @\n",
+       ". . . . . @ . @ @ @ @ . @ @ . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . @ . @\n",
+       ". . . @ @ . . @ @ . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . @ . @\n",
+       ". . . . . @ @ @ . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ .\n",
+       ". . . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . @ . @ . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . .\n",
+       ". . . . . . . . @ @ . . . . . . . . . . . . . . . . . @ . @ . . . @ @ . . . . . . . . . . . . .\n",
+       ". . . . @ @ @ . . @ @ . . . . . . . . . . . . . . . . @ . @ . . . . . . . . . . . . . . . . @ @\n",
+       ". . . . @ @ . . . @ @ . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . . . . @ @ @\n",
+       ". . . . @ . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . @ . . . . . . . @ . .\n",
+       ". . . . @ @ . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ . . . . . . . @ .\n",
+       ". . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . @ . . . . . . . .\n",
+       ". . . . @ . . @ . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . @ . . . @ @ . . . .\n",
+       ". . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . @ @ . . . @ . . @ . . .\n",
+       "@ @ . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . @ . . @ . . . . . . . @ . . @ . . .\n",
+       ". . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ @ @ . . . . . . @ @ . . . .\n",
+       ". . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ . . . . . . . . . . .\n",
+       "@ @ . @ @ . . . . . . . . . . @ @ . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . .\n",
+       "@ . . @ . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . .\n",
+       "@ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . @ . @ . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . @ . @ . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . @ . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . @ . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(rpentomino, 130, range(48), range(40))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 160, Population 111\n", + "
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . @\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ . @ . . @ .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ . . @ . @ @ . @ .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ @ . . @ @ . . . @\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ @ . @ @ @ @ @ . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . @ . . . @ @ . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . @ . @ . @ . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . @ . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ @ . . @ . . . . . . . @\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . @ . . . . . . @ @ .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . @ . . . . . . . . @ @ .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . . . . . . @ @ .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . @\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . @ @ @ . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . @ . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "zoo = (move(blinker, (5, 25)) | move(glider, (8, 13)) | move(blinker, (20, 25)) |\n", + " move(beacon, (24, 25)) | move(toad, (30, 25)) | move(block, (13, 25)) | move(block, (17, 33)))\n", + "\n", + "display_run(zoo, 160, range(48), range(40))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Generation 100, Population 72\n", + "
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . @ . . . @ @ . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . @ . @ . . @ . @ . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . @ . . . @ . . @ . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . @ @ . . . . @ . @ . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . @ @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . @ @ @ . @ @ . @ @ . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . @ @ . . . @ . @ @ @ . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . @ @ @ . . . . . @ . . @ . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . @ @ @ @ @ . @ @ @ @ @ @ @ . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . @ @ @ . @ @ @ @ @ @ @ @ . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . @ @ . @ @ @ @ @ . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+       ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display_run(growth, 100, range(40), range(40))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Outside of IPython\n", + "\n", + "If you want to run this code in your terminal, outside of an Ipython/Jupyter notebook, you can remove the line:\n", + "\n", + " from IPython.display import clear_output, display_html\n", + " \n", + "and add these lines:\n", + "\n", + " def clear_output(): print(\"\\033[;H\\033[2J\") # ANSI terminal home and clear\n", + " \n", + " def display_html(text, raw=False): print(text)\n", + " \n", + " def pre(text): return text\n", + " \n", + "# Coding Kata\n", + "\n", + "I once attended a [code kata](https://en.wikipedia.org/wiki/Kata_(programming%29) in which one of the exercises was to write the Game of Life without using any conditional (e.g. `if`) statements. I did it by using roughly the program shown here, but changing the lone `if` to a `filter` in `next_generation`:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "def next_generation(world):\n", + " \"The set of live cells in the next generation.\"\n", + " possible_cells = counts = neighbor_counts(world)\n", + " def good(cell): return counts[cell] == 3 or (counts[cell] == 2 and cell in world)\n", + " return set(filter(good, possible_cells))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Mean Misanthrope Density.ipynb b/pytudes/ipynb/Mean Misanthrope Density.ipynb new file mode 100644 index 0000000..73a1b44 --- /dev/null +++ b/pytudes/ipynb/Mean Misanthrope Density.ipynb @@ -0,0 +1,1075 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Puzzle of the Misanthropic Neighbors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consider [this puzzle](http://fivethirtyeight.com/features/can-you-solve-the-puzzle-of-your-misanthropic-neighbors/) from [The Riddler](http://fivethirtyeight.com/tag/the-riddler/):\n", + " \n", + "> *The misanthropes are coming. Suppose there is a row of some number, N, of houses in a new, initially empty development. Misanthropes are moving into the development one at a time and selecting a house at random from those that have nobody in them and nobody living next door. They keep on coming until no acceptable houses remain. At most, one out of two houses will be occupied; at least one out of three houses will be. But what’s the expected fraction of occupied houses as the development gets larger, that is, as N goes to infinity?*\n", + "\n", + "# Consider *N*=4 Houses\n", + "\n", + "![N houses](http://www.publicdomainpictures.net/pictures/180000/nahled/street-doodle.jpg)\n", + "\n", + "To make sure we understand the problem, let's try a simple example, with *N*=4 houses. We will represent the originally empty row of four houses by four dots:\n", + "\n", + " ....\n", + " \n", + "Now the first person chooses one of the four houses (which are all acceptable). We'll indicate an occupied house by a `1`, so the four equiprobable choices are:\n", + "\n", + " Choice 0: 1...\n", + " Choice 1: .1..\n", + " Choice 2: ..1.\n", + " Choice 3: ...1\n", + " \n", + "When a house is occupied, any adjacent houses become unacceptable. We'll indicate that with a `0`:\n", + "\n", + " Choice 0: 10..\n", + " Choice 1: 010.\n", + " Choice 2: .010\n", + " Choice 3: ..01\n", + " \n", + "In all four cases, a second occupant has a place to move in, but then there is no place for a third occupant. \n", + "The occupancy is 2 in all cases, and thus the *expected occpancy* is 2. The occupancy fraction, or *density*, is 2/*N* = 2/4 = 1/2.\n", + " \n", + "\n", + "# Consider *N*=7 Houses\n", + "\n", + "With *N*=7 houses, there are 7 equiprobable choices for the first occupant:\n", + "\n", + " Choice 0: 10.....\n", + " Choice 1: 010....\n", + " Choice 2: .010...\n", + " Choice 3: ..010..\n", + " Choice 4: ...010.\n", + " Choice 5: ....010\n", + " Choice 6: .....01\n", + " \n", + "Now we'll add something new: the lengths of the **runs** of consecutive acceptable houses to the left and right of the chosen house:\n", + "\n", + " Choice 0: 10..... runs = (0, 5)\n", + " Choice 1: 010.... runs = (0, 4)\n", + " Choice 2: .010... runs = (1, 3) \n", + " Choice 3: ..010.. runs = (2, 2) \n", + " Choice 4: ...010. runs = (3, 1) \n", + " Choice 5: ....010 runs = (4, 0) \n", + " Choice 6: .....01 runs = (5, 0) \n", + " \n", + "# Defining `occ(n)`\n", + "\n", + "This gives me a key hint as to how to analyze the problem. I'll define `occ(n)` to be the expected number of occupied houses in a row of `n` houses. So:\n", + "\n", + " Choice 0: 10..... runs = (0, 5); occupancy = occ(0) + 1 + occ(5)\n", + " Choice 1: 010.... runs = (0, 4); occupancy = occ(0) + 1 + occ(4)\n", + " Choice 2: .010... runs = (1, 3); occupancy = occ(1) + 1 + occ(3)\n", + " Choice 3: ..010.. runs = (2, 2); occupancy = occ(2) + 1 + occ(2)\n", + " Choice 4: ...010. runs = (3, 1); occupancy = occ(3) + 1 + occ(1)\n", + " Choice 5: ....010 runs = (4, 0); occupancy = occ(4) + 1 + occ(0)\n", + " Choice 6: .....01 runs = (5, 0); occupancy = occ(5) + 1 + occ(0) \n", + " \n", + "So we can say that `occ(n)` is:\n", + "\n", + "- 0 when `n` is 0 (because no houses means no occupants),\n", + "- 1 when `n` is 1 (because one isolated acceptable house has one occupant),\n", + "- else the mean, over the `n` choices for the first occupied house,\n", + "of the sum of that house plus the occupancy of the runs to the left and right.\n", + "\n", + "We can implement that:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from statistics import mean\n", + "\n", + "def occ(n):\n", + " \"The expected occupancy for a row of n houses (under misanthrope rules).\"\n", + " return (0 if n == 0 else\n", + " 1 if n == 1 else\n", + " mean(occ(L) + 1 + occ(R)\n", + " for (L, R) in runs(n)))\n", + "\n", + "def runs(n):\n", + " \"\"\"A list [(L, R), ...] where the i-th tuple contains the lengths of the runs\n", + " of acceptable houses to the left and right of house i.\"\"\"\n", + " return [(max(0, i - 1), max(0, n - i - 2))\n", + " for i in range(n)]\n", + "\n", + "def density(n): return occ(n) / n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's check that `occ(4)` is 2, as we computed it should be, and for other small values, up to 7:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: 0,\n", + " 1: 1,\n", + " 2: 1,\n", + " 3: 1.6666666666666667,\n", + " 4: 2,\n", + " 5: 2.466666666666667,\n", + " 6: 2.888888888888889,\n", + " 7: 3.323809523809524}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{n: occ(n) for n in range(8)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks good, although I can't prove the value above 4 are ccorrect. Now check that `runs(7)` is what we described above:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, 5), (0, 4), (1, 3), (2, 2), (3, 1), (4, 0), (5, 0)]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "runs(7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Dynamic Programming Version of `occ`\n", + "\n", + "The computation of `occ(n)` makes multiple calls to `occ(n-1), occ(n-2),` etc. To avoid re-computing the same calls over and over, we will modify `occ` to save previous results using [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming). I could implement that in one line with the decorator [`@functools.lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache), but then I would have to worry about the recursion limit. Instead I will explicitly manage a list, `cache`, such that `cache[n]` holds `occ(n)`:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def occ(n, cache=[0, 1]):\n", + " \"The expected occupancy for a row of n houses (under misanthrope rules).\"\n", + " # Store occ(i) in cache[i] for all as-yet-uncomputed values of i up to n:\n", + " for i in range(len(cache), n+1):\n", + " cache.append(mean(cache[L] + 1 + cache[R]\n", + " for (L, R) in runs(i)))\n", + " return cache[n]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's make sure this new version gets the same results as the old version:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "occ(4) == 2" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.323809523809524" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "occ(7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's make sure the caching makes computation pretty fast the first time, and *very* fast the second time:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.68 s, sys: 13.5 ms, total: 2.7 s\n", + "Wall time: 2.71 s\n" + ] + }, + { + "data": { + "text/plain": [ + "864.9617138385324" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time occ(2000)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 4 µs, sys: 0 ns, total: 4 µs\n", + "Wall time: 5.01 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "864.9617138385324" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time occ(2000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Plotting `density(n)`\n", + "\n", + "To get a feel for the limit of `density(n)`, start by drawing a plot over some small values of `n`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "plt.style.use('fivethirtyeight')\n", + "\n", + "def plot_density(ns):\n", + " \"Plot density(n) for each n in the list of numbers ns.\"\n", + " plt.xlabel('n houses'); plt.ylabel('density(n)')\n", + " plt.plot(ns, [density(n) for n in ns], 's-')\n", + " return density(ns[-1])" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.4353323288377046" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_density(range(1, 100))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is something funny going on with the first few values of `n`. Let's separately look at the first few:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.46203174603174607" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_density(range(1, 11))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And at a wider range:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.43240754751464183" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_density(range(100, 4000, 50))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The density is going down, and the curve is almost but not quite flat. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "# lim n → ∞ density(n)\n", + "\n", + "[The puzzle](http://fivethirtyeight.com/features/can-you-solve-the-puzzle-of-your-misanthropic-neighbors/)\n", + "is to figure out the limit of `density(n)` as `n` goes to infinity. The plot above makes it look like 0.432+something, but we can't answer the question just by plotting; we'll need to switch modes from *computational* thinking to *mathematical* thinking.\n", + "\n", + "At this point I started playing around with `density(n)`, looking at various values, differences of values, ratios of values, and ratios of differences of values, hoping to achieve some mathematical insight. Mostly I got dead ends.\n", + "But eventually I hit on something promising. I looked at the difference between density values (using the function `diff`), and particularly the difference as you double `n`:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0014849853757253895" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def diff(n, m): return density(n) - density(m)\n", + "\n", + "diff(100, 200)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And compared that to the difference when you double `n` again:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0007424926878626947" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diff(200, 400)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hmm—I noticed that the first difference is just about twice as much as the second. Let's check:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diff(100, 200) / diff(200, 400)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wow—not only is it *close* to twice as much, it is *exactly* twice as much (to the precision of floating point numbers). Let's try other starting values for `n`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n = 250; diff(n, 2*n) / diff(2*n, 4*n)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n = 500; diff(n, 2*n) / diff(2*n, 4*n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OK, I'm convinced this is real! \n", + "\n", + "Now, what mathematical function behaves like this? I figured out that *f*(*n*) = (1 / *n*) does. The ratio of the differences would be:\n", + "\n", + "$$\\frac{f(n) - f(2n)}{f(2n) - f(4n)} = \\frac{1/n - 1/(2n)}{1/(2n) - 1 / (4n)}\\;\\;$$\n", + "\n", + "Multiplying top and bottom by *n* you get:\n", + "\n", + "\n", + "$$\\frac{1 - 1/2}{1/2 - 1 /4} = \\frac{1/2}{1/4} = 2\\;\\;$$\n", + "\n", + "If the function (1 / *n*) fits the pattern, then so does any *affine transformation* of (1 / *n*), because we are taking the ratio of differences. So that means a density function of the form\n", + "\n", + " density(n) = A + B / n \n", + " \n", + "would fit the patterm. I can try a `scipy.optimize.curve_fit` to estimate the parameters *A* and *B*:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 4.70916321e-33, -1.30373854e-30],\n", + " [ -1.30373854e-30, 1.44885627e-27]])" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from scipy.optimize import curve_fit\n", + "\n", + "Ns = list(range(100, 5001, 100))\n", + "\n", + "def f(n, A, B): return A + B / n\n", + "\n", + "((A, B), covariance) = curve_fit(f=f, xdata=Ns, ydata=[density(n) for n in Ns])\n", + "\n", + "covariance" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `curve_fit` function returns a sequence of parameter values, and a covariance matrix. The fact that all the numbers in the covariance matrix are really small indicates that the parameters are a really good fit. Here are the parameters, `A` and `B`:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.43233235838169332, 0.29699707514503415)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A, B" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can plug them into a function that estimates the density:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "def estimated_density(n): return A + B / n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can test how close this function is to the true `density` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6.106226635438361e-16" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(abs(density(n) - estimated_density(n))\n", + " for n in range(200, 4000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That says that, for all values of `n` from 200 to 4,000, `density(n)` and `estimated_density(n)` agree at least through the first 15 decimal places!\n", + "\n", + "We now have a plausible answer to the puzzle:\n", + "\n", + "> lim n→∞ density(n) ≅ A = 0.43233235838169" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Why?\n", + "\n", + "Theis answer is empirically strong (15 decimal places of accuracy) but theoretically weak: we don't have a **proof**, and we don't have an explanation for **why** the density function has this form. We need some more mathematical thinking. \n", + "\n", + "I didn't have any ideas, so I looked to see if anyone else had written something about the number 0.432332358169 I tried several searches and found two interesting formulas:\n", + "\n", + "- Search: [`[0.4323323]`](https://www.google.com/search?q=0.4323323) Formula: `sinh(1) / exp(1)` [(Page)](http://arxiv.org/pdf/1310.4360.pdf)\n", + "- Search: [`[0.432332358]`](https://www.google.com/search?q=0.432332358) Formula: `0.5(1-e^(-2))` [(Page)](http://www.actuarialoutpost.com/actuarial_discussion_forum/archive/index.php/t-52095.html)\n", + "\n", + "I can verify that the two formulas are equivalent, and that they are indeed equal to `A` to at least 15 decimal places:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.43233235838169365, 0.43233235838169365, 0.43233235838169332)" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from math import sinh, exp, e\n", + "\n", + "S = sinh(1) / exp(1)\n", + "E = 0.5 * (1 - e ** (-2))\n", + "\n", + "S, E, A" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So I now have a suspicion that\n", + "\n", + "> lim n → ∞ density(n) = (1 - e-2) / 2\n", + "\n", + "but I still have no proof, nor any intuition as to why this is so." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# John Lamping to the Rescue\n", + "\n", + "I reported my results to Anne Paulson and John Lamping, who had originally related the problem to me, and the next day John wrote back with the following:\n", + "\n", + "
\n", + "I got a derivation of the formula!\n", + "\n", + "

Suppose that each house has a different \"attractiveness\", and that when it is a misanthrope's turn to pick a house, they consider the houses in order, from most attractive to least, and pick the first house not next to any other house. If the attractiveness are chosen independently, this process gives the same probabilities as each misanthrope picking from the available houses randomly.\n", + "\n", + "

To be more concrete, let the attractivenesses range from 0 to 1 with uniform probability, with lower numbers being being considered earlier, and hence more attractive. (This makes the math come out easier.)\n", + "\n", + "

Given the attractiveness, a, of a house, we can compute the chance that it will end up getting picked. It will get picked if and only if neither house on either side gets considered earlier and gets picked. Lets consider one side, and assume the houses, and their attractivenesses, are labeled a, b, c, d, e, f, g, ... with the house we are considering being a. There are an infinite number of cases where b won't get considered before a and picked. Here are the first few:\n", + "\n", + "

a < b (a is considered before b)\n", + "

a > b > c < d (Someone considered c first among these 4 and picked it. A later person considered b before a, but rejected it because c had already been chosen.)\n", + "

a > b > c > d > e < f (Someone considered e first among these 6, and picked it. A later person considered d, but rejected it because e was chosen, then considered c, which they picked. Still later, someone considered b, which they rejected because c had been chosen.)\n", + "\n", + "

We can write down the probabilities of these cases as a function of the attractiveness of a:\n", + "\n", + "

a < b: The chance that b is greater than a: 1 - a.\n", + "

a > b > c < d: Let y = a - c, so y is between 0 and a. The probability is the integral over the possible y of the chance that b is between a and c, times the chance that d is greater than c, or integral from 0 to a of y * (1 - a + y) dy.\n", + "

a > b > c > d > e < f: Let y = a - e. The probability is the integral of (the chance that b, c, and d are all between a and e, and ordered right, which is y^3 / 3!, times the chance that f is greater than e, which is (1 - a + y))\n", + "\n", + "

If you work out the definite integrals, you get\n", + "\n", + "

a < b: 1 - a\n", + "

a > b > c < d: a^2 / 2 - a^3 / 3!\n", + "

a > b > c > d > e < f: a^4 / 4! - a^5 / 5!\n", + "\n", + "

Add them all up, and you have 1 - a + a^2 / 2 - a^3 / 3! + a ^4 / 4! ... the Taylor expansion for e^-a. \n", + "\n", + "

Now, there will be a house at a if both adjacent houses are not picked earlier, so the chance is the square of the chance for one side: e^(-2a). Integrate that from 0 to 1, and you get 1/2 (1 - e^-2).\n", + "

\n", + "\n", + "You can compare John Lamping's solution to the solutions by [Jim Ferry](http://fivethirtyeight.com/features/the-perplexing-puzzle-of-the-proud-partygoers/) and [Andrew Mascioli](http://andrewmascioli.com/index.php/2016/04/24/the-misanthropic-neighborhood/). \n", + "\n", + "# Styles of Thinking\n", + "\n", + "It is clear that different write-ups of this problem display different styles of thinking. I'll attempt to name and describe them:\n", + "\n", + "- **Mathematical Publication Style**: This style uses sophisticated mathematics (e.g. generating functions, differentiation, asymptotic analysis, and manipulation of summations). It defines new abstractions without\n", + "necessarily trying to motivate them first, it is terse and formal, and it gets us to the conclusion in a way that is\n", + "clearly correct, but does not describe all the steps of how the author came up with the ideas. (Ferry and Mascioli)\n", + "- **Mathematical Exploration Style**: Like the Mathematical Publication Style, but with more explanatory prose. (Lamping)\n", + "- **Computational Thinking**: A more concrete style; tends to use programs with specific values of `n` rather than \n", + "creating a proof for all values of `n`; produces tables or plots to help guide intuition; verifies results\n", + "with tests or alternative implementations. (Norvig)\n", + "\n", + "In this specific puzzle, my steps were:\n", + "- Analyze the problem and implement code to solve it for small values of `n`.\n", + "- Plot results and examine them for insight.\n", + "- Play with the results and get a guess at a partial solution density(n) ≅ A + B / n.\n", + "- Solve numerically for `A` and `B`.\n", + "- Do a search with the numeric value of `A` to find a formula with that value.\n", + "- Given that formula, let Lamping figure out how it corresponds to the problem.\n", + "\n", + "This is mostly computational thinking, with a little mathematical thrown in. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Validation by Anticipating Objections\n", + "\n", + "Is our implementation of `occ(n)` correct? I think it is, but I can anticipate some objections and answer them:\n", + "\n", + "- *In `occ(n)`, is it ok to start from all empty houses, rather than considering layouts of partially-occupied houses?* Yes, because the problem states that initially all houses are empty, and each choice of a house breaks the street up into runs of acceptable houses, flanked by unacceptable houses. If we get the computation right for a run of `n` acceptable houses, then we can get the whole answer right. A key point is that the chosen first house breaks the row of houses into 2 runs of *acceptable* houses, not 2 runs of *unoccupied* houses. If it were unoccupied houses, then we would have to also keep track of whether there were occupied houses to the right and/or left of the runs. By considering runs of acceptable houses, eveything is clean and simple.\n", + "\n", + "- *In `occ(7)`, if the first house chosen is 2, that breaks the street up into runs of 1 and 3 acceptable houses. There is only one way to occupy the 1 house, but there are several ways to occupy the 3 houses. Shouldn't the average give more weight to the 3 houses, since there are more possibilities there?* No. We are calculating occupancy, and there is a specific number (5/3) which is the expected occupancy of 3 houses; it doesn't matter if there is one combination or a million combinations that contribute to that expected value, all that matters is what the expected value is.\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Validation by Simulation\n", + "\n", + "\n", + "A simulation can add credence to our implementation of `density(n)`, for two reasons:\n", + "- The code for the simulation can have a more direct correspondance to the problem statement.\n", + "- When two very different implementations get the same result, that is evidence supporting both of them.\n", + "\n", + "\n", + "The simulation will start with an empty set of occupied houses. We then go through the houses in random order, occupying just the ones that have no neighbor. (Note that `random.sample(range(n), n)` gives a random ordering of `range(n)`.)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "\n", + "def simulate(n):\n", + " \"Simulate moving in to houses, and return a sorted tuple of occupied houses.\"\n", + " occupied = set()\n", + " for house in random.sample(range(n), n):\n", + " if (house - 1) not in occupied and (house + 1) not in occupied:\n", + " occupied.add(house)\n", + " return sorted(occupied)\n", + "\n", + "def simulated_density(n, repeat=10000):\n", + " \"Estimate density by simulation, repeated `repeat` times.\"\n", + " return mean(len(simulate(n)) / n \n", + " for _ in range(repeat))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see if the simulation returns results that match the actual `density` function and the `estimated_density` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " n simulate density estimated\n", + " 10 0.4621 0.4620 0.4620\n", + " 25 0.4442 0.4442 0.4442\n", + " 50 0.4383 0.4383 0.4383\n", + " 100 0.4354 0.4353 0.4353\n", + " 200 0.4339 0.4338 0.4338\n", + " 400 0.4331 0.4331 0.4331\n" + ] + } + ], + "source": [ + "print(' n simulate density estimated')\n", + "for n in (10, 25, 50, 100, 200, 400):\n", + " print('{:4d} {:.4f} {:.4f} {:.4f}'\n", + " .format(n, simulated_density(n), density(n), estimated_density(n)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We get good agreement (at least to 3 decimal places), suggesting that either our three implementations are all correct, or we've made mistakes in all three. \n", + "\n", + "The `simulate` function can also give us insights when we look at the results it produces:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 2, 4, 6]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simulate(7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's repeat that multiple times, and store the results in a `Counter`, which tracks how many times it has seen each result:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({(0, 2, 4, 6): 3220,\n", + " (0, 2, 5): 1214,\n", + " (0, 3, 5): 1029,\n", + " (0, 3, 6): 827,\n", + " (1, 3, 5): 1417,\n", + " (1, 3, 6): 976,\n", + " (1, 4, 6): 1317})" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from collections import Counter\n", + "\n", + "Counter(tuple(simulate(7)) for _ in range(10000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That says that about 1/3 of the time, things work out so that the 4 even-numbered houses are occupied. But if anybody ever chooses an odd-numbered house, then we are destined to have 3 houses occupied (in one of 6 different ways, of which (1, 3 5) is the most common, probably because it is the only one that has three chances of getting started with an odd-numbered house)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Verification by Test\n", + "\n", + "Another way to gain more confidence in the code is to run a test suite:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ok'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test():\n", + " assert occ(0) == 0\n", + " assert occ(1) == occ(2) == 1\n", + " assert occ(3) == 5/3\n", + " assert density(3) == occ(3) / 3\n", + " assert density(100) == occ(100) / 100\n", + " assert runs(3) == [(0, 1), (0, 0), (1, 0)]\n", + " assert runs(7) == [(0, 5), (0, 4), (1, 3), (2, 2), (3, 1), (4, 0), (5, 0)]\n", + " for n in (3, 7, 10, 20, 100, 101, 200, 201):\n", + " for repeat in range(500):\n", + " assert_valid(simulate(n), n) \n", + " return 'ok'\n", + "\n", + "def assert_valid(occupied, n):\n", + " \"\"\"Assert that, in this collection of occupied houses, no house is adjacent to an\n", + " occupied house, and every unoccupied position is adjacent to an occupied house.\"\"\"\n", + " occupied = set(occupied) # coerce to set\n", + " for house in range(n):\n", + " if house in occupied:\n", + " assert not ((house - 1) in occupied or (house + 1) in occupied)\n", + " else:\n", + " assert (house - 1) in occupied or (house + 1) in occupied\n", + "\n", + "test()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conclusion\n", + "\n", + "I'm happy with my result:\n", + "\n", + "> lim n → ∞ density(n) = (1 - e-2) / 2 ≅ 0.43233235838169365 \n", + "\n", + "I got the fun of working on the puzzle, the satisfaction of seeing John Lamping work out a proof, and the awe of seeing the mathematically sophisticated solutions of Jim Ferry and Andrew Mascioli, solutions that I know I could never come up with, but that I could get near to by coming at the problem with a different style of thinking." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Palindrome.ipynb b/pytudes/ipynb/Palindrome.ipynb new file mode 100644 index 0000000..985ca0b --- /dev/null +++ b/pytudes/ipynb/Palindrome.ipynb @@ -0,0 +1,534 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Panama Palindrome\n", + "\n", + "## Utilities" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import random, re, bisect, time\n", + "\n", + "def is_palindrome(s):\n", + " \"Test if a string is a palindrome (only considering letters a-z).\"\n", + " s1 = canonical(s)\n", + " return s1 == reversestr(s1)\n", + "\n", + "def is_unique_palindrome(s):\n", + " \"Test if string s is a palindrome where each comma-separated phrase is unique.\"\n", + " return is_palindrome(s) and is_unique(phrases(s))\n", + "\n", + "def canonical(word, sub=re.compile('[^a-z]').sub):\n", + " \"The canonical form for comparing: only lowercase a-z.\"\n", + " return sub('', word.lower())\n", + "\n", + "def phrases(s):\n", + " \"Break a string s into comma-separated phrases.\"\n", + " return [phrase.strip() for phrase in s.split(',')]\n", + "\n", + "def reversestr(s):\n", + " \"Reverse a string.\"\n", + " return s[::-1]\n", + "\n", + "def is_unique(collection):\n", + " \"Return true if collection has no duplicate elements.\"\n", + " return len(collection) == len(set(collection))" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'test_utils passes'" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_utils():\n", + " assert is_unique_palindrome('A man, a plan, a canal, Panama!')\n", + " assert is_unique_palindrome('''A (man), a PLAN... a ``canal?'' -- Panama!''')\n", + " assert not is_unique_palindrome('A man, a plan, a radar, a canal, Panama.')\n", + " \n", + " assert is_palindrome('A man, a plan, a canal, Panama.')\n", + " assert is_palindrome('Radar. Radar? Radar!')\n", + " assert not is_palindrome('radars')\n", + "\n", + " assert phrases('A man, a plan, Panama') == ['A man', 'a plan', 'Panama']\n", + " assert canonical('A man, a plan, a canal, Panama') == 'amanaplanacanalpanama'\n", + " assert reversestr('foo') == 'oof'\n", + " assert is_unique([1, 2, 3])\n", + " assert not is_unique([1, 2, 2])\n", + " return 'test_utils passes'\n", + "\n", + "test_utils()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Dictionary" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "! [ -e npdict.txt ] || curl -O http://norvig.com/npdict.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 126144 204928 1383045 npdict.txt\r\n" + ] + } + ], + "source": [ + "! wc npdict.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "################ Reading in a dictionary\n", + "\n", + "class PalDict:\n", + " \"\"\"A dictionary with the following fields:\n", + " words: a sorted list of words: ['ant', 'bee', 'sea']\n", + " rwords: a sorted list of reversed words: ['aes', 'eeb', 'tna']\n", + " truename: a dict of {canonical:true} pairs, e.g. {'anelk': 'an elk', 'anneelk': 'Anne Elk'}\n", + " k:\n", + " and the followng methods:\n", + " \"\"\"\n", + " \n", + " def __init__(self, k=100, filename='npdict.txt'):\n", + " words, rwords, truename = [], [], {'': '', 'panama': 'Panama!'}\n", + " for tword in open(filename, 'r', encoding='ascii', errors='ignore').read().splitlines():\n", + " word = canonical(tword)\n", + " words.append(word)\n", + " rwords.append(reversestr(word))\n", + " truename[word] = tword\n", + " words.sort()\n", + " rwords.sort()\n", + " self.k = k\n", + " self.words = words\n", + " self.rwords = rwords\n", + " self.truename = truename\n", + " self.rangek = range(k)\n", + " self.tryharder = False\n", + "\n", + " def startswith(self, prefix):\n", + " \"\"\"Return up to k canonical words that start with prefix.\n", + " If there are more than k, choose from them at random.\"\"\"\n", + " return self._k_startingwith(self.words, prefix)\n", + "\n", + " def endswith(self, rsuffix):\n", + " \"\"\"Return up to k canonical words that end with the reversed suffix.\n", + " If you want words ending in 'ing', ask for d.endswith('gni').\n", + " If there are more than k, choose from them at random.\"\"\"\n", + " return [reversestr(s) for s in self._k_startingwith(self.rwords, rsuffix)]\n", + "\n", + " def __contains__(self, word):\n", + " return word in self.truename\n", + "\n", + " def _k_startingwith(self, words, prefix):\n", + " start = bisect.bisect_left(words, prefix)\n", + " end = bisect.bisect(words, prefix + 'zzzz')\n", + " n = end - start\n", + " if self.k >= n: # get all the words that start with prefix\n", + " results = words[start:end]\n", + " else: # sample from words starting with prefix \n", + " indexes = random.sample(range(start, end), self.k)\n", + " results = [words[i] for i in indexes]\n", + " random.shuffle(results)\n", + " ## Consider words that are prefixes of the prefix.\n", + " ## This is very slow, so don't use it until late in the game.\n", + " if self.tryharder:\n", + " for i in range(3, len(prefix)):\n", + " w = prefix[0:i]\n", + " if ((words == self.words and w in self.truename) or\n", + " (words == self.rwords and reversestr(w) in self.truename)):\n", + " results.append(w)\n", + " return results\n", + "\n", + "paldict = PalDict() \n", + "\n", + "def anpdictshort():\n", + " \"Find the words that are valid when every phrase must start with 'a'\"\n", + " def segment(word): return [s for s in word.split('a') if s]\n", + " def valid(word): return all(reversestr(s) in segments for s in segment(word))\n", + " words = [canonical(w) for w in open('anpdict.txt')]\n", + " segments = set(s for w in words for s in segment(w))\n", + " valid_words = [paldict.truename[w] for w in words if valid(w)]\n", + " file('anpdict-short2.txt', 'w').write('\\n'.join(valid_words))\n", + "\n", + "################ Search for a palindrome\n", + "\n", + "class Panama:\n", + " def __init__(self, L='A man, a plan', R='a canal, Panama', dict=paldict):\n", + " ## .left and .right hold lists of canonical words\n", + " ## .diff holds the number of characters that are not matched,\n", + " ## positive for words on left, negative for right.\n", + " ## .stack holds (action, side, arg) tuples\n", + " self.left = []\n", + " self.right = []\n", + " self.best = 0\n", + " self.seen = {}\n", + " self.diff = 0\n", + " self.stack = []\n", + " self.starttime = time.clock()\n", + " self.dict = dict\n", + " self.steps = 0\n", + " for word in L.split(','):\n", + " self.add('left', canonical(word))\n", + " for rword in reversestr(R).split(','):\n", + " self.add('right', canonical(reversestr(rword)))\n", + " self.consider_candidates()\n", + " \n", + " def search(self, steps=10*1000*1000):\n", + " \"Search for palindromes.\"\n", + " for self.steps in range(steps):\n", + " if not self.stack:\n", + " return 'done'\n", + " action, dir, substr, arg = self.stack[-1]\n", + " if action == 'added': # undo the last word added\n", + " self.remove(dir, arg)\n", + " elif action == 'trying' and arg: # try the next word if there is one\n", + " self.add(dir, arg.pop()) and self.consider_candidates()\n", + " elif action == 'trying' and not arg: # otherwise backtrack\n", + " self.stack.pop()\n", + " else:\n", + " raise ValueError(action)\n", + " self.report()\n", + " return self\n", + "\n", + " def add(self, dir, word):\n", + " \"add a word\"\n", + " if word in self.seen:\n", + " return False\n", + " else:\n", + " getattr(self, dir).append(word)\n", + " self.diff += factor[dir] * len(word)\n", + " self.seen[word] = True\n", + " self.stack.append(('added', dir, '?', word))\n", + " return True\n", + "\n", + " def remove(self, dir, word):\n", + " \"remove a word\"\n", + " oldword = getattr(self, dir).pop()\n", + " assert word == oldword\n", + " self.diff -= factor[dir] * len(word)\n", + " del self.seen[word]\n", + " self.stack.pop()\n", + " \n", + " def consider_candidates(self):\n", + " \"\"\"Push a new state with a set of candidate words onto stack.\"\"\"\n", + " if self.diff > 0: # Left is longer, consider adding on right\n", + " dir = 'right'\n", + " substr = self.left[-1][-self.diff:]\n", + " candidates = self.dict.endswith(substr)\n", + " elif self.diff < 0: # Right is longer, consider adding on left\n", + " dir = 'left'\n", + " substr = reversestr(self.right[-1][0:-self.diff])\n", + " candidates = self.dict.startswith(substr)\n", + " else: # Both sides are same size\n", + " dir = 'left'\n", + " substr = ''\n", + " candidates = self.dict.startswith('')\n", + " if substr == reversestr(substr):\n", + " self.report()\n", + " self.stack.append(('trying', dir, substr, candidates))\n", + " \n", + " def report(self):\n", + " \"Report a new palindrome to log file (if it is sufficiently big).\"\n", + " N = len(self)\n", + " if N > 13333:\n", + " self.dict.tryharder = True\n", + " if N > self.best and (N > 13000 or N > self.best+1000):\n", + " self.best = len(self)\n", + " self.bestphrase = str(self)\n", + " print('%5d phrases (%5d words) in %3d seconds (%6d steps)' % (\n", + " self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime,\n", + " self.steps))\n", + " assert is_unique_palindrome(self.bestphrase)\n", + "\n", + " def __len__(self):\n", + " return len(self.left) + len(self.right)\n", + "\n", + " def __str__(self):\n", + " truename = self.dict.truename\n", + " lefts = [truename[w] for w in self.left]\n", + " rights = [truename[w] for w in self.right]\n", + " return ', '.join(lefts + rights[::-1])\n", + " \n", + " def __repr__(self):\n", + " return ''.format(len(self))\n", + "\n", + "factor = {'left': +1, 'right': -1}\n", + "\n", + "# Note that we only allow one truename per canonical name. Occasionally\n", + "# this means we miss a good word (as in \"a node\" vs. \"an ode\"), but there\n", + "# are only 665 of these truename collisions, and most of them are of the\n", + "# form \"a mark-up\" vs. \"a markup\" so it seemed better to disallow them.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "126144" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(paldict.words)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "all tests pass\n", + " 1005 phrases ( 1239 words) in 0 seconds ( 18582 steps)\n", + " 2012 phrases ( 2478 words) in 0 seconds ( 41886 steps)\n", + " 3017 phrases ( 3710 words) in 0 seconds ( 64444 steps)\n", + " 4020 phrases ( 4957 words) in 0 seconds ( 92989 steps)\n", + " 5022 phrases ( 6184 words) in 1 seconds (128986 steps)\n", + " 6024 phrases ( 7408 words) in 1 seconds (162634 steps)\n", + " 7027 phrases ( 8607 words) in 1 seconds (204639 steps)\n", + " 8036 phrases ( 9846 words) in 2 seconds (254992 steps)\n", + " 9037 phrases (11050 words) in 2 seconds (320001 steps)\n", + "10039 phrases (12257 words) in 2 seconds (417723 steps)\n", + "11040 phrases (13481 words) in 3 seconds (565050 steps)\n", + "12043 phrases (14711 words) in 4 seconds (887405 steps)\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "################ Unit Tests\n", + " \n", + "def test2(p=PalDict()):\n", + " d = p.dict\n", + " def sameset(a, b): return set(a) == set(b)\n", + " assert 'panama' in d\n", + " assert d.words[0] in d\n", + " assert d.words[-1] in d\n", + " assert sameset(d.startswith('aword'), ['awording', 'awordbreak',\n", + " 'awordiness', 'awordage', 'awordplay', 'awordlore', 'awordbook',\n", + " 'awordlessness', 'aword', 'awordsmith'])\n", + " assert sameset(d.endswith('ytisob'), ['aglobosity', 'averbosity',\n", + " 'asubglobosity', 'anonverbosity', 'agibbosity'])\n", + " d.tryharder = True\n", + " assert sameset(d.startswith('oklahoma'), ['oklahoma', 'okla'])\n", + " d.tryharder = False\n", + " assert d.startswith('oklahoma') == ['oklahoma']\n", + " assert d.startswith('fsfdsfdsfds') == []\n", + " print('all tests pass')\n", + " return p\n", + "\n", + "p = Panama()\n", + "test2(p)\n", + "p.search().report()\n", + "p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " % Total % Received % Xferd Average Speed Time Time Time Current\n", + " Dload Upload Total Spent Left Speed\n", + "100 847k 100 847k 0 0 1037k 0 --:--:-- --:--:-- --:--:-- 1037k\n" + ] + } + ], + "source": [ + "! [ -e anpdict.txt ] || curl -O http://norvig.com/anpdict.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "anpdictshort()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 4527 9055 39467 anpdict-short.txt\r\n", + " 4527 9055 39467 anpdict-short2.txt\r\n", + " 69241 138489 867706 anpdict.txt\r\n", + " 126144 204928 1383045 npdict.txt\r\n", + " 204439 361527 2329685 total\r\n" + ] + } + ], + "source": [ + "! wc *npd*" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Letter-By-Letter Approach\n", + "\n", + "Can we go letter-by-letter instead of word-by-word? Advantages: \n", + "\n", + "* We can (if need be) be exhaustive at each decision point, trying all 26 possibilities.\n", + "* We can try the most likely letters first.\n", + "\n", + "Process\n", + "\n", + "* Keep left- nad right- partial phrase lists; and the current state:\n", + "\n", + " {left: ['aman', 'aplan'], right: ['acanal', panama'],\n", + " left_word: True, right_word: True, extra_chars: +3, palindrome: True}\n", + " \n", + "* Now consider all ways of extending:\n", + "\n", + " - Add the letter `'a'` to the left, either as a new word or a continuation of the old word (perhaps going for `'a planaria'`).\n", + " - Add a letter, any letter, to the right, either as a new word or a continuation of \n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from collections import namedtuple\n", + "\n", + "\n", + "def do(state, action, side, L): action(state, side, L)\n", + "def add(state, side, L): getattr(state, side)[-1] += L\n", + "def new(state, side, L): getattr(state, side).append(L)\n", + "def undo(action, letter):\n", + " if action == add:\n", + " elif action == new:\n", + " else:\n", + " raise ValueError()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Probability.ipynb b/pytudes/ipynb/Probability.ipynb new file mode 100644 index 0000000..ee8c703 --- /dev/null +++ b/pytudes/ipynb/Probability.ipynb @@ -0,0 +1,3322 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "
Peter Norvig, 12 Feb 2016
\n", + "\n", + "# A Concrete Introduction to Probability (using Python)\n", + "\n", + "\n", + "\n", + "\n", + "This notebook covers the basics of probability theory, with Python 3 implementations. (You should have some background in [probability](http://www.dartmouth.edu/~chance/teaching_aids/books_articles/probability_book/pdf.html) and [Python](https://www.python.org/about/gettingstarted/).) \n", + "\n", + "\n", + "In 1814, Pierre-Simon Laplace [wrote](https://en.wikipedia.org/wiki/Classical_definition_of_probability):\n", + "\n", + ">*Probability ... is thus simply a fraction whose numerator is the number of favorable cases and whose denominator is the number of all the cases possible ... when nothing leads us to expect that any one of these cases should occur more than any other.*\n", + "\n", + "![Laplace](https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/AduC_197_Laplace_%28P.S.%2C_marquis_de%2C_1749-1827%29.JPG/180px-AduC_197_Laplace_%28P.S.%2C_marquis_de%2C_1749-1827%29.JPG)\n", + "
Pierre-Simon Laplace
1814
\n", + "\n", + "\n", + "Laplace really nailed it, way back then! If you want to untangle a probability problem, all you have to do is be methodical about defining exactly what the cases are, and then careful in counting the number of favorable and total cases. We'll start being methodical by defining some vocabulary:\n", + "\n", + "\n", + "- **[Experiment](https://en.wikipedia.org/wiki/Experiment_(probability_theory%29):**\n", + " An occurrence with an uncertain outcome that we can observe.\n", + "
*For example, rolling a die.*\n", + "- **[Outcome](https://en.wikipedia.org/wiki/Outcome_(probability%29):**\n", + " The result of an experiment; one particular state of the world. What Laplace calls a \"case.\"\n", + "
*For example:* `4`.\n", + "- **[Sample Space](https://en.wikipedia.org/wiki/Sample_space):**\n", + " The set of all possible outcomes for the experiment. \n", + "
*For example,* `{1, 2, 3, 4, 5, 6}`.\n", + "- **[Event](https://en.wikipedia.org/wiki/Event_(probability_theory%29):**\n", + " A subset of possible outcomes that together have some property we are interested in.\n", + "
*For example, the event \"even die roll\" is the set of outcomes* `{2, 4, 6}`. \n", + "- **[Probability](https://en.wikipedia.org/wiki/Probability_theory):**\n", + " As Laplace said, the probability of an event with respect to a sample space is the number of favorable cases (outcomes from the sample space that are in the event) divided by the total number of cases in the sample space. (This assumes that all outcomes in the sample space are equally likely.) Since it is a ratio, probability will always be a number between 0 (representing an impossible event) and 1 (representing a certain event).\n", + "
*For example, the probability of an even die roll is 3/6 = 1/2.*\n", + "\n", + "This notebook will develop all these concepts; I also have a [second part](http://nbviewer.jupyter.org/url/norvig.com/ipython/ProbabilityParadox.ipynb) that covers paradoxes in Probability Theory." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Code for `P` \n", + "\n", + "`P` is the traditional name for the Probability function:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from fractions import Fraction\n", + "\n", + "def P(event, space): \n", + " \"The probability of an event, given a sample space of equiprobable outcomes.\"\n", + " return Fraction(len(event & space), \n", + " len(space))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Read this as implementing Laplace's quote directly: *\"Probability is thus simply a fraction whose numerator is the number of favorable cases and whose denominator is the number of all the cases possible.\"* \n", + " \n", + "\n", + "# Warm-up Problem: Die Roll" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "What's the probability of rolling an even number with a single six-sided fair die? \n", + "\n", + "We can define the sample space `D` and the event `even`, and compute the probability:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D = {1, 2, 3, 4, 5, 6}\n", + "even = { 2, 4, 6}\n", + "\n", + "P(even, D)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "It is good to confirm what we already knew.\n", + "\n", + "You may ask: Why does the definition of `P` use `len(event & space)` rather than `len(event)`? Because I don't want to count outcomes that were specified in `event` but aren't actually in the sample space. Consider:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "even = {2, 4, 6, 8, 10, 12}\n", + "\n", + "P(even, D)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here, `len(event)` and `len(space)` are both 6, so if just divided, then `P` would be 1, which is not right.\n", + "The favorable cases are the *intersection* of the event and the space, which in Python is `(event & space)`.\n", + "Also note that I use `Fraction` rather than regular division because I want exact answers like 1/3, not 0.3333333333333333." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "# Urn Problems\n", + "\n", + "Around 1700, Jacob Bernoulli wrote about removing colored balls from an urn in his landmark treatise *[Ars Conjectandi](https://en.wikipedia.org/wiki/Ars_Conjectandi)*, and ever since then, explanations of probability have relied on [urn problems](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=probability%20ball%20urn). (You'd think the urns would be empty by now.) \n", + "\n", + "![Jacob Bernoulli](http://www2.stetson.edu/~efriedma/periodictable/jpg/Bernoulli-Jacob.jpg)\n", + "
Jacob Bernoulli
1700
\n", + "\n", + "For example, here is a three-part problem [adapted](http://mathforum.org/library/drmath/view/69151.html) from mathforum.org:\n", + "\n", + "> An urn contains 23 balls: 8 white, 6 blue, and 9 red. We select six balls at random (each possible selection is equally likely). What is the probability of each of these possible outcomes:\n", + "\n", + "> 1. all balls are red\n", + "2. 3 are blue, 2 are white, and 1 is red\n", + "3. exactly 4 balls are white\n", + "\n", + "So, an outcome is a set of 6 balls, and the sample space is the set of all possible 6 ball combinations. We'll solve each of the 3 parts using our `P` function, and also using basic arithmetic; that is, *counting*. Counting is a bit tricky because:\n", + "- We have multiple balls of the same color. \n", + "- An outcome is a *set* of balls, where order doesn't matter, not a *sequence*, where order matters.\n", + "\n", + "To account for the first issue, I'll have 8 different white balls labeled `'W1'` through `'W8'`, rather than having eight balls all labeled `'W'`. That makes it clear that selecting `'W1'` is different from selecting `'W2'`.\n", + "\n", + "The second issue is handled automatically by the `P` function, but if I want to do calculations by hand, I will sometimes first count the number of *permutations* of balls, then get the number of *combinations* by dividing the number of permutations by *c*!, where *c* is the number of balls in a combination. For example, if I want to choose 2 white balls from the 8 available, there are 8 ways to choose a first white ball and 7 ways to choose a second, and therefore 8 × 7 = 56 permutations of two white balls. But there are only 56 / 2 = 28 combinations, because `(W1, W2)` is the same combination as `(W2, W1)`.\n", + "\n", + "We'll start by defining the contents of the urn:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'B1',\n", + " 'B2',\n", + " 'B3',\n", + " 'B4',\n", + " 'B5',\n", + " 'B6',\n", + " 'R1',\n", + " 'R2',\n", + " 'R3',\n", + " 'R4',\n", + " 'R5',\n", + " 'R6',\n", + " 'R7',\n", + " 'R8',\n", + " 'R9',\n", + " 'W1',\n", + " 'W2',\n", + " 'W3',\n", + " 'W4',\n", + " 'W5',\n", + " 'W6',\n", + " 'W7',\n", + " 'W8'}" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def cross(A, B):\n", + " \"The set of ways of concatenating one item from collection A with one from B.\"\n", + " return {a + b \n", + " for a in A for b in B}\n", + "\n", + "urn = cross('W', '12345678') | cross('B', '123456') | cross('R', '123456789') \n", + "\n", + "urn" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "23" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(urn)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can define the sample space, `U6`, as the set of all 6-ball combinations. We use `itertools.combinations` to generate the combinations, and then join each combination into a string:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "100947" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import itertools\n", + "\n", + "def combos(items, n):\n", + " \"All combinations of n items; each combo as a concatenated str.\"\n", + " return {' '.join(combo) \n", + " for combo in itertools.combinations(items, n)}\n", + "\n", + "U6 = combos(urn, 6)\n", + "\n", + "len(U6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I don't want to print all 100,947 members of the sample space; let's just peek at a random sample of them:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['B5 R2 W8 B1 R9 W5',\n", + " 'B5 W2 B6 W8 R5 B3',\n", + " 'B4 R8 B6 B1 R7 W5',\n", + " 'B5 B2 W7 R2 R4 W6',\n", + " 'B2 B4 B6 W8 R6 R5',\n", + " 'R2 R4 R9 W4 B3 W5',\n", + " 'R1 R6 R5 R9 R7 W5',\n", + " 'B5 R8 W7 B6 B3 W5',\n", + " 'B2 R8 W7 R5 W4 B3',\n", + " 'R1 W2 R3 W1 R7 W5']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import random\n", + "\n", + "random.sample(U6, 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Is 100,947 really the right number of ways of choosing 6 out of 23 items, or \"23 choose 6\", as mathematicians [call it](https://en.wikipedia.org/wiki/Combination)? Well, we can choose any of 23 for the first item, any of 22 for the second, and so on down to 18 for the sixth. But we don't care about the ordering of the six items, so we divide the product by 6! (the number of permutations of 6 things) giving us:\n", + "\n", + "$$23 ~\\mbox{choose}~ 6 = \\frac{23 \\cdot 22 \\cdot 21 \\cdot 20 \\cdot 19 \\cdot 18}{6!} = 100947$$\n", + "\n", + "Note that $23 \\cdot 22 \\cdot 21 \\cdot 20 \\cdot 19 \\cdot 18 = 23! \\;/\\; 17!$, so, generalizing, we can write:\n", + "\n", + "$$n ~\\mbox{choose}~ c = \\frac{n!}{(n - c)! \\cdot c!}$$\n", + "\n", + "And we can translate that to code and verify that 23 choose 6 is 100,947:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from math import factorial\n", + "\n", + "def choose(n, c):\n", + " \"Number of ways to choose c items from a list of n items.\"\n", + " return factorial(n) // (factorial(n - c) * factorial(c))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "100947" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "choose(23, 6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we're ready to answer the 4 problems: \n", + "\n", + "### Urn Problem 1: what's the probability of selecting 6 red balls? " + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(4, 4807)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "red6 = {s for s in U6 if s.count('R') == 6}\n", + "\n", + "P(red6, U6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's investigate a bit more. How many ways of getting 6 red balls are there?" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "84" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(red6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Why are there 84 ways? Because there are 9 red balls in the urn, and we are asking how many ways we can choose 6 of them:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "84" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "choose(9, 6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "So the probability of 6 red balls is then just 9 choose 6 divided by the size of the sample space:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(red6, U6) == Fraction(choose(9, 6), \n", + " len(U6))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### Urn Problem 2: what is the probability of 3 blue, 2 white, and 1 red?" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(240, 4807)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b3w2r1 = {s for s in U6 if\n", + " s.count('B') == 3 and s.count('W') == 2 and s.count('R') == 1}\n", + "\n", + "P(b3w2r1, U6)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can get the same answer by counting how many ways we can choose 3 out of 6 blues, 2 out of 8 whites, and 1 out of 9 reds, and dividing by the number of possible selections:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(b3w2r1, U6) == Fraction(choose(6, 3) * choose(8, 2) * choose(9, 1), \n", + " len(U6))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here we don't need to divide by any factorials, because `choose` has already accounted for that. \n", + "\n", + "We can get the same answer by figuring: \"there are 6 ways to pick the first blue, 5 ways to pick the second blue, and 4 ways to pick the third; then 8 ways to pick the first white and 7 to pick the second; then 9 ways to pick a red. But the order `'B1, B2, B3'` should count as the same as `'B2, B3, B1'` and all the other orderings; so divide by 3! to account for the permutations of blues, by 2! to account for the permutations of whites, and by 100947 to get a probability:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " P(b3w2r1, U6) == Fraction((6 * 5 * 4) * (8 * 7) * 9, \n", + " factorial(3) * factorial(2) * len(U6))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### Urn Problem 3: What is the probability of exactly 4 white balls?\n", + "\n", + "We can interpret this as choosing 4 out of the 8 white balls, and 2 out of the 15 non-white balls. Then we can solve it the same three ways:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(350, 4807)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "w4 = {s for s in U6 if\n", + " s.count('W') == 4}\n", + "\n", + "P(w4, U6)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(w4, U6) == Fraction(choose(8, 4) * choose(15, 2),\n", + " len(U6))" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(w4, U6) == Fraction((8 * 7 * 6 * 5) * (15 * 14),\n", + " factorial(4) * factorial(2) * len(U6))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Revised Version of `P`, with more general events\n", + "\n", + "To calculate the probability of an even die roll, I originally said\n", + "\n", + " even = {2, 4, 6}\n", + " \n", + "But that's inelegant—I had to explicitly enumerate all the even numbers from one to six. If I ever wanted to deal with a twelve or twenty-sided die, I would have to go back and change `even`. I would prefer to define `even` once and for all like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def even(n): return n % 2 == 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now in order to make `P(even, D)` work, I'll have to modify `P` to accept an event as either\n", + "a *set* of outcomes (as before), or a *predicate* over outcomes—a function that returns true for an outcome that is in the event:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def P(event, space): \n", + " \"\"\"The probability of an event, given a sample space of equiprobable outcomes.\n", + " event can be either a set of outcomes, or a predicate (true for outcomes in the event).\"\"\"\n", + " if is_predicate(event):\n", + " event = such_that(event, space)\n", + " return Fraction(len(event & space), len(space))\n", + "\n", + "is_predicate = callable\n", + "\n", + "def such_that(predicate, collection): \n", + " \"The subset of elements in the collection for which the predicate is true.\"\n", + " return {e for e in collection if predicate(e)}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here we see how `such_that`, the new `even` predicate, and the new `P` work:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2, 4, 6}" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "such_that(even, D)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(even, D)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2, 4, 6, 8, 10, 12}" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D12 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}\n", + "\n", + "such_that(even, D12)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(even, D12)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Note: `such_that` is just like the built-in function `filter`, except `such_that` returns a set.\n", + "\n", + "We can now define more interesting events using predicates; for example we can determine the probability that the sum of a three-dice roll is prime (using a definition of `is_prime` that is efficient enough for small `n`):" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(73, 216)" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "D3 = {(d1, d2, d3) for d1 in D for d2 in D for d3 in D}\n", + "\n", + "def prime_sum(outcome): return is_prime(sum(outcome))\n", + "\n", + "def is_prime(n): return n > 1 and not any(n % i == 0 for i in range(2, n))\n", + "\n", + "P(prime_sum, D3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Card Problems\n", + "\n", + "Consider dealing a hand of five playing cards. We can define `deck` as a set of 52 cards, and `Hands` as the sample space of all combinations of 5 cards:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "52" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "suits = 'SHDC'\n", + "ranks = 'A23456789TJQK'\n", + "deck = cross(ranks, suits)\n", + "len(deck)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['4H 7D QS 4D 9D',\n", + " 'QC 2D TS 9S 3D',\n", + " 'QC 3S KC 4C JC',\n", + " '9H 7C TS 7H JH',\n", + " 'QC JD AS JH 8H']" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Hands = combos(deck, 5)\n", + "\n", + "assert len(Hands) == choose(52, 5)\n", + "\n", + "random.sample(Hands, 5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can answer questions like the probability of being dealt a flush (5 cards of the same suit):" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(33, 16660)" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def flush(hand):\n", + " return any(hand.count(suit) == 5 for suit in suits)\n", + "\n", + "P(flush, Hands)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Or the probability of four of a kind:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 4165)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def four_kind(hand):\n", + " return any(hand.count(rank) == 4 for rank in ranks)\n", + "\n", + "P(four_kind, Hands)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Fermat and Pascal: Gambling, Triangles, and the Birth of Probability\n", + "\n", + "\n", + "
Pierre de Fermat
1654\n", + "
Blaise Pascal]
1654\n", + "
\n", + "\n", + "Consider a gambling game consisting of tossing a coin. Player H wins the game if 10 heads come up, and T wins if 10 tails come up. If the game is interrupted when H has 8 heads and T has 7 tails, how should the pot of money (which happens to be 100 Francs) be split?\n", + "In 1654, Blaise Pascal and Pierre de Fermat corresponded on this problem, with Fermat [writing](http://mathforum.org/isaac/problems/prob1.html):\n", + "\n", + ">Dearest Blaise,\n", + "\n", + ">As to the problem of how to divide the 100 Francs, I think I have found a solution that you will find to be fair. Seeing as I needed only two points to win the game, and you needed 3, I think we can establish that after four more tosses of the coin, the game would have been over. For, in those four tosses, if you did not get the necessary 3 points for your victory, this would imply that I had in fact gained the necessary 2 points for my victory. In a similar manner, if I had not achieved the necessary 2 points for my victory, this would imply that you had in fact achieved at least 3 points and had therefore won the game. Thus, I believe the following list of possible endings to the game is exhaustive. I have denoted 'heads' by an 'h', and tails by a 't.' I have starred the outcomes that indicate a win for myself.\n", + "\n", + " h h h h * h h h t * h h t h * h h t t *\n", + " h t h h * h t h t * h t t h * h t t t\n", + " t h h h * t h h t * t h t h * t h t t\n", + " t t h h * t t h t t t t h t t t t\n", + "\n", + ">I think you will agree that all of these outcomes are equally likely. Thus I believe that we should divide the stakes by the ration 11:5 in my favor, that is, I should receive (11/16)*100 = 68.75 Francs, while you should receive 31.25 Francs.\n", + "\n", + ">I hope all is well in Paris,\n", + "\n", + ">Your friend and colleague,\n", + "\n", + ">Pierre\n", + "\n", + "Pascal agreed with this solution, and [replied](http://mathforum.org/isaac/problems/prob2.html) with a generalization that made use of his previous invention, Pascal's Triangle. There's even [a book](https://smile.amazon.com/Unfinished-Game-Pascal-Fermat-Seventeenth-Century/dp/0465018963?sa-no-redirect=1) about it.\n", + "\n", + "We can solve the problem with the tools we have:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def win_unfinished_game(Hneeds, Tneeds):\n", + " \"The probability that H will win the unfinished game, given the number of points needed by H and T to win.\"\n", + " def Hwins(outcome): return outcome.count('h') >= Hneeds\n", + " return P(Hwins, continuations(Hneeds, Tneeds))\n", + "\n", + "def continuations(Hneeds, Tneeds):\n", + " \"All continuations of a game where H needs `Hneeds` points to win and T needs `Tneeds`.\"\n", + " rounds = ['ht' for _ in range(Hneeds + Tneeds - 1)]\n", + " return set(itertools.product(*rounds))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{('h', 'h', 'h', 'h'),\n", + " ('h', 'h', 'h', 't'),\n", + " ('h', 'h', 't', 'h'),\n", + " ('h', 'h', 't', 't'),\n", + " ('h', 't', 'h', 'h'),\n", + " ('h', 't', 'h', 't'),\n", + " ('h', 't', 't', 'h'),\n", + " ('h', 't', 't', 't'),\n", + " ('t', 'h', 'h', 'h'),\n", + " ('t', 'h', 'h', 't'),\n", + " ('t', 'h', 't', 'h'),\n", + " ('t', 'h', 't', 't'),\n", + " ('t', 't', 'h', 'h'),\n", + " ('t', 't', 'h', 't'),\n", + " ('t', 't', 't', 'h'),\n", + " ('t', 't', 't', 't')}" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "continuations(2, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(11, 16)" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "win_unfinished_game(2, 3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our answer agrees with Pascal and Fermat; we're in good company!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Non-Equiprobable Outcomes: Probability Distributions\n", + "\n", + "So far, we have made the assumption that every outcome in a sample space is equally likely. In real life, we often get outcomes that are not equiprobable. For example, the probability of a child being a girl is not exactly 1/2, and the probability is slightly different for a second child. An [article](http://people.kzoo.edu/barth/math105/moreboys.pdf) gives the following counts for two-child families in Denmark, where `GB` means a family where the first child is a girl and the second a boy:\n", + "\n", + " GG: 121801 GB: 126840\n", + " BG: 127123 BB: 135138\n", + " \n", + "We will introduce three more definitions:\n", + "\n", + "* [Frequency](https://en.wikipedia.org/wiki/Frequency_%28statistics%29): a number describing how often an outcome occurs. Can be a count like 121801, or a ratio like 0.515.\n", + "\n", + "* [Distribution](http://mathworld.wolfram.com/StatisticalDistribution.html): A mapping from outcome to frequency for each outcome in a sample space. \n", + "\n", + "* [Probability Distribution](https://en.wikipedia.org/wiki/Probability_distribution): A distribution that has been *normalized* so that the sum of the frequencies is 1.\n", + "\n", + "We define `ProbDist` to take the same kinds of arguments that `dict` does: either a mapping or an iterable of `(key, val)` pairs, and/or optional keyword arguments. " + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "class ProbDist(dict):\n", + " \"A Probability Distribution; an {outcome: probability} mapping.\"\n", + " def __init__(self, mapping=(), **kwargs):\n", + " self.update(mapping, **kwargs)\n", + " # Make probabilities sum to 1.0; assert no negative probabilities\n", + " total = sum(self.values())\n", + " for outcome in self:\n", + " self[outcome] = self[outcome] / total\n", + " assert self[outcome] >= 0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We also need to modify the functions `P` and `such_that` to accept either a sample space or a probability distribution as the second argument." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def P(event, space): \n", + " \"\"\"The probability of an event, given a sample space of equiprobable outcomes. \n", + " event: a collection of outcomes, or a predicate that is true of outcomes in the event. \n", + " space: a set of outcomes or a probability distribution of {outcome: frequency} pairs.\"\"\"\n", + " if is_predicate(event):\n", + " event = such_that(event, space)\n", + " if isinstance(space, ProbDist):\n", + " return sum(space[o] for o in space if o in event)\n", + " else:\n", + " return Fraction(len(event & space), len(space))\n", + " \n", + "def such_that(predicate, space): \n", + " \"\"\"The outcomes in the sample pace for which the predicate is true.\n", + " If space is a set, return a subset {outcome,...};\n", + " if space is a ProbDist, return a ProbDist {outcome: frequency,...};\n", + " in both cases only with outcomes where predicate(element) is true.\"\"\"\n", + " if isinstance(space, ProbDist):\n", + " return ProbDist({o:space[o] for o in space if predicate(o)})\n", + " else:\n", + " return {o for o in space if predicate(o)}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here is the probability distribution for Danish two-child families:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BB': 0.2645086533229465,\n", + " 'BG': 0.24882071317004043,\n", + " 'GB': 0.24826679089140383,\n", + " 'GG': 0.23840384261560926}" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DK = ProbDist(GG=121801, GB=126840,\n", + " BG=127123, BB=135138)\n", + "DK" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And here are some predicates that will allow us to answer some questions:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def first_girl(outcome): return outcome[0] == 'G'\n", + "def first_boy(outcome): return outcome[0] == 'B'\n", + "def second_girl(outcome): return outcome[1] == 'G'\n", + "def second_boy(outcome): return outcome[1] == 'B'\n", + "def two_girls(outcome): return outcome == 'GG'" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.4866706335070131" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(first_girl, DK)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.4872245557856497" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(second_girl, DK)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The above says that the probability of a girl is somewhere between 48% and 49%, but that it is slightly different between the first or second child." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.4898669165584115, 0.48471942072973107)" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(second_girl, such_that(first_girl, DK)), P(second_girl, such_that(first_boy, DK))" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.5101330834415885, 0.5152805792702689)" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(second_boy, such_that(first_girl, DK)), P(second_boy, such_that(first_boy, DK))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The above says that the sex of the second child is more likely to be the same as the first child, by about 1/2 a percentage point." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# More Urn Problems: M&Ms and Bayes\n", + "\n", + "Here's another urn problem (or \"bag\" problem) [from](http://allendowney.blogspot.com/2011/10/my-favorite-bayess-theorem-problems.html) prolific Python/Probability author [Allen Downey ](http://allendowney.blogspot.com/):\n", + "\n", + "> The blue M&M was introduced in 1995. Before then, the color mix in a bag of plain M&Ms was (30% Brown, 20% Yellow, 20% Red, 10% Green, 10% Orange, 10% Tan). Afterward it was (24% Blue , 20% Green, 16% Orange, 14% Yellow, 13% Red, 13% Brown). \n", + "A friend of mine has two bags of M&Ms, and he tells me that one is from 1994 and one from 1996. He won't tell me which is which, but he gives me one M&M from each bag. One is yellow and one is green. What is the probability that the yellow M&M came from the 1994 bag?\n", + "\n", + "To solve this problem, we'll first represent probability distributions for each bag: `bag94` and `bag96`:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "bag94 = ProbDist(brown=30, yellow=20, red=20, green=10, orange=10, tan=10)\n", + "bag96 = ProbDist(blue=24, green=20, orange=16, yellow=14, red=13, brown=13)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Next, define `MM` as the joint distribution—the sample space for picking one M&M from each bag. The outcome `'yellow green'` means that a yellow M&M was selected from the 1994 bag and a green one from the 1996 bag." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'brown blue': 0.07199999999999998,\n", + " 'brown brown': 0.03899999999999999,\n", + " 'brown green': 0.059999999999999984,\n", + " 'brown orange': 0.04799999999999999,\n", + " 'brown red': 0.03899999999999999,\n", + " 'brown yellow': 0.041999999999999996,\n", + " 'green blue': 0.023999999999999994,\n", + " 'green brown': 0.012999999999999998,\n", + " 'green green': 0.02,\n", + " 'green orange': 0.015999999999999997,\n", + " 'green red': 0.012999999999999998,\n", + " 'green yellow': 0.013999999999999999,\n", + " 'orange blue': 0.023999999999999994,\n", + " 'orange brown': 0.012999999999999998,\n", + " 'orange green': 0.02,\n", + " 'orange orange': 0.015999999999999997,\n", + " 'orange red': 0.012999999999999998,\n", + " 'orange yellow': 0.013999999999999999,\n", + " 'red blue': 0.04799999999999999,\n", + " 'red brown': 0.025999999999999995,\n", + " 'red green': 0.04,\n", + " 'red orange': 0.031999999999999994,\n", + " 'red red': 0.025999999999999995,\n", + " 'red yellow': 0.027999999999999997,\n", + " 'tan blue': 0.023999999999999994,\n", + " 'tan brown': 0.012999999999999998,\n", + " 'tan green': 0.02,\n", + " 'tan orange': 0.015999999999999997,\n", + " 'tan red': 0.012999999999999998,\n", + " 'tan yellow': 0.013999999999999999,\n", + " 'yellow blue': 0.04799999999999999,\n", + " 'yellow brown': 0.025999999999999995,\n", + " 'yellow green': 0.04,\n", + " 'yellow orange': 0.031999999999999994,\n", + " 'yellow red': 0.025999999999999995,\n", + " 'yellow yellow': 0.027999999999999997}" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def joint(A, B, sep=''):\n", + " \"\"\"The joint distribution of two independent probability distributions. \n", + " Result is all entries of the form {a+sep+b: P(a)*P(b)}\"\"\"\n", + " return ProbDist({a + sep + b: A[a] * B[b]\n", + " for a in A\n", + " for b in B})\n", + "\n", + "MM = joint(bag94, bag96, ' ')\n", + "MM" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "First we'll look at the \"One is yellow and one is green\" part:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'green yellow': 0.25925925925925924, 'yellow green': 0.7407407407407408}" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def yellow_and_green(outcome): return 'yellow' in outcome and 'green' in outcome\n", + "\n", + "such_that(yellow_and_green, MM)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can answer the question: given that we got a yellow and a green (but don't know which comes from which bag), what is the probability that the yellow came from the 1994 bag?" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.7407407407407408" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def yellow94(outcome): return outcome.startswith('yellow')\n", + "\n", + "P(yellow94, such_that(yellow_and_green, MM))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "So there is a 74% chance that the yellow comes from the 1994 bag.\n", + "\n", + "Answering this question was straightforward: just like all the other probability problems, we simply create a sample space, and use `P` to pick out the probability of the event in question, given what we know about the outcome.\n", + "But in a sense it is curious that we were able to solve this problem with the same methodology as the others: this problem comes from a section titled **My favorite Bayes's Theorem Problems**, so one would expect that we'd need to invoke Bayes Theorem to solve it. The computation above shows that that is not necessary. \n", + "\n", + "![Bayes](http://img1.ph.126.net/xKZAzeOv_mI8a4Lwq7PHmw==/2547911489202312541.jpg)\n", + "
Rev. Thomas Bayes
1701-1761\n", + "
\n", + "\n", + "Of course, we *could* solve it using Bayes Theorem. Why is Bayes Theorem recommended? Because we are asked about the probability of an event given the evidence, which is not immediately available; however the probability of the evidence given the event is. \n", + "\n", + "Before we see the colors of the M&Ms, there are two hypotheses, `A` and `B`, both with equal probability:\n", + "\n", + " A: first M&M from 94 bag, second from 96 bag\n", + " B: first M&M from 96 bag, second from 94 bag\n", + " P(A) = P(B) = 0.5\n", + " \n", + "Then we get some evidence:\n", + " \n", + " E: first M&M yellow, second green\n", + " \n", + "We want to know the probability of hypothesis `A`, given the evidence:\n", + " \n", + " P(A | E)\n", + " \n", + "That's not easy to calculate (except by enumerating the sample space). But Bayes Theorem says:\n", + " \n", + " P(A | E) = P(E | A) * P(A) / P(E)\n", + " \n", + "The quantities on the right-hand-side are easier to calculate:\n", + " \n", + " P(E | A) = 0.20 * 0.20 = 0.04\n", + " P(E | B) = 0.10 * 0.14 = 0.014\n", + " P(A) = 0.5\n", + " P(B) = 0.5\n", + " P(E) = P(E | A) * P(A) + P(E | B) * P(B) \n", + " = 0.04 * 0.5 + 0.014 * 0.5 = 0.027\n", + " \n", + "And we can get a final answer:\n", + " \n", + " P(A | E) = P(E | A) * P(A) / P(E) \n", + " = 0.04 * 0.5 / 0.027 \n", + " = 0.7407407407\n", + " \n", + "You have a choice: Bayes Theorem allows you to do less calculation at the cost of more algebra; that is a great trade-off if you are working with pencil and paper. Enumerating the state space allows you to do less algebra at the cost of more calculation; often a good trade-off if you have a computer. But regardless of the approach you use, it is important to understand Bayes theorem and how it works.\n", + "\n", + "There is one important question that Allen Downey does not address: *would you eat twenty-year-old M&Ms*?\n", + "😨" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Newton's Answer to a Problem by Pepys\n", + "\n", + "\n", + "
Isaac Newton
1693
\n", + "
Samuel Pepys
1693
\n", + "
\n", + "\n", + "[This paper](http://fermatslibrary.com/s/isaac-newton-as-a-probabilist) explains how Samuel Pepys wrote to Isaac Newton in 1693 to pose the problem:\n", + "\n", + "> Which of the following three propositions has the greatest chance of success? \n", + " 1. Six fair dice are tossed independently and at least one “6” appears. \n", + " 2. Twelve fair dice are tossed independently and at least two “6”s appear. \n", + " 3. Eighteen fair dice are tossed independently and at least three “6”s appear.\n", + " \n", + "Newton was able to answer the question correctly (although his reasoning was not quite right); let's see how we can do. Since we're only interested in whether a die comes up as \"6\" or not, we can define a single die and the joint distribution over *n* dice as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "die = ProbDist({'6':1/6, '-':5/6})\n", + "\n", + "def dice(n, die):\n", + " \"Joint probability from tossing n dice.\"\n", + " if n == 1:\n", + " return die\n", + " else:\n", + " return joint(die, dice(n - 1, die))" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'---': 0.5787037037037037,\n", + " '--6': 0.11574074074074073,\n", + " '-6-': 0.11574074074074073,\n", + " '-66': 0.023148148148148143,\n", + " '6--': 0.11574074074074073,\n", + " '6-6': 0.023148148148148143,\n", + " '66-': 0.023148148148148143,\n", + " '666': 0.0046296296296296285}" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dice(3, die)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we are ready to determine which proposition is more likely to have the required number of sixes:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def at_least(k, result): return lambda s: s.count(result) >= k" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6651020233196158" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(at_least(1, '6'), dice(6, die))" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6186673737322984" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(at_least(2, '6'), dice(12, die))" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5973456859478073" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(at_least(3, '6'), dice(18, die))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We reach the same conclusion Newton did, that the best chance is rolling six dice." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "
\n", + "\n", + "# Simulation\n", + "\n", + "Sometimes it is inconvenient to explicitly define a sample space. Perhaps the sample space is infinite, or perhaps it is just very large and complicated, and we feel more confident in writing a program to *simulate* one pass through all the complications, rather than try to *enumerate* the complete sample space. *Random sampling* from the simulation\n", + "can give an accurate estimate of the probability.\n", + "\n", + "# Simulating Monopoly\n", + "\n", + "![](http://buckwolf.org/a.abcnews.com/images/Entertainment/ho_hop_go_050111_t.jpg)
[Mr. Monopoly](https://en.wikipedia.org/wiki/Rich_Uncle_Pennybags)
1940—\n", + "\n", + "Consider [problem 84](https://projecteuler.net/problem=84) from the excellent [Project Euler](https://projecteuler.net), which asks for the probability that a player in the game Monopoly ends a roll on each of the squares on the board. To answer this we need to take into account die rolls, chance and community chest cards, and going to jail (from the \"go to jail\" space, from a card, or from rolling doubles three times in a row). We do not need to take into account anything about buying or selling properties or exchanging money or winning or losing the game, because these don't change a player's location. We will assume that a player in jail will always pay to get out of jail immediately. \n", + "\n", + "A game of Monopoly can go on forever, so the sample space is infinite. But even if we limit the sample space to say, 1000 rolls, there are $21^{1000}$ such sequences of rolls (and even more possibilities when we consider drawing cards). So it is infeasible to explicitly represent the sample space.\n", + "\n", + "But it is fairly straightforward to implement a simulation and run it for, say, 400,000 rolls (so the average square will be landed on 10,000 times). Here is the code for a simulation:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from collections import deque\n", + "import random\n", + "\n", + "# The board: as specified by https://projecteuler.net/problem=84\n", + "(GO, A1, CC1, A2, T1, R1, B1, CH1, B2, B3,\n", + " JAIL, C1, U1, C2, C3, R2, D1, CC2, D2, D3, \n", + " FP, E1, CH2, E2, E3, R3, F1, F2, U2, F3, \n", + " G2J, G1, G2, CC3, G3, R4, CH3, H1, T2, H2) = board = range(40)\n", + "\n", + "Deck = deque\n", + "\n", + "CC_deck = Deck([GO, JAIL] + 14 * [None])\n", + "CH_deck = Deck([GO, JAIL, C1, E3, H2, R1, {R1, R2, R3, R4}, {R1, R2, R3, R4}, {U1, U2}, -3] + 6 * [None])\n", + "\n", + "def monopoly(steps):\n", + " \"\"\"Simulate given number of steps of a Monopoly game, \n", + " and return the counts of how often each square is visited.\"\"\"\n", + " counts = [0] * len(board)\n", + " doubles = 0\n", + " random.shuffle(CC_deck)\n", + " random.shuffle(CH_deck)\n", + " goto(GO)\n", + " for _ in range(steps):\n", + " d1, d2 = random.randint(1, 6), random.randint(1, 6)\n", + " doubles = (doubles + 1 if d1 == d2 else 0)\n", + " goto(here + d1 + d2)\n", + " if here == G2J or doubles == 3:\n", + " goto(JAIL)\n", + " doubles = 0\n", + " elif here in (CC1, CC2, CC3):\n", + " do_card(CC_deck)\n", + " elif here in (CH1, CH2, CH3):\n", + " do_card(CH_deck)\n", + " counts[here] += 1\n", + " return counts\n", + "\n", + "def goto(square):\n", + " \"Update 'here' to be this square (and handle passing GO).\"\n", + " global here\n", + " here = square % len(board) \n", + "\n", + "def do_card(deck):\n", + " \"Take the top card from deck and do what it says.\"\n", + " card = deck[0] # The top card\n", + " deck.rotate(-1) # Move top card to bottom of deck\n", + " if card == None: # Don't move\n", + " pass\n", + " elif card == -3: # Go back 3 spaces\n", + " goto(here - 3)\n", + " elif isinstance(card, set): # Advance to next railroad or utility\n", + " goto(min({place for place in card if place > here} or card))\n", + " else: # Go to destination named on card\n", + " goto(card)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And the results:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "counts = monopoly(400000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I'll show a histogram of the squares, with a dotted red line at the average:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n/j+i2P3L3vNP/QAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline \n", + "import matplotlib.pyplot as plt\n", + "\n", + "plt.hist(list(range(40)), bins=40, weights=counts, normed=True)\n", + "plt.plot([0, 39], [1/40, 1/40], 'r--');" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "There is one square far above average: `JAIL`, at a little over 6%. There are four squares far below average: the three chance squares, `CH1`, `CH2`, and `CH3`, at around 1% (because 10 of the 16 chance cards send the player away from the square), and the \"Go to Jail\" square, square number 30 on the plot, which has a frequency of 0 because you can't end a turn there. The other squares are around 2% to 3% each, which you would expect, because 100% / 40 = 2.5%." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Central Limit Theorem / Strength in Numbers Theorem\n", + "\n", + "So far, we have talked of an *outcome* as being a single state of the world. But it can be useful to break that state of the world down into components. We call these components **random variables**. For example, when we consider an experiment in which we roll two dice and observe their sum, we could model the situation with two random variables, one for each die. (Our representation of outcomes has been doing that implicitly all along, when we concatenate two parts of a string, but the concept of a random variable makes it official.)\n", + "\n", + "The **Central Limit Theorem** states that if you have a collection of random variables and sum them up, then the larger the collection, the closer the sum will be to a *normal distribution* (also called a *Gaussian distribution* or a *bell-shaped curve*). The theorem applies in all but a few pathological cases. \n", + "\n", + "As an example, let's take 5 random variables reprsenting the per-game scores of 5 basketball players, and then sum them together to form the team score. Each random variable/player is represented as a function; calling the function returns a single sample from the distribution:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from random import gauss, triangular, choice, vonmisesvariate, uniform\n", + "\n", + "def SC(): return posint(gauss(15.1, 3) + 3 * triangular(1, 4, 13)) # 30.1\n", + "def KT(): return posint(uniform(5.2, 15.2) + 3 * triangular(1, 3.5, 9)) # 22.1\n", + "def DG(): return posint(vonmisesvariate(30, 2) * 3.08) # 14.0\n", + "def HB(): return posint(gauss(6.7, 1.5) if choice((True, False)) else gauss(16.7, 2.5)) # 11.7\n", + "def OT(): return posint(triangular(0, 12, 20) + uniform(0, 40) + gauss(6, 3)) # 37.0\n", + "\n", + "def posint(x): \"Positive integer\"; return max(0, int(round(x)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here is a function to sample a random variable *k* times, show a histogram of the results, and return the mean:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from statistics import mean\n", + "\n", + "def repeated_hist(rv, bins=10, k=200000):\n", + " \"Repeat rv() k times and make a histogram of the results.\"\n", + " samples = [rv() for _ in range(k)]\n", + " plt.hist(samples, bins=bins)\n", + " return mean(samples)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The two top-scoring players have scoring distributions that are slightly skewed from normal:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "30.12574" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nSS2GgySp5f8DHUe3a7aRZB8AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "repeated_hist(SC, bins=range(60))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "22.16258" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "repeated_hist(KT, bins=range(60))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The next two players have bi-modal distributions; some games they score a lot, some games not:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "14.005885" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "repeated_hist(DG, bins=range(60))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "11.702395" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "repeated_hist(HB, bins=range(60))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The fifth \"player\" (actually the sum of all the other players on the team) looks like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "36.338295" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nP+13wyYAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "repeated_hist(OT, bins=range(0, 70, 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we define the team score to be the sum of the five players, and look at the distribution:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "114.30268" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def GSW(): return SC() + KT() + DG() + HB() + OT()\n", + "\n", + "repeated_hist(GSW, bins=range(70, 160, 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sure enough, this looks very much like a normal distribution. The Central Limit Theorem appears to hold in this case. But I have to say \"Central Limit\" is not a very evocative name, so I propose we re-name this as the **Strength in Numbers Theorem**, to indicate the fact that if you have a lot of numbers, you tend to get the expected result." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Conclusion\n", + "\n", + "We've had an interesting tour and met some giants of the field: Laplace, Bernoulli, Fermat, Pascal, Bayes, Newton, ... even Mr. Monopoly and The Count.\n", + "\n", + "![The Count](http://img2.oncoloring.com/count-dracula-number-thir_518b77b54ba6c-p.gif)\n", + "
The Count
1972—
\n", + "\n", + "The conclusion is: be explicit about what the problem says, and then methodical about defining the sample space, and finally be careful in counting the number of outcomes in the numerator and denominator. Easy as 1-2-3. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "\n", + "# Appendix: Continuous Sample Spaces\n", + "\n", + "Everything up to here has been about discrete, finite sample spaces, where we can *enumerate* all the possible outcomes. \n", + "\n", + "But I was asked about *continuous* sample spaces, such as the space of real numbers. The principles are the same: probability is still the ratio of the favorable cases to all the cases, but now instead of *counting* cases, we have to (in general) compute integrals to compare the sizes of cases. \n", + "Here we will cover a simple example, which we first solve approximately by simulation, and then exactly by calculation.\n", + "\n", + "## The Hot New Game Show Problem: Simulation\n", + "\n", + "Oliver Roeder posed [this problem](http://fivethirtyeight.com/features/can-you-win-this-hot-new-game-show/) in the 538 *Riddler* blog:\n", + "\n", + ">Two players go on a hot new game show called *Higher Number Wins.* The two go into separate booths, and each presses a button, and a random number between zero and one appears on a screen. (At this point, neither knows the other’s number, but they do know the numbers are chosen from a standard uniform distribution.) They can choose to keep that first number, or to press the button again to discard the first number and get a second random number, which they must keep. Then, they come out of their booths and see the final number for each player on the wall. The lavish grand prize — a case full of gold bullion — is awarded to the player who kept the higher number. Which number is the optimal cutoff for players to discard their first number and choose another? Put another way, within which range should they choose to keep the first number, and within which range should they reject it and try their luck with a second number?\n", + "\n", + "We'll use this notation:\n", + "- **A**, **B**: the two players.\n", + "- *A*, *B*: the cutoff values they choose: the lower bound of the range of first numbers they will accept.\n", + "- *a*, *b*: the actual random numbers that appear on the screen.\n", + "\n", + "For example, if player **A** chooses a cutoff of *A* = 0.6, that means that **A** would accept any first number greater than 0.6, and reject any number below that cutoff. The question is: What cutoff, *A*, should player **A** choose to maximize the chance of winning, that is, maximize P(*a* > *b*)?\n", + "\n", + "First, simulate the number that a player with a given cutoff gets (note that `random.random()` returns a float sampled uniformly from the interval [0..1]):" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def number(cutoff):\n", + " \"Play the game with given cutoff, returning the first or second random number.\"\n", + " first = random.random()\n", + " return first if first > cutoff else random.random()" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6118974990212028" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number(.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now compare the numbers returned with a cutoff of *A* versus a cutoff of *B*, and repeat for a large number of trials; this gives us an estimate of the probability that cutoff *A* is better than cutoff *B*:" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Pwin(A, B, trials=30000):\n", + " \"The probability that cutoff A wins against cutoff B.\"\n", + " Awins = sum(number(A) > number(B) \n", + " for _ in range(trials))\n", + " return Awins / trials" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5018" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Pwin(.5, .6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now define a function, `top`, that considers a collection of possible cutoffs, estimate the probability for each cutoff playing against each other cutoff, and returns a list with the `N` top cutoffs (the ones that defeated the most number of opponent cutoffs), and the number of opponents they defeat: " + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from collections import Counter\n", + "\n", + "def top(N, cutoffs):\n", + " \"Return the N best cutoffs and the number of opponent cutoffs they beat.\"\n", + " winners = Counter(A if Pwin(A, B) > 0.5 else B\n", + " for (A, B) in itertools.combinations(cutoffs, 2))\n", + " return winners.most_common(N)" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 19.8 s, sys: 72.1 ms, total: 19.9 s\n", + "Wall time: 20 s\n" + ] + }, + { + "data": { + "text/plain": [ + "[(0.60000000000000009, 46),\n", + " (0.58000000000000007, 43),\n", + " (0.59000000000000008, 43),\n", + " (0.64000000000000012, 42),\n", + " (0.65000000000000013, 41)]" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from numpy import arange\n", + "\n", + "%time top(5, arange(0.50, 0.99, 0.01))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We get a good idea of the top cutoffs, but they are close to each other, so we can't quite be sure which is best, only that the best is somewhere around 0.60. We could get a better estimate by increasing the number of trials, but that would consume more time.\n", + "\n", + "## The Hot New Game Show Problem: Exact Calculation\n", + "\n", + "More promising is the possibility of making `Pwin(A, B)` an exact calculation. But before we get to `Pwin(A, B)`, let's solve a simpler problem: assume that both players **A** and **B** have chosen a cutoff, and have each received a number above the cutoff. What is the probability that **A** gets the higher number? We'll call this `Phigher(A, B)`. We can think of this as a two-dimensional sample space of points in the (*a*, *b*) plane, where *a* ranges from the cutoff *A* to 1 and *b* ranges from the cutoff B to 1. Here is a diagram of that two-dimensional sample space, with the cutoffs *A*=0.5 and *B*=0.6:\n", + "\n", + "\n", + "\n", + "The total area of the sample space is 0.5 × 0.4 = 0.20, and in general it is (1 - *A*) · (1 - *B*). What about the favorable cases, where **A** beats **B**? That corresponds to the shaded triangle below:\n", + "\n", + "\n", + "\n", + "The area of a triangle is 1/2 the base times the height, or in this case, 0.42 / 2 = 0.08, and in general, (1 - *B*)2 / 2. So in general we have:\n", + "\n", + " Phigher(A, B) = favorable / total\n", + " favorable = ((1 - B) ** 2) / 2 \n", + " total = (1 - A) * (1 - B)\n", + " Phigher(A, B) = (((1 - B) ** 2) / 2) / ((1 - A) * (1 - B))\n", + " Phigher(A, B) = (1 - B) / (2 * (1 - A))\n", + " \n", + "And in this specific case we have:\n", + "\n", + " A = 0.5; B = 0.6\n", + " favorable = 0.4 ** 2 / 2 = 0.08\n", + " total = 0.5 * 0.4 = 0.20\n", + " Phigher(0.5, 0.6) = 0.08 / 0.20 = 0.4\n", + "\n", + "But note that this only works when the cutoff *A* ≤ *B*; when *A* > *B*, we need to reverse things. That gives us the code:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Phigher(A, B):\n", + " \"Probability that a sample from [A..1] is higher than one from [B..1].\"\n", + " if A <= B:\n", + " return (1 - B) / (2 * (1 - A))\n", + " else:\n", + " return 1 - Phigher(B, A)" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.4" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Phigher(0.5, 0.6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We're now ready to tackle the full game. There are four cases to consider, depending on whether **A** and **B** gets a first number that is above or below their cutoff choices:\n", + "\n", + "| first *a* | first *b* | P(*a*, *b*) | P(A wins | *a*, *b*) | Comment |\n", + "|:-----:|:-----:| ----------- | ------------- | ------------ |\n", + "| *a* > *A* | *b* > *B* | (1 - *A*) · (1 - *B*) | Phigher(*A*, *B*) | Both above cutoff; both keep first numbers |\n", + "| *a* < *A* | *b* < *B* | *A* · *B* | Phigher(0, 0) | Both below cutoff, both get new numbers from [0..1] |\n", + "| *a* > *A* | *b* < *B* | (1 - *A*) · *B* | Phigher(*A*, 0) | **A** keeps number; **B** gets new number from [0..1] |\n", + "| *a* < *A* | *b* > *B* | *A* · (1 - *B*) | Phigher(0, *B*) | **A** gets new number from [0..1]; **B** keeps number |\n", + "\n", + "For example, the first row of this table says that the event of both first numbers being above their respective cutoffs has probability (1 - *A*) · (1 - *B*), and if this does occur, then the probability of **A** winning is Phigher(*A*, *B*).\n", + "We're ready to replace the old simulation-based `Pwin` with a new calculation-based version:" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def Pwin(A, B):\n", + " \"With what probability does cutoff A win against cutoff B?\"\n", + " return ((1-A) * (1-B) * Phigher(A, B) # both above cutoff\n", + " + A * B * Phigher(0, 0) # both below cutoff\n", + " + (1-A) * B * Phigher(A, 0) # A above, B below\n", + " + A * (1-B) * Phigher(0, B)) # A below, B above" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That was a lot of algebra. Let's define a few tests to check for obvious errors:" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ok'" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test():\n", + " assert Phigher(0.5, 0.5) == Phigher(0.7, 0.7) == Phigher(0, 0) == 0.5\n", + " assert Pwin(0.5, 0.5) == Pwin(0.7, 0.7) == 0.5\n", + " assert Phigher(.6, .5) == 0.6\n", + " assert Phigher(.5, .6) == 0.4\n", + " return 'ok'\n", + "\n", + "test()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's repeat the calculation with our new, exact `Pwin`:" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0.62000000000000011, 48),\n", + " (0.6100000000000001, 47),\n", + " (0.60000000000000009, 46),\n", + " (0.59000000000000008, 45),\n", + " (0.63000000000000012, 44)]" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "top(5, arange(0.50, 0.99, 0.01))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is good to see that the simulation and the exact calculation are in rough agreement; that gives me more confidence in both of them. We see here that 0.62 defeats all the other cutoffs, and 0.61 defeats all cutoffs except 0.62. The great thing about the exact calculation code is that it runs fast, regardless of how much accuracy we want. We can zero in on the range around 0.6:" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0.6180000000000001, 199),\n", + " (0.6170000000000001, 198),\n", + " (0.6160000000000001, 197),\n", + " (0.61900000000000011, 196),\n", + " (0.6150000000000001, 195),\n", + " (0.6140000000000001, 194),\n", + " (0.6130000000000001, 193),\n", + " (0.62000000000000011, 192),\n", + " (0.6120000000000001, 191),\n", + " (0.6110000000000001, 190)]" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "top(10, arange(0.500, 0.700, 0.001))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This says 0.618 is best, better than 0.620. We can get even more accuracy:" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0.61802999999999531, 200),\n", + " (0.61801999999999535, 199),\n", + " (0.61803999999999526, 198),\n", + " (0.6180099999999954, 197),\n", + " (0.61799999999999544, 196)]" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "top(5, arange(0.61700, 0.61900, 0.00001))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So 0.61803 is best. Does that number [look familiar](https://en.wikipedia.org/wiki/Golden_ratio)? Can you prove that it is what I think it is?\n", + "\n", + "To understand the strategic possibilities, it is helpful to draw a 3D plot of `Pwin(A, B)` for values of *A* and *B* between 0 and 1:" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "from mpl_toolkits.mplot3d.axes3d import Axes3D\n", + "\n", + "def map2(fn, A, B):\n", + " \"Map fn to corresponding elements of 2D arrays A and B.\"\n", + " return [list(map(fn, Arow, Brow))\n", + " for (Arow, Brow) in zip(A, B)]\n", + "\n", + "cutoffs = arange(0.00, 1.00, 0.02)\n", + "A, B = np.meshgrid(cutoffs, cutoffs)\n", + "\n", + "fig = plt.figure(figsize=(10,10))\n", + "ax = fig.add_subplot(1, 1, 1, projection='3d')\n", + "ax.set_xlabel('A')\n", + "ax.set_ylabel('B')\n", + "ax.set_zlabel('Pwin(A, B)')\n", + "ax.plot_surface(A, B, map2(Pwin, A, B));" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What does this [Pringle of Probability](http://fivethirtyeight.com/features/should-you-shoot-free-throws-underhand/) show us? The highest win percentage for **A**, the peak of the surface, occurs when *A* is around 0.5 and *B* is 0 or 1. We can confirm that, finding the maximum `Pwin(A, B)` for many different cutoff values of `A` and `B`:" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "cutoffs = (set(arange(0.00, 1.00, 0.01)) | \n", + " set(arange(0.500, 0.700, 0.001)) | \n", + " set(arange(0.61700, 0.61900, 0.00001)))" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.625, 0.5, 0.0]" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max([Pwin(A, B), A, B]\n", + " for A in cutoffs for B in cutoffs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So **A** could win 62.5% of the time if only **B** would chose a cutoff of 0. But, unfortunately for **A**, a rational player **B** is not going to do that. We can ask what happens if the game is changed so that player **A** has to declare a cutoff first, and then player **B** gets to respond with a cutoff, with full knowledge of **A**'s choice. In other words, what cutoff should **A** choose to maximize `Pwin(A, B)`, given that **B** is going to take that knowledge and pick a cutoff that minimizes `Pwin(A, B)`? " + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.5, 0.61802999999999531, 0.61802999999999531]" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(min([Pwin(A, B), A, B] for B in cutoffs)\n", + " for A in cutoffs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And what if we run it the other way around, where **B** chooses a cutoff first, and then **A** responds?" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.5, 0.61802999999999531, 0.61802999999999531]" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "min(max([Pwin(A, B), A, B] for A in cutoffs)\n", + " for B in cutoffs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In both cases, the rational choice for both players in a cutoff of 0.61803, which corresponds to the \"saddle point\" in the middle of the plot. This is a *stable equilibrium*; consider fixing *B* = 0.61803, and notice that if *A* changes to any other value, we slip off the saddle to the right or left, resulting in a worse win probability for **A**. Similarly, if we fix *A* = 0.61803, then if *B* changes to another value, we ride up the saddle to a higher win percentage for **A**, which is worse for **B**. So neither player will want to move from the saddle point.\n", + "\n", + "The moral for continuous spaces is the same as for discrete spaces: be careful about defining your space; count/measure carefully, and let your code take care of the rest." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/ProbabilityParadox.ipynb b/pytudes/ipynb/ProbabilityParadox.ipynb new file mode 100644 index 0000000..56ed36c --- /dev/null +++ b/pytudes/ipynb/ProbabilityParadox.ipynb @@ -0,0 +1,3102 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "
Peter Norvig, 3 Oct 2015, revised Oct-Feb 2016
\n", + "\n", + "# Probability, Paradox, and the Reasonable Person Principle\n", + "\n", + "In [another notebook](http://nbviewer.jupyter.org/url/norvig.com/ipython/Probability.ipynb), I introduced the basics of probability theory. I'll duplicate the code we developed there:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from fractions import Fraction\n", + "\n", + "class ProbDist(dict):\n", + " \"A Probability Distribution; an {outcome: probability} mapping.\"\n", + " def __init__(self, mapping=(), **kwargs):\n", + " self.update(mapping, **kwargs)\n", + " # Make probabilities sum to 1.0; assert no negative probabilities\n", + " total = sum(self.values())\n", + " for outcome in self:\n", + " self[outcome] = self[outcome] / total\n", + " assert self[outcome] >= 0\n", + " \n", + "def P(event, space): \n", + " \"\"\"The probability of an event, given a sample space of equiprobable outcomes. \n", + " event: a collection of outcomes, or a predicate that is true of outcomes in the event. \n", + " space: a set of outcomes or a probability distribution of {outcome: frequency}.\"\"\"\n", + " if is_predicate(event):\n", + " event = such_that(event, space)\n", + " if isinstance(space, ProbDist):\n", + " return sum(space[o] for o in space if o in event)\n", + " else:\n", + " return Fraction(len(event & space), len(space))\n", + " \n", + "def such_that(predicate, space): \n", + " \"\"\"The outcomes in the sample space for which the predicate is true.\n", + " If space is a set, return a subset {outcome,...};\n", + " if space is a ProbDist, return a ProbDist {outcome: frequency,...};\n", + " in both cases only with outcomes where predicate(element) is true.\"\"\"\n", + " if isinstance(space, ProbDist):\n", + " return ProbDist({o:space[o] for o in space if predicate(o)})\n", + " else:\n", + " return {o for o in space if predicate(o)}\n", + " \n", + "is_predicate = callable\n", + "\n", + "def cross(A, B):\n", + " \"The set of ways of concatenating one item from collection A with one from B.\"\n", + " return {a + b \n", + " for a in A for b in B}\n", + "\n", + "def joint(A, B, sep=''):\n", + " \"\"\"The joint distribution of two independent probability distributions. \n", + " Result is all entries of the form {a+sep+b: P(a)*P(b)}\"\"\"\n", + " return ProbDist({a + sep + b: A[a] * B[b]\n", + " for a in A\n", + " for b in B})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "In this notebook we use this code to show how to solve some particularly perplexing paradoxical probability problems.\n", + "\n", + "# Child Paradoxes\n", + "\n", + "In 1959, [Martin Gardner]() [posed](https://en.wikipedia.org/wiki/Boy_or_Girl_paradox) these two problems:\n", + "\n", + "- **Child Problem 1.** Mr. Jones has two children. The older child is a boy. What is the\n", + "probability that both children are boys?\n", + "\n", + "- **Child Problem 2.** Mr. Smith has two children. At least one of them is a boy. What is\n", + "the probability that both children are boys? \n", + "\n", + "Then in 2006, Mike & Tom Starbird came up with a variant, which Gary Foshee introduced to Gardner fans in 2010:\n", + "\n", + "- **Child Problem 3.** I have two children. At least one of them is a boy born on Tuesday. What is\n", + "the probability that both children are boys? \n", + "\n", + "Problems 2 and 3 are considered *paradoxes* because they have surprising answers that people\n", + "argue about. \n", + "\n", + "(Assume the probability of a boy is exactly 1/2, and is independent of any siblings.)\n", + "\n", + "![Martin Gardner](https://upload.wikimedia.org/wikipedia/commons/0/04/Martin_Gardner.jpeg)\n", + "
Martin Gardner
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### Child Problem 1: Older child is a boy. What is the probability both are boys?\n", + "\n", + "We use `'BG'` to denote the outcome in which the older child is a boy and the younger a girl. The sample space, `S`, of equi-probable outcomes is:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "S = {'BG', 'BB', 'GB', 'GG'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's define predicates for the conditions of having two boys, and of the older child being a boy:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def two_boys(outcome): return outcome.count('B') == 2\n", + "\n", + "def older_is_a_boy(outcome): return outcome.startswith('B')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can answer Problem 1:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(older_is_a_boy, S))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "You're probably thinking that was a lot of mechanism just to get the obvious answer. But in the next problems, what is obvious becomes less obvious.\n", + "\n", + "### Child Problem 2: At least one is a boy. What is the probability both are boys? \n", + "\n", + "Implementing this problem and finding the answer is easy:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def at_least_one_boy(outcome): return 'B' in outcome" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 3)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(at_least_one_boy, S))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Understanding the answer is tougher. Some people think the answer should be 1/2. Can we justify the answer 1/3? We can see there are three equiprobable outcomes in which there is at least one boy:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BB', 'BG', 'GB'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "such_that(at_least_one_boy, S)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Of those three outcomes, only one has two boys, so the answer of 1/3 is indeed justified. \n", + "\n", + "But some people *still* think the answer should be 1/2.\n", + "Their reasoning is *\"If one child is a boy, then there are two equiprobable outcomes for the other child, so the probability that the other child is a boy, and thus that there are two boys, is 1/2.\"* \n", + "\n", + "When two methods of reasoning give two different answers, we have a [paradox](https://en.wikipedia.org/wiki/Paradox). Here are three responses to a paradox:\n", + "\n", + "1. The very fundamentals of mathematics must be incomplete, and this problem reveals it!!!\n", + "2. I'm right, and anyone who disagrees with me is an idiot!!!\n", + "3. I have the right answer for one interpretation of the problem, and you have the right answer\n", + "for a different interpretation of the problem.\n", + "\n", + "If you're [Bertrand Russell](https://en.wikipedia.org/wiki/Russell%27s_paradox) or [Georg Cantor](https://en.wikipedia.org/wiki/Cantor%27s_paradox), you might very well uncover a fundamental flaw in mathematics; for the rest of us, I recommend Response 3. When I believe the answer is 1/3, and I hear someone say the answer is 1/2, my response is not *\"You're wrong!\"*, rather it is *\"How interesting! You must have a different interpretation of the problem; I should try to discover what your interpretation is, and why your answer is correct for your interpretation.\"* The first step is to be more precise in *my* wording of the experiment:\n", + "\n", + "- **Child Experiment 2a.** Mr. Smith is chosen at random from families with two children. He is asked if at least one of his children is a boy. He replies \"yes.\"\n", + "\n", + "The next step is to envision another possible interpretation of the experiment:\n", + "\n", + "- **Child Experiment 2b.** Mr. Smith is chosen at random from families with two children. He is observed at a time when he is accompanied by one of his children, chosen at random. The child is observed to be a boy. \n", + "\n", + "Experiment 2b needs a different sample space, which we will call `S2b`. It consists of 8 outcomes, not just 4; for each of the 4 outcomes in `S`, we have a choice of observing either the older child or the younger child. We will use the notation `'GB/g?'` to mean that the older child is a girl, the younger a boy, the older child was observed to be a girl, and the younger was not observed. The sample space is therefore:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "S2b = {'BB/b?', 'BB/?b', \n", + " 'BG/b?', 'BG/?g', \n", + " 'GB/g?', 'GB/?b', \n", + " 'GG/g?', 'GG/?g'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can figure out the subset of this sample space in which we observe Mr. Smith with a boy:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BB/?b', 'BB/b?', 'BG/b?', 'GB/?b'}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def observed_boy(outcome): return 'b' in outcome\n", + "\n", + "such_that(observed_boy, S2b)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And finally we can determine the probability that he has two boys, given that we observed him with a boy:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(observed_boy, S2b))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The paradox is resolved. Two reasonable people can have different interpretations of the problem, and can each reason flawlessly to reach different conclusions, 1/3 or 1/2. \n", + "\n", + "Which interpretation of the problem is \"better?\" We could debate that, or we could just agree to use unambiguous wording (that is, use the language of Experiment 2a or Experiment 2b, not the ambiguous language of Problem 2). \n", + "\n", + "## The Reasonable Person Principle\n", + "\n", + "It is an unfortunate fact of human nature that we often assume the other person is an idiot. As [George Carlin puts it](https://www.youtube.com/watch?v=XWPCE2tTLZQ) *\"Have you ever noticed when you're driving that anybody driving slower than you is an idiot, and anyone going faster than you is a maniac?\"*\n", + "\n", + "\n", + "
George Carlin
\n", + "\n", + "The opposite assumption—that other people are more likely to be **reasonable** rather than **idiots** is known as the **[reasonable person principle](http://www.cs.cmu.edu/~weigand/staff/)**. It is a guiding principle at Carnegie Mellon University's School of Computer Science, and is a principle I try to live by as well.\n", + "\n", + "Now let's return to an even more paradoxical problem.\n", + "\n", + "### Child Problem 3. One is a boy born on Tuesday. What's the probability both are boys?\n", + "\n", + "Most people can not imagine how the boy's birth-day-of-week could be relevant, and feel the answer should be the same as Problem 2. But to be sure, we need to clearly describe the experiment, define the sample space, and calculate. First:\n", + "\n", + "- **Child Experiment 3a.** A parent is chosen at random from families with two children. She is asked if at least one of her children is a boy born on Tuesday. She replies \"yes.\"\n", + "\n", + "Next we'll define a sample space. We'll use the notation \"`G1B3`\" to mean the older child is a girl born on the first day of the week (Sunday) and the younger a boy born on the third day of the week (Tuesday). We'll call the resulting sample space `S3`." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "196" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sexesdays = cross('BG', '1234567')\n", + "S3 = cross(sexesdays, sexesdays)\n", + "len(S3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "That's too many to print, but we can sample them:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['G2G3', 'G6B7', 'B1G7', 'B4B7', 'B4G6', 'G5G5', 'B5G4', 'G4B4']" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import random\n", + "random.sample(S3, 8)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We determine below that the probability of having at least one boy is 3/4, both in `S3` (where we keep track of the birth day of week) and in `S` (where we don't):" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(3, 4)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(at_least_one_boy, S3)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(3, 4)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(at_least_one_boy, S)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The probability of two boys is 1/4 in either sample space:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 4)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, S3)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 4)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, S)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And the probability of two boys given at least one boy is 1/3 in either sample space:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 3)" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(at_least_one_boy, S3))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 3)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(at_least_one_boy, S))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We will define a predicate for the event of at least one boy born on Tuesday: " + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def at_least_one_boy_tues(outcome): return 'B3' in outcome" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We are now ready to answer Problem 3:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(13, 27)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(at_least_one_boy_tues, S3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "13/27? \n", + "\n", + "How many saw that coming? 13/27 is quite different from 1/3, but rather close to 1/2. So \"at least one boy born on Tuesday\" is quite different from \"at least one boy.\" Are you surprised? Do you accept the answer, or do you think we did something wrong? Are there other interpretations of the experiment that lead to other answers?\n", + "\n", + "Here is one alternative interpretation:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "- **Child Experiment 3b.** A parent is chosen at random from families with two children. She is observed at a time when she is accompanied by one of her children, chosen at random. The child is observed to be a boy who reports that his birth day is Tuesday.\n", + "\n", + "We can represent outcomes in this sample space with the notation `G1B3/??b3`, meaning the older child is a girl born on Sunday, the younger a boy born on Tuesday, the older was not observed, and the younger was." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def observed_boy_tues(outcome): return 'b3' in outcome\n", + "\n", + "S3b = {children + '/' + observation\n", + " for children in S3\n", + " for observation in (children[:2].lower()+'??', '??'+children[-2:].lower())} " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['G4G5/??g5', 'B1B5/b1??', 'G6G4/g6??', 'B1G2/??g2', 'G5G6/g5??']" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.sample(S3b, 5)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can answer this version of Child Problem 3:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(two_boys, such_that(observed_boy_tues, S3b))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "So with the wording of Child Experiment 3b, the answer is the same as 2b.\n", + "\n", + "Still confused? Let's build a visualization tool to make things more concrete.\n", + "\n", + "# Visualization\n", + "\n", + "We'll display the results as a two dimensional grid of outcomes. An outcome will be colored white if it does not satisfy the condition stated in the problem; green if the outcome contains two boys; and yellow if it does satisfy the condition, but does not have two boys. Every cell in a row has the same older child, and every cell in a column has the same younger child. Here's the code to display a table:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from IPython.display import HTML\n", + "\n", + "def Pgrid(space, n, event, condition):\n", + " \"\"\"Display sample space in a grid, color-coded: green if event and condition is true; \n", + " yellow if only condition is true; white otherwise.\"\"\"\n", + " # n is the number of characters that make up the older child.\n", + " olders = sorted(set(outcome[:n] for outcome in space))\n", + " return HTML('' +\n", + " cat(row(older, space, event, condition) for older in olders) +\n", + " '
' + \n", + " 'P({} | {}) = {}'.format(\n", + " event.__name__, condition.__name__, \n", + " P(event, such_that(condition, space))))\n", + "\n", + "def row(older, space, event, condition):\n", + " \"Display a row where an older child is paired with each of the possible younger children.\"\n", + " thisrow = sorted(outcome for outcome in space if outcome.startswith(older))\n", + " return '' + cat(cell(outcome, event, condition) for outcome in thisrow) + ''\n", + "\n", + "def cell(outcome, event, condition): \n", + " \"Display outcome in appropriate color.\"\n", + " color = ('lightgreen' if event(outcome) and condition(outcome) else\n", + " 'yellow' if condition(outcome) else\n", + " 'white')\n", + " return '{}'.format(color, outcome) \n", + "\n", + "cat = ''.join" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can use this visualization tool to see that in Child Problem 1, there is one outcome with two boys (green) out of a total of two outcomes where the older is a boy (green and yellow) so the probability of two boys given that the older is a boy is 1/2." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
BBBG
GBGG
P(two_boys | older_is_a_boy) = 1/2" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 1\n", + "Pgrid(S, 1, two_boys, older_is_a_boy)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "For Child Problem 2, we see the probability of two boys (green) given at least one boy (green and yellow) is 1/3. " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
BBBG
GBGG
P(two_boys | at_least_one_boy) = 1/3" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 2\n", + "Pgrid(S, 1, two_boys, at_least_one_boy)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The answer is still 1/3 when we consider the day of the week of each birth. " + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
B1B1B1B2B1B3B1B4B1B5B1B6B1B7B1G1B1G2B1G3B1G4B1G5B1G6B1G7
B2B1B2B2B2B3B2B4B2B5B2B6B2B7B2G1B2G2B2G3B2G4B2G5B2G6B2G7
B3B1B3B2B3B3B3B4B3B5B3B6B3B7B3G1B3G2B3G3B3G4B3G5B3G6B3G7
B4B1B4B2B4B3B4B4B4B5B4B6B4B7B4G1B4G2B4G3B4G4B4G5B4G6B4G7
B5B1B5B2B5B3B5B4B5B5B5B6B5B7B5G1B5G2B5G3B5G4B5G5B5G6B5G7
B6B1B6B2B6B3B6B4B6B5B6B6B6B7B6G1B6G2B6G3B6G4B6G5B6G6B6G7
B7B1B7B2B7B3B7B4B7B5B7B6B7B7B7G1B7G2B7G3B7G4B7G5B7G6B7G7
G1B1G1B2G1B3G1B4G1B5G1B6G1B7G1G1G1G2G1G3G1G4G1G5G1G6G1G7
G2B1G2B2G2B3G2B4G2B5G2B6G2B7G2G1G2G2G2G3G2G4G2G5G2G6G2G7
G3B1G3B2G3B3G3B4G3B5G3B6G3B7G3G1G3G2G3G3G3G4G3G5G3G6G3G7
G4B1G4B2G4B3G4B4G4B5G4B6G4B7G4G1G4G2G4G3G4G4G4G5G4G6G4G7
G5B1G5B2G5B3G5B4G5B5G5B6G5B7G5G1G5G2G5G3G5G4G5G5G5G6G5G7
G6B1G6B2G6B3G6B4G6B5G6B6G6B7G6G1G6G2G6G3G6G4G6G5G6G6G6G7
G7B1G7B2G7B3G7B4G7B5G7B6G7B7G7G1G7G2G7G3G7G4G7G5G7G6G7G7
P(two_boys | at_least_one_boy) = 1/3" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 2, with days of week enumerated\n", + "Pgrid(S3, 2, two_boys, at_least_one_boy)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "Now for the paradox of Child Problem 3:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
B1B1B1B2B1B3B1B4B1B5B1B6B1B7B1G1B1G2B1G3B1G4B1G5B1G6B1G7
B2B1B2B2B2B3B2B4B2B5B2B6B2B7B2G1B2G2B2G3B2G4B2G5B2G6B2G7
B3B1B3B2B3B3B3B4B3B5B3B6B3B7B3G1B3G2B3G3B3G4B3G5B3G6B3G7
B4B1B4B2B4B3B4B4B4B5B4B6B4B7B4G1B4G2B4G3B4G4B4G5B4G6B4G7
B5B1B5B2B5B3B5B4B5B5B5B6B5B7B5G1B5G2B5G3B5G4B5G5B5G6B5G7
B6B1B6B2B6B3B6B4B6B5B6B6B6B7B6G1B6G2B6G3B6G4B6G5B6G6B6G7
B7B1B7B2B7B3B7B4B7B5B7B6B7B7B7G1B7G2B7G3B7G4B7G5B7G6B7G7
G1B1G1B2G1B3G1B4G1B5G1B6G1B7G1G1G1G2G1G3G1G4G1G5G1G6G1G7
G2B1G2B2G2B3G2B4G2B5G2B6G2B7G2G1G2G2G2G3G2G4G2G5G2G6G2G7
G3B1G3B2G3B3G3B4G3B5G3B6G3B7G3G1G3G2G3G3G3G4G3G5G3G6G3G7
G4B1G4B2G4B3G4B4G4B5G4B6G4B7G4G1G4G2G4G3G4G4G4G5G4G6G4G7
G5B1G5B2G5B3G5B4G5B5G5B6G5B7G5G1G5G2G5G3G5G4G5G5G5G6G5G7
G6B1G6B2G6B3G6B4G6B5G6B6G6B7G6G1G6G2G6G3G6G4G6G5G6G6G6G7
G7B1G7B2G7B3G7B4G7B5G7B6G7B7G7G1G7G2G7G3G7G4G7G5G7G6G7G7
P(two_boys | at_least_one_boy_tues) = 13/27" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 3\n", + "Pgrid(S3, 2, two_boys, at_least_one_boy_tues)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We see there are 27 relevant outcomes, of which 13 are green. So 13/27 really does seem to be the right answer. This picture also gives us a way to think about why the answer is not 1/3. Think of the yellow-plus-green area as a horizontal stripe and a vertical stripe, with an overlap. Each stripe is half yellow and half green, so if there were no overlap at all, the probability of green would be 1/2. When each stripe takes up half the sample space and the overlap is maximal, the probability is 1/3. And in the Problem 3 table, where the overlap is small, the probability is close to 1/2 (but slightly smaller).\n", + "\n", + "One way to look at it is that if I tell you very specific information (such as a boy born on Tuesday), it is unlikely that this applies to both children, so we have smaller overlap and a probability closer to 1/2, but if I give you broad information (a boy), this is more likely to apply to either child, resulting in a larger overlap, and a probability closer to 1/3.\n", + "\n", + "You can read some more discussions of the problem by (in alphabetical order) \n", + "[Alex Bellos](https://www.newscientist.com/article/dn18950-magic-numbers-a-meeting-of-mathemagical-tricksters?full=true),\n", + "[Alexander Bogomolny](http://www.cut-the-knot.org/Probability/BearBornOnTuesday.shtml),\n", + "[Andrew Gelman](http://andrewgelman.com/2010/05/27/hype_about_cond/),\n", + "[David Bigelow](https://web.viu.ca/bigelow2/Problem%201127%20Solution.pdf),\n", + "[Julie Rehmeyer](https://www.sciencenews.org/article/when-intuition-and-math-probably-look-wrong),\n", + "[Keith Devlin](https://www.maa.org/external_archive/devlin/devlin_05_10.html),\n", + "[Peter Lynch](http://mathsci.ucd.ie/~plynch/Publications/BIMS-TwoChildParadox.pdf),\n", + "[Tanya Khovanova](http://arxiv.org/pdf/1102.0173v1.pdf),\n", + "and\n", + "[Wendy Taylor & Kaye Stacey](http://www.aamt.edu.au/Journals/Sample-articles/amt70_2_taylor.pdf)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The Sleeping Beauty Paradox\n", + "\n", + "The [Sleeping Beauty Paradox](https://en.wikipedia.org/wiki/Sleeping_Beauty_problem) is another tricky one:\n", + "\n", + ">Sleeping Beauty volunteers to undergo the following experiment and is told all of the following details: On Sunday she will be put to sleep. Then a fair coin will be tossed,\n", + "to determine which experimental procedure to undertake:\n", + "- Heads: Beauty will be awakened and interviewed on Monday only.\n", + "- Tails: Beauty will be awakened and interviewed on Monday and Tuesday only.\n", + "\n", + ">In all cases she is put back to sleep with an amnesia-inducing drug that makes her forget that awakening and sleep until the next one. In any case, she will be awakened on Wednesday without interview and the experiment ends. Any time Beauty is awakened and interviewed, she is asked, \"What is your belief now for the proposition that the coin landed heads?\"\n", + "\n", + "What should Sleeping Beauty say when she is interviewed? First, she should define the sample space. She could use the notation `'heads/Monday/interviewed'` to mean the outcome where the coin flip was heads, it is Monday, and she is interviewed. So there are 4 equiprobable outcomes:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "B = {'heads/Monday/interviewed', 'heads/Tuesday/sleep',\n", + " 'tails/Monday/interviewed', 'tails/Tuesday/interviewed'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "At this point, you're probably expecting me to define predicates, like this:\n", + "\n", + " def heads(outcome): return 'heads' in outcome\n", + " def interviewed(outcome): return 'interviewed' in outcome\n", + " \n", + "We've seen a lot of predicates like this. I think it is time to heed the \"[don't repeat yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)\" principle, so I will define a predicate-defining function, `T`. Think of \"`T`\" for \"it is true that\":" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def T(property):\n", + " \"Return a predicate that is true of all outcomes that have 'property' as a substring.\"\n", + " return lambda outcome: property in outcome" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can get the answer:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 3)" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "heads = T(\"heads\")\n", + "interviewed = T(\"interviewed\")\n", + "\n", + "P(heads, such_that(interviewed, B))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Note: I could have done that in one line: `P(T(\"heads\"), such_that(T(\"interviewed\"), B))`\n", + "\n", + "This problem is considered a paradox because there are people who argue that the answer should be 1/2, not 1/3. I admit I'm having difficulty coming up with a sample space that supports the \"halfer\" position. \n", + "\n", + "I do know of a question that has the answer 1/2:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(heads, B) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "But that seems like the wrong question; we want the probability of heads given that Sleeping Beauty was interviewed, not the unconditional probability of heads.\n", + "\n", + "The \"halfers\" argue that before Sleeping Beauty goes to sleep, her unconditional probability for heads should be 1/2. When she is interviewed, she doesn't know anything more than before she went to sleep, so nothing has changed, so the probability of heads should still be 1/2. I find two flaws with this argument. First, if you want to convince me, show me a sample space; don't just make philosophical arguments. (Although a philosophical argument can be employed to help you define the right sample space.) Second, while I agree that before she goes to sleep, Beauty's *unconditional* probability for heads should be 1/2, I would say that both before she goes to sleep and when she is awakened, her *conditional* probability of heads *given that she is being interviewed* should be 1/3, as shown by the sample space." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The Monty Hall Paradox\n", + "\n", + "[This](https://en.wikipedia.org/wiki/Monty_Hall_problem) is one of the most famous probability paradoxes. It can be stated as follows:\n", + "\n", + "> Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, \"Do you want to switch your choice to door No. 2?\" Is it to your advantage to switch your choice?\n", + "\n", + "\n", + "
Monty Hall
\n", + "\n", + "Much has been written about this problem, but to solve it all we have to do is be careful about how we understand the problem, and about defining our sample space. I will define outcomes of the form `'Car1/Lo/Pick1/Open2'`, which means:\n", + "* `Car1`: The producers of the show randomly placed the car behind door 1.\n", + "* `Lo`: The host randomly commits to the strategy of opening the lowest-numbered allowable door. A door is allowable if it does not contain the car and was not picked by the contestant. Alternatively, the host could have chosen to open the highest-numbered allowable door (`Hi`).\n", + "* `Pick1`: The contestant picks door 1. Our sample space will only consider cases where the contestant picks door 1, but by symmetry, the same arguments could be used if the contestant picked door 2 or 3.\n", + "* `Open2`: After hearing the contestant's choice, and following the strategy, the host opens a door; in this case door 2.\n", + "\n", + "We can see that the sample space has 6 equiprobable outcomes involving `Pick1`:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "M = {'Car1/Lo/Pick1/Open2', 'Car1/Hi/Pick1/Open3',\n", + " 'Car2/Lo/Pick1/Open3', 'Car2/Hi/Pick1/Open3',\n", + " 'Car3/Lo/Pick1/Open2', 'Car3/Hi/Pick1/Open2'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now, assuming the contestant picks door 1 and the host opens door 3, we can ask:\n", + "- What are the possible outcomes remaining?\n", + "- What is the probability that the car is behind door 1? \n", + "- Or door 2?" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Car1/Hi/Pick1/Open3', 'Car2/Hi/Pick1/Open3', 'Car2/Lo/Pick1/Open3'}" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "such_that(T(\"Open3\"), M)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 3)" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(T(\"Car1\"), such_that(T(\"Open3\"), M))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(2, 3)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(T(\"Car2\"), such_that(T(\"Open3\"), M))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We see that the strategy of **switching** from door 1 to door 2 will win the car 2/3 of the time, whereas the strategy of **sticking** with the original pick wins the car only 1/3 of the time. So if you like cars more than goats, you should switch. But don't feel bad if you got this one wrong; it turns out that Monty Hall himself, who opened many doors while hosting *Let's Make a Deal* for 13 years, didn't know the answer either, as revealed in this letter from Monty to Prof. Lawrence Denenberg, when Denenberg asked for permission to use the problem in his textbook:\n", + "\n", + "\n", + "If you were Denenberg, how would you answer Monty, in non-mathematical terms? I would try something like this:\n", + "\n", + "> When the contestant makes her initial pick, she has 1/3 chance of picking the car, and there is a 2/3 chance the car is behind one of the other doors. That's still true after you open a door, but now the 2/3 chance for *either* other door becomes concentrated as 2/3 behind *one* other door, so the contestant should switch.\n", + "\n", + "But that type of argument was not persuasive to everyone. [Marilyn vos Savant](http://marilynvossavant.com/game-show-problem/) reports that many of her readers (including, she is pleased to point out, many Ph.D.s) still insist the answer is that it doesn't matter if the contestant switches; the odds are 1/2 either way. Let's try to discover what problem and what sample space those people are dealing with. Perhaps they are reasoning like this:\n", + "\n", + "They define outcomes of the form `'Car1/Pick1/Open2/Goat'`, which means:\n", + "* `Car1`: First the car is randomly placed behind door 1.\n", + "* `Pick1`: The contestant picks door 1. \n", + "* `Open2`: The host opens one of the two other doors at random (so the host might open the door with the car).\n", + "* `Goat`: We observe there is a goat behind the opened door.\n", + "\n", + "Under this interpretation, the sample space of all outcomes involving `Pick1` is:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "M2 = {'Car1/Pick1/Open2/Goat', 'Car1/Pick1/Open3/Goat',\n", + " 'Car2/Pick1/Open2/Car', 'Car2/Pick1/Open3/Goat',\n", + " 'Car3/Pick1/Open2/Goat', 'Car3/Pick1/Open3/Car'}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And we can calculate the probability of the car being behind each door, given that the contestant picks door 1 and the host opens door 3 to reveal a goat:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(T(\"Car1\"), such_that(T(\"Open3/Goat\"), M2))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(1, 2)" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(T(\"Car2\"), such_that(T(\"Open3/Goat\"), M2))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(0, 1)" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "P(T(\"Car3\"), such_that(T(\"Open3/Goat\"), M2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "So we see that under this interpretation it doesn't matter if you switch or not. \n", + "\n", + "Is this a valid interpretation? I agree that the wording of the problem can be seen as being ambiguous. However, this interpretation has a serious problem: in all the history of *Let's Make a Deal*, it was never the case that the host opened up a door with the grand prize. This strongly suggests (but does not prove) that `M` is the correct sample space, not `M2`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "# Simulating the Monty Hall Problem\n", + "\n", + "Some people might be more convinced by a simulation than by a probability argument. Here is code for a simulation:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "import random\n", + "\n", + "\n", + "def monty(strategy):\n", + " \"\"\"Simulate this sequence of events:\n", + " 1. The host randomly chooses a door for the 'car'\n", + " 2. The contestant randomly makes a 'pick' of one of the doors\n", + " 3. The host randomly selects a non-car, non-pick door to be 'opened.' \n", + " 4. If strategy == 'switch', contestant changes 'pick' to the other unopened door\n", + " 5. Return true if the pick is the door with the car.\"\"\"\n", + " doors = (1, 2, 3)\n", + " car = random.choice(doors)\n", + " pick = random.choice(doors)\n", + " opened = random.choice([d for d in doors if d != car and d != pick])\n", + " if strategy == 'switch':\n", + " pick = next(d for d in doors if d != pick and d != opened)\n", + " return (pick == car)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can confirm that the contestant wins about 2/3 of the time with the `switch` strategy, and only wins about 1/3 of the time with the `stick` strategy:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({False: 33110, True: 66890})" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from collections import Counter\n", + "\n", + "Counter(monty('switch') for _ in range(10 ** 5))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({False: 66738, True: 33262})" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Counter(monty('stick') for _ in range(10 ** 5))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Reasoning with Probability Distributions\n", + "\n", + "So far, we have made the assumption that every outcome in a sample space is equally likely. In real life, the probability of a child being a girl is not exactly 1/2. As mentioned in the [previous notebook](http://nbviewer.jupyter.org/url/norvig.com/ipython/Probability.ipynb), an [article](http://people.kzoo.edu/barth/math105/moreboys.pdf) gives the following counts for two-child families in Denmark:\n", + "\n", + " GG: 121801 GB: 126840\n", + " BG: 127123 BB: 135138\n", + "\n", + "Let's implement that:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BB': 0.2645086533229465,\n", + " 'BG': 0.24882071317004043,\n", + " 'GB': 0.24826679089140383,\n", + " 'GG': 0.23840384261560926}" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DK = ProbDist(GG=121801, GB=126840,\n", + " BG=127123, BB=135138)\n", + "DK" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now let's try the first two Child Problems with the probability distribution `DK`. Since boys are slightly more probable than girls, we expect a little over 1/2 for Problem 1, and a little over 1/3 for problem 2:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5152805792702689" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 1 in DK\n", + "P(two_boys, such_that(older_is_a_boy, DK))" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.3473082824253857" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 2 in DK\n", + "P(two_boys, such_that(at_least_one_boy, DK))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "It all looks good. Now let's leave Denmark behind and try a new problem:\n", + "\n", + "### Child Problem 4. One is a boy born on Feb. 29. What is the probability both are boys?\n", + "\n", + "* **Child Problem 4.** I have two children. At least one of them is a boy born on leap day, February 29. What is the probability that both children are boys? Assume that 51.5% of births are boys and that birth days are distributed evenly across the 4×365 + 1 days in a 4-year cycle.\n", + "\n", + "We will use the notation `GLBN` to mean an older girl born on leap day (`L`) and a younger boy born on a non-leap day (`N`). " + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "sexes = ProbDist(B=51.5, G=48.5) # Probability distribution over sexes\n", + "days = ProbDist(L=1, N=4*365) # Probability distribution over Leap days and Non-leap days\n", + "child = joint(sexes, days) # Probability distribution for one child family\n", + "S4 = joint(child, child) # Probability distribution for two-child family" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's check out these last two probability distributions:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BL': 0.00035249828884325804,\n", + " 'BN': 0.5146475017111568,\n", + " 'GL': 0.0003319644079397673,\n", + " 'GN': 0.48466803559206023}" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "child" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'BLBL': 1.2425504363742495e-07,\n", + " 'BLBN': 0.00018141236371064045,\n", + " 'BLGL': 1.170168857556332e-07,\n", + " 'BLGN': 0.0001708446532032245,\n", + " 'BNBL': 0.00018141236371064045,\n", + " 'BNBN': 0.26486205101753507,\n", + " 'BNGL': 0.00017084465320322452,\n", + " 'BNGN': 0.24943319367670777,\n", + " 'GLBL': 1.170168857556332e-07,\n", + " 'GLBN': 0.00017084465320322452,\n", + " 'GLGL': 1.102003681388002e-07,\n", + " 'GLGN': 0.0001608925374826483,\n", + " 'GNBL': 0.0001708446532032245,\n", + " 'GNBN': 0.24943319367670777,\n", + " 'GNGL': 0.0001608925374826483,\n", + " 'GNGN': 0.2349031047246665}" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "S4" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can solve the problem. Since \"boy born on a leap day\" applies to so few children, we expect the probability of two boys to be just ever so slightly below the baseline rate for boys, 51.5%." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5149145040963757" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Child Problem 4\n", + "boy_born_on_leap_day = T(\"BL\")\n", + "\n", + "P(two_boys, such_that(boy_born_on_leap_day, S4))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The St. Petersburg Paradox\n", + "\n", + "The [St. Petersburg paradox](https://en.wikipedia.org/wiki/St._Petersburg_paradox) from 1713, named for the home town of the [Bernoullis](http://www.storyofmathematics.com/18th_bernoulli.html), and introduced by [Daniel Bernoulli](), the nephew of Jacob Bernoulli (the urn guy):\n", + "\n", + "> *A casino offers a game of chance for a single player in which a fair coin is tossed at each stage. The pot starts at 2 dollars and is doubled every time a head appears. The first time a tail appears, the game ends and the player wins whatever is in the pot. Thus the player wins 2 dollars if a tail appears on the first toss, 4 dollars if a head appears on the first toss and a tail on the second, etc. What is the expected value of this game to the player?*\n", + "\n", + "To calculate the expected value, we see there is a 1/2 chance of a tail on the first toss (yielding a pot of $2) and if not that, a 1/2 × 1/2 = 1/4 chance of a tail on the second toss (yielding a pot of $4), and so on. So in total, the expected value is:\n", + "\n", + " 2 * (1/2) + 4 * (1/4) + 8 * (1/8) + ... = 1 + 1 + 1 + ... = ∞\n", + "\n", + "The expected value is infinite! But anyone playing the game would not expect to win an infinite amount; thus the paradox.\n", + "\n", + "## Response 1: Limited Resources\n", + "\n", + "The first major response to the paradox is that the casino's resources are limited. Once you break their bank, they can't pay out any more, and thus the expected return is finite. Let's consider the case where the bank has a limit to their resources, and create a probability distribution for the problem. We keep doubling the pot and halving the probability of winning the amount in the pot (half because you get the pot on a tail but not a head), until we reach the limit." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def st_pete(limit):\n", + " \"Return the probability distribution for the St. Petersburg Paradox with a limited bank.\"\n", + " P = {} # The probability distribution\n", + " pot = 2 # Amount of money in the pot\n", + " pr = 1/2. # Probability that you end up with the amount in pot\n", + " while pot < limit:\n", + " P[pot] = pr\n", + " pot = pot * 2\n", + " pr = pr / 2\n", + " P[limit] = pr * 2 # pr * 2 because you get limit for heads or tails\n", + " return ProbDist(P)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's try with the casino limited to 100 million dollars:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2: 0.5,\n", + " 4: 0.25,\n", + " 8: 0.125,\n", + " 16: 0.0625,\n", + " 32: 0.03125,\n", + " 64: 0.015625,\n", + " 128: 0.0078125,\n", + " 256: 0.00390625,\n", + " 512: 0.001953125,\n", + " 1024: 0.0009765625,\n", + " 2048: 0.00048828125,\n", + " 4096: 0.000244140625,\n", + " 8192: 0.0001220703125,\n", + " 16384: 6.103515625e-05,\n", + " 32768: 3.0517578125e-05,\n", + " 65536: 1.52587890625e-05,\n", + " 131072: 7.62939453125e-06,\n", + " 262144: 3.814697265625e-06,\n", + " 524288: 1.9073486328125e-06,\n", + " 1048576: 9.5367431640625e-07,\n", + " 2097152: 4.76837158203125e-07,\n", + " 4194304: 2.384185791015625e-07,\n", + " 8388608: 1.1920928955078125e-07,\n", + " 16777216: 5.960464477539063e-08,\n", + " 33554432: 2.9802322387695312e-08,\n", + " 67108864: 1.4901161193847656e-08,\n", + " 100000000: 1.4901161193847656e-08}" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "StP = st_pete(limit=10**8)\n", + "StP" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we define the function `EV` to compute the [expected value](https://en.wikipedia.org/wiki/Expected_value) of a probability distribution: " + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def EV(P):\n", + " \"The expected value of a probability distribution.\"\n", + " return sum(P[v] * v \n", + " for v in P)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "27.490116119384766" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EV(StP)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "This says that for a casino with a bankroll of 100 million dollars, if you want to maximize your expected value, you should be willing to pay up to $27.49 to play the game. Would you pay that much? I wouldn't, and neither would Daniel Bernoulli. \n", + "\n", + "## Response 2: Value of Money\n", + "\n", + "Daniel Bernoulli came up with a second response to the paradox based on the idea that if you have a lot of money, then additional money becomes less valuable to you. If I had nothing, and I won $1000, I would be very happy. But if I already had a million dollars and I won $1000, it would be less valuable. How much less valuable? Bernoulli proposed, and [experiments confirm](https://books.google.com/books?id=1oEa-BiARWUC&pg=PA205&lpg=PA205&dq=mr+beard+oil+wildcatter+value+of+money+utility&source=bl&ots=cBDIX-rkTz&sig=GHB8-inorWrU39vA8JYV_sCtqB8&hl=en&sa=X&ved=0CCAQ6AEwAGoVChMI5fu-p8qlyAIViKWICh0XAAz5#v=onepage&q=mr%20beard%20oil%20wildcatter%20value%20of%20money%20utility&f=false), that *the value of money is roughly logarithmic.* That is, rational bettors don't try to maximize their expected monetary value, they try to maximize their *expected utility*: the amount of \"happiness\" that the money is worth.\n", + "I'll write the function `util` to describe what a dollar amount is worth to a hypothetical gambler. `util` says that a dollar is worth a dollar, until the amount is \"enough\" money. After that point, each additional dollar is worth half as much (only brings half as much happiness). Value keeps accumulating at this rate until we reach the next threshold of \"enough,\" when the utility of additional dollars is halfed again. The exact details of `util` are not critical; what matters is that overall money becomes less valuable after we have won a lot of it." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def util(dollars, enough=1000): \n", + " \"The value of money: only half as valuable after you already have enough.\"\n", + " if dollars < enough:\n", + " return dollars\n", + " else:\n", + " additional = dollars-enough\n", + " return enough + util(additional / 2, enough * 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "A table and a plot will give a feel for the `util` function. Notice the characteristics concave-down shape of the plot." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 100 $ = 100 util\n", + " 1,000 $ = 1,000 util\n", + " 10,000 $ = 4,250 util\n", + " 100,000 $ = 15,937 util\n", + " 1,000,000 $ = 51,593 util\n", + " 10,000,000 $ = 162,460 util\n", + " 100,000,000 $ = 535,646 util\n", + " 1,000,000,000 $ = 1,658,229 util\n" + ] + } + ], + "source": [ + "for d in range(2, 10):\n", + " m = 10 ** d\n", + " print('{:15,d} $ = {:10,d} util'.format(m, int(util(m))))" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Y axis is util(x); x axis is in thousands of dollars.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline \n", + "import matplotlib.pyplot as plt\n", + "\n", + "plt.plot([util(x) for x in range(1000, 10000000, 1000)])\n", + "print('Y axis is util(x); x axis is in thousands of dollars.')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now I will define the function `EU`, which computes the [expected utility](http://wiki.lesswrong.com/wiki/Expected_utility) of the game:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def EU(P, U):\n", + " \"The expected utility of a probability distribution, given a utility function.\"\n", + " return sum(P[e] * U(e) \n", + " for e in P)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "13.096907431492582" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EU(StP, util)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "That says we should pay up to $13.10 to play the game, which sounds more reasonable than $27.49.\n", + "\n", + "# Understanding St. Petersburg through Simulation\n", + "\n", + "Before I plunk down my $13, I'd like to understand the game better. I'll write a simulation of the game:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def flip(): return random.choice(('head', 'tail'))\n", + "\n", + "def simulate_st_pete(limit=10**9):\n", + " \"Simulate one round of the St. Petersburg game, and return the payoff.\"\n", + " pot = 2\n", + " while flip() == 'head':\n", + " pot = pot * 2\n", + " if pot > limit:\n", + " return limit\n", + " return pot" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I will run the simulation 100,000 times (with a random seed specified for reproducability) and make the results into a probability distribution:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2: 0.49755,\n", + " 4: 0.2506,\n", + " 8: 0.1259,\n", + " 16: 0.06322,\n", + " 32: 0.03151,\n", + " 64: 0.01607,\n", + " 128: 0.00751,\n", + " 256: 0.0037,\n", + " 512: 0.00191,\n", + " 1024: 0.00106,\n", + " 2048: 0.00045,\n", + " 4096: 0.00029,\n", + " 8192: 0.0001,\n", + " 16384: 6e-05,\n", + " 32768: 5e-05,\n", + " 65536: 1e-05,\n", + " 1048576: 1e-05}" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.seed(123456)\n", + "\n", + "results = ProbDist(Counter(simulate_st_pete() for _ in range(100000)))\n", + "results" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The results are about what you would expect: about half the pots are 2, a quarter are 4, an eighth are 8, and higher pots are more and more unlikely. Let's check expected utility and expected value:" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(13.2477575, 26.71606)" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EU(results, util), EV(results)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "These are not too far off from the theoretial values.\n", + "\n", + "To see better how things unfold, I will define a function to plot the running average of repeated rounds:" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def running_averages(iterable):\n", + " \"For each element in the iterable, yield the mean of all elements seen so far.\" \n", + " total, n = 0, 0\n", + " for x in iterable:\n", + " total, n = total + x, n + 1\n", + " yield total / n\n", + "\n", + "def plot_running_averages(fn, n):\n", + " \"Plot the running average of calling the function n times.\"\n", + " plt.plot(list(running_averages(fn() for _ in range(n))))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's do ten repetitions of plotting the running averages of 100,000 rounds:" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n+L0QYp0QYo0Q4nUhhEUIES6EWCCE2CyE+FIIEdpZhdXBQdM0rXscc3AQQsQBtwCjpJTDABNwKXA3\nsEhKmQl8DdzTGQUFKG/SwUHTNK07dDStZAQChRAmIAAoAc4FXm79/cvAeR08xh665qBpmtY9jjk4\nSClLgb8BhaigUCelXATESCkrWp9TDkR3RkFBBwdN07TuYjrWHYUQYahaQjJQB7wjhLgckPs9df/H\ne8yePXvP/ZycHHJycg55TB0cNE073uTm5pKbm9vtxxVSHvTcfegdhbgQOF1KeW3r4yuB8cAUIEdK\nWSGEiAW+kVIOPsD+8kiPXdZQxtBnh1LnrMNxrwOjwXhMZdY0Tets71VW8kZFBe9lZ3fL8YQQSClF\nVx+nI20OhcB4IYRNCCGAU4ENwMfA1a3PuQr4qEMlbGU2mokIiGBX067OeDlN0zTtEI45rSSlXCaE\neBdYCbhbf/4HCAbeFkLMAgqAizqjoAAJIQkU1xfTP7h/Z72kpmmadgDHHBwApJQPAg/ut7kGmNqR\n1z2Y+OB4ShpKGMvYrnh5TdM0rVWvGiHdVnPQNE3TupYODpqmaVo7vS44lDSU+LsYmqZpfV6vCg7x\nwfG65qBpmtYNelVw0GklTdO07tErg8OxDtzTNE3TjkyvCg6BlkACzYFUNlf6uyiapml9Wq8KDgBJ\noUkU1hX6uxiapml9Wq8LDslhyRTUFvi7GJqmaX1arwsOSSG65qBpmtbVel1wKKgr4A8L/uDvYmia\npvVpvS44WIwWfxdB0zStz+t1weGZGc8QZgvzdzE0TdP6tF4XHPrZ++H1ealpqfF3UTRN0/qsXhcc\nhBCkR6STX5Pv76Jomqb1Wb0uOACkh6eTv1sHB03TtK7SK4PDspJlXPrepf4uhqZpWp/VK4NDdGC0\nv4ugaZrWp/XK4PDyeS8zMHKgv4uhaZrWZ/XK4JARmUFBbQEur8vfRdE0TeuTemVwsBgtJIcls7V6\nq7+Lomma1if1yuAAkBWVxfrK9f4uhqZpWp/Ua4NDdnQ263at83cxNE3T+iQdHDRN07R2dHDQNE3T\n2um1wSEjIoOi+iJa3C3+LoqmaVqf02uDg9loJiMiQzdKa5qmdYFeGxwARvUfxcqylf4uhqZpWp/T\noeAghAgVQrwjhNgohFgvhDhBCBEuhFgghNgshPhSCBHaWYXd36j+o1hRtqKrXl7TNO241dGawz+A\nz6WUg4HhwCbgbmCRlDIT+Bq4p4PHOKjR/UeTV5bXVS+vaZp23Drm4CCECAFOklK+CCCl9Egp64Bz\ngZdbn/YycF6HS3kQw2OHs75yPW6vu6sOoWmadlzqSM0hFagSQrwohMgTQvxHCGEHYqSUFQBSynKg\ny6ZQDbIEkRyazIbKDV11CE3TtOOSqYP7jgJuklIuF0I8gUopyf2et//jPWbPnr3nfk5ODjk5OUdd\niFH9R5FXlsfw2OFHva+maVpPl5ubS25ubrcfV0h50HP3oXcUIgZYIqVMa308CRUc0oEcKWWFECIW\n+Ka1TWL//eWRHrusoYxR/xlF2e1l7X4394e5vL3+bZZft/yY3oemaVpHvFdZyRsVFbyXnd0txxNC\nIKUUXX2cY04rtaaOioQQbQsrnAqsBz4Grm7ddhXwUUcKeDgGYWBF2QqONchpmqZp7XW0t9KtwOtC\niFWo3kpzgEeBaUKIzaiA8UgHj3FIt0+4HYCi+qKuPIymadpxpSNtDkgpVwNjD/CrqR153aMhhODs\ngWfzU/FPJIUmdddhNU3T+rRePUK6zQnxJ/BTyU/+LoamaVqf0SeCw/iE8SwtXurvYmiapvUZfSI4\njI0fy6ryVfx58Z9ZVrLM38XRNE3r9fpEcAixhpAekc4DuQ9w3SfX+bs4mqZpvV6fCA4AgeZAAFZX\nrPZzSTRN03q/PhMcEkMT99yvbq72Y0k0TdN6vz4THF47/7U997/Z+Y0fS6Jpmtb79ZngYDaaAUgO\nTeaW+bf4uTS9w/Ll4PH4uxSapvVEfSY4APju9/HGBW9Q3liup9M4AmPHwvjxsGuXv0uiaVpP06eC\ngxCCiYkTSQ9PZ1X5Kn8Xp8cLCIATT1RBYsUKeOwxGDcOGhv9XTJN0/ytQ9Nn9FT5u/MZ89wYvPd7\n/V2UHs1ggIcegsmTYcyYvdvHj4d334VBg/xXNk3T/KtP1Rza5F6VS3Josr+L0SsIATNnwvbt6vHc\nuXDLLTB4MMyb59+yaZrmP32y5nBS8km0eFrIr8knPSLd38XpFVJTQUp1EwJOOAFmzIAff4THH4eo\nKH+XUNO07tQnaw4GYeCsjLP4aHOXLiXR6x2ozV60LiEyYgRs3QqhoTB8OHz+efeWTdM0/+qTwQHg\nV1m/4q31b/m7GD2eOMR6UoGB8NRT8OabcP31MGsWNDd3X9k0TfOfPhscpqROobCukI2VG/1dlF5v\n8mRYs0Z1eQ0KgjfeOHCtQ9O0vqPPBofCnSZ+O/Ja/vXzv/xdlB7raE7w4eHw6afw3HNw112qp9NL\nL+kgoWl9VZ8MDmVlkJ4OCcW38fra16l31vu7SD3WodJKB/Kb38DOnfD++/D00zBxonqNV19V7RJ6\nQJ2m9Q19Mji05cWXfB3J1LSpvLL6Ff8WqI8xGuH882HpUtWjCeDJJ+HMMyEmBjIyYKPO5mlar9Yn\ng0Pb1fDLL8N1w2/h6WVP6+k0DqCjH4nJBH/6k3qdZctg/nzYsQNOPhmGDIHrroPy8s4pq6Zp3atP\nBgdQ/fYHDIC6tZOwGC18teMrfxepRzratNLBGI0wfTqkpMALL0B1NQQHQ//+6hiLFun2CU3rTfps\ncAC491545RXBzeNu5ullT/u7OMeViAj429/UWIm5c2HaNMjMVI3abre/S6dp2uH06eBw4YXw8ccw\nXFzBR5s/0pPx7ac7ruQHDIA//hG8XnjgAfjrX8FigT//WU/wp2k9WZ8ODkFB6uf40XZmZMxg3nI9\nWdD+OiutdDgGA1x+OSxZomoP336r0k5XXql6lx0LnabStK7Tp4MDQEmJ+nlD7Iv8e8W/2Vm706/l\n6Un8dXI980zVBtEWFIYMgWuugcLCoyuTwQCXXqoWLfLqCXg1rVP1+eAQF6d+nnNqNJOSJvHMsmf8\nW6AeprtqDgcSG6vGR6xeDQ0NkJysTvh/+xssWHBkgWL4cLUehdkM//yneh1N0zquxwWHP3z5B2a+\nNbNTX7OyUv28OeYtHl/yOKUNpZ36+lrHJCWp9SOam+GLL+DZZ+H00yEsDP71r4O3TQgBd94JPh/8\n8AMsXqwCzE03qdfTDd+adux6XHD4fOvnfLDpg059zX791KCtS85U1YjrPrmuU1+/t+ppOfuAABUU\ntm1TJ/znn4evvlLdY++8E4qKDryfEDBhggoIa9aov/evfqUCxa23Qn5+t74NTesTOhwchBAGIUSe\nEOLj1sfhQogFQojNQogvhRChR/N68SHxHS3SAb39NqSlwfvjd/Fj0Y+UNRxjK2hvtnLl3kaYVv5M\nKx2KEOoE/957aoCdxwNDh6q/4bvvqscHkpAADz6oAt/ChdDUpJY+TUtT2w80cvull1QQycvreQFT\n0/ylM2oOtwEb9nl8N7BISpkJfA3cczQvlhCS0AlFas9kgjvugBefieKq4Vdx4+c30uJu6ZJj9Vgz\nZ6qz51NP9aoW3LQ0+PvfVYP1rFnwj3+o2sThTuRZWWpAXnm5mt7ju+9U43dmpnq8Y4d63ptvqnTW\nBRfAsGFqLe0lS1SAuvlm+P57naLSjj8dCg5CiARgBvD8PpvPBV5uvf8ycN7RvGZCsAoOXTHdxdVX\nw08/wfn97uXDTR9in2Nna/XWTj9OjzVggAoMH3wAJhN3eB9R+ZteIiQE7rtPneQ/+USNmziSmo/Z\nDOeco3pIud0wZ446+aelqcF5CxbAX/6i0k9PPw1btsAZZ6iZaGNj4cYb1Up4M2eqWWkPlt7StL6k\nozWHJ4A/AvueyWOklBUAUspyIPpoXjDYGgxAnbOug0VrLyBAzSo6eWw/7j/5AQDOfONMvL7ecxXd\nIV6vunT++muYN48rfK9gjo1Qrblta4T2EiNHwuzZR58WM5lUDeGtt6ClBa69Fk49VU0WaDCotSue\ne07VNlavVsFozRoVMGbOhNxcGDVK1UruuEMFHKezK96hpvnXMa8hLYQ4E6iQUq4SQuQc4qkHPePM\nnj17z/2cnBxycva+THF9MWG2sGMt3kHdcw88/DCkF9/PuaXn8dHu85i3Yh43jr2x04/V4/h8ahIk\nIeC66xhx429pfvS/mCZN2vucRx6B224Dm81/5ewmNhtcdJG6Heh3iYl7H0dHwxVXqJvXq9on5s+H\n+++HdetUUJk+XdU40tK67z30VJWVcMMNMH686iwwerS6ONOOXm5uLrm5ud1/YCnlMd2AOUAhsB0o\nAxqBV4GNqNoDQCyw8SD7ywN5+LuHJbORn2/5fM+20vpSGft47AGffyD5+VKmph7896+9JmW/fupS\nOXtEk+w3t58sqis64tfvtSZNknLx4j0PjUYpXS4pZX29+lCef15tDAuT8pVXpPR4/FfWXqS6Wsr/\n/U/Kq6+WMjZWypAQKadNk/Jf/1L/i8ejFSvU9+vWW6UcM0ZKu13KE06Q8ve/l/Kdd6QsLvZ3CTvP\nu7t2yZlr13bb8VrPncd87j7S2zGnlaSU/yelTJJSpgGXAF9LKa8EPgGubn3aVcBHx/L6O2p3HGvR\nDuuyy6CqSt1ft8qO/X+LSXwikUZXH5/sp63msA8hUPNYXH65yrl5PGpCqmefhdBQ1frrcvmnvL1E\nRARcfDG8+KLqDPbll2pw3iefqEWnhg1TNdYffuhV/QA6bORI9e/z88+qJjF3rqqBvfKK+nwiItRz\nbrhBdVvOy9Mpup6kK8Y5PAJME0JsBk5tfXxUBIL8mq7rnC6EyiEDXHUVFOYNwf7O19zx5R+77Jjd\nqqpKjRwbOVIlxdt4vSqx3uqgTQwnnaTOZC+9pL7dUVEq91Jd3aXF7gsMBpVKeewxtTKexwP//rfa\nftNNajGkyy7b2/uqFzXzdIjdrtb5uPtude1RWak6h9x0k2r0/+47+PWvVTpv+HC1Fsjzz8OKFeBw\n+Lv0x6djbnPYl5RyMbC49X4NMLUjr5cekU7+7q4duZSRoXqsjBmjGhfvvPMU5r30PPPyBL77fYie\nOgDgSERFqYUUysrUt2zQINWR/wA1h4MSQk1re+GFqi/n+eer0WWXXaZW+Bk0qGvfQx9hNKqlVCdO\nVDPSFhfDZ5/B66/D7berP9VZZ8GJJ6rc/KBBv4jffZYQ6juYkfHL7U6n6gjw009qxPs//qF6kZnN\n6lpn8mTVfjFqFMTH99xxOn1BpwSHzpYens78bfO7/Djjx6uff/yjulieMOF1SFtI+lPpbL9te5cf\nv8skJqoRZE1N8MQTqsvNGWeo3+135jmiL9ekSepSb9s29XqTJ6sJje65R53VtCOWkADXX69uUsKm\nTfDNN+r2179CbS2ccIIKFBMmqP/R4GB/l7r7WK1q0OK4cXu3ORyqBlFYqBr/n31WpaA8HpWyGz5c\n3YYNUxd6x0Ffim7RI4NDSlgKLq+LwrpCkkKTuuWY48erlHvRpu0s75fCa2te44phV3TLsTud0ahG\nb6Wmqsd/+5vqovXZZ+ob1OqoUxoDBsAzz8Djj6vE8eTJKlX1j3+oDy8wsPPew3FACBg8WN1ubO0s\nV1GharRLlqixF999p/L0Z54J2dmQk6P+hKYe+c3tGjabugbZ/zqkokLVMlavVtOsPPGEWlwqPl79\nq6anq55jEyao0fXHU5DtDD3yX6ytC2vyk8nIB7ovKfv005CREUTNp1VcWRNJRkQGJySc0G3H71IW\ni0oN7eeYquUBAerS99prVWvjY4+p7q+gUk7XXLM3MGlHJSYGzjtP3QA8+QVsX9/CoqJMvlwgmDNH\n9Q8YO1alqiZMUENXkpJUSsblUv0IjgcxMXDaaerWxuWCnTtVm+LatapG9r//qWndhVApqbagUVWl\n0srZ2arGcbx8bkeqRwYHf7HZVA+TkSPB9kwZ4202cq/5hskpk/1dtJ7JYFA5kHffhc2bVZJ43TqV\nE2jrDnbzzfC736nkutOp8ira4Xk8MG8epptvZiAwMCKCGxMT4boZNAwczc9yDF9vS+KxxwS5uarB\nt7lZ7ZqQoGoX2dkwYoQKHJmZsGuX+nmkzU69kcUCAweq21ln7d3u8ajMaEEBbN+u2jHaamnPPw8b\nNqgR+G01ucxM1cQ2YoQKJhaL/96Tv/TY4PDF5V8w8+3Onbr7SIwYoa4+LBYLtnk7yRHJFP2hqMvm\nfPKnTu0pk5mpbqDSTp99pr6BX3+tEsJtM+UNGKCGFl9ySftLNSkPXJXZulV923/9a9Xl9pRTVAtl\nZ5FSlXPYMBXEeoLiYhVYp0yB115T/5QLF0JJCcHvvcSUn29iiterLn1vz6IlcwRrzKMZcGYmtfUG\n1q5VcfrVV1XHs/p69bLBwerPlJ2tbkOHqltsbN9u3DWZVB+N/v33tjXuy+dTH/nGjSpQbNyoPrfG\nRtU9ua2L7bhxqlKcmqrm90pNhbJQI15z3/vwemxwOC39NGwmm19mTzWbVVvupElJtCzYRiKJlN5e\nSv/g/t1elq7WJSeEfVNYd9yhLmnfflt9s4qK4D//UXNwx8er502Zotovpk1T81P89rcwY4aa1yIk\nRJ3Z4uJUF5U//UnVUuLj1fNnzlT5lY4k4QsLYWprBzurVZ01Z85Uxx892n8J/uRklUxv89vf7r0v\npTprLV0KP/9MwKJPOOHn++H3u4kcN450m43zcnLgrlEwciS+oBAMBqipUR/funUq7fLZZ+qnlOpt\nDxum0lTDh6satMVyfPSeMhhUDSspSU0bvy+nU/2LWCzqI9+xQ91+/ln9W6/bFkpVWRgJ0b8MGgMG\nqN5nmZm9M2UlpJ86Wgsh5IGO/cj3j1DrqOWRqY8Q9VgUN4+9metGX8eo/4yi7PYjCxTbt6vv+vYO\ndjgqK9u7khyB5fy4cjcTMgYf9AJ3Xy5XBQaDHZPJD61gqanqSvgweX8h1BWTX64Yd+9WjdoffKDS\nUeHhatuDD6rL2/nzVZ1/7Fh1afv996rLCqh8wDvvqG9obq7KFcyYoS6TTzkF55QzWJt2LsMuHHhk\n6YAdO1SA2rJFzcK3bp06C+TmqrNCTo4KXosWqRP2jBkq2R8Z2XWfz86d6rg7dx7dfhUVqh9o21J6\neXlqciiLRXWFys5WqcC2ecwHDEBu2UpVZCaraxJZvUbw00/q425bxjU5WZ3kFi9WjcKjR6sTXnS0\nCiaJie3/h/LyVCzLy+uEz6KHe6+yktdKKngyPHtP4NixQ3Xu27xZ3YKD1dcxLGzPx05GhkpZpaSo\nlFdgoPoaHO77KIRAStnl39oeW3MAsBqtPLH0Ca4b7Z/Fefr3V+eI+HigKZaJA2P5538ruGVWDNdc\nA//978H33bDhUmprv2HUqKWEhPSRRu3OFB6uGrHbGrKLilRAuOACddL9/e9Vnf6rr1SbxogRe/eN\niVEpF+Chh6B2bRFjd35MdIKkPuE8Uj75grhlORRdGUi6bxsbx19N0MzTSLhqKkRF4XQepLuj2ay6\nBZ155t5tFRUqKPzwgzpjpqSo+b4vu0z9g4wcqWbpa25WAWPqVJW38Fd6KiZGTUF7zjl7t3k8KjVX\nUqKuBpYsgR9/VHOV5+YigKjoaKa63UwdMUIF4wez8QwbhWNANmu3WFm1StUmsrLUn2rBAhWrGxvV\nWx86VNU4srJ++ac6XhhMKogmJ6uYvq+2St7OnSo+5+erP8f8+eoCtrBQZQ3tdlVJbUtbhYWpc8/g\nwSqrmpGhtnWXHl1z+L7we2774jY+vfRTv9Qc9iUlpI7eQsHKgXu2XXaZulg9ULV748araW5eT0PD\ncgBGjlxCaOgBkp1d4ShqDr19hO6wYSqWbNmiTlClpaot/FcX+PjTmSsoePFr1hcG03/Nl5zQkkuZ\nNYXPHVMoSojEcrKJYWcmcWqajehLb0fmb0VKJ0bjEXTJ9Xph/Xp1hvz+e3VlHhiortKXLVOX05Mn\nqwE0kyapKujRVNGOtebQEW1T0a5apd7bypXqLBYXp85OI0eqCJGdraoOre0+1dXqbW/YoHZbtUrd\nPB6V+RsyRL3EiBHqfkxM972l7vBeZSVvVFTwXnb2Me3v9arMaViYqjzvW/tYt06ltbZsUX8Kkwlq\na3XNgRPiTyC/Jp/qliOftuHRR1Uvg84mBOzMG8g1f/2CD1d+x8d//jVnTcjEalVVwgNF9Li4mwgM\nzCIvbxwrV04gJeUvJCXdjcHQoz/2XiUqCv7v/1TzQBsV8AwIMZZ+08cyGoAbKdjmZtvLKxi7/J+c\nW/I+Ue83UPduED96RjPG4OJPsx5ixIhvGDmyhn79hhARMZ2wsJOx2dLaj5g3GlVkGjZMdd3dl8ej\n8inffgtvvKEa3+12dTV/0kkqVTZsmGrf6EliY9Vt36S706nSdps2qTP+O++ohTQKClSCftAgIg0G\nTomM5JRRo+DCwXDfIJaX9OfqawTXXqsCxuLFKoO4fr06wbU1iGdl7R0pHRd3fLRv7M9oVBVpUPNN\nRUSo1N0lx1p5AAAgAElEQVT+pFSBuLsqpT36LGU2mpmYOJGfin864n3uvlv97Kpu9i/eO50pqys5\n++MT+Pv8F3j8NxcwfLi6UE9Pb//8kJCx5ORIHI5i1q6dQVHR44wZs4qAgJSuKeAR6u01hkM52AV6\n8gAzyX8ZT0HBV3i9KQSnPkTwhg1Eff4VW9YOx+O5nFdfvYN777UxeHARw4atw+X6gpNP/orx48OI\nippEWNiUw//tTKa9w3zvuEN92Pn5akTb99/DvHnq8fDh6iwwfrwKFqmpPW8godW6t2/ovqkqp1NV\nzTduVIGwbTTa22/Dpk2MbGrhf3IQ2R9nc15WFsxSEUCmD6C4wsz69SpQLF2qat9bt6qrZ59PVZgG\nDtybpgoIUCfMxMTO7aTW2wjRNRe+B9OjgwOoAPGnb/50xM8//3x1hdKVq3VdOfxKzEYzl753IX94\n8nbsPz7CgAEmvvtOZRAOxGZLYMyYVRQV/Z28vHG43ZVYrQmMGPGd3wPFcUsIyMrCmpXFUOC11s2N\njbB0aSq5uaksXix55pnfcNttRtLTC0lP/5bMzOcZPVqQnr6S/v3PoqLiZUJDJxESMp6QkAlYrXHt\njzNggLq11TIaG1XDcV6eWij78svV9thYFTCsVpWM7qms1r2DAma273K+Lnc3T1y3kZfGr1O5ka+/\nhi1bEEVFJCYlkThwINMHDYJJQ+Ba9ToNxjA2b1bNPJs3w+qlLXz8XD1L8qMxGAWNjSpAZGaqRt22\nHH9iovoZE3N81jy6So8PDg+d8hDjnh9HqDWUGa/P4IwBZ3DLCbcc9PlGI9xyC/zzn2qlsH3WE+pU\nl2Rfwqj+o8h8OpPMqE959d0fOOmkSIzGvb08XnttIIsXw8svq7y4EAaSku4gPHwKa9acjsUSz4oV\nYwgPP5WUlAcJDOy+yez6cs2ho4KCVJuV6t0qABuNjbBmTTorVqTx88+1zJ7tYceOEDIyShgwwMjE\nibGkpn5JRMTNBASYCA4eQ1DQaIKDRxMYmI3VmoAQAo+nDqMxGBEUpHJh++bDXC51Nb5+vUoyT5jg\np0+g47wh4awJmgjXTfzlLxwO9R63bFERIDdXTZa0cSPBVitjvF5ISuLMceOgpADyFqlqQ1YW3oxB\nVIemUmhIZZtMZ+22NJb8GEFhkaCgQHU/T09X37XMzL2NuCkpKniEhPjjk+i9enxwyI7OxuFxYDaY\nmb9tPvO3zT9kcAD1TxEernpFnnmmSvF2hYGRA/Hd72POd3O4e/lwPl3xIf9+YAzR0XDRRVfx9tvq\ni9Gvn+pc8/e/q2pxcPAoTjyxEoCWlu38/HM2lZVvExPzawYMeBKzObxrCqwds6CgttlVBaD+Ps3N\nkJeXxvLlaSxfDi+8cDabNz8NwNChu8nM3Ep6+lIGDHiKtLSVhIam0NDwEwZDAEFBwzEagwgNnYTV\nmkBQ0CgCA7MwDBrUt2e8tdlUvmjIkF9u9/lUT4LychU8ysvVhz5njmrbWL8e4+bNRO/YQfSOPMbk\n53NJfr7KRUVEQFoa7qQ0ao39KAgZyqamVHasSuO5BcnkF1koKFDfveRkNYI8IUHVPiIiVCBJSlIZ\nPXUR55+Ppqfp8cFBCME5meewaPsiTko6ie8Kv2Nn7U5SwlIOuV9YmKrtjhunJg+dM6frynfvyfcy\nLGYYV300ndBpoTz366+59qJTAGhogE8/VWnmcePUZGr7DusPCEjj5JObaWkpYtOmK/nhhwji4m4i\nNfUhzOau7bemvwQdY7erNOK+qUSXS+XPt28P58cfx1FVNY4vvriVLVskAwfWM2ZMDRMnxjJ48Boi\nIz/E7d5Nbe33FBQ8hMtVgcUSQ0jIeGy2dGy2FIKChhEYmI3RaPffG+0OBoMaONE2eGJ/MTFqLMq+\npFQRur4eCgow5+cTlZdHVP0KxpS9q7r7FBdDTAxyTBrOuDRqQlKosCRQ4opmy6pYFpYk8I/qGLbv\nEDQ3q9iVkKCCRVvaqu2WkqJ+d7y0e/T44ABw09ib+GzLZ3tGKP/tx7/xzxn/POx+zz2nTswPP6z6\nF//rX11XxrMzz+bba74l619ZXLs7hf/MH0h4y8MEBc3kkkvUSmFvvglnn62e/+KLaqEhIdTiJ+ee\nmwjk8v77mzCbT6W09Bksljiysz8kJKTzqz46rdQ1LBbViJqVtfdvDdDSIli5MpQlS0JZuBDmzDmB\n/PwTsFpV225aGmRne8jOLiUtbSVxcd8TGvokQjTidle0BoqReDx1NDQsx+3ehc2WRnDwaMCA11tP\nYOBQgoKGExg4FLt9IAZDD+sN1dmEUJf7gYF758Voa7tp4/FAURFi+3Zs+fnEFRYSV/wtIysrVb/n\noiJoaVFn/pgYPKGRtNS72BU7jDJnHI3fNlLUHMnHjUmsrE6ioMJGS3gcsQmmPTWQ2mGwMwnmF6lx\nCXFxqkbS29s/ekVwyI7KRiLZVLWJi7Iu4umfn2butLkEmA+9YrkQqna6ZIlKCZx+Opx7bteVc0jU\nEOQDklpHLe9+O5aPG2+gaVUDVw6/EoMwcNllKkjceadql3z8cTVV8003qf1//3u48spBGAwl3H57\nDRMnXseaNdOx2wcRG/trYmNnYTB03mWLrjl0n4CAvYv+tKmrU2n3tlz42rUmVqxI4v33k9i48VzK\nyx8jIgLGjvWRnFxFfPw2YmN/JCUlgSFDpmM0BtDUtA6XqxSjcRA+n4Oqqg/ZufPPOJ0FWK3JBAZm\nExiYjd0+sDVoZGIwHEezyO07qmzf9p19NTSoVFZBAab6eoI3bCDYaiK9dBXYiiHQCLYGqFgPvkpk\nvRl3aRRNLQm0bLaxcVUC62KC2bZlGAsbo1hdFU+JI4LA2BBsyTH0TzASELC35hEXt/cWHd1zJ0Ls\nFcFBCIHVaGVNxRrumXQPb69/m9m5s3l02qNHtP+ECardKydHdZu7oouXaQizhXFi4okkRUdw8Zf/\nj6d/fprrR1/P+ITxOD1OrrjDwGOPjeTVV/d2Xvn2W9UF/rHH1MywV18dwezZ73LHHW6uvTaXysq5\nFBbOJSHhNgIDswgJmdD3Uw19XGjoLxe1GTRIrdHUpqlJdWYqKzOQnx/Npk3RfPjhRDZu3HctiOkM\nHqz2bbsZjeDzuWhu3kJT01qamtbvCRoOxw6s1gTs9kzs9kwCAjKxWvsTFDSitdH8yM9UnkYPnhoP\n5mgzRlsPPcPto6LidQoLHyUoaAQWSxxWazxWawIWSwymAeFYhpyIyRRx2FUghduNpbwcS1ER4du3\nU7ljB7FlZVzcf42a+ra0FFldja+2HrFiN44tUdQHxVHxQzw1tngKvAn81BLPpoZ4NjfG44iMJzwh\nkLgEw57aSGKiqgxFRamMWr9+3V8T6RXBAcBmstHiaQHgm6u+4Xef/Y6Hpz6MQRzZJzZ5smp7uPJK\n1b186NCuLK0yNGYY1XdW8+baN7nig19GpEuzL2XOuXPweFL49FM1uSaoL/Z556k0WEkJ/PnPZjIz\npwHTmDmzgssvP4eIiGUABAePIzX1IcLDT0Uc4efQRqeVer7AQHXBsD8pVXfPjRv33r74Qo1Tq6pS\nPWZDQizEx2eTnJy9Zx6ftDTo39+Nx7Od5ubNNDdvpqFhOSUlS/F4qnG5ygGwWhMxm6MIDZ2E3T6w\n9QQah9WaiMUSs+fkuf3O7ZQ+W4qwCIxBRiwxFixxFmwpNkrNIbhroqj6qA5LnAVrghVzlBmDqftz\nLS07W2j4uYHqmJ8xWWIwbBiDK6wCh30tjsbP8Vqq8YrdOJvLQfgwNsdhcsRj8vTHao7DGhhPQHgS\n9n79sccmERAah0hMVGfwiRPZVlnJ2xUVXLzPCGkBGAFcLuzl5dhLS4ktKVFf6pISKFkPJSXI4hLY\nno+o8OFdbcFrtOARZpxY2W4bQpEvmm9dcRS442kOi1NdnbtJrwkOFqOqChfWFXJx1sVYjVYW5i/k\n9AGnH2bPvebMUaMyzz5bdTHvjmH8BmHg8mGXc+nQS2l0NbKzdidhtjBeWvUSo/8zmlkjZnH31LsJ\nCGg/iVt8vGrIvu8+1V7y448xXHPNT5x1lo9Zs8oIDn6U/Pw7aGpaQ0zMFSQm/pGgoPaNeV6vg507\n/0Rk5FmEhk7ac3Wo00rdQ3olGOi0dcmF2DuY+ZRTfvm7pibVS3T5chVAjEb1v/7aa6p9tqLCTP/+\nmSQnZ5KergJJ2xi3rCwXAQH1NDdvpLl5M15vHU1N66iuno/LVYrTWYTP58BmS8duz6BhnIOwU+OJ\nHDcIoyMKX70JUR2HLLDjW+rDW++h9LlSXGUuWra04G30YulvwRJjwRRhwhpnVYEjzootxYY1yYo1\nwYowCNxVbqwJVgw2A8LYsc+t7LkyCucUYnmgDk9xGnUvDCPslDBcZS7MMWaEU+Jc14Rw+0h+tB8y\ntBSXLMblK8XZWExTzbd4yirwWauRwVUQUg8mL9RGYdqdTES/Iq6qS+GnpUmYff2xBvTHFpSAyROL\npb+NgOh+2IdmYznAXOECVLT3ejHW1WHctQtLdTV2k4nRDQ17aiKegkIcO5biLS7nmQ59Gkeu1wQH\nIQSvnv8q4xPGI4TghjE3MP316bTc24LNdOSLxl52mfrynHmmGrAacOhmi05jEAZCrCEMi1En7/sn\n389vR/2Wvyz+C5lPZ3Ld6Ou4YPAFjI5rP24+MVE1qoOqUTzxTCPX3hCFxfgUEyZI0tK2M23ah1RU\nDAdgojuQ+qrPCU+6GqMxELe7gqKix6mp+RKnsxiPZzcguOCCx2lqmo7dPrjTTlzaXo5iB8YAI2vP\nWkv90nrCp4YTODwQ+yA79oF2LDEWjEFG3NVupEdiH2zHGNCx9ExgoJoCaeTIA//e5VIdeNoWvdm6\nVc3woXpYWbDZ+pGefhJpaSftWTGt7WdCAvh8tTgc+TQ3b6WlfikypB6HIx+HIxevsU5dkdt2skuM\nxvfDPORf/0iwLZkoWxpWcwLGpgSMtTHI2jDcpW6cpU5atrVQs7AGZ5ETZ5ETz27PL8ps7mfGXeXG\nEmshIDMAa38r5hjznuBiDDRiCjOpmktr4Nn//zn1oVS8l8ZiNIaQ/HzOYT7FrIP+RkqJ1+GiZVc5\nztpqmoIL2Fi+geJSG0m2JtyU0WRZQV3953isJfhaimFNOOysAYcdURuNsSUaT0kA1IVAXTgB4bE4\n19qRFVHYo5KwBsVgibRhjorCEjsIS7wF8zAzpnATlmgzpHZPOrnXBAfgF2s6XzX8Kn732e946qen\nuPPEO4/qdR54QK2bkpmp+jV/9ZXqXdDd4oLjePasZ7lj4h3c8NkNPPz9w7/4/V+n/JWzBp61J6CA\n6qL7Z08oXA4UTaT0u6dpeGkkD/7lNgICbuOWm2oZ7xtMZeVbrPvuVgyGAPr1U91mxo5dg9NZQm3t\nd3i9guTkRaxd+098Pif9+p1LdPSlrTWLXt7NogfwtnhZmrgUU7gJT62HofOHgg8a1zRS/0M95S+W\nU/9j/S/2EVaBJUqlZox2I9YkK8YgI8FjgwlIDcCWattzZX2sLBZ1ok9La1/rkFKlpdpWStu+XU1G\n+8or6n5lJcTFhZGaOprExNEYVp1GWIKJcVeEkJKiarmLF8PQoZKqKi8tLT4SEm7D4SjE4dhOY2Me\nDsdOWpz5+KxOAoakYR2ZiMUSTZAlnkhrPGZzJCZTP6zWWMzmaIyE4d7lQRgEPqcPx3YHjiIHnt0e\nXKUuGlc30rKtBXelG2EWuCpcSKfcEzys8VZa8luIuqBzJiQSQmAKsBKcnExwcjL9GMXyykl8VVHB\njYeYeM/n8+LYXUFTxQ6aqwpxxu7GGN+Iq6Uct7cA4/QKfIEVOD1lNMtaDN4IDK5gRHMY1IciN9ug\nLghfefdNy9qrgsO+AswBrLp+FSPmjWDm4JkMiBhwxPsKodaWHTxYzSU2YYJ6HBd3+H27QnpEOguv\nXIjX52VJ8RLeXv82NS015NfkM/zfw4kNiuWaEdcwa+SsPe9z661b2Vy1mdVXz2dD5d94ffWbeEpO\nY+4353BtuZ0Z196EafylXDOjhlMCfkCIp5ASLJZ4YmIuwe2GJ564mLlzobl5K5WV77J168243dVE\nRs4gImIG4eFTMJl64SolPYD0SgyBBibVTEJ65Z7USOSMg68B4XP7cJY4cRY68bl8OAuc1C2pY/fC\n3ZQVlOHYoU6KtjSbChZpNmypNgLSA7Bn2rEl2yh4qIDdX+0mcFggpmAT5n5mrAlWSv9diiHQgDXe\nStCwoD372lJsGCwGDBYDQqgG0KgoteTD/pxO1fOzbfjAqg0+CqpMlH6oJo9dtgz+/W+IiREUF5uI\njYXIyBkHfK8eTx0tLfk4nSW43btwOktpbFyJ212N212Fy1WB270Lr7cRs7kfFkscLS1b8RrrCcwa\nhsUSg9tdo3piAVJ6sFrjEcKARSQimiLx1djwVdoxVVdjH++lvGkdISH+GXVuMBixR8Zhj4wDTjzk\nc30+F253JW73bjwe9Xl4vU243dW4XBXQhV3y99VrgwPA8NjhDIsZRsY/M5APHF0Lq8WiFuPweNRM\nrqNGqYXI95+LvTsZDUYmJU1iUtLeUVXzzp7Hx5s/ZtH2RUx8YSJDY4ZiNpiJCYxhQMQAzhyo1h54\nbeZrSCn5tuBbwiY0cOmvm3nn25N46K5Y7q2+9xfHGTK2nBNHReDzWXC74aOPMsjMvIcxY+6hpWUz\nVVXzWb78PUpLH6C2dizDhuUzcOBpREScQVDQ8IPWLGpqFmGzJRIQMOCoer30dUeaMzeYDQSkBBCQ\nsjfX2f83v1x90NPowZHvoGVHi7qKznewe8Fumjc14yx2It2SxLsSsSXZcOx04Ch00LiqEUOggX7n\n9cNZ7KRpQxM1X9bg2OGgeZNaeNoSZ1HBIknl/tt+WuOtWKItWGItWK1izxRRAJt/qiZohJP4G44+\nzWEyhRIcPIrg4FGHfF7bidLpLKGlZRuBgdlI6cHlqsDh2IHBYMPlKsPl2oXJFIbbvYtax1dI6cYT\nXE+zcSO+6GZqmsJwOouJjr7sqMva3QwGS2tPqviDPOPIeml2VK8ODgC5V+USMTeCDzd9yHmDzjuq\nfYVQox3vu0+Nn7n4Ypg1C/76154zgMVkMDFz8ExmDp7JE6c/wYebPiQ1LPWAYzyEEExOmQy2UOZc\nl8Och1OREpbnecjd8jP5jmVsLCklv7iWl1aPxBcxGYtlMACx8U48Tgvjx2cSFpbJa6/tfd2goGbi\n4mrIzFzK5MkPMmTIQhISphIePgWLJY7Q0EkYjcGsWTMNmy0Fp7OUoKDhhIZOIizsFMLCJmMy6Ylt\nOoMpyETQ8CCChge1+530SlyVLiwxliNuQ5I+ifRJXKUuHDsdOIucOAocNK5ppPrTapwlTlwVLjy7\nPVj6W1Sw6G/B2t9Kw/IGgka0L0dn2vdEGRIy7vA7aJ2m1weH8IBwXj3/VW6dfyvnv3U+5xkagKP/\nh506Vc2mPHAgPPKIWlf3GNfu6DJWk5WLsy/m4uyLj3gfIWDsaBNjR08A9lapaxobiR6/iJyHHmBX\nmZXNprexNw+k2vEbKjeeTehpn2OZMI+zh53EySmTCK2exndfXMgbb5zNpk0GMjLqGTFiOZmZLxMa\n+l/S0oqx2WD8+B14vc00NPxMbe13FBc/yYYNlyCEGau1P6GhkwkJGUdw8DgCAwcjpRchTLqdoxMI\no8Aae3SjooVBIAwCW5KqNRyMz9ma8ipx4ipz4SpzYQgwEHZyNy5NpnWrXh8cAC4fejlvrH2Dovoi\nPhwSzEDPCuDQ1dUDychQI+mvv16ll+64A26/vW/OpRJoDsKw5TwWXd9W23qV4vpiFuQvYEH+vRQU\nLOaJ05+gtKGUT7Z9wOKC/4ctwcaEuydwTdzphNScQtHaaeTmns6CBRAY6CU1tYnx4yEry0509GQG\nDZpMTMx9DBvmorFxDS5XKQ7HTnbv/prCwkdoadm6pzyhoScTFDS89TYCuz0Lo/HIe6FpXctgNRCQ\nFkBAWjd179P8rk8EByEEb134Fk8ve5r/+/r/mFs3moTAHUDKUb+Wzaam2N65UwWJ//xHDUR68sm9\nqzX1VQkhCcwaOYtZI2f9YvsfJvwBn/SxoXIDn275lGW7FrOk+BG2ubcx6JxBnHtNJlOSptNQkE7z\nziGs3xjLvHlGNm1S+6elWdi1awyNjSpfPXSo6p47cmQ9YWE7GTYsiqKi7WzeXEp4+E/Y7fNwOjcT\nEhKHxRJPQMAA7PZMzOYI7PbBmExhWCwxGI0hSOmjdbjRAUkpkdLTqdOOaNrx4JiDgxAiAXgFiAF8\nwHNSyqeEEOHAW0AysBO4SEpZ1wllPaRgazD3nHQPeU/dQ+WYW1l8/kDGPTeCpNAknj3zWaICj64r\nW0qKGnX6v/+p6TZeeUW1Rdx5p5qupS84mqENBmEgOzqb7Oi9ubYWdwsbqzbyzY5vWFy8kPy6f+MM\ncVKYXEj27dlcHzuSQZFDiGw6kbqtWQxItSGlStmVl8Orr4bgdg9j40aoqupPUpKksHDv/BGZmQ4G\nDSonNXUtGRlFREevITr6WSyWSlyucny+ZmprF7F+/TyCglYTEJDROo9QJjZbClJ6WbNmGgB2+yBs\ntlQCAjJobt7cOmGdpmkH05HTnAf4g5RylRAiCFghhFgAXAMsklLOFULcBdwD3N0JZT1iFwY+xcoV\nJn42PsHPpT/z3sb3WPe7dWRFH3xwy4EIAZdeqm7LlsEf/6jmZnr0UTXKWgiYOxfuukvNkfTrX6tp\nOnrDeLLOmD4jwBzAqP6jGNV/FLdz+57tja5G8sryyCvLY3PVRvLKX2fd7nXEe+IZHjuczcGbKZJF\nnHXzWQyNHsqvTAHc+tnvKTR6ARgVNYFJiScR1XwS7BpKTcEZfPKJSQ3c2uHDYvURHWUgc2ALK1cG\n8pe/ZJKa+gMORyFSuqit/Ya6uu9wOHYCRsaOXY2UPtXHvmUrUroICzvlwG9K0zSgA8FBSlkOlLfe\nbxRCbAQSgHOBya1PexnIpZuDA0Dk8r+z/NnfER0YzYXvXEj2s9n8OOtHJiQeWz/ncePU5H1ffAFX\nX61GtU+dCosWwfTpaobNtkFFTz6pUlFhPbytrquCWJAliJOTT+bk5JP3bPP4PGyu2szK8pWUx5dj\nMVpocjVR0VjBxqqN9A+NZsGVC/D4PJQ3lpNXlsca52usNa4lPywfToSo06Jw1hXjbInA6UikuXEy\nseel8fyutazclEKQJYhB/YYSFTqdtKTHibJH0eBqwGYOxGgwEhTUDRNqaVof0SkJEiFECjACWArE\nSCkrQAUQIUR0ZxzjWGREZgCw8MqFfLL5Eyb+dyJvXfgWF2VddEyvJwSccYZaBjQvD55/XgWHu+5S\nDdhSwrvvqlUPy8pUAJk8Wc20aT/OJ1A1GUxkRWcdce1t+oDpe+67vW4K6gooqS+huL6YGRkzsJvt\nbKvZxtpda6lsMlDSUMI3O7/hzXVv4vQ4KaovoqalBlDzciWGJBJsDSYxJJFASyAJwQnEh8QTbgsn\nJSyFtPA04oLjMBr0+AxNg04IDq0ppXeB21prEPsnLLp0/s+1a88lImI68fG/O+hzfD43Zw2cwcrr\nVzJy3kgufvdinjv7OX4z8jfHNKeQwaBmUR0zRo0IbSOECgS/+pVaU33tWnjhBVXTmDZNpaIuuqh7\nJvw7nN40K6vZaGZAxIB2o+APF2zqHHUYhAGz0UxhXSHbarZR0ViB2WimpL6ETVWbqGquoqKpgu27\nt1PVXEV8cDyJoYkkhCRgN9lJDE0k3BZOfEg8sUGxfF/4PVajlbjgOJJCk0gKTSImKIaalhoCzYF7\nxp9UNVXh8Xn4ctuXxATFEBEQQUxgDFZTH1+A5zjW7G6morECicRmsu35fyhrKCPAHECwJRif9LG+\ncj1htrA9t7ZJRXuaDgUHIYQJFRhelVJ+1Lq5QggRI6WsEELEArsOtv/s2bP33M/JySEnJ0dNIfnF\nhzD8djW15BlnHLIM1dUfU139MS5XKSkpDwLt+8vv2HEfRUVzGT06j4o7Knhj7Rtc+8m1zPluDh9c\n/AHDY4cf7Vs/tPnzCS0oJuccyaWXQk2NqmF89hnceqt6SkKCWlf6wgvVxGYdIaWk0eslyGjE2+BF\n7vZQ+34lptFh2DPtGIONOLY7MEeZsfbfe3LqDW0jHRFq2zv1x8DIgQyMHHjI5zs8DorqiiiuL6ao\nvojtu7dT01JDRWMFX+/8muL6YgpqCxgbPxar0UpRfRGFdYXUOmpxeV17vuSB5kBa6lp43/M+f1/y\nd3Y17aK6uZqymJnI6KmY3TVYDIJA3AhTIB5DAP2EixizkQiTQU1z4qljefEPuL0uoi0W4m127DhJ\nD4knNjCK/oFRRNijiAuKJTIwmhZhI8QgCTAaaXI1sX33dsIDwokIiCDYEqxrRN0g/NFwXF4XdrMd\nq9GK2+em0dUIQJQ9inpnPU6vE4CMiAx2O3ZT66jFKIyEWEOwmqyEWEP2BI1gSzDBlmCqNlSxa/0u\njAYjJkP39Ybp6JH+C2yQUv5jn20fA1ejxnhfBXx0gP0AuO++2e17/vhUoyRTpqjL7127oLW7u9u9\nG7P5l/1Jg4JGEVWZTcBvHqKl/EnMWWXsPwjOYLAREDCA1aun4PHUMiXiTFz31vPi6jeZ9uo0clJy\n+Mf0f+xZhnR/NTULCAzM+sVwdim9gEHVPP7yF5VPuvxyNcT6pptI3LEDfvcVTPovERERXFRdzUWD\nBvHvN85iadh0dtXbWLxYrQyWnKxi4KmnqsdH2xvqsaIi7tq+nXCTidO3W/lvnYfl80uxzfMitjp/\n8VxrkhWfEYJHhzDFG0nd0gA1QVmi9bifmdVmspERmbEnHXmkmlxNNLmbiLJH0eRuorShlKbaJhqe\namDhlQv3PG/aqlWcHGInw+xmV/NuSlvqKHY00+JtwuCuo6TJyTZpoN5noEaasUecSGxgFC3Cys9e\nHyWvONsAACAASURBVLu9AgdmaAJLQwsugw8oVTdvMwgTSC+4G8BdhxUPHk8jPlctVukiWLixW0IJ\nsAQTaDQQYjQQbDQRarZS3bwLu8mOwRpJUkAgiQEhRJitmPEQawshOTiK6MAo7Oa9+VGf9B3xeirH\ng3BbOKtuWEVs0N41F2RrFV0IgZSSZnczVpN1z0leSonT66TeWU+zu5lGVyO1jlpqHbU0OBtocDXg\niHHQMqkFl9dFi6eFb176plveT0e6sp6Imht0rRBiJSp99H+ooPC2EGIWUAAcNMHf0HCAsQP2QPVz\n3Tr1Mzoa6ksB+OGHiNZjmxk58oc9aysn3LccYx5AI/8MCeY99yYgE2j74wiioy+nf/9rWLo0nd27\nF/LD9yEMBH684jPu+f5Fkp9M5rT007hp7E2ckXEGGys3MqjfIIQQrFmj1owwGoPxeht+UdyQkPEM\n/rYBa1gI8oVnMN51FwCbns8kKuJ8Iusy1dJuXi9s3EjABx9witsNDQ1cDDx96lR2xk5g8YYT+P6/\nhdy+60RswwaSPdzCxKpSUs4OJStLMv//t3fuYXIVZcL/1bn2vXsuPTOZTJLJ/SYJG+4IEm4KoqiI\nsJpFZOWTRfxWYT9uuqv7Lbqi7uLlU0FWRR8VNlnk7hIQQYEAQgi5EiCZkEySuc/0TE93nz7X+v44\nnclgAHEhDDDn9zzn6TrVdfpUvV2n3lNVb9W7MYG/pUiyp0zy0BStuk1zq8Cv+CzY8kvublA54qhT\nefYegTQEj16d5uakYKcFzb1AXkWPqyjbbZY9DbOHhjh63ghrl7uodliBlYSC9CTJQ5IYeQMloZA9\nLktqSYrEwgTGlNe+LcNEMep5JFUVpZZPX0ruHBjgpp4emnSdJsNgmmnSpOu0GAZTTJMGTSOmKMT+\nh/4ak0aSpBHW25SRYl7DPDzT4zEee0k6Q1FYlm3gjIZX3nzvz+HXGpsB12XY85gdi2EFAUpgIxB4\nQmfI8xh0XfpdF0dKBhybzsoIu61RdlcrjLpVhHSxfIfBwKfsSirCQJcaJSeFURmhjIOLhicMfMVB\nKiPgbUR4o2iBReCO4KtJVLeAIT3iQiICm6QqSCmQEJKEqmIqBqZm4mkZsrpBRlHI6jqaGmOYOHW6\nQZMZpzmWJK3FUaRD3kzSEk8zJZ5De5v3ePYphX3hffVk/PcxLfYXuR34Ol//84neAF6PtdIaXnn1\n0Smv5TeCYH/Y80YQQg8Hw6dMAbpDpwu/+Q1TMq3wrf0D9VK6rFt3JMnkuxBCwz9sMeq8JcjvfBvn\nfQv4zGUL6Kz/DrZ9Lo8/HvYG2touIxabwfLl4V7xAwN30d9/G3ueP4N/mn8GXzni+1y77g+8/+b9\nu0jOrpuNqZmUywofXnwhe4fXs6FnPZceejzvn3Mmhp6hVHqGknIjO4+r0nsqGF4dUza20de2ieYj\nT4W6k8JJh/EUCuHexnPmoDz9NLM2b2bWLRfB4CBfdKqwFoa2LyQYzlG4s43dHMU8clhMY4QE7q2C\nocBlqPZzZ/Ilyswgxpc5gQAFj6/Nn8/X2trG/1/sqFbZOq/MvLMTVKtwxLllvnhPmc3lMjv2jGLt\ntVlUNpjiS9q2WrT2CuLrHBKrukhudxGOJLkgQWJhArPNJHVoiuSiJLGZsdfth+DlqO6q4g65mFNN\n9Eb9z25Vvatapf2JJzCFYKppsqNaHfvuqHSaMxsa6HUcNpZK9LkuPY5Dj+PwYi1dTtNChWEYtBgG\nz1UqVHyfmfE4OU3DDQI0IViUTDLVNGk1DBp1nXpdp07TyGnamFI6WKi13282DJqNcBgrrSiMf5Qz\nuk77AY5KXmkTt9eGLyUF16WzMszuyggjgaSMSU5V6LaK9NslBuwSI65LRSqM+gHDfsBwIAhkANIj\nbY9gSRUbcGQV3esjCByqGDhCx5OAGiNQ4gRqHBQdfAs1sNADG026mATEREBCAV9NYigapqKSVlWy\nmkZGM8gZMUwthid0snqMOj1GVjdJqmG6lKqiCkFSVTGEIFG7Nq2q6EK8IS9AuWtzVL0qDYkGuka7\nMFQDgcD2bXRFJ2kkyZgZ0kY6/DTTJPTEmKKIa3EUoRDTYmTMDAOVAWzPflOHB4WcoJlJIYTs65Pk\na2vTfv/78A95YvM5DG/bzLX66aFfz+uuC124AQ//Icmxx3YDAR0dV9DdfSMAx/7ybIxlJ8JnP8vH\nPgaXpP4Xy3/2Y4oLYMtXILf0k0ybdhmp1IFzC543yq5dX2P37m9gGFOpb/wo3epJFBwf13e5ds21\n7B7agCfSjNhFpqankjbT9Jf7qXpVvnj8F/n899dinn4ywSfOxfdHKRb/SNnaxcwZl4/tGeRXfda/\nZz3Sk8TnxtEyGolFCaQvyRyZIbk4id5QW8VrWQxe9zCVe59l2uz1BHffg1IYQppxWHIIYv48aGlh\nJD+HtdsVlqy6nE8tW8u2nbOo9o9w2twOUssPZ+XK0PdsPh9uDXLEEaHf4sHB0Mz2U5+CSmW/LKq+\nz9ZKhd22jSclOyyLTeUy60rhuOlgr8XMTsGybo0FHQqxLo/mnQGJ7oAgq6BWJFpSxR90yZ2QQ6/X\nkVJSXFNEy2moGRXpSIQhMFoMtJxGbEaM2IxY6CGs5hWstL5E90+66V/VDwK0eg1/1EfLaKBA+rA0\nRouB3qCjN+noeR2j2eDFjMelxZ2sPvkw9noOQ65LSlVJewotlopWp6HGVLpu7KL4eJGen/VgTjfR\nMhpKXIEGDadRxWpUKNbDkBHQlI+hlySFvKCnXjKYClBSKrs0h27PZdB1GfI8hlyXchCQ13Uqvk/S\ngp982OfaNVkadJ2kqvLQ8DA3zJv3unoOkwnb9+i2huksDdFjlxl0LIbsCgNOhWHXps/1EF4J6Y0y\n4nmM+gFl36cSBFSDAM8t4fo2LhqBoqPpGTQ9hdCSIAxQNFAMpKLjCxNXGEihgPQRgYsIqgjpg19F\nBDYaHvg2VWeYpGaAniMWVPG0FHpgM/rMZSxvX05Mi3Hn83ey6wu7UISCpmjUxeooOSWEECT0BBW3\nQtEuUrSLjNqjFO0ilmdR9apjh+u7uIE7ls5QDWZkZ/C5oz6HlPKgd+EnVDn09Mgxy53bHplNvb+D\nnz/3IZq3buPa724ZS1v6/MWkvncDf3hA5bjlo6hq+FZUvfEa1ie/zBG/Ohn1zLPh7/6Oj30sNB/9\n/r9X2XDE+zH/66HQn+IXvgBXXQWXXRYqncbGl+RHSkmx+AQ7dlzJyMhjNDZ+kClTLiKXW85jj7Vw\n9NE70fX9Cxc6hjq49dlb2VHYwUlfvom7Z7o8dsJMLj78Yv710X9luDrMvIZ5nDH3DPKJPMvrl7Pn\nmD0kr0ySacmQ3ZMlWBNQ+G2BxMIE9h4bfzScb6k7pY7KCxXSh6d516/H7f5nWbB2LaUXXkD09LBz\nzRqmr1tHr2EwZ9MmyGYZHAzNbNetCx21nHsuFIuwZUvoRW7NGsa2sUgkQkdHrxUpJf2uy3bLYptl\nsce2sYMA1/EZ6bXp77PoHLZwRn2mojO3S6HV1dg5WzBtfpqcpdBu69QVYD0VghGfVJdPvlcS7w/Q\n+nxkt4M34JE5JkP+7Dwtn2pBr9cJ7IArH3+ObS8U6R2sMmdEo6Ws0FJUaBwRZAug9noovR6pEqHC\naDFwB13szv3zLmpGxS/6NK1oIr0sTeNZjfhFH3/Uxy24uH0uTk+4sVx1d5Xqi1UUU0FNq+HupIMe\nfsnHL/uhB7I6DSWmENgBalqFVh3yOpojKd46SDC0dExxOEHAOU1NZN8pS+z/BC/wOO/28+ge7SYb\nyxLX4mTMDFkzy6A1SKFaIGtmxyZgB6wB2tJtJI0kqlBJGSnSZjgJm9ATxPU4cS0+9pa9pnMNfeU+\nDNVAUzRMzQzTaXFMzcRUzZd8Or5DIANysRzrutext7gXCOvxsD3M3uJedFVHEQoSieu59JZ7MbU4\n03Lt9FUGGXXKJM0cmhYnEBoeKooaR9FilAPJrx+9nHS8iaQep6e4i5996GdkY1kSeoL3zn7vGybb\nLVu2MDQ0hJSSE0444Z2vHLq75Zi/7M///iN8hDu4uRP+wzuXh2atZPr0L9LQ8AEqSjsXfuldXHHm\nEMd/80SU+x8MFxJ873vhvhZdXfDRj8Ktt44ph+uuC71XsX07fPrT8PDD4Y1mzgyHdY47Du65J2w9\nzzsvdI21MNy+2vNK9PXdwq5d12DbuwE47rjhV3R8E6xYwQtHzGLjqYfw0IsP8aOnf8TdH7+bpJHk\nkV2PsHLLSvpL/fRZBxpumaqJL32OmnoUf5X4Kw7RD2HW4CwSDyWYe85cvFM87u+4n7SZZsga4rmB\n51jZX2DPSAckZnB861KSsUauW3gE07PTSeiJCZ8XsIOA3dUqva7LtkqFx4pFNCHosm1sKem2bTaU\ny5ydz1MNAkwh6HIcumybbsch7QoaUwZ506RO05ifSNBqGFzW0cG/zpzJsnSaBYkEvY7DHttmV7XK\nXtum13U5OpPh4qYpOL21nUPN0AdxbHYMxVTwhj2kLzEaX5/5oJQSf9THK3j4lo835BHYAYEV4PSF\nSkQGkumXT3+DpPrWZ7g6TN036rjpQzehKzq+9LFcixF7hIpbwQs8ZtXNIpABI9URdo3sojnZTNEO\nPeKVnBJlt8yoM0rFrVBxK1iuRckpUbSL7B3dyycO+QRpI40XeNi+PZbG9m1szx77dHwHX/ok9ATD\n1WE6Rzr5yIKPoCoqlmvhBi5SSubWz6XklrBcCy/wGLQGmVU3i8Z4I5ZnYXs2M3IzKDklSk6JilvB\n9m2qXhXLtZBIrj/j+rBXgPiLd2EAKJfLXHTRRTz33HM8/fTTtLe3E4vFCIKAWCxGuVymo6ODZcuW\nEY/HWbNmzTtfOezZI3lU7+Om7m7mFK7hbH7NzZ3wsPdX3DDrmbG0cw/dxuE/OZ5bDuvhhJNA/PXH\n4ZZbwi9PPz2cp1i9GoBrl/+ER885nt9c08YP79zMZ+bPR73ttnDJcnMzpFLhxj7XXgs//CFceGG4\nag3gsMNCu9PTTw/TL1mCOztPYeQhmprOCSdJFIXv7dnDvUNDdNs2J9XV8Q9XX03DBz5A7PzzAbi5\nt5dHR0ZYnstxbCbDVNPEHXB5atFTvLs/9AJV9aps7N0YPlC1Ludjux9jc/9m7nnhHkpOiVl1s9hR\n2IGhGpw+53Q6Ch3Ynk2vNKkTHh+ccyq7hnays28nJUp0lbuQhBV+dm42lmORMTI0ZhpJG2nq4/VM\nSU+hLdOG5Vr0lftYmF9IfbyelJGiJdXC3uJebtt6G0II6uP1ZM0sjYlGpmWnMTU99aCPeQZSUvA8\num2b3bbNdsui7Pt0Ow4vWBY3L1xI3Ttxm9x3AMPVYdq/087wVcMTnZW3FR0dHcyZM4ebbrqJ6dOn\nM2PGDKrVKoqi4DgOtm2zYMECMpnQJ0ptkvudrRwWrXmKZ2t2wJeJH7JLNvFC51qavQ4unzVCkQyN\nDALwre05Lm0fpvePX+UT//iPCAiHiZYvh1Wrwh7BP/0T4qGHoCsG/2cpC76+il3NzVixGJ/+zW/4\n+qZN5D/zGfwPfpCyEGQ0jQufew4hBJc0NZG54w6mfvazFA49lMb169HGTWjuXrSIac8+izzhBO6P\nx3mhvZ0HDj+c+MyZnPP1r3PbkUfy0BlnMDMWY02xSFZVOS6b5cnRUfpdl0Msk2+ucHjoqTY6LIsA\neG9dHXMTCd6VTNJsGAy5LhlV5XnLQkdijb5IoTrIovwimpJNPFQo8IXt29lYLrN6yRJ23XorF110\n0VgeY/EYTVOb6Cx1QgPQDFqDhjakkW/Ko+ZUurwutJxGJVkh4SWo0+qoBBXKbhnP8AhEQFzEWV6/\nHGlKXM2l5JfYXdzNYGVwrHeydWAruViOOfVz6Cn1sKOwg7n1c9k2tI2FjQtJGkmmZaYxPTudulgd\nDYkGWtOtFO0ig5VB8sk8Tckm8onaZzL/miw2vvvEd7l+7fXkYjnq4nU0JZvImTkkElM1SRkpUkYK\nQzVekqYuVkfKSGFqJnEtTkyLIWvrM8ebY5ad8tiQxZ/i+m7oQ7hmhvhM9zNYnkVdrI5cLEfKSKEI\nBS/wSJtpBK8+uekFHqpQX5Jm36rulJFCU7SDaipackps6NlAxsyQMTMkjWQoI/WlZs0/X/9z7t9x\nPzkzF1pm6UkSemIsvM9+3/EdvvTgl/5ir4xvNXzfR1GU1+4wSUpGR0fRdR3DMFBfxupt69at7Nix\ng0QiQSKRIB6PE4vFiMVibN68mQsuuIDe3t7XdL9JoRx48HdQq/yX8H16aOGeziJneb/gM7PgRB5i\nplbmp94HkDLcruLmm+H4Y47ht5dcgrliRfhjF1wA73kPXHAB9avWct7GInd+cy4v3t/B6kqFnzU3\ns85x2G6/1Ob/zCDgLkXhPdksL1gWPY4DwEcaG7lzYIAAaB4aYkFnJ5ePjrIG6CqXOe3JJzlz2zYS\nphl6Ygfc22/nqRNPZMB1ebJY5J/a2zFr7uSKnseznSOUjniWOx5vZmulwoJEgkoQcOfAAAXPwxQC\nW0oMIXCkJL9nD/3nnTeW11hTE04uR92iRZw0YwZbf/1rNu/Zw7nLl/PNK65g+oIFlDIZdnd1MbBp\nE0cefzzW6Ci5uXPpHxzk+e3b6d67Fz8IaMznWbduHYVCASEEXV1ddHV1cdoZp7GzfyfWgEVvVy+7\nd++ms7OTSqXCtGnTcKRDbkqCZMImnU6BrdFvlchMSaPF4rTKLNm2eupjedy4gKBIOSPpsoepYDHK\nKF12Fw3xBqZnp1NwCgxYA/SX++kr9xHTYjQmGsnFctTH68mYGVrTrST1JDEtRspIcc3D17DikBWc\nt/Q8ClaBvnLfmF14X7mPfDLPSHWEUWeUslumaBfpL/czXB2m7JbHhgPcwCWQwdhYNzBmR64pGqpQ\nSegJUkaKuB7HkAqbh8I9yE0R9lxs6XJUcj6FoMywX6ESVPFlgKpolN3ymMJKanFSRorO0T3hqlkt\njuVZlN0yhmpQH68nqScxNZNn+58la2YpOSV86WOoxpjCSxvpsXH5lJGiYBVoTjVjqubYOL0XeOiq\njqmajNgj5BN50mZ6TIYDlQEM1cBQDVY9u4oHdjzA4vxiinaRslum5JTwAo+kHiqKpJFkT3EPZ8w9\ng+Xty8fWdFTcyljY8qywnHqSfDLPV0/66kFpMw42Z512Grffdx8QNsCmYWCaJoZhjDXkpmli7vus\nHRs2bKC7uxvTNHEcJ7y29l08Hicej7Njxw7mzZvHlClTKJfLVKvVsSPwfQ5rb+euv/mbcFQjHg9X\nqFarob2/lOHip9ohrrlmEiiH390HSjj2ewnfZ1ndIj69oYePe//BZ2bBkcd7JB95BIAzf/Fe7vqp\nS319Pblcjlwuxy233EJ/fz+zr7uOny9dylU//Sns2gXMBB7g+uvvZ8WKFaTTaQAqvs8DhQK/2LSJ\nUx95BO2JJ1i1fDkr16whHY8zEIvRtHhxOIE9bRosXXrAQoyt/f2sfPZZPqfrNOZyEAQ4dpzCjetQ\nKwMklubwElMwR57HCAYplBdS7GsgtrSFjn/pHxtWYuXKcAX4rl3I1avpOuUUqj09TCsUKOfzbGhs\n5ItPPcU/X3ghpY4O+hSFp0dGMHfuJLd+PdtVlbMOOYSPZrOoe/eG3t97esB1w9/X9f1hgIaG0DRJ\n18PZ6IYGaG3df0yZsv+zpSWcxX7gAVixgnI+z55Uim1BQHLXLgY0jf7Fixkol9ldKjFXUbALBXTL\n4sVUCs+ycHyfPmBA02jwfTAMBoVgMAiwAFtKSp6HLgRN8TgtSLL1SYycgZmLIVIqtgl9ho0wBH/c\ns5N8PoutuKTWx5mmNpPL5TBMk3gySVNLC00tLdTn8+imiWGapFIptm3bRkdHBw0NDWHdSSRI7diB\nnkuRa2pElG2UXJxcYyN1mToS6Qz5qo+z4wUqF19IaWqeSkLH6u/CNzSWnXYBTrGANdSH3j9IuuSG\ncisWw2N0FIpFgqoFmoYtPcpT85RkFcur0jjsEqiCmGKiaDp6Ms1QzqSSNKgmDBJ6glkiXM8jVQVb\nE5SG+yjZo4zms5R0yWhcoRRT6NGq1NsKtiopaj7luIYwTDBNbDVgGBshFFwRYOFRFR6jOCiaTp2Z\npapKPtZ6Kh+eeXponZBMQiyGZ1uU1YCy4lF2SlRci0VNi9E1I3S+7rqh83XPA9MM614QhGX3/f2N\n2THHhHvNGEZY7wwjTK+qYbwQoelctRo+Z/u+N4zw+iAI0+6LG3/si4NwqHj8oevhdfvuYxhhgzs0\nFJZR0+Cxx8IXu3H5Ov666/hSXR3LGxvRXRe7WsW2bRzfp+r7VD0P2/OwfR9bCGxVxfZ9PF3nuESC\nelUFw8BzHOxSCdv3sTwPSwhMTWPaPt/D+2z4NS2898hImL9TTgmHvvP5UI6mCZlMWIZ98vY8xFe+\n8s5XDv/9AHxcvZ0RclzC9zm7dRlP3LOWoe5tXHX1v1Ff/z7cIMB4+OFwjuHGG9m0axcL2tq4/vrr\n+fvPfQ4InUrcD/wS0Fvnkmcuw8M/Yfr0E3mu5nHm/PPP56ijjmLFihVjY3dIGW7X8cc/wq9+BU89\ntb9RjcUIqi7FuuPItI2inHAsNDZSvX892x47jAJH0MTv0CkywHFYhGsKdMPCdkw8PBKajeul0LVh\nMuwAApZMvwHmzuX4++5jrRC8e9o0Fjc3U9/eTteLLzJz1iyaEwke3LSJzt5e/nDkkaH9aWtrWPGn\nTQvNjc46izE74H34PvT3QzodPgQAjhM+hIVCGFethg/F0FA4qd/dHU7ojz92h5Pw5PPwiU+Ew3eD\ng+Fv+364ev21dLmlDNO5bqi4hofHGk96epC9vVijo/Sm03Rv3cpgUxOjw8MMDw0xXCrhWxYpx8G0\nbQYHBzm9pYW9lQr5WAzFsiiMjuK6LuVqlf5qlV7HoRAEuIBjGJQUhbIQZA2DQysVhlSVYcuiBFQy\nGQZ8n+2OQ5thMOQ4VIIAKwgoS4kmBIqikEinyWUy1NXVka2rI5FKveSNMB6P09PTg67rpFKp/cMG\nsRgJ00RRFCzXxXEcPM/D9zx838evVvEcB79axa1WqVYq4HmYikJCVUmYJqamEdM0koZByjCI53Ik\nDAMjCFA8j4SUpFwXpbkZISWUSshyGb9UIum6xJJJdCnRFQUNUIKAmJSolhX+D6USuwcG8MtlzGqV\nF4tFYq6LoSgI30e3bQwhMIXACAJWeR6W7xMTgrimEVNV4p6H5nmoiQRapYKRz6MpCoaUoOtsv/JK\nVClRpUQJAgwpQ7kA5UqFpGFgGgZGJoMJGLV7aVJSdhyk76N43tgRF4K4lMSDAN3zwqGfchk5Okpl\neJigVCJw3fDwfYIgIHAcZLVKsHcvQXs7tuNAczNmWxvKjBl09vXhVatcfNtt/GjlSo59z3tetVoj\nZdhQ+37YcDtOaEkIoaI0jPBZTSTCtL4fpt937T4l4Xnhs2HbofXka1yEOSmGle7+LVyh/YCtLOS3\nDSuZnZ3Hyv96hOHuF7n239aPpd1T7GLGpZcRlCRcHG6wN+Vhh0t238mPpc2P167lfs9j8RVXcP75\nn+R734Nvfzu0Vurp6WH16tWsXr2alStXAjBnzhz+9m//lvnz59Pc3MySJUswTZPu7m5aW1vRdZ2h\noSE+dOKZVDZaKCgcoixmrqajO/ORSA797KG0T29nwwMb6O7tInWKTrDYoLW1lfe/f/9COk3V8Pyw\nYiyaP58Z9fXMisdZ+eST3PDjH5PIZNiyZQt79uxh27ZtLFy4kIGBATZs2MA555zD1Vdf/Sb+KzWk\nfGklfrtRrYYKqFoNe0tDQ+HDus80rr7+Vfco8X0/bMh9n0qlwsjICENDQ4yMjFCpVHAch0qlgmVZ\nWJZFpbZYpK6ubiy+UqlQqVQIgmBMmaiqOnZomvaScDweD7dSsO2x623bplqtUi6XKZVKY/Gu647l\nrVQqMTg4iOu6ZLNZdF1HVVUsy6JareK6Lq7r4nkeQRBQrVYRQhAEwdjq3RkzZlAulzEMg+bmZuza\n8KvjOGMTorZtMzw8zBc+//lwOKSWT8uyxmTled6YEnQch1KpRFNTE83Nzfi1htpxHCzLYmBgANu2\naWlpGcunbdtj93Rdl1QqhaIoYQMfBPi+/xLZeJ43Vt597ZimaSiKMnaImpIff67rOoqiYNs2QRDQ\n09PDEUccgaqqrFq1imnTph3c+vk6mRTK4fb7IFfrGU6d+r+JxWbxq1V/YLhnJ9d+6xmKxbBntabr\nQU6+6GT+Yck/8J7N58J9Nkm+wsk8OPZ7PzjnP/jANy+kvR3uuAMuvbRmyvonOI7D71b/jhuuv4G7\nVt91wPfJZJIFCxbQ399PZ2cny/PLYSEsnbOUF7e9yF2PhNfMnTuXzs5ObNtm1qxZVCoVCoUCU6dO\nxXEcHn/8cbLZLJ2dncyZM4f+/n76+vro6uqio6ODvXv38uUvf5lUKnVAHiIiDhZSShzHGWtwFUUh\nfsBq6rcHvu+PlQXCZ3cy8GYphwldjfOrW+GST4ThvXv/H9OnXzW2l3ShEL7gAcQ+9FM0X8PqsHDX\nCq5lER9nKb0czY94H1KF9asO5XOrwvSPP/7K9zQMg/lPzOfS1ZdyKZei53XK/WV66GFm3UwKhQLP\nPP0Mo4yygAUcvuRwDn3g0Jf9Lc/z6OnpYerUqa9o2bB4cWj33NbWRltbG8uWLfvLBRUR8Qaxb7L0\nnYCqqm9bxfZ2YEJ7DsrfwO8+DWs74HgNskd9ijvuHmK4fzff+Na6V73+D/UfpXWomT3j9vXbRJYH\nprdTTsbQEoJ/qWyk7uQ6kkuS2LttFFOh+Mcihd8WmPGPM5j+xekIEW5ep8QUnG4H3/IxmgysHRax\n6TFQQM9FdvURERFvDSbFsFJ3ErbeDdZn4P3b4axz4PZF8OHyDO741k5mz7uZG19opf9YjUvWf+pz\nMAAABulJREFUtzJYmcWl4gdsNRZzr30it5z8Y079+w/hjXg0ndNE38o+hu4dYviRYZy9oVnqtMun\n0fPzHtw+FzWtouU0MsdkmPnVmSTmTnL3bBEREW87JoVykMBoG3xzLlxT26I8fzkMbK6HeweB8eVf\njMlxVPnRWMzjt+7lmI+2vpnZjoiIiJhQ3izlMOHmKOk9oWL42vHhef+34Ox7b6COIQxg7uy56LoB\nbOErZ3aHiVwXnniCY856eec8ERERERGvjwnvOYwne1yCkUcrL5uek0+Gzk6IxWDjxoOev4iIiIi3\nIpOm5wDwrgX/l3oGKT5aRsehmR549FH45CfDlbyKEu4t3dUFp5020dmNiIiIeMcz4RvLj5iwJdlC\nE4dzdG4tN/y+nqVLm4FmePe7Jzp7EREREZOSCe855K4Gtdflsct/y5q+HEsPdNYWEREREfEmM+Fz\nDt9iPcsocLJcPiH5iIiIiHg7MSlWSF/P33EYBY7rOXYisxERERER8SdM6LDSrsy5nCSXYzS/PpeN\nERERERFvLBOqHI4uRttSRERERLwVmVDlsOTWhRN5+4iIiIiIV2BiJ6Qn6N4RERERb1cm1SK4iIiI\niIi3FpFyiIiIiIg4gEg5REREREQcwEFTDkKI04QQzwkhXhBCXHmw7hMRERER8cZzUJSDEEIBvg+8\nD1gMfFwIseBg3OudwO9///uJzsJbhkgW+4lksZ9IFm8+B6vncCSwTUq5S0rpAv8JfOgg3ettT1Tx\n9xPJYj+RLPYTyeLN52Aph6nA7nHne2pxERERERFvA6IJ6YiIiIiIAzgoi+CEEEcD/yylPK12fhUg\npZTfGJcmWgEXERER8T/gzVgEd7CUgwo8D5wMdANPAh+XUm59w28WEREREfGGc1C27JZS+kKIzwH3\nEw5d/SRSDBERERFvHyZsb6WIiIiIiLcuEzIh/U5cICeEaBNCPCiE2CKE2CSE+PtafJ0Q4n4hxPNC\niPuEENlx11wthNgmhNgqhHjvuPhlQoiNNfl8Z1y8IYT4z9o1jwshpr+5pfzLEEIoQoh1Qoi7aueT\nUhZCiKwQ4r9qZdsihDhqEsviUiHE5lo5flXL+6SQhRDiJ0KIXiHExnFxb0rZhRDn19I/L4T45GvK\nsJTyTT0IFdJ2YAagA+uBBW92Pg5CuVqAQ2vhFOGcywLgG8AVtfgrgWtr4UXAM4RDe+01mezryf0R\nOKIW/m/gfbXwxcAPa+Fzgf+c6HL/GZlcCvwSuKt2PillAfwMuKAW1oDsZJQF0ArsAIza+Urg/Mki\nC+A44FBg47i4g152oA7oqNW73L7wn83vBAjoaODecedXAVdO9B93EMp5B3AK8BzQXItrAZ57uXID\n9wJH1dI8Oy7+r4Hra+HVwFG1sAr0T3Q5X6X8bcBvgeXsVw6TThZABuh4mfjJKItWYFetsdKAuybb\nM0L4UjxeORzMsvf9aZra+fXAuX8urxMxrPSOXyAnhGgnfEN4gvCP7wWQUvYATbVkfyqHvbW4qYQy\n2cd4+YxdI6X0gWEhRP1BKcTr59vA5cD4Sa3JKIuZwIAQ4qbaENuNQogEk1AWUsou4N+BTsJyjUgp\nH2ASymIcTQex7CO1sr/Sb70q0SK4NxghRAq4Ffi8lLLESxtHXub8dd3uDfytNwwhxBlAr5RyPa+e\nx3e8LAjfkJcBP5BSLgPKhG+Fk7Fe5Ai30ZlB2ItICiFWMAll8Sq8Zco+EcphLzB+kqitFve2Rwih\nESqGX0gp76xF9wohmmvftwB9tfi9wLRxl++TwyvFv+QaEa4lyUgphw5CUV4v7wbOFELsAG4BThJC\n/ALomYSy2APsllKurZ3/mlBZTMZ6cQqwQ0o5VHuzvR04lskpi328GWX/H7W5E6EcngLmCCFmCCEM\nwvGwuyYgHweDnxKOB353XNxdwKdq4fOBO8fF/3XNwmAmMAd4sta1HBFCHCmEEMAn/+Sa82vhjwEP\nHrSSvA6klF+UUk6XUs4i/H8flFKeB9zN5JNFL7BbCDGvFnUysIVJWC8Ih5OOFkLEamU4GXiWySUL\nwUvf6N+Mst8HnCpCq7k64NRa3KszQZMypxFa82wDrproSaI3qEzvBnxC66tngHW1ctYDD9TKez+Q\nG3fN1YRWCFuB946LPwzYVJPPd8fFm8CqWvwTQPtEl/s1yOUE9k9IT0pZAEsJX4rWA7cRWo1MVll8\npVaujcDPCS0WJ4UsgJuBLsAmVJQXEE7OH/SyEyqgbcALwCdfS36jRXAREREREQcQTUhHRERERBxA\npBwiIiIiIg4gUg4REREREQcQKYeIiIiIiAOIlENERERExAFEyiEiIiIi4gAi5RARERERcQCRcoiI\niIiIOID/DzOM3GEve64NAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "random.seed('running')\n", + "\n", + "for i in range(10):\n", + " plot_running_averages(simulate_st_pete, 100000);" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "What can we see from this? Nine of the 10 repetitions have a final expected value payoff (after 100,000 rounds) between 10 and 35. So a price around $13 still seems reasonable. One outlier has an average payoff just over 100, so if you are feeling lucky you might be willing to pay more than $13.\n", + "\n", + "# The Ellsburg Paradox\n", + "\n", + "The [Ellsburg Paradox](https://en.wikipedia.org/wiki/Ellsberg_paradox) has it all: an urn problem; a paradox; a conclusion that can only be resolved through psychology, not mathematics alone; and a colorful history with an inventor, [Daniel Ellsburg](https://en.wikipedia.org/wiki/Daniel_Ellsberg), who went on to become the releaser of the [Pentagon Papers](https://en.wikipedia.org/wiki/Pentagon_Papers). The paradox is as follows:\n", + "\n", + "> An urn contains 33 red balls and 66 other balls that are either black or yellow. You don't know the mix of black and yellow, just that they total 66. A single ball is drawn at random. You are asked which of these two gambles you would prefer:\n", + "- **R**: Win 100 for a red ball.\n", + "- **B**: Win 100 for a black ball.\n", + "\n", + "> Separately, you are also asked which of these two gambles you prefer:\n", + "- **RY**: Win 100 for a red or yellow ball.\n", + "- **BY**: Win 100 for a black or yellow ball.\n", + "\n", + "Many people reason as follows: \n", + "- **R**: I win 1/3 of the time\n", + "- **B**: I win somewhere between 0 and 2/3 of the time, but I'm not sure of the probability. \n", + "- **RY**: I win at least 1/3 of the time and maybe up to 100% of the time; I'm not sure. \n", + "- **BY**: I win 2/3 of the time. \n", + "- Overall, I prefer the relative certainty of **R** over **B** and of **BY** over **RY**.\n", + "\n", + "The paradox is that, from an expected utility point of view, that reasoning is inconsistent, no matter what the mix of black and yellow balls is (or no matter what you believe the mix might be). **RY** and **BY** are just the same gambles as **R** and **B**, but with an additional 100 for a yellow ball. So if you prefer **R** over **B**, you should prefer **RY** over **BY** (and if you prefer **B** over **R** you should prefer **BY** over **RY**), for any possible mix of black and yellow balls.\n", + "\n", + "Let's demonstrate. For each possible number of black balls (on the *x* axis), we'll plot the expected value of each of the four gambles; **R** as a solid red line, **B** as a solid black line, **RY** as a dotted red line, and **BY** as a dotted black line:" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "image/png": "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\n+v93Q77WPQv5rgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def ellsburg():\n", + " show('R', 'r')\n", + " show('B', 'k')\n", + " show('RY', 'r:')\n", + " show('BY', 'k:')\n", + " plt.xlabel('Number of black balls')\n", + " plt.ylabel('Expected value of each gamble')\n", + " \n", + "blacks = list(range(67))\n", + "all_urns = [Counter(R=33, B=b, Y=66-b) for b in blacks]\n", + " \n", + "def show(colors, line):\n", + " scores = [score(colors, urn) for urn in all_urns]\n", + " plt.plot(blacks, scores, line)\n", + " \n", + "def score(colors, urn): return sum(urn[c] for c in colors)\n", + "\n", + "ellsburg()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "We see that for any number of black balls up to 33, the solid red line is above the solid black line, which means **R** is better than **B**. The two gambles are equal with 33 black balls, and from there on, **B** is better than **R**.\n", + "\n", + "Similarly, up to 33 black balls, the dashed red line is above the dashed black line, so **RY** is better than **BY**. They are equal at 33, and after that, **BY** is better than **RY**. So in summary, **R** > **B** if and only if **RY** > **BY**.\n", + "\n", + "It is pretty clear that this holds for every possible mix of black and yellow balls, taken one at a time. But what if you believe that the mix might be one of several possibilities? For example, if we assume that any number of black balls from 0 to 66 is equally likely, then we can use a function, `expected_score` to give the expected return for a gamble (as specified by the colors in the gamble), averaged over a collection of possible urns, each with a different black/yellow mix:" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "R 33.0\n", + "B 33.0\n", + "RY 66.0\n", + "BY 66.0\n" + ] + } + ], + "source": [ + "def expected_score(colors, urns): \n", + " return sum(score(colors, urn) for urn in urns) / len(urns)\n", + "\n", + "def compare(urns):\n", + " for colors in ('R', 'B', 'RY', 'BY'):\n", + " print(colors.ljust(2), expected_score(colors, urns))\n", + " \n", + "compare(all_urns)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "This says that **B** and **R** have an equal expected return, as do **BY** and **RY**.\n", + "\n", + "Now imagine that you believe that any mix is possible, but that a majority of black balls is more likely, in particular that the urns in the second half of the list of `all_urns` are twice as likely as those in the first half. Then we will see that **B** > **R** and **BY** > **RY**:" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "R 33.0\n", + "B 38.554455445544555\n", + "RY 60.445544554455445\n", + "BY 66.0\n" + ] + } + ], + "source": [ + "compare(all_urns[:33] + 2 * all_urns[33:])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "If we believe the first half of the list (with fewer black balls) is twice as likely, we get this:" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "R 33.0\n", + "B 27.39\n", + "RY 71.61\n", + "BY 66.0\n" + ] + } + ], + "source": [ + "compare(2 * all_urns[:33] + all_urns[33:])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "This time the preferences are reversed for both gambles, **R** > **B** and **RY** > **BY**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "So why do many people prefer **R** > **B** and **BY** > **RY**? One explanation is *risk aversion*; it feels safer to take a definite 1/3 chance of winning, rather than a gamble that might be as good as 2/3, but might be as bad as 0. This is irrational thinking (in the sense that those who follow this strategy will win less), but people are sometimes irrational." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "# Simpson's Paradox\n", + "\n", + "This has nothing to do with the TV show. D'oh! In 1951, statistician [Edward Simpson](https://en.wikipedia.org/wiki/Edward_H._Simpson) (who worked with Alan Turing at Bletchley Park during World War II), noted that it is possible to take a sample space in which **A** is better than **B**, and split it into two groups, such that **B** is better than **A** in both groups. \n", + "\n", + "For example, here is data from trials of two treatments for kidney stones, **A** and **B**, separated into two subgroups or cases: first, for small kidney stones, and second for large ones. In all cases we record the number of good and bad outcomes of the treatment:" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "# Good and bad outcomes for kidney stone treatments A and B,\n", + "# each in two cases: [small_stones, large_stones]\n", + "A = [Counter(good=81, bad=6), Counter(good=192, bad=71)]\n", + "B = [Counter(good=234, bad=36), Counter(good=55, bad=25)]\n", + "\n", + "def success(case): return ProbDist(case)['good']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "Let's compare probabilities of success:" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.9310344827586207, 0.7300380228136882]" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[success(case) for case in A]" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.8666666666666667, 0.6875]" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[success(case) for case in B]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "We see that for small stones, **A** is better, 93% to 87%, and for large stones, **A** is also better, 75% to 69%. So **A** is better no matter what, right?\n", + "\n", + "Not so fast.\n", + "\n", + "We can add up `Counter`s to get the overall success rate for **A** and **B**, over all cases:" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.78" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "success(A[0] + A[1])" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8257142857142857" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "success(B[0] + B[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "Overall, **B** is more successful, 83% to 78%, even though **A** is better in both cases. So if you had kidney stones, and you want the highest chance of success, which treatment would you prefer? If you knew you had small stones (or large stones), the evidence supports **A**. But if the size was unknown, does that mean you should prefer **B**? Analysts agree that the answer is no, you should stick with **A**. The only reason why **B** has a higher overall success rate is that doctors choose to do **B** more often on the easier, small stone cases, and reserve **A** for the harder, large stone cases. **A** is better, but it has a lower overall percentage because it is given the difficult patients.\n", + "\n", + "Here's another example, showing the batting averages for two baseball players, Derek Jeter and David Justice, for the years 1995 and 1996 (I should say that Justice is considered a very good player, but Jeter is considered even better, a sure-bet future Hall of Fame player):" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "run_control": {} + }, + "outputs": [], + "source": [ + "Jeter = [Counter(hit=12, out=36), Counter(hit=183, out=399)]\n", + "Justice = [Counter(hit=104, out=307), Counter(hit=45, out=95)]\n", + "\n", + "def BA(case): \"Batting average\"; return ProbDist(case)['hit']" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.25, 0.31443298969072164]" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[BA(year) for year in Jeter]" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.25304136253041365, 0.32142857142857145]" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[BA(year) for year in Justice]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "So Justice had a higher batting average than Jeter for both 1995 and 1996. Let's check overall:" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.30952380952380953" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "BA(Jeter[0] + Jeter[1])" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "run_control": {} + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.27041742286751363" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "BA(Justice[0] + Justice[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "Overall, Jeter had a significantly higher batting average. How did Jeter manage to do worse both years, then? Because in 1995, Jeter was injured for much of the year, and his low batting average was over a small number of at-bats. In 1996, Jeter was healthy, but Justice was injured for much of the year; however he managed a high average in his few at-bats.\n", + "\n", + "For the kidney stone data, we trust the individual cases, not the overall, because there are biases that lead to patients being assigned to one treatment or the other. For the batting average data, we trust the overall numbers, because there are no such biases, and because larger numbers lead to a closer approximation to a true value. The data alone can't tell you what to believe; you need the story (and the model) behind the data as well." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Conclusion\n", + "\n", + "We've seen how to manage probability paradoxes. Just be explicit about what the problem says, and then methodical about defining the sample space, and finally be careful in counting the number of outcomes in the numerator and denominator. But the bigger lesson is: treat those around you as reasonable people, and when they have different opinions, try to discover what problem they are solving.\n", + "\n", + "*Note*: Mohammed El-Beltagy created a very nice [translation of an earlier version of this page to Julia](http://nbviewer.ipython.org/gist/mbeltagy/3ba5f77da6382da192c3). \n", + "." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Project Euler Utils.ipynb b/pytudes/ipynb/Project Euler Utils.ipynb new file mode 100644 index 0000000..933288f --- /dev/null +++ b/pytudes/ipynb/Project Euler Utils.ipynb @@ -0,0 +1,1011 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "
Peter Norvig, 20 Jan 2017
\n", + "\n", + "# Python Utilities for Project Euler\n", + "\n", + "After showing my utilities for [Advent of Code](http://adventofcode.org), I got some feedback:\n", + "\n", + " 1. Some of these are recipes in the `itertools` module (with different names).\n", + " 2. What about utilities for [Project Euler](https://projecteuler.net/about)?\n", + " \n", + "My answers: \n", + "\n", + " 1. I agree! I have renamed some of my utilities to be consistent with the `itertools` recipes.\n", + " 2. Here you go." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Imports\n", + "\n", + "In Project Euler I am writing short programs for my own consumption, so brevity is important, and I use `\"from\"` imports more often than I normally would:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from collections import defaultdict, deque, Counter, namedtuple, abc\n", + "from fractions import Fraction\n", + "from functools import lru_cache, wraps\n", + "from itertools import chain, cycle, islice, combinations, permutations, repeat, takewhile, zip_longest\n", + "from itertools import product as crossproduct, count as count_from\n", + "from math import ceil, floor, factorial, gcd, log, sqrt, inf\n", + "import random\n", + "import time" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Utilities\n", + "\n", + "Here are the general utility functions (and data objects) I define:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "million = 10 ** 6 # 1,000,000\n", + "Ø = frozenset() # Empty set\n", + "distinct = set # Function to return the distinct elements of a collection of hashables\n", + "identity = lambda x: x # The function that returns the argument\n", + "cat = ''.join # Concatenate strings\n", + "\n", + "def first(iterable, default=False):\n", + " \"Return the first element of an iterable, or default if it is empty.\"\n", + " return next(iter(iterable), default)\n", + "\n", + "def first_true(iterable, pred=None, default=None):\n", + " \"\"\"Returns the first true value in the iterable.\n", + " If no true value is found, returns *default*\n", + " If *pred* is not None, returns the first item\n", + " for which pred(item) is true.\"\"\"\n", + " # first_true([a,b,c], default=x) --> a or b or c or x\n", + " # first_true([a,b], fn, x) --> a if fn(a) else b if fn(b) else x\n", + " return next(filter(pred, iterable), default)\n", + "\n", + "def upto(iterable, maxval):\n", + " \"From a monotonically increasing iterable, generate all the values <= maxval.\"\n", + " # Why <= maxval rather than < maxval? In part because that's how Ruby's upto does it.\n", + " return takewhile(lambda x: x <= maxval, iterable)\n", + "\n", + "def multiply(numbers):\n", + " \"Multiply all the numbers together.\"\n", + " result = 1\n", + " for n in numbers:\n", + " result *= n\n", + " return result\n", + "\n", + "def transpose(matrix): return tuple(zip(*matrix))\n", + "\n", + "def isqrt(n):\n", + " \"Integer square root (rounds down).\"\n", + " return int(n ** 0.5)\n", + "\n", + "def ints(start, end):\n", + " \"The integers from start to end, inclusive. Equivalent to range(start, end+1)\"\n", + " return range(start, end+1)\n", + "\n", + "def groupby(iterable, key=identity):\n", + " \"Return a dict of {key(item): [items...]} grouping all items in iterable by keys.\"\n", + " groups = defaultdict(list)\n", + " for item in iterable:\n", + " groups[key(item)].append(item)\n", + " return groups\n", + "\n", + "def grouper(iterable, n, fillvalue=None):\n", + " \"\"\"Collect data into fixed-length chunks:\n", + " grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx\"\"\"\n", + " args = [iter(iterable)] * n\n", + " return zip_longest(*args, fillvalue=fillvalue)\n", + "\n", + "def overlapping(iterable, n):\n", + " \"\"\"Generate all (overlapping) n-element subsequences of iterable.\n", + " overlapping('ABCDEFG', 3) --> ABC BCD CDE DEF EFG\"\"\"\n", + " if isinstance(iterable, abc.Sequence):\n", + " yield from (iterable[i:i+n] for i in range(len(iterable) + 1 - n))\n", + " else:\n", + " result = deque(maxlen=n)\n", + " for x in iterable:\n", + " result.append(x)\n", + " if len(result) == n:\n", + " yield tuple(result)\n", + " \n", + "def pairwise(iterable):\n", + " \"s -> (s0,s1), (s1,s2), (s2, s3), ...\"\n", + " return overlapping(iterable, 2)\n", + " \n", + "def sequence(iterable, type=tuple):\n", + " \"Coerce iterable to sequence: leave it alone if it is already a sequence, else make it of type.\"\n", + " return iterable if isinstance(iterable, abc.Sequence) else type(iterable)\n", + "\n", + "def join(iterable, sep=''):\n", + " \"Join the itemsin iterable, converting each to a string first.\"\n", + " return sep.join(map(str, iterable))\n", + "\n", + "def grep(pattern, lines):\n", + " \"Print lines that match pattern.\"\n", + " for line in lines:\n", + " if re.search(pattern, line):\n", + " print(line)\n", + " \n", + "def nth(iterable, n, default=None):\n", + " \"Returns the nth item (or a default value).\"\n", + " return next(islice(iterable, n, None), default)\n", + "\n", + "def ilen(iterable):\n", + " \"Length of any iterable (consumes generators).\"\n", + " return sum(1 for _ in iterable)\n", + "\n", + "def quantify(iterable, pred=bool):\n", + " \"Count how many times the predicate is true.\"\n", + " return sum(map(pred, iterable))\n", + "\n", + "def powerset(iterable):\n", + " \"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)\"\n", + " seq = sequence(iterable)\n", + " return flatten(combinations(seq, r) for r in range(len(seq) + 1))\n", + "\n", + "def shuffled(iterable):\n", + " \"Create a new list out of iterable, and shuffle it.\"\n", + " new = list(iterable)\n", + " random.shuffle(new)\n", + " return new\n", + " \n", + "flatten = chain.from_iterable\n", + "\n", + "def int_cache(f):\n", + " \"\"\"Like lru_cache, but designed for functions that take a non-negative integer as argument;\n", + " when you ask for f(n), this caches all lower values of n first. That way, even if f(n) \n", + " recursively calls f(n-1), you will never run into recursionlimit problems.\"\"\"\n", + " cache = [] # cache[i] holds the result of f(i)\n", + " @wraps(f)\n", + " def memof(n):\n", + " for i in ints(len(cache), n):\n", + " cache.append(f(i))\n", + " return cache[n]\n", + " memof._cache = cache\n", + " return memof" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Primes\n", + "\n", + "My class `Primes` does what I need for the many Project Euler problems that involve primes:\n", + "\n", + "* Iterate through the primes up to 2 million.\n", + "* Instantly check whether an integer up to 2 million is a prime.\n", + "* With a bit more computation, check if, say, a 12-digit integer is prime.\n", + "\n", + "I precompute the primes up to 2 million, using \n", + "a [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes), and then cache\n", + "the primes as both a list (to iterate through) and a set (to check membership). If there are `n`\n", + "primes currently cached and you ask for `primes[n+1]` (either directly, or indirectly by iterating over `primes`), \n", + "then the cache will be automatically doubled in size. But if you just ask if, say, \"`123456789011 in primes`\",\n", + "then I use repeted trial division without extending the cache." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 144 ms, sys: 18.7 ms, total: 163 ms\n", + "Wall time: 190 ms\n" + ] + } + ], + "source": [ + "class Primes:\n", + " \"\"\"Given `primes = Primes(2 * million)`, we can do the following:\n", + " * for p in primes: # iterate over infinite sequence of primes\n", + " * 37 in primes => True # primality test\n", + " * primes[0] => 2, primes[1] => 3 # nth prime\n", + " * primes[:5] => [2, 3, 5, 7, 11] # first 5 primes\n", + " * primes[5:9] => [13, 17, 19, 23] # slice of primes \n", + " * primes.upto(10) => 2, 3, 5, 7 # generate primes less than or equal to given value\"\"\"\n", + "\n", + " def __init__(self, n):\n", + " \"Create an iterable generator of primes, with initial cache of all primes <= n.\"\n", + " # sieve keeps track of odd numbers: sieve[i] is True iff (2*i + 1) has no factors (yet) \n", + " N = n // 2 # length of sieve\n", + " sieve = [True] * N\n", + " for i in range(3, isqrt(n) + 1, 2):\n", + " if sieve[i // 2]: # i is prime\n", + " # Mark start, start + i, start + 2i, ... as non-prime\n", + " start = i ** 2 // 2\n", + " sieve[start::i] = repeat(False, len(range(start, N, i)))\n", + " self._list = [2] + [2*i+1 for i in range(1, N) if sieve[i]]\n", + " self._set = set(self._list)\n", + " self.maxn = n # We have tested for all primes < self.maxn\n", + "\n", + " def __contains__(self, n):\n", + " \"Is n a prime?\"\n", + " # If n is small, look in _set; otherwise try prime factors up to sqrt(n)\n", + " if n <= self.maxn:\n", + " return n in self._set\n", + " else:\n", + " return not any(n % p == 0 for p in self.upto(n ** 0.5))\n", + "\n", + " def __getitem__(self, index):\n", + " \"Return the ith prime, or a slice: primes[0] = 2; primes[1] = 3; primes[1:4] = [3, 5, 7].\"\n", + " stop = (index.stop if isinstance(index, slice) else index)\n", + " if stop is None or stop < 0:\n", + " raise IndexError('Number of primes is infinite: https://en.wikipedia.org/wiki/Euclid%27s_theorem')\n", + " while len(self._list) <= stop:\n", + " # If asked for the ith prime and we don't have it yet, we will expand the cache.\n", + " self.__init__(2 * self.maxn)\n", + " return self._list[index]\n", + " \n", + " def upto(self, n):\n", + " \"Yield all primes <= n.\"\n", + " if self.maxn < n:\n", + " self.__init__(max(n, 2 * self.maxn))\n", + " return upto(self._list, n)\n", + " \n", + "%time primes = Primes(2 * million)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are 148,933 primes under 2 million, which is a small enough number that I'm not concerned with the memory consumed by `._list` and `._set`. If I needed to store 100 million primes, I would make different tradeoffs. For example, instead of a list and a set, I would probably just keep `sieve`, and make it be an `array('B')`. This would take less space (but for \"small\" sizes like 2 million, the current implementation is both faster and simpler).\n", + "\n", + "\n", + "# Factors\n", + "\n", + "Project Euler also has probems about prime factors, and divisors. I need to:\n", + "\n", + "* Quickly find the prime factors of any integer up to a million.\n", + "* With a bit more computation, find the prime factors of a 12-digit integer.\n", + "* Find the complete factorization of a number.\n", + "* Compute Euler's totient function.\n", + "\n", + "I will cache the factors of all the integers up to a million. To be more precise, I don't actually keep a list of all the factors of each integer; I only keep the largest prime factor. From that, I can easily compute all the other factors by repeated division. If asked for the factors of a number greater than a million, I do trial division until I get it under a million. In addition, `Factors` provides `totient(n)` for computing [Euler's totient function](https://en.wikipedia.org/wiki/Euler's_totient_function), or Φ(n), and `ndivisors(n)` for the total [number of divisors](http://primes.utm.edu/glossary/xpage/tau.html) of `n`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class Factors:\n", + " \"\"\"Given `factors = Factors(million)`, we can do the following:\n", + " * factors(360) => [5, 3, 3, 2, 2, 2] # prime factorization\n", + " * factors.largest[360] => 5 # largest prime factor\n", + " * distinct(factors(360)) => {2, 3, 5} # distinct prime factors\n", + " * factors.ndivisors(28) => 6 # How many positive integers divide n?\n", + " * factors.totient(36) => 12 # How many integers below n are relatively prime to n?\"\"\"\n", + " def __init__(self, maxn):\n", + " \"Initialize largest[n] to be the largest prime factor of n, for n < maxn.\"\n", + " self.largest = [1] * maxn\n", + " for p in primes.upto(maxn):\n", + " self.largest[p::p] = repeat(p, len(range(p, maxn, p)))\n", + " \n", + " def ndivisors(self, n):\n", + " \"The number of divisors of n.\"\n", + " # If n = a**x * b**y * ..., then ndivisors(n) = (x+1) * (y+1) * ...\n", + " exponents = Counter(self(n)).values()\n", + " return multiply(x + 1 for x in exponents)\n", + " \n", + " def totient(self, n):\n", + " \"Euler's Totient function, Φ(n): number of integers < n that are relatively prime to n.\"\n", + " # totient(n) = n∏(1 - 1/p) for p ∈ distinct(factors(n))\n", + " return int(n * multiply(1 - Fraction(1, p) for p in distinct(self(n))))\n", + " \n", + " def __call__(self, n):\n", + " \"Return a list of the numbers in the prime factorization of n.\"\n", + " result = []\n", + " # Need to make n small enough so that it is in the self.largest table\n", + " if n >= len(self.largest):\n", + " for p in primes:\n", + " while n % p == 0:\n", + " result.append(p)\n", + " n = n // p\n", + " if n < len(self.largest):\n", + " break\n", + " # Now n is in the self.largest table; divide by largest[n] repeatedly:\n", + " while n > 1:\n", + " p = self.largest[n]\n", + " result.append(p)\n", + " n = n // p\n", + " return result\n", + " \n", + "factors = Factors(million)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "148933" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(primes._list)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Tests\n", + "\n", + "Here are some unit tests (which also serve as usage examples):" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'pass'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " global primes, factors\n", + " primes = Primes(2 * million)\n", + " factors = Factors(million)\n", + " \n", + " assert first('abc') == first(['a', 'b', 'c']) == 'a'\n", + " assert first(primes) == 2\n", + " assert cat(upto('abcdef', 'd')) == 'abcd'\n", + " assert multiply([1, 2, 3, 4]) == 24\n", + " assert transpose(((1, 2, 3), (4, 5, 6))) == ((1, 4), (2, 5), (3, 6))\n", + " assert isqrt(9) == 3 == isqrt(10)\n", + " assert ints(1, 100) == range(1, 101)\n", + " assert identity('anything') == 'anything'\n", + " assert groupby([-3, -2, -1, 1, 2], abs) == {1: [-1, 1], 2: [-2, 2], 3: [-3]}\n", + " assert sequence('seq') == 'seq'\n", + " assert sequence((i**2 for i in range(5))) == (0, 1, 4, 9, 16)\n", + " assert join(range(5)) == '01234'\n", + " assert join(range(5), ', ') == '0, 1, 2, 3, 4'\n", + " assert cat(['do', 'g']) == 'dog'\n", + " assert nth('abc', 1) == nth(iter('abc'), 1) == 'b'\n", + " assert quantify(['testing', 1, 2, 3, int, len], callable) == 2 # int and len are callable\n", + " assert quantify([0, False, None, '', [], (), {}, 42]) == 1 # Only 42 is truish\n", + " assert set(powerset({1, 2, 3})) == {(), (1,), (1, 2), (1, 2, 3), (1, 3), (2,), (2, 3), (3,)}\n", + " assert first_true([0, None, False, {}, 42, 43]) == 42\n", + " assert list(grouper(range(8), 3)) == [(0, 1, 2), (3, 4, 5), (6, 7, None)]\n", + " assert list(pairwise((0, 1, 2, 3, 4))) == [(0, 1), (1, 2), (2, 3), (3, 4)]\n", + " assert list(overlapping((0, 1, 2, 3, 4), 3)) == [(0, 1, 2), (1, 2, 3), (2, 3, 4)]\n", + " assert list(overlapping('abcdefg', 4)) == ['abcd', 'bcde', 'cdef', 'defg'] \n", + " @int_cache\n", + " def fib(n): return (n if n <= 1 else fib(n - 1) + fib(n - 2))\n", + " f = str(fib(10000))\n", + " assert len(f) == 2090 and f.startswith('33644') and f.endswith('66875')\n", + "\n", + " assert 37 in primes\n", + " assert primes[0] == 2 and primes[1] == 3 and primes[10] == 31\n", + " assert primes[:5] == [2, 3, 5, 7, 11]\n", + " assert primes[5:9] == [13, 17, 19, 23]\n", + " assert 42 not in primes\n", + " assert 1299721 in primes\n", + " assert million not in primes\n", + " assert (2 ** 13 - 1) in primes\n", + " assert (2 ** 31 - 1) in primes\n", + " assert list(primes.upto(33)) == [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]\n", + " assert primes.maxn == 2 * million # Make sure we didn't extend cache\n", + " assert len(primes._set) == len(primes._list) == 148933\n", + " \n", + " assert factors(720) == [5, 3, 3, 2, 2, 2, 2]\n", + " assert distinct(factors(720)) == {2, 3, 5}\n", + " assert factors(37) == [37]\n", + " assert distinct(factors(72990720)) == {2, 3, 5, 11}\n", + " assert factors.ndivisors(6) == 4\n", + " assert factors.ndivisors(28) == 6\n", + " assert factors.ndivisors(720) == 30\n", + " assert factors.largest[720] == 5\n", + " assert factors.totient(36) == 12\n", + " assert factors.totient(43) == 42\n", + " for n in (28, 36, 37, 99, 101): \n", + " assert list(primes.upto(n)) == list(upto(primes, n))\n", + " assert factors.totient(n) == quantify(gcd(n, d) == 1 for d in ints(1, n))\n", + " assert n == sum(factors.totient(d) for d in ints(1, n) if n % d == 0)\n", + "\n", + "\n", + "\n", + " return 'pass'\n", + "\n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Timing\n", + "\n", + "My implementation is fast enough to solve Project Euler problems, as you can see from the timing numbers below:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 130 ms, sys: 14.7 ms, total: 144 ms\n", + "Wall time: 151 ms\n", + "CPU times: user 166 ms, sys: 10.4 ms, total: 177 ms\n", + "Wall time: 178 ms\n" + ] + } + ], + "source": [ + "# Instantiate both primes and factors\n", + "%time primes = Primes(2 * million)\n", + "%time factors = Factors(million)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5 µs, sys: 1e+03 ns, total: 6 µs\n", + "Wall time: 9.06 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check primality for numbers in cache\n", + "%time 1000003 in primes" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5 µs, sys: 0 ns, total: 5 µs\n", + "Wall time: 8.11 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time 1000001 in primes" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 100 µs, sys: 1 µs, total: 101 µs\n", + "Wall time: 103 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check primality for numbers beyond the cache\n", + "%time 2000003 in primes" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 10 µs, sys: 1e+03 ns, total: 11 µs\n", + "Wall time: 16 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "[19753, 5]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Factor numbers in cache\n", + "%time factors(98765)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 9 µs, sys: 1 µs, total: 10 µs\n", + "Wall time: 11.9 µs\n" + ] + }, + { + "data": { + "text/plain": [ + "[5, 5, 5, 5, 3, 3, 3, 3, 2, 2, 2, 2]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time factors(810000)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 8.38 ms, sys: 247 µs, total: 8.63 ms\n", + "Wall time: 11.3 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "[74843, 74843]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Factor numbers beyond the cache\n", + "%time factors(74843 ** 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "31999727999744007303991249934683126567194480546211\n", + "CPU times: user 152 ms, sys: 2.27 ms, total: 155 ms\n", + "Wall time: 168 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "[1000003, 1000003, 1000003, 1999993, 1999993, 1999993, 1999993, 1999993]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = 1000003 ** 3 * 1999993 ** 5\n", + "print(x)\n", + "%time factors(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15.5 ms, sys: 810 µs, total: 16.3 ms\n", + "Wall time: 19.1 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "37550402023" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time sum(primes.upto(million))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.67 ms, sys: 152 µs, total: 2.82 ms\n", + "Wall time: 3.99 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "62260698721" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sum of the first 100,000 primes\n", + "%time sum(primes[:100000])" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 62.9 ms, sys: 1.78 ms, total: 64.6 ms\n", + "Wall time: 70.9 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "1000003" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# First prime greater than a million\n", + "%time first(p for p in primes if p > million)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 23 ms, sys: 941 µs, total: 23.9 ms\n", + "Wall time: 26.7 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "19186879" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sum of the integers up to 10,000 that have exactly 3 distinct factors\n", + "%time sum(n for n in range(1, 10000) if len(distinct(factors(n))) == 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 88.2 ms, sys: 2.42 ms, total: 90.6 ms\n", + "Wall time: 97.2 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "65796" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sum of the integers up to 10,000 that have exactly 3 divisors\n", + "%time sum(n for n in range(1, 10000) if factors.ndivisors(n) == 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 326 ms, sys: 3.1 ms, total: 329 ms\n", + "Wall time: 337 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "30393486" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The sum of the totient function of the integers up to 1000 \n", + "%time sum(map(factors.totient, range(1, 10000)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Project Euler Regression Testing\n", + "\n", + "My strategy for managing solutions to problems, and doing regression tests on them:\n", + "* My solution to problem 1 is the function `problem_1()`, which returns the solution when called (and so on for other problems).\n", + "* Once I have verified the answer to a problem (checking it on the Project Euler site), I store it in a dict called `solutions`.\n", + "* Running `verify()` checks that all `problem_`*n* functions return the correct solution. \n", + "\n", + "Project Euler asks participants not to publish solutions to problems, so I will comply, and instead show the solution to three fake problems:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def problem_1(N=100):\n", + " \"Sum of integers: Find the sum of all the integers from 1 to 100 inclusive.\"\n", + " return sum(ints(1, N))\n", + "\n", + "def problem_2(): \n", + " \"Two plus two: how much is 2 + 2?\"\n", + " return int('2' + '2')\n", + "\n", + "def problem_42():\n", + " \"What is life?\"\n", + " return 6 * 7\n", + "\n", + "solutions = {1: 5050, 2: 4} " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Num Time Status Answer Problem Description Expected\n", + "=== ========== ====== ================ ===================== ========\n", + " 1 0.00 sec ok 5050 Sum of integers \n", + " 2 0.00 sec WRONG! 22 Two plus two 4\n", + " 42 0.00 sec NEW! 42 What is life? \n" + ] + } + ], + "source": [ + "def verify(problem_numbers=range(1, 600)):\n", + " \"\"\"Main test harness function to verify problems. Pass in a collection of ints (problem numbers).\n", + " Prints a message giving execution time, and whether answer was expected.\"\"\"\n", + " print('Num Time Status Answer Problem Description Expected')\n", + " print('=== ========== ====== ================ ===================== ========')\n", + " for p in problem_numbers:\n", + " name = 'problem_{}'.format(p)\n", + " if name in globals():\n", + " fn = globals()[name]\n", + " t0 = time.time()\n", + " answer = fn()\n", + " t = time.time() - t0\n", + " desc = (fn.__doc__ or '??:').split(':')[0]\n", + " status = ('NEW!' if p not in solutions else \n", + " 'WRONG!' if answer != solutions[p] else\n", + " 'SLOW!' if t > 60 else\n", + " 'ok')\n", + " expected = (solutions[p] if status == 'WRONG!' else '')\n", + " print('{:3d} {:6.2f} sec {:>6} {:<16} {:<21} {}'\n", + " .format(p, t, status, answer, desc, expected))\n", + "\n", + "verify()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/PropositionalLogic.ipynb b/pytudes/ipynb/PropositionalLogic.ipynb new file mode 100644 index 0000000..5617c14 --- /dev/null +++ b/pytudes/ipynb/PropositionalLogic.ipynb @@ -0,0 +1,483 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Translating English Sentences into Propositional Logic Statements\n", + "\n", + "In a Logic course, one exercise is to turn an English sentence like this:\n", + "\n", + "> *Sieglinde will survive, and either her son will gain the Ring and Wotan’s plan will be fulfilled or else Valhalla will be destroyed.*\n", + "\n", + "Into a formal Propositional Logic statement: \n", + "\n", + " P ⋀ ((Q ⋀ R) ∨ S)\n", + " \n", + "along with definitions of the propositions:\n", + "\n", + " P: Sieglinde will survive\n", + " Q: Sieglinde’s son will gain the Ring\n", + " R: Wotan’s plan will be fulfilled\n", + " S: Valhalla will be destroyed\n", + "\n", + "For some sentences, it takes detailed knowledge to get a good translation. The following two sentences are ambiguous, with different preferred interpretations, and translating them correctly requires knowledge of eating habits:\n", + "\n", + " I will eat salad or I will eat bread and I will eat butter. P ∨ (Q ⋀ R)\n", + " I will eat salad or I will eat soup and I will eat ice cream. (P ∨ Q) ⋀ R\n", + "\n", + "But for many sentences, the translation process is automatic, with no special knowledge required. I will develop a program to handle these easy sentences. The program is based on the idea of a series of translation rules of the form:\n", + "\n", + " Rule('{P} ⇒ {Q}', 'if {P} then {Q}', 'if {P}, {Q}')\n", + " \n", + "which means that the logic translation will have the form `'P ⇒ Q'`, whenever the English sentence has either the form `'if P then Q'` or `'if P, Q'`, where `P` and `Q` can match any non-empty subsequence of characters. Whatever matches `P` and `Q` will be recursively processed by the rules. The rules are in order—top to bottom, left to right, and the first rule that matches in that order will be accepted, no matter what, so be sure you order your rules carefully. One guideline I have adhered to is to put all the rules that start with a keyword (like `'if'` or `'neither'`) before the rules that start with a variable (like `'{P}'`); that way you avoid accidentally having a keyword swallowed up inside a `'{P}'`.\n", + "\n", + "Consider the example sentence `\"If loving you is wrong, I don't want to be right.\"` This should match the pattern \n", + "`'if {P}, {Q}'` with the variable `P` equal to `\"loving you is wrong\"`. But I don't want the variable `Q` to be \n", + "`\"I don't want to be right\"`, rather, I want to have `~Q` equal to `\"I do want to be right\"`. So in addition to having a set of `Rule`s to handle the `'if {P}, {Q}'` patterns, I will also have a list of `negations` to handle `\"don't\"` and the like.\n", + "\n", + "Here is the code to process `Rule` definitions (using [regular expressions](https://docs.python.org/3.5/library/re.html), which can sometimes be confusing.)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "\n", + "def Rule(output, *patterns):\n", + " \"A rule that produces `output` if the entire input matches any one of the `patterns`.\" \n", + " return (output, [name_group(pat) + '$' for pat in patterns])\n", + "\n", + "def name_group(pat):\n", + " \"Replace '{Q}' with '(?P.+?)', which means 'match 1 or more characters, and call it Q'\"\n", + " return re.sub('{(.)}', r'(?P<\\1>.+?)', pat)\n", + " \n", + "def word(w):\n", + " \"Return a regex that matches w as a complete word (not letters inside a word).\"\n", + " return r'\\b' + w + r'\\b' # '\\b' matches at word boundary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what a rule looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(('{P} ⇒ {Q}',\n", + " ['if (?P

.+?) then (?P.+?)$', 'if (?P

.+?), (?P.+?)$']),)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Rule('{P} ⇒ {Q}', 'if {P} then {Q}', 'if {P}, {Q}')," + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And now the actual rules. If your sentence is not translated correctly, you can attempt to augment these rules to handle your sentence." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "rules = [\n", + " Rule('{P} ⇒ {Q}', 'if {P} then {Q}', 'if {P}, {Q}'),\n", + " Rule('{P} ⋁ {Q}', 'either {P} or else {Q}', 'either {P} or {Q}'),\n", + " Rule('{P} ⋀ {Q}', 'both {P} and {Q}'),\n", + " Rule('~{P} ⋀ ~{Q}', 'neither {P} nor {Q}'),\n", + " Rule('~{A}{P} ⋀ ~{A}{Q}', '{A} neither {P} nor {Q}'), # The Kaiser neither ...\n", + " Rule('~{Q} ⇒ {P}', '{P} unless {Q}'),\n", + " Rule('{P} ⇒ {Q}', '{Q} provided that {P}', '{Q} whenever {P}', \n", + " '{P} implies {Q}', '{P} therefore {Q}', \n", + " '{Q}, if {P}', '{Q} if {P}', '{P} only if {Q}'),\n", + " Rule('{P} ⋀ {Q}', '{P} and {Q}', '{P} but {Q}'),\n", + " Rule('{P} ⋁ {Q}', '{P} or else {Q}', '{P} or {Q}'),\n", + " ]\n", + "\n", + "negations = [\n", + " (word(\"not\"), \"\"),\n", + " (word(\"cannot\"), \"can\"),\n", + " (word(\"can't\"), \"can\"),\n", + " (word(\"won't\"), \"will\"),\n", + " (word(\"ain't\"), \"is\"),\n", + " (\"n't\", \"\"), # matches as part of a word: didn't, couldn't, etc.\n", + " ]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the mechanism to process these rules. The key function is `match_rule`, which matches an English sentence against a rule. The function returns two values, a string representing the translation of the English sentence into logic, and `defs`, a dictionary of `{Variable: \"value\"}` pairs. If `match_rule` finds that the rule matches, it recursively calls `match_rules` to match each of the subgroups of the regular expression (the `P` and `Q` in `if {P}, then {Q}`).\n", + "The function `match_literal` handles negations, and is where the `defs` dictionary actually gets updated." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def match_rules(sentence, rules, defs):\n", + " \"\"\"Match sentence against all the rules, accepting the first match; or else make it an atom.\n", + " Return two values: the Logic translation and a dict of {P: 'english'} definitions.\"\"\"\n", + " sentence = clean(sentence)\n", + " for rule in rules:\n", + " result = match_rule(sentence, rule, defs)\n", + " if result: \n", + " return result\n", + " return match_literal(sentence, negations, defs)\n", + " \n", + "def match_rule(sentence, rule, defs):\n", + " \"Match rule, returning the logic translation and the dict of definitions if the match succeeds.\"\n", + " output, patterns = rule\n", + " for pat in patterns:\n", + " match = re.match(pat, sentence, flags=re.I)\n", + " if match:\n", + " groups = match.groupdict()\n", + " for P in sorted(groups): # Recursively apply rules to each of the matching groups\n", + " groups[P] = match_rules(groups[P], rules, defs)[0]\n", + " return '(' + output.format(**groups) + ')', defs\n", + " \n", + "def match_literal(sentence, negations, defs):\n", + " \"No rule matched; sentence is an atom. Add new proposition to defs. Handle negation.\"\n", + " polarity = ''\n", + " for (neg, pos) in negations:\n", + " (sentence, n) = re.subn(neg, pos, sentence, flags=re.I)\n", + " polarity += n * '~'\n", + " sentence = clean(sentence)\n", + " P = proposition_name(sentence, defs)\n", + " defs[P] = sentence\n", + " return polarity + P, defs\n", + " \n", + "def proposition_name(sentence, defs, names='PQRSTUVWXYZBCDEFGHJKLMN'):\n", + " \"Return the old name for this sentence, if used before, or a new, unused name.\"\n", + " inverted = {defs[P]: P for P in defs}\n", + " if sentence in inverted:\n", + " return inverted[sentence] # Find previously-used name\n", + " else:\n", + " return next(P for P in names if P not in defs) # Use a new unused name\n", + " \n", + "def clean(text): \n", + " \"Remove redundant whitespace; handle curly apostrophe and trailing comma/period.\"\n", + " return ' '.join(text.split()).replace(\"’\", \"'\").rstrip('.').rstrip(',')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('(P ⇒ ~Q)', {'P': 'loving you is wrong', 'Q': 'I do want to be right'})" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "match_rule(\"If loving you is wrong, I don't want to be right\",\n", + " Rule('{P} ⇒ {Q}', 'if {P}, {Q}'),\n", + " {})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are some more test sentences and a top-level function to handle them:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "English: Polkadots and Moonbeams. \n", + "\n", + "Logic: (P ⋀ Q)\n", + "P: Polkadots\n", + "Q: Moonbeams\n", + "\n", + "English: If you liked it then you shoulda put a ring on it. \n", + "\n", + "Logic: (P ⇒ Q)\n", + "P: you liked it\n", + "Q: you shoulda put a ring on it\n", + "\n", + "English: If you build it, he will come. \n", + "\n", + "Logic: (P ⇒ Q)\n", + "P: you build it\n", + "Q: he will come\n", + "\n", + "English: It don't mean a thing, if it ain't got that swing. \n", + "\n", + "Logic: (~P ⇒ ~Q)\n", + "P: it is got that swing\n", + "Q: It do mean a thing\n", + "\n", + "English: If loving you is wrong, I don't want to be right. \n", + "\n", + "Logic: (P ⇒ ~Q)\n", + "P: loving you is wrong\n", + "Q: I do want to be right\n", + "\n", + "English: Should I stay or should I go. \n", + "\n", + "Logic: (P ⋁ Q)\n", + "P: Should I stay\n", + "Q: should I go\n", + "\n", + "English: I shouldn't go and I shouldn't not go. \n", + "\n", + "Logic: (~P ⋀ ~~P)\n", + "P: I should go\n", + "\n", + "English: If I fell in love with you, would you promise to be true and help me\n", + "understand. \n", + "\n", + "Logic: (P ⇒ (Q ⋀ R))\n", + "P: I fell in love with you\n", + "Q: would you promise to be true\n", + "R: help me understand\n", + "\n", + "English: I could while away the hours conferrin' with the flowers, consulting\n", + "with the rain and my head I'd be a scratchin' while my thoughts are busy\n", + "hatchin' if I only had a brain. \n", + "\n", + "Logic: (P ⇒ (Q ⋀ R))\n", + "P: I only had a brain\n", + "Q: I could while away the hours conferrin' with the flowers, consulting with the rain\n", + "R: my head I'd be a scratchin' while my thoughts are busy hatchin'\n", + "\n", + "English: There's a federal tax, and a state tax, and a city tax, and a street\n", + "tax, and a sewer tax. \n", + "\n", + "Logic: (P ⋀ (Q ⋀ (R ⋀ (S ⋀ T))))\n", + "P: There's a federal tax\n", + "Q: a state tax\n", + "R: a city tax\n", + "S: a street tax\n", + "T: a sewer tax\n", + "\n", + "English: A ham sandwich is better than nothing and nothing is better than\n", + "eternal happiness therefore a ham sandwich is better than eternal happiness. \n", + "\n", + "Logic: ((P ⋀ Q) ⇒ R)\n", + "P: A ham sandwich is better than nothing\n", + "Q: nothing is better than eternal happiness\n", + "R: a ham sandwich is better than eternal happiness\n", + "\n", + "English: If I were a carpenter and you were a lady, would you marry me anyway?\n", + "and would you have my baby. \n", + "\n", + "Logic: ((P ⋀ Q) ⇒ (R ⋀ S))\n", + "P: I were a carpenter\n", + "Q: you were a lady\n", + "R: would you marry me anyway?\n", + "S: would you have my baby\n", + "\n", + "English: Either Danny didn't come to the party or Virgil didn't come to the\n", + "party. \n", + "\n", + "Logic: (~P ⋁ ~Q)\n", + "P: Danny did come to the party\n", + "Q: Virgil did come to the party\n", + "\n", + "English: Either Wotan will triumph and Valhalla will be saved or else he won't\n", + "and Alberic will have the final word. \n", + "\n", + "Logic: ((P ⋀ Q) ⋁ (~R ⋀ S))\n", + "P: Wotan will triumph\n", + "Q: Valhalla will be saved\n", + "R: he will\n", + "S: Alberic will have the final word\n", + "\n", + "English: Sieglinde will survive, and either her son will gain the Ring and\n", + "Wotan's plan will be fulfilled or else Valhalla will be destroyed. \n", + "\n", + "Logic: (P ⋀ ((Q ⋀ R) ⋁ S))\n", + "P: Sieglinde will survive\n", + "Q: her son will gain the Ring\n", + "R: Wotan's plan will be fulfilled\n", + "S: Valhalla will be destroyed\n", + "\n", + "English: Wotan will intervene and cause Siegmund's death unless either Fricka\n", + "relents or Brunnhilde has her way. \n", + "\n", + "Logic: (~(R ⋁ S) ⇒ (P ⋀ Q))\n", + "P: Wotan will intervene\n", + "Q: cause Siegmund's death\n", + "R: Fricka relents\n", + "S: Brunnhilde has her way\n", + "\n", + "English: Figaro and Susanna will wed provided that either Antonio or Figaro pays\n", + "and Bartolo is satisfied or else Marcellina's contract is voided and the\n", + "Countess does not act rashly. \n", + "\n", + "Logic: ((((P ⋁ Q) ⋀ R) ⋁ (S ⋀ ~T)) ⇒ (U ⋀ V))\n", + "P: Antonio\n", + "Q: Figaro pays\n", + "R: Bartolo is satisfied\n", + "S: Marcellina's contract is voided\n", + "T: the Countess does act rashly\n", + "U: Figaro\n", + "V: Susanna will wed\n", + "\n", + "English: If the Kaiser neither prevents Bismarck from resigning nor supports the\n", + "Liberals, then the military will be in control and either Moltke's plan will be\n", + "executed or else the people will revolt and the Reich will not survive. \n", + "\n", + "Logic: ((~PQ ⋀ ~PR) ⇒ (S ⋀ (T ⋁ (U ⋀ ~V))))\n", + "P: the Kaiser\n", + "Q: prevents Bismarck from resigning\n", + "R: supports the Liberals\n", + "S: the military will be in control\n", + "T: Moltke's plan will be executed\n", + "U: the people will revolt\n", + "V: the Reich will survive\n" + ] + } + ], + "source": [ + "sentences = '''\n", + "Polkadots and Moonbeams.\n", + "If you liked it then you shoulda put a ring on it.\n", + "If you build it, he will come.\n", + "It don't mean a thing, if it ain't got that swing.\n", + "If loving you is wrong, I don't want to be right.\n", + "Should I stay or should I go.\n", + "I shouldn't go and I shouldn't not go.\n", + "If I fell in love with you,\n", + " would you promise to be true\n", + " and help me understand.\n", + "I could while away the hours\n", + " conferrin' with the flowers,\n", + " consulting with the rain\n", + " and my head I'd be a scratchin'\n", + " while my thoughts are busy hatchin'\n", + " if I only had a brain.\n", + "There's a federal tax, and a state tax, and a city tax, and a street tax, and a sewer tax.\n", + "A ham sandwich is better than nothing \n", + " and nothing is better than eternal happiness\n", + " therefore a ham sandwich is better than eternal happiness.\n", + "If I were a carpenter\n", + " and you were a lady,\n", + " would you marry me anyway?\n", + " and would you have my baby.\n", + "Either Danny didn't come to the party or Virgil didn't come to the party.\n", + "Either Wotan will triumph and Valhalla will be saved or else he won't and Alberic will have \n", + " the final word.\n", + "Sieglinde will survive, and either her son will gain the Ring and Wotan’s plan \n", + " will be fulfilled or else Valhalla will be destroyed.\n", + "Wotan will intervene and cause Siegmund's death unless either Fricka relents \n", + " or Brunnhilde has her way.\n", + "Figaro and Susanna will wed provided that either Antonio or Figaro pays and Bartolo is satisfied \n", + " or else Marcellina’s contract is voided and the Countess does not act rashly.\n", + "If the Kaiser neither prevents Bismarck from resigning nor supports the Liberals, \n", + " then the military will be in control and either Moltke's plan will be executed \n", + " or else the people will revolt and the Reich will not survive'''.split('.')\n", + "\n", + "import textwrap\n", + "\n", + "def logic(sentences, width=80): \n", + " \"Match the rules against each sentence in text, and print each result.\"\n", + " for s in map(clean, sentences):\n", + " logic, defs = match_rules(s, rules, {})\n", + " print('\\n' + textwrap.fill('English: ' + s +'.', width), '\\n\\nLogic:', logic)\n", + " for P in sorted(defs):\n", + " print('{}: {}'.format(P, defs[P]))\n", + "\n", + "logic(sentences)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks pretty good! But far from perfect. Here are some errors:\n", + "\n", + "* `Should I stay` *etc.*:
questions are not propositional statements.\n", + "\n", + "* `If I were a carpenter`:
doesn't handle modal logic.\n", + "\n", + "* `nothing is better`:
doesn't handle quantifiers.\n", + "\n", + "* `Either Wotan will triumph and Valhalla will be saved or else he won't`:
gets `'he will'` as one of the propositions, but better would be if that referred back to `'Wotan will triumph'`.\n", + "\n", + "* `Wotan will intervene and cause Siegmund's death`:
gets `\"cause Siegmund's death\"` as a proposition, but better would be `\"Wotan will cause Siegmund's death\"`.\n", + "\n", + "* `Figaro and Susanna will wed`:
gets `\"Figaro\"` and `\"Susanna will wed\"` as two separate propositions; this should really be one proposition. \n", + "\n", + "* `\"either Antonio or Figaro pays\"`:
gets `\"Antonio\"` as a proposition, but it should be `\"Antonio pays\"`.\n", + "\n", + "* `If the Kaiser neither prevents`:
uses the somewhat bogus propositions `PQ` and `PR`. This should be done in a cleaner way. The problem is the same as the previous problem with Antonio: I don't have a good way to attach the subject of a verb phrase to the multiple parts of the verb/object, when there are multiple parts.\n", + "\n", + "\n", + "\n", + "I'm sure more test sentences would reveal many more types of errors.\n", + "\n", + "There's also [a version](proplogic.py) of this program that is in Python 2 and uses only ASCII characters; if you have a Mac or Linux system you can download this as [`proplogic.py`](proplogic.py) and run it with the command `python proplogic.py`. Or you can run it [online](https://www.pythonanywhere.com/user/pnorvig/files/home/pnorvig/proplogic.py?edit)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/Riddler Battle Royale.ipynb b/pytudes/ipynb/Riddler Battle Royale.ipynb new file mode 100644 index 0000000..a10e594 --- /dev/null +++ b/pytudes/ipynb/Riddler Battle Royale.ipynb @@ -0,0 +1,868 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Riddler Battle Royale\n", + "\n", + "\n", + "\n", + "> [538's *The Riddler* Asks](http://fivethirtyeight.com/features/the-battle-for-riddler-nation-round-2/): *In a distant, war-torn land, there are 10 castles. There are two warlords: you and your archenemy, with whom you’re competing to collect the most victory points. Each castle has its own strategic value for a would-be conqueror. Specifically, the castles are worth 1, 2, 3, …, 9, and 10 victory points. You and your enemy each have 100 soldiers to distribute, any way you like, to fight at any of the 10 castles. Whoever sends more soldiers to a given castle conquers that castle and wins its victory points. If you each send the same number of troops, you split the points. You don’t know what distribution of forces your enemy has chosen until the battles begin. Whoever wins the most points wins the war. Submit a plan distributing your 100 soldiers among the 10 castles.*\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Load some useful modules\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import csv\n", + "import random\n", + "from collections import Counter\n", + "from statistics import mean" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's play with this and see if we can find a good solution. Some implementation choices:\n", + "* A `Plan` will be a tuple of 10 soldier counts (one for each castle).\n", + "* `castles` will hold the indexes of the castles. Note that index 0 is castle 1 (worth 1 point) and index 9 is castle 10 (worth 10 points).\n", + "* `half` is half the total number of points; if you get more than this you win.\n", + "* `plans` will hold a set of plans that were submitted in the previous contest.\n", + "* `play(A, B)` gives the single game reward for Plan A against Plan B: 1 if A wins, 0 if A loses, and 1/2 for a tie.\n", + "* `reward(a, b, payoff)` returns payoff, payoff/2, or 0, depending on whether `a` is bigger than `b`." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "Plan = tuple \n", + "castles = range(10)\n", + "half = 55/2 \n", + "plans = {Plan(map(int, row[:10])) \n", + " for row in csv.reader(open('battle_royale.csv'))}\n", + "\n", + "def play(A, B): \n", + " \"Play Plan A against Plan B and return a reward (0, 1/2, or 1).\"\n", + " A_points = sum(reward(A[c], B[c], c + 1) for c in castles)\n", + " return reward(A_points, half) \n", + "\n", + "def reward(a, b, payoff=1): return (payoff if a > b else payoff / 2 if a == b else 0) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some tests:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "assert reward(6, 5, 9) == 9 # 6 soldiers defeat 5, winning all 9 of the castle's points\n", + "assert reward(6, 6, 8) == 4 # A tie on an 8-point castle is worth 4 points\n", + "assert reward(6, 7, 7) == 0 # No points for a loss\n", + "assert reward(30, 25) == 1 # 30 victory points beats 25\n", + "\n", + "assert len(plans) == 1202\n", + "\n", + "assert play((26, 5, 5, 5, 6, 7, 26, 0, 0, 0),\n", + " (25, 0, 0, 0, 0, 0, 0, 25, 25, 25)) == 1 # A wins game\n", + "\n", + "assert play((26, 5, 5, 5, 6, 7, 26, 0, 0, 0),\n", + " (0, 25, 0, 0, 0, 0, 0, 25, 25, 25)) == 0 # B wins game\n", + "\n", + "assert play((25, 5, 5, 5, 6, 7, 26, 0, 0, 0),\n", + " (25, 0, 0, 0, 0, 0, 0, 25, 25, 25)) == 1/2 # Tie game" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's run a tournament, playing each plan against every other, and returning a list of `[(plan, mean_game_points),...]`. I will also define `show` to pretty-print these results and display a histogram:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def tournament(plans):\n", + " \"Play each plan against each other; return a sorted list of [(plan: mean_points)]\"\n", + " rankdict = {A: mean_points(A, plans) for A in plans}\n", + " return Counter(rankdict).most_common()\n", + "\n", + "def mean_points(A, opponents): \n", + " \"Mean points for A playing against all opponents (but not against itself).\"\n", + " return mean(play(A, B) for B in opponents if B is not A)\n", + "\n", + "def show(rankings, n=10): \n", + " \"Pretty-print the n best plans, and display a histogram of all plans.\"\n", + " print('Top', n, 'of', len(rankings), 'plans:')\n", + " for (plan, points) in rankings[:n]:\n", + " print(pplan(plan), pct(points))\n", + " plt.hist([s for (p, s) in rankings], bins=20)\n", + " \n", + "def pct(x): return '{:6.1%}'.format(x)\n", + "def pplan(plan): return '(' + ', '.join('{:2}'.format(c) for c in plan) + ')'" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[((0, 25, 0, 0, 0, 0, 0, 25, 25, 25), 1),\n", + " ((26, 5, 5, 5, 6, 7, 26, 0, 0, 0), 0.5),\n", + " ((25, 0, 0, 0, 0, 0, 0, 25, 25, 25), 0)]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# This is what the result of a tournament looks like:\n", + "tournament({(26, 5, 5, 5, 6, 7, 26, 0, 0, 0),\n", + " (25, 0, 0, 0, 0, 0, 0, 25, 25, 25),\n", + " (0, 25, 0, 0, 0, 0, 0, 25, 25, 25)})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 10 of 1202 plans:\n", + "( 0, 3, 4, 7, 16, 24, 4, 34, 4, 4) 85.6%\n", + "( 5, 7, 9, 11, 15, 21, 25, 2, 2, 3) 84.1%\n", + "( 3, 5, 8, 10, 13, 1, 26, 30, 2, 2) 83.3%\n", + "( 2, 2, 6, 12, 2, 18, 24, 30, 2, 2) 83.3%\n", + "( 2, 8, 2, 2, 10, 18, 26, 26, 3, 3) 83.2%\n", + "( 3, 6, 7, 9, 11, 2, 27, 31, 2, 2) 83.2%\n", + "( 1, 1, 1, 5, 11, 16, 28, 29, 3, 5) 82.8%\n", + "( 1, 3, 1, 1, 17, 20, 21, 30, 3, 3) 82.6%\n", + "( 3, 6, 10, 12, 16, 21, 26, 2, 2, 2) 82.4%\n", + "( 6, 6, 6, 11, 20, 21, 21, 3, 3, 3) 82.2%\n" + ] + }, + { + "data": { + "image/png": "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\n4m8ATnvjYfE5sOcAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# A tournament with all 1202 plans:\n", + "rankings = tournament(plans)\n", + "show(rankings)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It looks like there are a few really bad plans in there. Let's just keep the top 1000 plans (out of 1202), and re-run the rankings:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Top 10 of 1000 plans:\n", + "( 0, 3, 4, 7, 16, 24, 4, 34, 4, 4) 87.4%\n", + "( 5, 5, 5, 5, 5, 5, 27, 30, 6, 7) 84.8%\n", + "( 5, 5, 5, 5, 5, 5, 30, 30, 5, 5) 84.2%\n", + "( 3, 3, 5, 5, 7, 7, 30, 30, 5, 5) 84.1%\n", + "( 1, 2, 3, 4, 6, 16, 25, 33, 4, 6) 82.5%\n", + "( 2, 2, 2, 5, 5, 26, 26, 26, 3, 3) 82.4%\n", + "( 1, 1, 1, 5, 11, 16, 28, 29, 3, 5) 82.0%\n", + "( 0, 1, 3, 3, 11, 18, 25, 33, 3, 3) 82.0%\n", + "( 5, 7, 9, 11, 15, 21, 25, 2, 2, 3) 81.7%\n", + "( 0, 0, 5, 5, 25, 3, 25, 3, 31, 3) 81.5%\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAEACAYAAACwB81wAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEORJREFUeJzt3X2MbHV9x/H3By6Pileo5W4E9Fqb8mDVhrYEoymj1qLW\nArGGio0VrabpgyXVtkJTc29TE9SkaU2qTYhWb5q2FrVRamtAClNDKqEKCApcEQsilqWiEKjKg3z7\nxwy4XO7enZ0zT7u/9yuZ5MzZ8zu/787O+exvzpyHVBWSpM1vv3kXIEmaDQNfkhph4EtSIwx8SWqE\ngS9JjTDwJakRawZ+kg8lWU5y3Yp5hye5JMnuJBcn2briZ+cluTnJjUl+aVqFS5LWZ5QR/oeBU/eY\ndy5waVUdC1wGnAeQ5ATgTOB44BXAB5JkcuVKksa1ZuBX1RXAd/eYfTqwazi9CzhjOH0a8NGqeriq\nbgVuBk6aTKmSpC7G3Yd/ZFUtA1TVncCRw/lHAbevWO6O4TxJ0pxN6ktbr88gSQtuy5jtlpNsq6rl\nJEvAXcP5dwDHrFju6OG8J0jiPwlJGkNVjfXd6Kgj/Awfj7oIOHs4/QbgUyvmvzbJgUmeBfwkcNVq\nK62qhX/s2LFj7jVYp3Vu5Do3Qo0bqc4u1hzhJ/kHoAf8WJJvADuAdwMfS/Im4DYGR+ZQVTckuRC4\nAXgI+J3qWqEkaSLWDPyqet0qP/rFVZY/Hzi/S1GSpMnzTNs19Hq9eZcwEuucLOucnI1QI2ycOrvI\nvPa4JHFvjyStUxJqyl/aSpI2OANfkhph4EtSIwx8SWqEgS9JjTDwJakRBr4kNcLAl1axtLSdJOt+\nLC1tn3fp0l554pW0isHN2sZ5j6bzRa6k1XjilSRpTQa+JDXCwJekRhj4ktQIA1+SGmHgS1IjDHxJ\naoSBL0mNMPAlqREGviQ1wsCXpEYY+JLUCANfkhph4EtSIwx8SWqEgS9JjTDwJakRBr4kNcLAlybu\nIO+Fq4XkPW2lVXS5p633wtW0eE9bSdKaDHxJaoSBL0mNMPAlqREGviQ1olPgJ/mDJF9Ocl2Sv09y\nYJLDk1ySZHeSi5NsnVSxkqTxjR34SZ4OvBU4saqeB2wBzgLOBS6tqmOBy4DzJlGoJKmbrrt09gee\nlGQLcAhwB3A6sGv4813AGR37kCRNwNiBX1XfAv4C+AaDoL+3qi4FtlXV8nCZO4EjJ1GoJKmbLeM2\nTPJUBqP5ZwL3Ah9L8us88RTDVU8d3Llz52PTvV6PXq83bjna5JaWtrO8fNu6223b9kzuvPPWyRck\nzUi/36ff709kXWNfWiHJa4BTq+otw+evB04GXgL0qmo5yRJweVUdv5f2XlpBI+tymYMO7/Gx+/TS\nCpqWeV1a4RvAyUkOzmDLeClwA3ARcPZwmTcAn+rQhzaZpaXtY11YTFJ3nS6elmQH8FrgIeAa4M3A\nYcCFwDHAbcCZVXXPXto6wm/QRho1b6Ra1Y4uI3yvlqmZ2kghupFqVTu8WqYkaU0GviQ1wsCXpEYY\n+JLUCANfkhph4EtSIwx8SWqEgS9JjTDwJakRBr4kNcLAl6RGGPiS1AgDX5IaYeBLUiMMfElqhIEv\nSY0w8CWpEQa+JDXCwJekRhj4ktQIA1+SGmHgS1IjDHyNZWlpO0nW/ZA0P6mq+XSc1Lz6VneD8B7n\n7zf7duO+z+bxO7pNaC1JqKqxRk+O8CWpEQa+JDXCwJc2uHG/T1la2j7v0jVj7sPXWNyHv+8+Z1lr\nlzrdBjce9+FLktZk4EtSIwx8SWqEgS9JjTDwJakRBv4m4aF5ktbiYZmbxKwPzfOwzH33uVH+Fm6D\nG0+XwzK3dOx4K/BB4KeBR4A3AV8F/gl4JnArcGZV3dulH2l8B22gi7ZtpFq1EXXdpfM+4N+q6njg\n+cBNwLnApVV1LHAZcF7HPqQOHmAw+h3nsVFqlUYz9i6dJE8BrqmqZ+8x/ybglKpaTrIE9KvquL20\nd5fOBLlLZ9Lt5tHnxtiFpPma15m2zwK+neTDSa5OckGSQ4FtVbUMUFV3Akd26EOSNCFdAn8LcCLw\n/qo6Efg/Brtz9hwyOISQpAXQ5UvbbwK3V9UXhs8/wSDwl5NsW7FL567VVrBz587Hpnu9Hr1er0M5\nkrT59Pt9+v3+RNbV6bDMJP8BvKWqvppkB3Do8Effqar3JHkHcHhVnbuXtu7DnyD34U+63Tz6dB++\n1tZlH37XwH8+g8MyDwC+DrwR2B+4EDgGuI3BYZn37KWtgT9B4wfwwQyODhnHxgg1A3/1dm6DG8/c\nAr8LA3+yNv+I28CfRju3wY3H6+FLktZk4EtSIwx8SWqEgS9JjTDwJakRBr4kNcLAl6RGGPiS1AgD\nX5IaYeBLUiMMfElqhIEvSY0w8CWpEQa+JDXCwJekRhj4ktQIA19q1kEkWfdj//2fNFa7JCwtbZ/3\nL90073i1SXjHq0m3m0efm73doK3bfTfe8UqStCYDX5IaYeBLUiMMfElqhIEvSY0w8CWpEQa+JDXC\nwJekRhj4ktQIA1+SGmHgS1IjDHxJaoSBL0mNMPAlqREGviQ1wsCXpEYY+JLUCANfkhrROfCT7Jfk\n6iQXDZ8fnuSSJLuTXJxka/cyJUldTWKEfw5ww4rn5wKXVtWxwGXAeRPoQ5LUUafAT3I08Erggytm\nnw7sGk7vAs7o0ockaTK6jvD/EvgjHn8L+21VtQxQVXcCR3bsQ5I0AWMHfpJfBpar6log+1i09vEz\nSdKMbOnQ9oXAaUleCRwCHJbk74A7k2yrquUkS8Bdq61g586dj033ej16vV6HciRp8+n3+/T7/Yms\nK1XdB+BJTgHeXlWnJXkvcHdVvSfJO4DDq+rcvbSpSfStgSSM92HKdovT52ZvN2jrdt9NEqpqX3tV\nVjWN4/DfDbwsyW7gpcPnkqQ5m8gIf6yOHeFPlCP8SbebR5+bvd2grdt9N4s2wpckLSADX5IaYeAv\nmKWl7SRZ90OS1uI+/AXjvvhFaTePPjd7u0Fbt/tu3IcvSVqTgS9JjTDwJakRBr4kNcLAl6RGGPiS\n1AgDX5IaYeBPwbgnT3kClTa/g8baLpaWts+78E3BE6+mYPyTp2DjnESz2dvNo8/N3q5bn5s1L9bL\nE68kSWsy8CWpEQa+JDXCwJekRhj4ktQIA1+SGmHgS1IjDHxJaoSBL0mNMPAlqREGviQ1wsCXpEYY\n+JLUCANfkhph4EtSIwx8SWqEgS9JjTDwJakRBr6kTWvc+0tv1nvoek/bKfCetpuh3Tz63OztuvU5\nTl6Mvy0u7j10vaetJGlNBr4kNcLAl6RGjB34SY5OclmSryS5PsnvD+cfnuSSJLuTXJxk6+TKlSSN\nq8sI/2HgbVX1HOAFwO8mOQ44F7i0qo4FLgPO616mJKmrsQO/qu6sqmuH0/cDNwJHA6cDu4aL7QLO\n6FqkpNYdNNbhlXq8LZNYSZLtwM8AVwLbqmoZBv8Ukhw5iT4ktewBxj+EVI/qHPhJngx8HDinqu5P\nsudfZdW/0s6dOx+b7vV69Hq9ruVI0qbS7/fp9/sTWVenE6+SbAE+DXymqt43nHcj0Kuq5SRLwOVV\ndfxe2nri1d5bj9nWdpNtN48+N3u7efTpiVcrdT0s82+BGx4N+6GLgLOH028APtWxD0nSBIw9wk/y\nQuBzwPUM/oUW8CfAVcCFwDHAbcCZVXXPXto7wt976zHb2m6y7ebR52ZvN48+HeE/rq3X0tm73bt3\n8+IXv4oHH3xo3W3vvvs2WtggNne7efS52dvNo08Df6WJHKWzGd1yyy3cf/9R3HffR9bZ8nbgF6ZQ\nkSR1Y+Dvw377HQpsX2erxRwVSJLX0pGkRhj4ktQIA1+SGmHgS1IjDHxJaoSBL0mNMPAlqREGviQ1\nwsCXpEYY+JLUCANfkhph4EtSIwx8SWqEgS9JjTDwJakRBr4kPcFBJFn3Y2lp+7wL3ydvgCJJT/AA\n49zMaHl5rDsPzowjfElqhIEvSY0w8CWpEQa+JDXCwJekRhj4ktQIA1+SGmHgS1IjDHxJaoSBL0mN\nMPAlqREGviQ1wsCXpIlZ7KtserVMSZqYxb7KpiN8SWqEgS9JjZha4Cd5eZKbknw1yTum1Y8kaTRT\nCfwk+wF/DZwKPAc4K8lx0+hr+vrzLkBz0Z93ASPqz7uAEfTnXcCI+vMuYOqmNcI/Cbi5qm6rqoeA\njwKnT6mvKevPuwDNRX/eBYyoP+8CRtCfdwEj6s+7gKmbVuAfBdy+4vk3h/MkSXPiYZmrOOCAA3jg\ngS9w4IFf4+CDvzhyu6rvcd99UyxMksY0rcC/A3jGiudHD+c9TrLYd3gf+F8efPDmMdp1+d3GbWu7\nybabR5+btd2fzaHPcdrNr85Z5GGq1n+SwJorTfYHdgMvBf4HuAo4q6punHhnkqSRTGWEX1U/TPJ7\nwCUMvif4kGEvSfM1lRG+JGnxTP1M27VOwEpybJL/TPKDJG+bdj2rGaHO1yX50vBxRZLnLmidpw1r\nvCbJVUleuGg1rlju55M8lOTVs6xvRf9rvZanJLknydXDx58uYp3DZXrDv/mXk1w+6xqHNaz1ev7h\nsMark1yf5OEkT13AOp+S5KIk1w7rPHvWNQ7rWKvOpyb55+H2fmWSE9ZcaVVN7cHgH8rXgGcCBwDX\nAsftsczTgJ8F/hx42zTr6VjnycDW4fTLgSsXtM5DV0w/F7hx0Wpcsdy/A58GXr2gr+UpwEXzeE+u\ns86twFeAo4bPn7aIde6x/KuASxexTuA84PxHX0vgbmDLAtb5XuCdw+ljR3k9pz3CX/MErKr6dlV9\nEXh4yrXsyyh1XllV9w6fXsl8zisYpc7vrXj6ZOCRGdYHo59091bg48BdsyxuhVHrnPehZKPU+Trg\nE1V1Bwy2qRnXCOs/2fIs4B9nUtnjjVJnAYcNpw8D7q6qWefTKHWeAFwGUFW7ge1JfnxfK5124G+U\nE7DWW+ebgc9MtaK9G6nOJGckuRH4F+BNM6rtUWvWmOTpwBlV9TfML1BH/Zu/YPjR/l9H+sg8eaPU\n+VPAEUkuT/JfSV4/s+p+ZORtKMkhDD4lf2IGde1plDr/GjghybeALwHnzKi2lUap80vAqwGSnMTg\nUPij97VST7xapyQvBt4IvGjetaymqj4JfDLJi4B3AS+bc0l7+itg5T7JeY+iV/NF4BlV9b0krwA+\nySBcF80W4ETgJcCTgM8n+XxVfW2+Za3qV4ArquqeeReyilOBa6rqJUmeDXw2yfOq6v55F7aHdwPv\nS3I1cD1wDfDDfTWYduCPdALWAhj1RLHnARcAL6+q786otpXW9XpW1RVJfiLJEVX1nalXNzBKjT8H\nfDSDM02eBrwiyUNVddGMaoQR6ly5gVfVZ5J8YMavJYz2en4T+HZV/QD4QZLPAc9nsA94Vtbz3nwt\n89mdA6PV+UbgfICquiXJfwPHAV+YSYUDo7w/72PFJ/hhnV/f51qn/MXD/vzoi4cDGXzxcPwqy+4A\n3j7LL0bWU+fwxb8ZOHkeNa6jzmevmD4RuH3Ratxj+Q8zny9tR3ktt62YPgm4dUHrPA747HDZQxmM\n9k5YtDqHy21l8CXoIbN+Ldfxer4f2PHoe4DBrpUjFrDOrcABw+m3AB9Za71THeHXKidgJfmtwY/r\ngiTbGPznPAx4JMk5DN6sM/v4NEqdwDuBI4APDEemD1XVSbOqcR11/mqS3wAeBL4PnLmANT6uySzr\ne6zT0ep8TZLfBh5i8Fr+2iLWWVU3JbkYuI7BR/oLquqGRatzuOgZwMVV9f1Z1rfOOt8FfCTJdcNm\nf1yz/VQ3ap3HA7uSPMLgKK3fXGu9nnglSY3wFoeS1AgDX5IaYeBLUiMMfElqhIEvSY0w8CWpEQa+\nJDXCwJekRvw/BVQV7pgMVw8AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plans = {A for (A, _) in rankings[:1000]}\n", + "rankings = tournament(plans)\n", + "show(rankings)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The top 10 plans are still winning over 80%, and the top plan remains `(0, 3, 4, 7, 16, 24, 4, 34, 4, 4)`. This is an interesting plan: it places most of the soldiers on castles 4+5+6+8, which totals only 23 points, so it needs to pick up 5 more points from the other castles (that have mostly 4 soldiers attacking each one). Is this a good strategy? Where should we optiomally allocate soldiers? \n", + "\n", + "To gain some insight, I'll create a plot with 10 curves, one for each castle. Each curve maps the number of soldiers sent to the castle (on the x-axis) to the expected points won (against the 1000 plans) on the y-axis:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plotter(plans, X=range(41)):\n", + " X = list(X)\n", + " def mean_reward(c, s): return mean(reward(s, p[c], c+1) for p in plans)\n", + " for c in range(10):\n", + " plt.plot(X, [mean_reward(c, s) for s in X], '.-')\n", + " plt.xlabel('Number of soldiers (on each of the ten castles)')\n", + " plt.ylabel('Expected points won')\n", + " plt.grid()\n", + " \n", + "plotter(plans)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For example, this says that for castle 10 (the orange line at top), there is a big gain in expected return as we increase from 0 to 4 soldiers, and after that the gains are relatively less steep. This plot is interesting, but I can't see how to directly read off a best plan from it.\n", + "\n", + "## Hillclimbing\n", + "\n", + "Instead I'll see if I can improve the existing plans, using a simple *hillclimbing* strategy: Take a Plan A, and change it by randomly moving some soldiers from one castle to another. If that yields more `mean_points`, then keep the updated plan, otherwise discard it. Repeat." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def hillclimb(A, plans=plans, steps=1000):\n", + " \"Try to improve Plan A, repeat `steps` times; return new plan and total.\"\n", + " m = mean_points(A, plans)\n", + " for _ in range(steps):\n", + " B = mutate(A)\n", + " m, A = max((m, A), \n", + " (mean_points(B, plans), B))\n", + " return A, m\n", + "\n", + "def mutate(plan):\n", + " \"Return a new plan that is a slight mutation.\"\n", + " plan = list(plan) # So we can modify it.\n", + " i, j = random.sample(castles, 2)\n", + " plan[i], plan[j] = random_split(plan[i] + plan[j])\n", + " return Plan(plan)\n", + "\n", + "def random_split(n):\n", + " \"Split the integer n into two integers that sum to n.\"\n", + " r = random.randint(0, n)\n", + " return r, n - r" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how well this works. Remember, the best plan so far had a score of `87.4%`. Can we improve on that?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 3, 4, 15, 7, 21, 3, 31, 3, 13), 0.916)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hillclimb((0, 3, 4, 7, 16, 24, 4, 34, 4, 4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We got an improvement. Let's see what happens if we start with other plans:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 5, 5, 12, 7, 22, 3, 31, 3, 12), 0.912)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hillclimb((10, 10, 10, 10, 10, 10, 10, 10, 10, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((1, 3, 4, 14, 7, 21, 3, 31, 4, 12), 0.9105)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hillclimb((0, 1, 2, 3, 4, 18, 18, 18, 18, 18))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 5, 5, 15, 7, 21, 3, 31, 6, 7), 0.9065)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hillclimb((2, 3, 5, 5, 5, 20, 20, 20, 10, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 2, 6, 7, 18, 1, 26, 2, 32, 6), 0.8855)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hillclimb((0, 0, 5, 5, 25, 3, 25, 3, 31, 3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What if we hillclimb 20 times longer?" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((0, 5, 6, 14, 9, 21, 3, 31, 3, 8), 0.9065)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hillclimb((0, 3, 4, 7, 16, 24, 4, 34, 4, 4), steps=20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Opponent modeling\n", + "\n", + "To have a chance of winning the second round of this contest, we have to predict what the other entries will be like. Nobody knows for sure, but I can hypothesize that the entries will be slightly better than the first round, and try to approximate that by hillclimbing from each of the first-round plans for a small number of steps:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def hillclimbers(plans, steps=100):\n", + " \"Return a sorted list of [(improved_plan, mean_points), ...]\"\n", + " pairs = {hillclimb(plan, plans, steps) for plan in plans}\n", + " return sorted(pairs, key=lambda pair: pair[1], reverse=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[((29, 19, 2, 10, 6, 5, 3, 1, 25, 0), 1),\n", + " ((11, 9, 18, 3, 1, 11, 0, 27, 0, 0), 1),\n", + " ((0, 25, 0, 0, 0, 0, 0, 25, 25, 25), 1)]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# For example:\n", + "hillclimbers({(26, 5, 5, 5, 6, 7, 26, 0, 0, 0),\n", + " (25, 0, 0, 0, 0, 0, 0, 25, 25, 25),\n", + " (0, 25, 0, 0, 0, 0, 0, 25, 25, 25)})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I will define `plans2` (and `rankings2`) to be my estimate of the entries for round 2:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 6min 11s, sys: 3.21 s, total: 6min 14s\n", + "Wall time: 6min 17s\n", + "Top 10 of 1000 plans:\n", + "( 1, 4, 5, 15, 6, 21, 3, 31, 3, 11) 90.8%\n", + "( 0, 3, 5, 14, 7, 21, 3, 30, 4, 13) 90.6%\n", + "( 0, 4, 6, 15, 9, 21, 4, 31, 5, 5) 90.2%\n", + "( 2, 4, 3, 13, 5, 22, 3, 32, 4, 12) 90.1%\n", + "( 0, 3, 5, 15, 8, 21, 4, 32, 6, 6) 90.0%\n", + "( 0, 3, 5, 15, 6, 24, 3, 31, 5, 8) 90.0%\n", + "( 0, 3, 6, 13, 6, 21, 5, 30, 4, 12) 90.0%\n", + "( 3, 4, 5, 15, 7, 21, 2, 31, 6, 6) 89.9%\n", + "( 2, 3, 3, 13, 6, 21, 3, 30, 5, 14) 89.8%\n", + "( 0, 2, 2, 12, 2, 23, 4, 31, 3, 21) 89.8%\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%time rankings2 = hillclimbers(plans)\n", + "plans2 = {A for (A, _) in rankings2}\n", + "show(rankings2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even though we only took 100 steps, the `plans2` plans are greatly improved: Almost all of them defeat 75% or more of the first-round `plans`. The top 10 plans are all very similar, targeting castles 4+6+8+10 (for 28 points), but reserving 20 or soldiers to spread among the other castles. Let's look more carefully at every 40th plan, plus the last one:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "( 1, 4, 5, 15, 6, 21, 3, 31, 3, 11) 90.8%\n", + "( 0, 6, 3, 13, 3, 22, 2, 32, 4, 15) 88.9%\n", + "( 1, 3, 6, 13, 9, 22, 1, 30, 4, 11) 88.3%\n", + "( 2, 2, 1, 13, 3, 21, 2, 32, 3, 21) 87.9%\n", + "( 0, 2, 5, 5, 15, 2, 28, 31, 5, 7) 87.6%\n", + "( 2, 2, 4, 14, 9, 1, 27, 30, 6, 5) 87.3%\n", + "( 3, 2, 3, 12, 3, 28, 3, 32, 6, 8) 87.0%\n", + "( 1, 3, 2, 5, 18, 3, 26, 3, 33, 6) 86.7%\n", + "( 0, 4, 4, 6, 15, 3, 29, 30, 5, 4) 86.5%\n", + "( 5, 5, 4, 5, 13, 22, 2, 29, 3, 12) 86.2%\n", + "( 5, 6, 5, 6, 16, 24, 26, 1, 5, 6) 85.9%\n", + "( 0, 2, 5, 15, 8, 3, 20, 36, 6, 5) 85.7%\n", + "( 5, 1, 6, 12, 2, 24, 5, 32, 4, 9) 85.4%\n", + "( 2, 5, 8, 16, 11, 3, 2, 36, 5, 12) 85.1%\n", + "( 2, 7, 3, 15, 14, 2, 3, 31, 9, 12) 84.8%\n", + "( 6, 5, 8, 6, 7, 22, 30, 3, 7, 6) 84.6%\n", + "( 5, 3, 3, 5, 3, 21, 26, 26, 3, 5) 84.4%\n", + "( 0, 2, 4, 13, 2, 22, 17, 33, 2, 5) 84.0%\n", + "( 0, 7, 12, 6, 8, 21, 2, 29, 12, 3) 83.5%\n", + "( 5, 5, 4, 13, 18, 2, 26, 2, 6, 19) 83.0%\n", + "( 5, 6, 3, 15, 17, 24, 4, 2, 5, 19) 82.5%\n", + "( 5, 6, 5, 9, 6, 22, 34, 1, 7, 5) 81.8%\n", + "( 4, 3, 7, 17, 17, 22, 3, 3, 5, 19) 81.0%\n", + "( 0, 1, 2, 11, 12, 13, 28, 27, 2, 4) 80.4%\n", + "( 5, 6, 13, 16, 15, 26, 2, 4, 7, 6) 78.9%\n", + "( 0, 0, 1, 13, 0, 1, 24, 21, 36, 4) 70.3%\n" + ] + } + ], + "source": [ + "for (p, m) in rankings2[::40] + [rankings2[-1]]:\n", + " print(pplan(p), pct(m))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see a wider variety in plans as we go farther down the rankings. Now for the plot:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plotter(plans2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that many castles (e.g. 9 (green), 8 (blue), 7 (black), 6 (yellowish)) have two plateaus. Castle 7 (black) has a plateau at 3.5 points for 6 to 20 soldiers (suggesting that 6 soldiers is a good investment and 20 soldiers a bad investment), and then another plateau at 7 points for everything above 30 soldiers.\n", + "\n", + "Now that we have an estimate of the opponents, we can use `hillclimbers` to try to find a plan that does well against all the others:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 5min 40s, sys: 1 s, total: 5min 41s\n", + "Wall time: 5min 42s\n", + "Top 10 of 1000 plans:\n", + "( 3, 8, 10, 18, 21, 3, 5, 6, 10, 16) 99.9%\n", + "( 1, 9, 10, 17, 21, 6, 4, 6, 9, 17) 99.9%\n", + "( 1, 8, 10, 18, 21, 4, 4, 6, 11, 17) 99.9%\n", + "( 0, 10, 10, 17, 20, 4, 5, 6, 7, 21) 99.9%\n", + "( 2, 11, 1, 16, 18, 7, 6, 6, 8, 25) 99.8%\n", + "( 1, 8, 11, 19, 20, 4, 6, 5, 7, 19) 99.8%\n", + "( 0, 1, 11, 15, 18, 7, 6, 5, 13, 24) 99.8%\n", + "( 2, 10, 1, 17, 18, 9, 5, 6, 8, 24) 99.8%\n", + "( 1, 9, 10, 17, 19, 4, 6, 6, 9, 19) 99.8%\n", + "( 0, 2, 11, 18, 21, 4, 6, 8, 8, 22) 99.8%\n" + ] + }, + { + "data": { + "image/png": "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\nPqzoGSj/xk4AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%time rankings3 = hillclimbers(plans2)\n", + "show(rankings3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can try even harder to improve the champ:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((3, 9, 10, 17, 21, 3, 5, 6, 7, 19), 1)" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "champ, _ = rankings3[0]\n", + "hillclimb(champ, plans2, 10000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are some champion plans from previous runs of this notebook:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "champs = {\n", + " (0, 1, 3, 16, 20, 3, 4, 5, 32, 16),\n", + " (0, 1, 9, 16, 15, 24, 5, 5, 8, 17),\n", + " (0, 1, 9, 16, 16, 24, 5, 5, 7, 17),\n", + " (0, 2, 9, 16, 15, 24, 5, 5, 8, 16),\n", + " (0, 2, 9, 16, 15, 25, 5, 4, 7, 17),\n", + " (0, 3, 4, 7, 16, 24, 4, 34, 4, 4),\n", + " (0, 3, 5, 6, 20, 4, 4, 33, 8, 17),\n", + " (0, 4, 5, 7, 20, 4, 4, 33, 7, 16),\n", + " (0, 4, 6, 7, 19, 4, 4, 31, 8, 17),\n", + " (0, 4, 12, 18, 21, 7, 6, 4, 8, 20),\n", + " (0, 4, 12, 19, 25, 4, 5, 6, 8, 17),\n", + " (0, 5, 6, 7, 18, 4, 5, 32, 7, 16),\n", + " (0, 5, 7, 3, 18, 4, 4, 34, 8, 17),\n", + " (1, 2, 9, 16, 15, 24, 5, 4, 7, 17),\n", + " (1, 2, 9, 16, 15, 24, 5, 4, 8, 16),\n", + " (1, 2, 11, 16, 15, 24, 5, 4, 7, 15),\n", + " (1, 3, 14, 18, 24, 4, 5, 6, 8, 17),\n", + " (1, 6, 3, 16, 16, 24, 5, 5, 7, 17),\n", + " (2, 3, 7, 16, 16, 25, 5, 5, 8, 13),\n", + " (2, 3, 8, 16, 12, 25, 5, 4, 8, 17),\n", + " (2, 3, 8, 16, 15, 24, 5, 4, 7, 16),\n", + " (2, 3, 8, 16, 15, 25, 4, 5, 8, 14),\n", + " (2, 3, 8, 16, 16, 24, 5, 5, 8, 13),\n", + " (2, 3, 9, 15, 12, 25, 4, 5, 8, 17),\n", + " (2, 3, 9, 16, 12, 24, 5, 5, 8, 16),\n", + " (2, 4, 12, 18, 24, 4, 6, 5, 8, 17),\n", + " (3, 3, 7, 16, 16, 24, 5, 5, 8, 13),\n", + " (3, 3, 8, 16, 12, 25, 4, 4, 8, 17),\n", + " (3, 3, 8, 16, 15, 25, 5, 4, 7, 14),\n", + " (3, 4, 12, 18, 23, 4, 6, 5, 8, 17),\n", + " (3, 4, 15, 18, 23, 4, 5, 6, 8, 14),\n", + " (3, 5, 7, 16, 5, 4, 5, 34, 7, 14),\n", + " (3, 6, 13, 17, 23, 4, 6, 5, 8, 15),\n", + " (4, 3, 12, 18, 23, 4, 5, 6, 8, 17),\n", + " (4, 5, 3, 15, 11, 23, 5, 5, 10, 19),\n", + " (4, 6, 3, 16, 14, 25, 5, 5, 8, 14),\n", + " (4, 6, 3, 16, 16, 24, 5, 5, 7, 14),\n", + " (4, 6, 3, 16, 16, 24, 5, 5, 8, 13),\n", + " (5, 3, 12, 17, 23, 4, 5, 6, 8, 17),\n", + " (5, 5, 3, 16, 12, 25, 4, 5, 8, 17),\n", + " (5, 6, 3, 16, 16, 24, 5, 5, 7, 13),\n", + " (5, 6, 7, 3, 21, 4, 27, 5, 8, 14),\n", + " (5, 6, 8, 3, 18, 4, 27, 5, 8, 16),\n", + " (5, 6, 8, 3, 20, 4, 27, 5, 8, 14),\n", + " (5, 6, 8, 3, 21, 4, 27, 5, 8, 13)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can evaluate each of them against the original `plans`, against the improved `plans2`, against their fellow champs, and against all of those put together:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Plan plans plans2 champs all\n", + "( 0, 5, 7, 3, 18, 4, 4, 34, 8, 17) 85.5% 96.0% 68.5% 90.2%\n", + "( 0, 4, 6, 7, 19, 4, 4, 31, 8, 17) 84.7% 95.0% 63.0% 89.2%\n", + "( 0, 1, 3, 16, 20, 3, 4, 5, 32, 16) 85.6% 95.2% 31.5% 89.0%\n", + "( 0, 3, 5, 6, 20, 4, 4, 33, 8, 17) 84.1% 95.2% 60.9% 89.0%\n", + "( 0, 5, 6, 7, 18, 4, 5, 32, 7, 16) 84.3% 96.3% 28.3% 88.9%\n", + "( 3, 5, 7, 16, 5, 4, 5, 34, 7, 14) 85.2% 95.7% 18.5% 88.8%\n", + "( 5, 6, 8, 3, 18, 4, 27, 5, 8, 16) 81.8% 96.4% 64.1% 88.6%\n", + "( 0, 4, 5, 7, 20, 4, 4, 33, 7, 16) 84.7% 95.0% 18.5% 88.2%\n", + "( 5, 6, 8, 3, 20, 4, 27, 5, 8, 14) 82.0% 96.2% 48.9% 88.2%\n", + "( 0, 1, 9, 16, 15, 24, 5, 5, 8, 17) 78.2% 98.6% 72.8% 88.0%\n", + "( 5, 6, 7, 3, 21, 4, 27, 5, 8, 14) 81.8% 96.0% 51.1% 88.0%\n", + "( 0, 1, 9, 16, 16, 24, 5, 5, 7, 17) 79.1% 98.5% 46.7% 87.8%\n", + "( 5, 6, 8, 3, 21, 4, 27, 5, 8, 13) 82.0% 95.2% 45.7% 87.6%\n", + "( 2, 3, 9, 15, 12, 25, 4, 5, 8, 17) 78.5% 97.9% 58.7% 87.5%\n", + "( 4, 5, 3, 15, 11, 23, 5, 5, 10, 19) 76.8% 97.8% 97.8% 87.5%\n", + "( 2, 3, 8, 16, 12, 25, 5, 4, 8, 17) 78.2% 98.1% 57.6% 87.5%\n", + "( 2, 3, 8, 16, 15, 25, 4, 5, 8, 14) 79.7% 97.9% 31.5% 87.5%\n", + "( 0, 2, 9, 16, 15, 24, 5, 5, 8, 16) 78.5% 98.2% 50.0% 87.4%\n", + "( 2, 3, 7, 16, 16, 25, 5, 5, 8, 13) 79.3% 97.5% 44.6% 87.4%\n", + "( 4, 6, 3, 16, 14, 25, 5, 5, 8, 14) 79.0% 97.4% 48.9% 87.3%\n", + "( 5, 5, 3, 16, 12, 25, 4, 5, 8, 17) 78.1% 97.8% 60.9% 87.3%\n", + "( 4, 6, 3, 16, 16, 24, 5, 5, 7, 14) 80.3% 97.2% 21.7% 87.3%\n", + "( 2, 3, 8, 16, 15, 24, 5, 4, 7, 16) 80.2% 97.8% 10.9% 87.2%\n", + "( 1, 2, 9, 16, 15, 24, 5, 4, 7, 17) 79.8% 97.8% 19.6% 87.2%\n", + "( 0, 2, 9, 16, 15, 25, 5, 4, 7, 17) 79.1% 97.9% 31.5% 87.2%\n", + "( 2, 3, 8, 16, 16, 24, 5, 5, 8, 13) 79.5% 97.5% 29.3% 87.2%\n", + "( 2, 3, 9, 16, 12, 24, 5, 5, 8, 16) 78.0% 98.2% 45.7% 87.1%\n", + "( 3, 3, 8, 16, 15, 25, 5, 4, 7, 14) 80.3% 97.6% 6.5% 87.1%\n", + "( 1, 2, 9, 16, 15, 24, 5, 4, 8, 16) 79.2% 97.6% 27.2% 87.0%\n", + "( 3, 3, 7, 16, 16, 24, 5, 5, 8, 13) 79.8% 97.1% 26.1% 87.0%\n", + "( 4, 6, 3, 16, 16, 24, 5, 5, 8, 13) 80.0% 96.7% 28.3% 87.0%\n", + "( 3, 3, 8, 16, 12, 25, 4, 4, 8, 17) 78.8% 97.8% 28.3% 87.0%\n", + "( 5, 6, 3, 16, 16, 24, 5, 5, 7, 13) 80.9% 96.5% 8.7% 86.9%\n", + "( 1, 2, 11, 16, 15, 24, 5, 4, 7, 15) 79.9% 97.2% 6.5% 86.7%\n", + "( 1, 6, 3, 16, 16, 24, 5, 5, 7, 17) 75.2% 97.9% 41.3% 85.5%\n", + "( 5, 3, 12, 17, 23, 4, 5, 6, 8, 17) 64.3% 99.5% 84.8% 82.0%\n", + "( 4, 3, 12, 18, 23, 4, 5, 6, 8, 17) 64.0% 99.5% 88.0% 81.9%\n", + "( 3, 4, 12, 18, 23, 4, 6, 5, 8, 17) 63.2% 99.5% 88.0% 81.5%\n", + "( 2, 4, 12, 18, 24, 4, 6, 5, 8, 17) 63.0% 99.5% 91.3% 81.5%\n", + "( 3, 4, 15, 18, 23, 4, 5, 6, 8, 14) 63.4% 99.5% 76.1% 81.3%\n", + "( 3, 6, 13, 17, 23, 4, 6, 5, 8, 15) 63.2% 99.4% 78.3% 81.2%\n", + "( 1, 3, 14, 18, 24, 4, 5, 6, 8, 17) 62.4% 99.5% 93.5% 81.2%\n", + "( 0, 4, 12, 19, 25, 4, 5, 6, 8, 17) 62.1% 99.5% 95.7% 81.1%\n", + "( 1, 9, 11, 17, 21, 6, 5, 4, 10, 16) 62.1% 100.0% 76.1% 80.9%\n", + "( 0, 4, 12, 18, 21, 7, 6, 4, 8, 20) 61.4% 99.6% 100.0% 80.9%\n", + "( 1, 7, 13, 17, 23, 6, 6, 5, 8, 14) 62.4% 99.5% 78.3% 80.9%\n", + "( 0, 3, 4, 7, 16, 24, 4, 34, 4, 4) 87.4% 37.6% 0.0% 61.1%\n" + ] + } + ], + "source": [ + "def μ(plan, plans): return pct(mean_points(plan,plans))\n", + "all = plans | plans2 | champs\n", + "\n", + "print('Plan plans plans2 champs all')\n", + "for p in sorted(champs, key=lambda p: -mean_points(p, all)):\n", + " print(pplan(p), μ(p, plans), μ(p, plans2), μ(p, champs), μ(p, all))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Which plan is best? In the end, we don't know, because we don't know the pool we will be competing against." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/SET.ipynb b/pytudes/ipynb/SET.ipynb new file mode 100644 index 0000000..7534eae --- /dev/null +++ b/pytudes/ipynb/SET.ipynb @@ -0,0 +1,697 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# SET\n", + "\n", + "How many cards are there? There are four features (color, shape, shading, and number of figures) on each card, and each feature can take one of three values. So the number of cards is:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "81" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "3 ** 4" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "How many sets are there?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1080.0" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "81 * 80 * 1 / 6" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "How many sets does each card participate in? We need to look at the number of sets (1080) and the number of cards in a set (3), divided by the number of cards (81):" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "40.0" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1080 * 3 / 81" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "Note that each *pair* of cards participates in exactly one set.\n", + "\n", + "How many layouts of 12 cards are there? The answer is (81 choose 12):" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "70724320184700.0" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from math import factorial as fact\n", + "\n", + "def C(n, k): \n", + " \"Number of ways of choosing k things from n things.\"\n", + " return fact(n) / fact(n-k) / fact(k)\n", + "\n", + "C(81, 12)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "That's a lot of digits; hard to read. This should help:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "70.7243201847" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "M = 10 ** 6 # Million\n", + "T = 10 ** 12 # Trillion\n", + "\n", + "C(81, 12) / T" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "70 trillion layouts. Of those some will have 6 sets, some more, some less.\n", + "\n", + "In a layout of 12 cards, how many triples (that could potentially be a set) are there?" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "220.0" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "C(12, 3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": {} + }, + "source": [ + "So, what we're looking for is when exactly 6 of these are sets, and the other 214 are not." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2173.5413336637" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "C(1080, 6) / T" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "81" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from itertools import product\n", + "\n", + "feature = (1, 2, 3)\n", + "\n", + "Card = tuple\n", + "\n", + "cards = set(product(feature, feature, feature, feature))\n", + "len(cards)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def match(card1, card2):\n", + " return Card(match_feature(card1[i], card2[i]) \n", + " for i in (0, 1, 2, 3))\n", + "\n", + "def match_feature(f1, f2):\n", + " return f1 if f1 == f2 else 6 - f1 - f2" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, 3, 1, 3)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "match((1, 2, 3, 3),\n", + " (1, 1, 2, 3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "2173 trillion; even worse.\n", + "\n", + "How many layouts are there where:\n", + "- The first six cards form no sets\n", + "- The last six cards each form a set?" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "246.7179" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "81 * 80 * (79 - 1) * (78 - 3) * (77 - 6) * (76 - 10) / fact(6) / M" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1.091475" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "15 * 21 * 28 * 36 * 45 * 55 / fact(6) / M" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All tests pass.\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for the instruction booklet\n", + "-----+--------+--------+----------------\n", + " 12 | 33 | 1 | 33:1\n", + " 15 | 2,500 | 1 | 2500:1\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for initial layout\n", + "-----+--------+--------+----------------\n", + " 12 | 96,844 | 3,156 | 31:1\n", + " 15 | 99,963 | 37 | 2702:1\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for game play\n", + "-----+--------+--------+----------------\n", + " 12 | 86,065 | 5,871 | 15:1\n", + " 15 | 5,595 | 64 | 87:1\n", + " 18 | 57 | 0 | inft:1\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for initial layout, but no sets before dealing last 3 cards\n", + "-----+--------+--------+----------------\n", + " 12 | 26,426 | 3,242 | 8:1\n", + " 15 | 3,207 | 35 | 92:1\n" + ] + } + ], + "source": [ + "import random\n", + "import collections \n", + "import itertools \n", + "\n", + "\"\"\"\n", + "Game of Set (Peter Norvig 2010-2015)\n", + "\n", + "How often do sets appear when we deal an array of cards?\n", + "How often in the course of playing out the game?\n", + "\n", + "Here are the data types we will use:\n", + "\n", + " card: A string, such as '3R=0', meaning \"three red striped ovals\".\n", + " deck: A list of cards, initially of length 81.\n", + " layout: A list of cards, initially of length 12.\n", + " set: A tuple of 3 cards.\n", + " Tallies: A dict: {12: {True: 33, False: 1}}} means a layout of size 12\n", + " tallied 33 sets and 1 non-set.\n", + "\"\"\"\n", + "\n", + "#### Cards, dealing cards, and defining the notion of sets.\n", + "\n", + "CARDS = [number + color + shade + symbol \n", + " for number in '123' \n", + " for color in 'RGP' \n", + " for shade in '@O=' \n", + " for symbol in '0SD']\n", + "\n", + "def deal(n, deck): \n", + " \"Deal n cards from the deck.\"\n", + " return [deck.pop() for _ in range(n)]\n", + "\n", + "def is_set(cards):\n", + " \"Are these 3 cards a set? No if any feature has 2 values.\"\n", + " for f in range(4):\n", + " values = {card[f] for card in cards}\n", + " if len(values) == 2: \n", + " return False\n", + " return True\n", + "\n", + "def find_set(layout):\n", + " \"Return a set found from this layout, if there is one.\"\n", + " for cards in itertools.combinations(layout, 3):\n", + " if is_set(cards):\n", + " return cards\n", + " return ()\n", + "\n", + "#### Tallying set:no-set ratio\n", + "\n", + "def Tallies(): \n", + " \"A data structure to keep track, for each size, the number of sets and no-sets.\"\n", + " return collections.defaultdict(lambda: {True: 0, False: 0})\n", + "\n", + "def tally(tallies, layout):\n", + " \"Record that a set was found or not found in a layout of given size; return the set.\"\n", + " s = find_set(layout)\n", + " tallies[len(layout)][bool(s)] += 1\n", + " return s\n", + " \n", + "#### Three experiments\n", + "\n", + "def tally_initial_layout(N, sizes=(12, 15)):\n", + " \"Record tallies for N initial deals.\"\n", + " tallies = Tallies()\n", + " deck = list(CARDS)\n", + " for deal in range(N):\n", + " random.shuffle(deck)\n", + " for size in sizes:\n", + " tally(tallies, deck[:size])\n", + " return tallies\n", + "\n", + "def tally_initial_layout_no_prior_sets(N, sizes=(12, 15)):\n", + " \"\"\"Simulate N initial deals for each size, keeping tallies for Sets and NoSets,\n", + " but only when there was no set with 3 fewer cards.\"\"\"\n", + " tallies = Tallies()\n", + " deck = list(CARDS)\n", + " for deal in range(N):\n", + " random.shuffle(deck)\n", + " for size in sizes:\n", + " if not find_set(deck[:size-3]):\n", + " tally(tallies, deck[:size])\n", + " return tallies\n", + "\n", + "def tally_game_play(N):\n", + " \"Record tallies for the play of N complete games.\"\n", + " tallies = Tallies()\n", + " for game in range(N):\n", + " deck = list(CARDS)\n", + " random.shuffle(deck)\n", + " layout = deal(12, deck)\n", + " while deck:\n", + " s = tally(tallies, layout)\n", + " # Pick up the cards in the set, if any\n", + " for card in s: layout.remove(card)\n", + " # Deal new cards\n", + " if len(layout) < 12 or not s:\n", + " layout += deal(3, deck) \n", + " return tallies\n", + "\n", + "def experiments(N):\n", + " show({12: [1, 33], 15: [1, 2500]}, \n", + " 'the instruction booklet')\n", + " show(tally_initial_layout(N), \n", + " 'initial layout')\n", + " show(tally_game_play(N // 25), \n", + " 'game play')\n", + " show(tally_initial_layout_no_prior_sets(N), \n", + " 'initial layout, but no sets before dealing last 3 cards')\n", + "\n", + "\n", + "def show(tallies, label):\n", + " \"Print out the counts.\"\n", + " print()\n", + " print('Size | Sets | NoSets | Set:NoSet ratio for', label)\n", + " print('-----+--------+--------+----------------')\n", + " for size in sorted(tallies):\n", + " y, n = tallies[size][True], tallies[size][False]\n", + " ratio = ('inft' if n==0 else int(round(float(y)/n)))\n", + " print('{:4d} |{:7,d} |{:7,d} | {:4}:1'\n", + " .format(size, y, n, ratio))\n", + "\n", + "def test():\n", + " assert len(CARDS) == 81 == len(set(CARDS))\n", + " assert is_set(('3R=O', '2R=S', '1R=D'))\n", + " assert not is_set(('3R=0', '2R=S', '1R@D'))\n", + " assert find_set(['1PO0', '2G=D', '3R=0', '2R=S', '1R=D']) == ('3R=0', '2R=S', '1R=D')\n", + " assert not find_set(['1PO0', '2G=D', '3R=0', '2R=S', '1R@D'])\n", + " photo = '2P=0 3P=D 2R=0 3GO0 2POD 3R@D 2RO0 2ROS 1P@S 2P@0 3ROS 2GOD 2P@D 1GOD 3GOS'.split()\n", + " assert not find_set(photo)\n", + " assert set(itertools.combinations([1, 2, 3, 4], 3)) == {(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)}\n", + " print('All tests pass.')\n", + "\n", + "test()\n", + "experiments(100000)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for the instruction booklet\n", + "-----+--------+--------+----------------\n", + " 12 | 33 | 1 | 33:1\n", + " 15 | 2,500 | 1 | 2500:1\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for initial layout\n", + "-----+--------+--------+----------------\n", + " 12 | 9,696 | 304 | 32:1\n", + " 15 | 9,995 | 5 | 1999:1\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for game play\n", + "-----+--------+--------+----------------\n", + " 12 | 8,653 | 542 | 16:1\n", + " 15 | 513 | 5 | 103:1\n", + " 18 | 5 | 0 | inft:1\n", + "\n", + "Size | Sets | NoSets | Set:NoSet ratio for initial layout, but no sets before dealing last 3 cards\n", + "-----+--------+--------+----------------\n", + " 12 | 2,630 | 294 | 9:1\n", + " 15 | 293 | 1 | 293:1\n" + ] + } + ], + "source": [ + "experiments(10000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "run_control": {} + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Scrabble.ipynb b/pytudes/ipynb/Scrabble.ipynb new file mode 100644 index 0000000..7dbea70 --- /dev/null +++ b/pytudes/ipynb/Scrabble.ipynb @@ -0,0 +1,13389 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "

Peter Norvig
29 December 2015
\n", + "\n", + "# Refactoring a Crossword Game Program\n", + "\n", + "In my [CS 212 class](https://www.udacity.com/course/design-of-computer-programs--cs212) on Udacity, the [most complex lesson](https://www.udacity.com/course/viewer#!/c-cs212/l-48634860) involved a crossword game program (for games such as Scrabble® and Words with Friends®). The program was developed *incrementally*. First I asked \"what words can be made with a rack of seven letters, reagardless of the board?\", then I asked \"how can you place words onto a single row of the board?\", and finally, I, with the help of the students, developed a program to find the highest scoring play anywhere on the board. This approach made for a good sequence of exercises, each building on the previous one. But the code ended up being overly complicated—it accumlated [technical debt](https://en.wikipedia.org/wiki/Technical_debt)—because it kept around old ideas from each iteration.\n", + "\n", + "In this notebook I will refactor the program to pay off the technical debt.\n", + "\n", + "# Vocabulary\n", + "\n", + "Our program uses these concepts:\n", + "\n", + "* **Dictionary**: A set of all legal words. Each word has only the letters A-Z.\n", + "* **Word**: a string of uppercase letters. \n", + "* **Tile**: a letter (or a blank) that can be played on the board to form words. \n", + "* **Blank**: a tile with no letter on it; the player who places it on the board gets to choose which letter it will represent. \n", + "* **Rack**: a collection of up to seven tiles that a player uses to make words.\n", + "* **Board**: a grid of squares onto which players play tiles to make words. \n", + "* **Square**: a location on the board; a square can hold one tile. (In the code, the variable name `s` always stands for a square number, and `sq` for the contents of a square, which can be a tile or empty.)\n", + "* **Bonus**: some squares give you bonus scores: double or triple letter or word scores.\n", + "* **Play**: a play consists of placing some tiles on the board to form a continuous string of letters in one direction (across or down), such that only valid words are formed, and such that one of the letters is placed on an anchor square.\n", + "* **Anchor square**: Every play must place a letter on an anchor square: either the center start square or a square that is adjacent to a tile previously played on the board. \n", + "* **Direction:** Every play must be in either the across or down direction. (The variable `dir` always stands for a direction, and is `1` for across and `17` for down.)\n", + "* **Cross word**: a word formed in the *other* direction from a play. For example, a play forms a word in the across direction, and in doing so, places a letter that extends a word in the down direction. Any new extended *cross word* must be in the dictionary.\n", + "* **Score**: the points awarded for a play, consisting of the sum of the word scores for each word created (the main word and possibly any cross words), plus a *bingo* bonus if all seven letters are used. \n", + "* **Word score**: Each word scores the sum of the letter scores for each tile (either placed by the player or already on the board but part of the word) times the word bonus score. The word bonus score starts at 1, and is multiplied by 2 for each double word square and 3 for each triple word square covered by a tile on this play.\n", + "* **Letter score**: The letter score is the value on the letter tile (for example, 1 for `A` and 10 for `Q`) times the letter bonus score. The letter bonus is 2 when a tile is first placed on a double letter square (or the center star) and 3 when first placed on a triple letter square; it is 1 for a tile already on the board, or for a new tile played on a non-letter-bonus square. The letter score for a blank tile is always zero.\n", + "* **Bingo**: a bonus gained by using all seven tiles in one play. In Words with Friends® the bingo bonus is 35; in Scrabble® it is 50.\n", + "* **Game**: players take turns making plays until one player has no more tiles. After making a play, the player's\n", + "rack is replenished with tiles until the player has 7 tiles or until the bag of tiles is empty.\n", + "* **Prefix**: a string of zero or more letters that starts some word in the dictionary. Not a concept that has to do\n", + "with the *rules* of the game; it will be important in our *algorithm* that finds valid plays.\n", + "\n", + "This notebook uses these imports:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from __future__ import division, print_function\n", + "from collections import defaultdict, namedtuple\n", + "from IPython.display import HTML, display\n", + "import random" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "# Dictionary and Words\n", + "\n", + "We will represent the dictionary as a set of words. A word is an uppercase string of letters, like `'WORD'`. There are several standard dictionaries used by different communities of players; we will use the ENABLE dictionary—we can cache a local copy with this shell command:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "! [ -e enable1.txt ] || curl -O http://norvig.com/ngrams/enable1.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can define what words are, load the dictionary, and show how the dictionary works:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def Word(w) -> str: return w.strip().upper()\n", + "\n", + "def is_word(word) -> bool: \n", + " \"Is this a legal word in the dictionary?\"\n", + " return word.upper() in DICTIONARY" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "DICTIONARY = {Word(w) for w in open('enable1.txt')}" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "172820" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(DICTIONARY)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['RATANY',\n", + " 'CONFERRING',\n", + " 'PHOTOTOXICITIES',\n", + " 'BESTIRS',\n", + " 'STRENGTH',\n", + " 'JACKSMELTS',\n", + " 'INVERSION',\n", + " 'PILEUP',\n", + " 'EYEBARS',\n", + " 'KNUCKLEHEADED']" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.sample(DICTIONARY, 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'HELLO' in DICTIONARY" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Tiles, Blanks, and Racks\n", + "\n", + "We'll represent a tile as a one-character string, like `'W'`. We'll represent a rack as a string of tiles, usually of length 7, such as `'EELRTTS'`. (I also considered a `collections.Counter` to represent a rack, but felt that `str` was simpler, and with the rack size limited to 7, efficiency was not a major issue.)\n", + "\n", + "The blank tile causes some complications. We'll represent a blank in a player's rack as the underscore character, `'_'`. But once the blank is played on the board, it must be used as if it was a specific letter. However, it doesn't score the points of the letter. I chose to use the lowercase version of the letter to represent this. That way, we know what letter the blank is standing for, and we can distinguish between scoring and non-scoring tiles. For example, `'EELRTT_'` is a rack that contains a blank; and `'LETTERs'` is a word played on the board that uses the blank to stand for the letter `S`. \n", + "\n", + "We'll define `letters` to give all the distinct letters that can be made by a rack, and `remove` to remove letters from a rack (after they have been played)." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "BLANK = '_' # The blank tile (as it appears in the rack)\n", + "cat = ''.join # Function to concatenate strings\n", + "\n", + "def letters(rack) -> str:\n", + " \"All the distinct letters in a rack (including lowercase if there is a blank).\"\n", + " if BLANK in rack:\n", + " return cat(set(rack.replace(BLANK, ''))) + 'abcdefghijklmnopqrstuvwxyz'\n", + " else:\n", + " return cat(set(rack))\n", + " \n", + "def letters(rack) -> str:\n", + " \"All the distinct letters in a rack (including lowercase if there is a blank).\"\n", + " if BLANK in rack:\n", + " return letters(rack.replace(BLANK, '')) + 'abcdefghijklmnopqrstuvwxyz'\n", + " else:\n", + " return cat(set(rack))\n", + " \n", + "def remove(tiles, rack) -> str:\n", + " \"Return a copy of rack with the given tile(s) removed.\"\n", + " for tile in tiles:\n", + " if tile.islower(): tile = BLANK\n", + " rack = rack.replace(tile, '', 1)\n", + " return rack" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "is_word('LETTERs')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ERLST'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "letters('LETTERS')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ERLTabcdefghijklmnopqrstuvwxyz'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "letters('EELRTT_')" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'LTER'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "remove('SET', 'LETTERS')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'LE'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "remove('TREaT', 'LETTER_') " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# The Board, Squares, Directions, and Bonus Squares\n", + "\n", + "In the [previous version](https://www.udacity.com/course/viewer#!/c-cs212/l-48634860) of this program, the board was a two-dimensional matrix, and a square on the board was denoted by a `(row, col)` pair of indexes. There's nothing wrong with that representation, but for this version we will choose a different representation that is simpler in most ways:\n", + "\n", + "* The board is represented as a one-dimensional list of squares.\n", + "* The default board is 15×15 squares, but\n", + "we will include a *border* around the outside, making the board size 17×17. \n", + "* Squares are denoted by integer indexes, from 0 to 288.\n", + "* To move in the `ACROSS` direction from one square to the next, increment the square index by 1.\n", + "* To move in the `DOWN` direction from one square to the next, increment the square index by 17.\n", + "* The border squares are filled with a symbol, `OFF`, indicating that they are off the board.\n", + "The advantage of the border is that the code never has to check if it is at the edge of the board; it can always\n", + "look at the neighboring square without fear of indexing off the end of the board.\n", + "* Each square on the board is initially filled by a symbol indicating the bonus value of the square. When a tile is placed on a square,\n", + "the tile replaces the bonus value.\n", + "\n", + "How will we implement this? We'll define `Board` as a subclass of `list` and give it two additional attributes: \n", + "\n", + "- `down`: the increment to move in the down direction; 17 for a standard board.\n", + "- `directions`: the four increments to move to any neighboring square; `(1, 17, -1, -17)` in a standard board.\n", + "\n", + "Jupyter/Ipython notebooks have a special convention for displaying objects in HTML. We will adopt it as a method of `Board`:\n", + "\n", + "- `_repr_html_`: return a string of HTML that displays the board as a table." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "ACROSS = 1 # The 'across' direction; 'down' depends on the size of the board\n", + "OFF = '#' # A square that is off the board\n", + "EMPTY = '.:;-=*'\n", + "SL, DL, TL, DW, TW, STAR = EMPTY # Single/double/triple letter; double/triple word; star\n", + "\n", + "Square = int # Squares are implemented as integer indexes.\n", + "Direction = int # Directions are implemented as integer increments\n", + "\n", + "class Board(list):\n", + " \"\"\"A Board is a (linear) list of squares, each a single character.\n", + " Note that board[s + down] is directly below board[s].\"\"\"\n", + "\n", + " def __init__(self, squares, bingo=None):\n", + " list.__init__(self, squares)\n", + " self.bingo = bingo or squares.bingo\n", + " down = int(len(squares)**0.5)\n", + " self.down = down\n", + " self.directions = (ACROSS, down, -ACROSS, -down)\n", + " \n", + " def _repr_html_(self) -> str: return board_html(self)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We'll define the standard boards for Words with Friends® and Scrabble®:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "WWF = Board(\"\"\"\n", + "# # # # # # # # # # # # # # # # #\n", + "# . . . = . . ; . ; . . = . . . #\n", + "# . . : . . - . . . - . . : . . #\n", + "# . : . . : . . . . . : . . : . #\n", + "# = . . ; . . . - . . . ; . . = #\n", + "# . . : . . . : . : . . . : . . #\n", + "# . - . . . ; . . . ; . . . - . #\n", + "# ; . . . : . . . . . : . . . ; #\n", + "# . . . - . . . * . . . - . . . #\n", + "# ; . . . : . . . . . : . . . ; #\n", + "# . - . . . ; . . . ; . . . - . #\n", + "# . . : . . . : . : . . . : . . #\n", + "# = . . ; . . . - . . . ; . . = #\n", + "# . : . . : . . . . . : . . : . #\n", + "# . . : . . - . . . - . . : . . #\n", + "# . . . = . . ; . ; . . = . . . #\n", + "# # # # # # # # # # # # # # # # #\n", + "\"\"\".split(), bingo=35)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "SCRABBLE = Board(\"\"\"\n", + "# # # # # # # # # # # # # # # # #\n", + "# = . . : . . . = . . . : . . = #\n", + "# . - . . . ; . . . ; . . . - . #\n", + "# . . - . . . : . : . . . - . . #\n", + "# : . . - . . . : . . . - . . : #\n", + "# . . . . - . . . . . - . . . . #\n", + "# . ; . . . ; . . . ; . . . ; . #\n", + "# . . : . . . : . : . . . : . . #\n", + "# = . . : . . . * . . . : . . = #\n", + "# . . : . . . : . : . . . : . . #\n", + "# . ; . . . ; . . . ; . . . ; . #\n", + "# . . . . - . . . . . - . . . . #\n", + "# : . . - . . . : . . . - . . : #\n", + "# . . - . . . : . : . . . - . . #\n", + "# . - . . . ; . . . ; . . . - . #\n", + "# = . . : . . . = . . . : . . = #\n", + "# # # # # # # # # # # # # # # # #\n", + "\"\"\".split(), bingo=50)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "assert len(WWF) == len(SCRABBLE) == 17 * 17\n", + "assert all(sq in EMPTY or sq == OFF for sq in WWF + SCRABBLE)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Displaying the Board in HTML\n", + "\n", + "I want to diaplay the board in HTML, as a table with different background colors for the bonus squares; and gold-colored letter tiles. I also want to display the point values for each letter on the tiles; I'll use a `defaultdict` of `{letter: int}` named `POINTS` for that." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def board_html(board) -> str:\n", + " \"An HTML representation of the board.\"\n", + " size = board.down - 2\n", + " squares = [square_html(sq) for sq in board if sq != OFF]\n", + " row = ('' + '{}' * size)\n", + " return ('' + row * size + '
').format(*squares)\n", + " \n", + "board_colors = {\n", + " DL: ('lightblue', 66, 'DL'),\n", + " TL: ('lightgreen', 66, 'TL'),\n", + " DW: ('lightcoral', 66, 'DW'),\n", + " TW: ('orange', 66, 'TW'),\n", + " SL: ('whitesmoke', 66, ''),\n", + " STAR: ('violet', 100, '✭')}\n", + "\n", + "def square_html(sq) -> str:\n", + " \"An HTML representation of a square.\"\n", + " color, size, text = board_colors.get(sq, ('gold', 120, sq))\n", + " if text.isupper(): \n", + " text = '{}{}'.format(text, POINTS.get(text, ''))\n", + " params = \"width:25px; height:25px; text-align:center; padding:0px;\"\n", + " style = \"background-color:{}; font-size:{}%\".format(color, size, text)\n", + " return '' + text\n", + "\n", + "POINTS = defaultdict(int, \n", + " A=1, B=3, C=3, D=2, E=1, F=4, G=2, H=4, I=1, J=8, K=5, L=1, M=3, \n", + " N=1, O=1, P=3, Q=10, R=1, S=1, T=1, U=1, V=4, W=4, X=8, Y=4, Z=10)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDW
TLDLDLTL
DWDW
TLDLDLTL
DWTLTLDW
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "WWF" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWDLTWDLTW
DWTLTLDW
DWDLDLDW
DLDWDLDWDL
DWDW
TLTLTLTL
DLDLDLDL
TWDLDLTW
DLDLDLDL
TLTLTLTL
DWDW
DLDWDLDWDL
DWDLDLDW
DWTLTLDW
TWDLTWDLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "SCRABBLE" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Plays\n", + "\n", + "A `Play` describes the placement of tiles on the board. We will implement `Play` as a named tuple of four components:\n", + "- `start`: the index number of the square that holds the first letter in the word.\n", + "- `dir`: the direction, with 1 indicating `ACROSS` and `board.down` (normally, 17) indicating `DOWN`.\n", + "- `letters`: the letters of the word, in order, as a `str`. Blanks are lowercase. Some letters are from the rack; some may have been on the board.\n", + "- `rack`: the letters that would remain in the player's rack after making this play. Not strictly necessary as part of the play, but useful information.\n", + "\n", + "The function `make_play` returns a new board with the play made on it. It does not do any checking to see if the play is legal." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "Play = namedtuple('Play', 'start, dir, letters, rack')\n", + "\n", + "def make_play(board, play) -> Board:\n", + " \"Make the play on a copy of board and return the copy.\"\n", + " copy = Board(board)\n", + " end = play.start + len(play.letters) * play.dir\n", + " copy[play.start:end:play.dir] = play.letters\n", + " return copy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Example Board\n", + "\n", + "Let's test out what we've done so far. I'll take some words from a previous game and put them on `board`:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2DWB3E1C3DWI1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'E',\n", + " '.',\n", + " 'C',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DOWN = WWF.down\n", + "plays = {Play(145, DOWN, 'ENTER', ''),\n", + " Play(144, ACROSS, 'BE', ''),\n", + " Play(138, DOWN, 'GAVE', ''),\n", + " Play(158, DOWN, 'MUSES', ''),\n", + " Play(172, ACROSS, 'VIRULeNT', ''),\n", + " Play(213, ACROSS, 'RED', ''),\n", + " Play(198, ACROSS, 'LYTHE', ''),\n", + " Play(147, DOWN, 'CHILDREN', ''),\n", + " Play(164, ACROSS, 'HEARD', ''),\n", + " Play(117, DOWN, 'BRIDLES', ''),\n", + " Play(131, ACROSS, 'TOUR', '')}\n", + "\n", + "board = Board(WWF)\n", + "for play in plays:\n", + " board = make_play(board, play)\n", + "board" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Strategy for Finding Legal Plays\n", + "\n", + "This is our strategy for finding all possible legal plays on a board:\n", + "\n", + "1. Find all *anchor squares* on the board. An anchor square is an empty square that is adjacent to a letter on the board—every legal move must place a letter on an anchor square. (One exception: on the game's first play, there are no letters on the board, and the `STAR` square in the center counts as the only anchor square.)\n", + "2. Using just the letters in the rack, find all *prefixes* of words in the dictionary. For example, with the rack `ABC`, we find that `B`, `BA`, and `BAC` are all prefixes of the word `BACK` (and the rack contains other prefixes of other words as well).\n", + "3. For each anchor square and for both directions (across and down):\n", + " - Try each prefix before the anchor (that is, to the left or above the anchor). Don't allow a prefix to extend to another anchor or off the board. That means we won't have to worry about *cross words* for the prefix. If there are already letters on the board before the anchor point, use them as the (only possible) prefix rather than using the prefixes from the rack. For each prefix that fits:\n", + " - Starting at the anchor, march forward (or down) one square at a time, trying to fill empty squares with each possible letter from the rack that forms a valid prefix of a word in the dictionary. If the march forward hits letters that are already on the board, make sure they form a valid prefix too. Also check that any cross words are valid words. When we make a complete word (with an empty or `OFF` square ahead), yield the play that made the word.\n", + " \n", + "So, each legal play will have zero or more prefix letters (which either all come from the rack or all were already on the board), followed by one letter from the rack covering an anchor square, followed by zero or more additional letters (which can be a mix of letters from the rack and letters already on the board), followed by an empty or `OFF` square." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Prefixes\n", + "\n", + "Here we define the set of all prefixes of all words in the dictionary, and investigate the set:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def dict_prefixes(dictionary) -> set:\n", + " \"The set of all prefixes of each word in a dictionary.\"\n", + " return {word[:i] for word in dictionary for i in range(len(word))}\n", + "\n", + "PREFIXES = dict_prefixes(DICTIONARY)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "276374" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(PREFIXES)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1.5992014813100335" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(PREFIXES) / len(DICTIONARY)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['TOASTM',\n", + " 'SYNTAX',\n", + " 'BOOGEYM',\n", + " 'MASSAS',\n", + " 'TONS',\n", + " 'PYROT',\n", + " 'ETHNOCENTRICIT',\n", + " 'TROOPIA',\n", + " 'EVENTFULNES',\n", + " 'PENITENTIA']" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.sample(PREFIXES, 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here are all the prefixes from a tiny dictionary of three words. Note that the empty string is a prefix, and we include `HELP` because it is a prefix of `HELPER`, but we don't include `HELPER`, because there is no letter we can add to `HELPER` to make a word in this dictionary:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'', 'H', 'HE', 'HEL', 'HELL', 'HELP', 'HELPE'}" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dict_prefixes({'HELLO', 'HELP', 'HELPER'})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The function `rack_prefixes` gives the set of prefixes that can be made just from the letters in the rack. Most of the work is done by `extend_prefixes`, which accumulates a set of prefixes into `results`:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def rack_prefixes(rack) -> set: \n", + " \"All word prefixes that can be made by the rack.\"\n", + " return extend_prefixes('', rack, set())\n", + "\n", + "def extend_prefixes(prefix, rack, results) -> set:\n", + " if prefix.upper() in PREFIXES:\n", + " results.add(prefix)\n", + " for L in letters(rack):\n", + " extend_prefixes(prefix+L, remove(L, rack), results)\n", + " return results" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'', 'A', 'AB', 'AC', 'B', 'BA', 'BAC', 'C', 'CA', 'CAB'}" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rack = 'ABC'\n", + "rack_prefixes(rack)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The number of prefixes in a rack is usually on the order of a hundred, unless there is a blank in the rack:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "155" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(rack_prefixes('LETTERS'))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "120" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(rack_prefixes('HJRIPUM'))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1590" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(rack_prefixes('LETTER_'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Anchor Squares\n", + "\n", + "An anchor square is either the star in the middle of the board, or an empty square that is adjacent to a letter:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def is_anchor(board, s) -> bool:\n", + " \"Is this square next to a letter already on the board? (Or is it a '*')?\"\n", + " return (board[s] == STAR or\n", + " board[s] in EMPTY and any(board[s + d].isalpha() for d in board.directions))\n", + "\n", + "def all_anchors(board) -> list:\n", + " \"A list of all anchor squares on the board.\"\n", + " return [s for s in range(len(board)) if is_anchor(board, s)]" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[144]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The only anchor on an empty board is the star in the middle\n", + "all_anchors(WWF) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Plays on Example Board\n", + "\n", + "Let's work through the process of finding plays on the example `board`. First, we'll find all the anchors:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "53" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "anchors = all_anchors(board)\n", + "len(anchors)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "To visualize these anchors, we'll make each one be a star, on a copy of `board`:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLB3
TLDLT1O1U1R1
G2DWB3E1C3I1
A1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1I1L1
E1S1E1L1Y4T1H4E1
TWE1R1E1D2S1
DLS1R1DL
DLDWE1DL
TWTLTLN1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '*',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '*',\n", + " '*',\n", + " '*',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '*',\n", + " '*',\n", + " '.',\n", + " '*',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '*',\n", + " 'G',\n", + " '*',\n", + " '-',\n", + " '*',\n", + " '.',\n", + " '*',\n", + " 'B',\n", + " 'E',\n", + " '*',\n", + " 'C',\n", + " '*',\n", + " '*',\n", + " '*',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " '*',\n", + " 'A',\n", + " '*',\n", + " '*',\n", + " 'M',\n", + " '*',\n", + " '*',\n", + " '*',\n", + " 'N',\n", + " '*',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '*',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " '*',\n", + " 'I',\n", + " '*',\n", + " '*',\n", + " '*',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '*',\n", + " 'E',\n", + " '*',\n", + " '*',\n", + " 'S',\n", + " '*',\n", + " '*',\n", + " '*',\n", + " 'E',\n", + " '*',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '*',\n", + " '.',\n", + " '*',\n", + " 'E',\n", + " '*',\n", + " '.',\n", + " '*',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " '*',\n", + " '*',\n", + " '*',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '*',\n", + " 'S',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " '*',\n", + " '*',\n", + " 'R',\n", + " '*',\n", + " '.',\n", + " ':',\n", + " '*',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '*',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '*',\n", + " 'E',\n", + " '*',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '*',\n", + " 'N',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board2 = Board(board)\n", + "for a in anchors:\n", + " board2[a] = STAR\n", + " \n", + "board2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we'll define a rack, and find all the prefixes for the rack:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "88" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rack = 'ABCHKNQ'\n", + "\n", + "prefixes = rack_prefixes(rack)\n", + "len(prefixes)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "' BANQ BH KANB KAC HACK ACK QAN BAH CAB CHAB BAN HACKB NA CH KHAN CAH AH ANKH H BHA CHAK CANK BAC KAH NAK KBA CN ABH ANK QA HAN NACH Q CAN BA BAK K HAC A AQ HAK BHAK CA NAB NAC AB BHAN KNAC C AK CHA KA HANK HACKN ACQ HANC N B ANC BANK KN HA KAN BACH CHAQ BACKH AN ABN KAB KACH KB AHC CHAN CAK BANKC BACK ANH KH ACKN AC BANC KNA KHA HAB ANCH ACH ACN'" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "' '.join(prefixes)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We won't go through all the anchor/prefix combinations; we'll just pick one: the anchor above the `M` in `MUSES`:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2DWB3E1C3DWI1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " '-',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'E',\n", + " '.',\n", + " 'C',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board3 = Board(board)\n", + "anchor = 141\n", + "board3[anchor] = STAR\n", + "board3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "There's only room for prefixes of length 0 or 1, because anything longer than that would hit the anchor to the right of the `G` in `GAVE`; to avoid duplication of effort, we only allow words to run into other anchors on the right, not the left. Let's try the 1-letter prefix `B` first:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2B3B3E1C3DWI1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " 'B',\n", + " '*',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'E',\n", + " '.',\n", + " 'C',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board3[140] = 'B'\n", + "board3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can start to march forward. On the anchor square we can place any letter from the rack that makes a valid prefix, and that also turns `\".MUSES\"` into a valid word. There's only one such letter, `A`:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2B3A1B3E1C3DWI1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " 'B',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'E',\n", + " '.',\n", + " 'C',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board3[141] = 'A'\n", + "assert 'BA' in PREFIXES and is_word('A' + 'MUSES')\n", + "board3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can continue marching forward, trying letters from the rack that form valid prefixes. Let's try the combination `CK`:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2B3A1C3K5B3E1C3DWI1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " 'B',\n", + " 'A',\n", + " 'C',\n", + " 'K',\n", + " 'B',\n", + " 'E',\n", + " '.',\n", + " 'C',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board3[142:144] = 'CK'\n", + "assert 'BACK' in PREFIXES\n", + "board3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We've spelled the word `BACK`, but we can't count it as a legal play, because there isn't an empty square to the right of `BACK`; there are two existing letters, `BE`. Fortunately, `BACKBE` is a valid prefix, so we can continue to the next empty square, where we can choose an `N`:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2B3A1C3K5B3E1N1C3DWI1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " 'B',\n", + " 'A',\n", + " 'C',\n", + " 'K',\n", + " 'B',\n", + " 'E',\n", + " 'N',\n", + " 'C',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board3[146] = 'N'\n", + "assert 'BACKBENC' in PREFIXES\n", + "board3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We continue to the next square (a double word square), and place an `H`, which completes a word, `BACKBENCH` (with an empty square to the right), and simultaneously makes a cross word, `THE`:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2B3A1C3K5B3E1N1C3H4I1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " 'B',\n", + " 'A',\n", + " 'C',\n", + " 'K',\n", + " 'B',\n", + " 'E',\n", + " 'N',\n", + " 'C',\n", + " 'H',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board3[148] = 'H'\n", + "assert is_word('BACKBENCH') and is_word('THE')\n", + "board3" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We've found a valid play; we can now backtrack to consider other letters for this and other prefix/anchor combinations. Now let's code this up! \n", + "\n", + "# Code for Finding All Plays\n", + "\n", + "The function `all_plays` generates all legal plays by looking at every anchor square, trying all prefix plays, and then trying to extend each one, one letter at a time. (Note that it also generates the empty play, because a player always has the option of passing.)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def all_plays(board, rack):\n", + " \"\"\"Generate all plays that can be played on board with this rack.\n", + " Try placing every possible prefix before every anchor point; \n", + " then extend one letter at a time, looking for valid plays.\"\"\"\n", + " yield Play(0, ACROSS, '', rack) # The empty play (no letters, no points)\n", + " prefixes = rack_prefixes(rack)\n", + " for anchor in all_anchors(board):\n", + " for dir in (ACROSS, board.down):\n", + " for play in prefix_plays(prefixes, board, anchor, dir, rack):\n", + " yield from extend_play(board, play)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now for the function `prefix_plays`, which returns a list of all partial plays consisting of a prefix placed before the anchor. Note that these are not *legal* plays; they are *partial* plays, some of which will end up being extended into legal plays. \n", + "\n", + "There are two cases: if there are letters on the board immediately before the anchor, then those letters form the only allowable prefix. If not, we can use any prefix from the rack up to `maxlen`, which is the number of empty squares that do not run into another anchor, nor off the board." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def prefix_plays(prefixes, board, anchor, dir, rack):\n", + " \"Return all Plays of a prefix to the left/above anchor.\"\n", + " if board[anchor-dir].isalpha(): # Prefix already on the board; only 1 prefix\n", + " start = scan_letters(board, anchor, -dir)\n", + " yield Play(start, dir, cat(board[start:anchor:dir]), rack)\n", + " else: # Prefixes from rack fit in space before anchor\n", + " maxlen = (anchor - scan_to_anchor(board, anchor, -dir)) // dir\n", + " for prefix in prefixes:\n", + " if len(prefix) <= maxlen:\n", + " yield Play(anchor - len(prefix) * dir, dir, prefix, remove(prefix, rack))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now `extend_play` takes a partial play, determines the square, `s`, that is one square past the end of the play, and tries all possible letters there. If adding a letter forms a valid prefix (and also does not form an invalid cross word), then we continue on (by calling `extend_play` recursively). If adding the letter forms a valid word, we yield the play." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def extend_play(board, play):\n", + " \"Explore all ways of adding to end of play; return ones that form full words.\"\n", + " s = play.start + play.dir * len(play.letters)\n", + " if board[s] == OFF: return\n", + " cword = crossword(board, s, play.dir)\n", + " possible_letters = board[s].upper() if board[s].isalpha() else letters(play.rack)\n", + " for L in possible_letters:\n", + " prefix2 = play.letters + L\n", + " if prefix2.upper() in PREFIXES and valid_crossword(cword, L):\n", + " rack2 = play.rack if board[s].isalpha() else remove(L, play.rack)\n", + " play2 = Play(play.start, play.dir, prefix2, rack2)\n", + " if is_word(prefix2) and not board[s + play.dir].isalpha():\n", + " yield play2\n", + " yield from extend_play(board, play2)\n", + "\n", + "def scan_letters(board, s, dir) -> Square:\n", + " \"Return the last square number going from s in dir that is a letter.\"\n", + " while board[s + dir].isalpha():\n", + " s += dir\n", + " return s\n", + "\n", + "def scan_to_anchor(board, s, dir) -> Square:\n", + " \"Return the last square number going from s in dir that is not an anchor nor off board.\"\n", + " while board[s + dir] != OFF and not is_anchor(board, s + dir):\n", + " s += dir\n", + " return s" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Crosswords\n", + "\n", + "If adding a letter in, say, the `ACROSS` direction also adds on to a word in the `DOWN` direction, then we need to make sure that this *cross word* is also valid. The function `crossword` finds the cross word at square `s` and returns it with a `'.'` indicating the empty square where the new letter will be placed, so we would get `'.MUSES'` and `'T.E'` for the two crosswords in the `'BACKBENCH'` play." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def crossword(board, s, dir) -> str:\n", + " \"\"\"The word that intersects s in the other direction from dir.\n", + " Use '.' for the one square that is missing a letter.\"\"\"\n", + " def canonical(L): return L if L.isalpha() else '.'\n", + " d = other(dir, board)\n", + " start = scan_letters(board, s, -d)\n", + " end = scan_letters(board, s, d)\n", + " return cat(canonical(board[s]) for s in range(start, end+d, d))\n", + "\n", + "def valid_crossword(cword, L) -> bool:\n", + " \"Is placing letter L valid (with respective to the crossword)?\"\n", + " return len(cword) == 1 or cword.replace('.', L).upper() in DICTIONARY\n", + "\n", + "def other(dir, board) -> Direction:\n", + " \"The other direction (across/down) on the board.\"\n", + " return board.down if dir == ACROSS else ACROSS" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'.MUSES'" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "crossword(board, 141, ACROSS)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'T.E'" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "crossword(board, 148, ACROSS)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The function `valid_crossword` checks if replacing the empty square with a specific letter will form a valid word:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "valid_crossword('.MUSES', 'A')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can now see all the prefix plays for the anchor at 141 (just above `MUSES`):" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{Play(start=140, dir=1, letters='A', rack='BCHKNQ'),\n", + " Play(start=140, dir=1, letters='B', rack='ACHKNQ'),\n", + " Play(start=140, dir=1, letters='C', rack='ABHKNQ'),\n", + " Play(start=140, dir=1, letters='H', rack='ABCKNQ'),\n", + " Play(start=140, dir=1, letters='K', rack='ABCHNQ'),\n", + " Play(start=140, dir=1, letters='N', rack='ABCHKQ'),\n", + " Play(start=140, dir=1, letters='Q', rack='ABCHKN'),\n", + " Play(start=141, dir=1, letters='', rack='ABCHKNQ')}" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(prefix_plays(rack_prefixes(rack), board, 141, 1, rack))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And we can see all the ways to extend the play of `'B'` there:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{Play(start=140, dir=1, letters='BA', rack='CHKNQ'),\n", + " Play(start=140, dir=1, letters='BACKBENCH', rack='Q'),\n", + " Play(start=140, dir=1, letters='BAH', rack='CKNQ'),\n", + " Play(start=140, dir=1, letters='BAN', rack='CHKQ')}" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(extend_play(board, Play(start=140, dir=1, letters='B', rack='ACHKNQ')))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Scoring\n", + "\n", + "Now we'll show how to count up the points made by a play. The score is the sum of the word score for the play, plus a bingo score if all seven letters are used, plus the sum of the word scores for any cross words. The word score is the sum of the letter scores (where each letter score may be doubled or tripled by a bonus square when the letter is first played on the square), all multiplied by any word bonus(es) encountered by the newly-placed letters." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def score(board, play) -> int:\n", + " \"The number of points scored by making this play on the board.\"\n", + " return (word_score(board, play) \n", + " + bingo(board, play) \n", + " + sum(word_score(board, cplay) \n", + " for cplay in cross_plays(board, play)))\n", + "\n", + "def word_score(board, play) -> int:\n", + " \"Points for a single word, counting word- and letter-bonuses.\"\n", + " total, word_bonus = 0, 1\n", + " for (s, L) in enumerate_play(play):\n", + " sq = board[s]\n", + " word_bonus *= (3 if sq == TW else 2 if sq == DW else 1)\n", + " total += POINTS[L] * (3 if sq == TL else 2 if sq == DL else 1)\n", + " return word_bonus * total\n", + "\n", + "def bingo(board, play) -> int:\n", + " \"A bonus for using 7 letters from the rack.\"\n", + " return (board.bingo if (play.rack == '' and letters_played(board, play) == 7) \n", + " else 0)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here are the various helper functions:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def letters_played(board, play) -> int:\n", + " \"The number of letters played from the rack.\"\n", + " return sum(board[s] in EMPTY for (s, L) in enumerate_play(play))\n", + " \n", + "def enumerate_play(play) -> list:\n", + " \"List (square_number, letter) pairs for each tile in the play.\"\n", + " return [(play.start + i * play.dir, L) \n", + " for (i, L) in enumerate(play.letters)]\n", + " \n", + "def cross_plays(board, play):\n", + " \"Generate all plays for words that cross this play.\"\n", + " cross = other(play.dir, board)\n", + " for (s, L) in enumerate_play(play):\n", + " if board[s] in EMPTY and (board[s-cross].isalpha() or board[s+cross].isalpha()):\n", + " start, end = scan_letters(board, s, -cross), scan_letters(board, s, cross)\n", + " before, after = cat(board[start:s:cross]), cat(board[s+cross:end+cross:cross])\n", + " yield Play(start, cross, before + L + after, play.rack)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "What should the `BACKBENCH` play score? The word covers two double-word bonuses, but no letter bonuses. The sum of the letter point values is 3+1+3+5+3+1+1+3+4 = 24, and 24×2×2 = 96. The cross word `AMUSES` scores 8, and `THE` is on a double word bonus, so it scores 6×2 = 12. There is one letter remaining in the rack, so no bingo, just a total score of 96 + 8 + 12 = 116." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "116" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "score(board, Play(start=140, dir=1, letters='BACKBENCH', rack='Q'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can find the highest scoring play by enumerating all plays and taking the one with the maximum score:" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def highest_scoring_play(board, rack) -> Play: \n", + " \"Return the Play that gives the most points.\"\n", + " return max(all_plays(board, rack), key=lambda play: score(board, play))" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Play(start=140, dir=1, letters='BACKBENCH', rack='Q')" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "highest_scoring_play(board, rack)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDWB3
TLDLDLT1O1U1R1
G2B3A1C3K5B3E1N1C3H4I1
TLA1M3N1H4E1A1R1D2
V4I1R1U1L1eN1T1TLI1DWL1
E1DLS1DLE1L1Y4T1H4E1
TWTLE1DWR1E1D2TLS1
DLS1R1DL
DLDWDWE1DL
TWTLTLN1TW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'B',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'T',\n", + " 'O',\n", + " 'U',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'G',\n", + " '.',\n", + " 'B',\n", + " 'A',\n", + " 'C',\n", + " 'K',\n", + " 'B',\n", + " 'E',\n", + " 'N',\n", + " 'C',\n", + " 'H',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'A',\n", + " '.',\n", + " '.',\n", + " 'M',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " 'H',\n", + " 'E',\n", + " 'A',\n", + " 'R',\n", + " 'D',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'V',\n", + " 'I',\n", + " 'R',\n", + " 'U',\n", + " 'L',\n", + " 'e',\n", + " 'N',\n", + " 'T',\n", + " ';',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'L',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'E',\n", + " ':',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'L',\n", + " 'Y',\n", + " 'T',\n", + " 'H',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'R',\n", + " 'E',\n", + " 'D',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'E',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'N',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "make_play(board, Play(start=140, dir=1, letters='BACKBENCH', rack='Q'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Playing a Game\n", + "\n", + "Now let's play a complete game. We start with a bag of tiles with the official Scrabble® distribution:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "100" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "BAG = 'AAAAAAAAABBCCDDDDEEEEEEEEEEEEFFGGGHHIIIIIIIIIJKLLLLMMNNNNNNOOOOOOOOPPQRRRRRRSSSSTTTTTTUUUUVVWWXYYZ__'\n", + "len(BAG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Then the function `play_game` will take a list of *player strategies* as input, and play those strategies against each other over the course of a game. A strategy is a function that takes a board and a rack as input and returns a play. For example, `highest_scoring_play` is a strategy. If the optional argument `verbose` is true, then the board is displayed after each play." + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def play_game(strategies=[highest_scoring_play, highest_scoring_play], \n", + " board=WWF, verbose=True) -> list:\n", + " \"A number of players play a game; return a list of their scores.\"\n", + " board = Board(board)\n", + " bag = list(BAG)\n", + " random.shuffle(bag)\n", + " scores = [0 for _ in strategies]\n", + " racks = [replenish('', bag) for _ in strategies]\n", + " while True:\n", + " old_board = board\n", + " for (p, strategy) in enumerate(strategies):\n", + " board = make_one_play(board, p, strategy, scores, racks, bag, verbose)\n", + " if racks[p] == '':\n", + " # Player p has gone out; game over\n", + " return subtract_remaining_tiles(racks, scores, p)\n", + " if old_board == board:\n", + " # No player has a move; game over\n", + " return scores\n", + "\n", + "def make_one_play(board, p, strategy, scores, racks, bag, verbose) -> Board:\n", + " \"\"\"One player, player p, chooses a move according to the strategy.\n", + " We make the move, replenish the rack, update scores, and return the new Board.\"\"\"\n", + " rack = racks[p]\n", + " play = strategy(board, racks[p])\n", + " racks[p] = replenish(play.rack, bag)\n", + " points = score(board, play)\n", + " scores[p] += points\n", + " board = make_play(board, play)\n", + " if verbose:\n", + " display(HTML('Player {} with rack {} makes {}
for {} points; draws: {}; scores: {}'\n", + " .format(p, rack, play, points, racks[p], scores)),\n", + " board)\n", + " return board\n", + "\n", + "def subtract_remaining_tiles(racks, scores, p) -> list:\n", + " \"Subtract point values from each player and give them to player p.\"\n", + " for i in range(len(racks)):\n", + " points = sum(POINTS[L] for L in racks[i])\n", + " scores[i] -= points\n", + " scores[p] += points\n", + " return scores\n", + "\n", + "def replenish(rack, bag) -> str:\n", + " \"Fill rack with 7 letters (as long as there are letters left in the bag).\"\n", + " while len(rack) < 7 and bag:\n", + " rack += bag.pop()\n", + " return rack" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "IPython.OutputArea.auto_scroll_threshold = 9999;" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%javascript\n", + "IPython.OutputArea.auto_scroll_threshold = 9999;" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "Player 0 with rack NIEUTBT makes Play(start=144, dir=1, letters='BUTTE', rack='NI')
for 14 points; draws: NITDINC; scores: [14, 0]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDW
TLDLDLTL
DWB3U1T1T1E1
TLDLDLTL
DWTLTLDW
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack IMIOOEE makes Play(start=144, dir=17, letters='BIOME', rack='IOE')
for 18 points; draws: IOEP_OL; scores: [14, 18]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLDL
TWTLDWTLTW
DLDLDLDL
DWTLTLDW
TLDLDLTL
DWB3U1T1T1E1
TLDLI1DLTL
DWTLO1TLDW
DLDLM3DLDL
TWTLE1TLTW
DLDLDLDL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack NITDINC makes Play(start=63, dir=17, letters='INCIDENT', rack='')
for 48 points; draws: RRAXDFA; scores: [62, 18]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLI1DL
TWTLDWN1TW
DLDLDLC3DL
DWTLTLI1DW
TLDLDLD2TL
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1TLT1DW
DLDLM3DLDL
TWTLE1TLTW
DLDLDLDL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack IOEP_OL makes Play(start=212, dir=1, letters='EOLOPIlE', rack='')
for 80 points; draws: OFUADSE; scores: [62, 98]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLI1DL
TWTLDWN1TW
DLDLDLC3DL
DWTLTLI1DW
TLDLDLD2TL
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1TLT1DW
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLDLDL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack RRAXDFA makes Play(start=230, dir=1, letters='FAX', rack='RRDA')
for 45 points; draws: RRDACGA; scores: [107, 98]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLI1DL
TWTLDWN1TW
DLDLDLC3DL
DWTLTLI1DW
TLDLDLD2TL
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1TLT1DW
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack OFUADSE makes Play(start=180, dir=1, letters='FETUS', rack='OAD')
for 32 points; draws: OADTYTI; scores: [107, 130]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLI1DL
TWTLDWN1TW
DLDLDLC3DL
DWTLTLI1DW
TLDLDLD2TL
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1F4E1T1U1S1
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack RRDACGA makes Play(start=112, dir=1, letters='CAIRD', rack='RGA')
for 28 points; draws: RGAEESA; scores: [135, 130]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLI1DL
TWTLDWN1TW
DLDLDLC3DL
DWTLC3A1I1R1D2
TLDLDLD2TL
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1F4E1T1U1S1
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWDWDL
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack OADTYTI makes Play(start=248, dir=1, letters='TOADY', rack='TI')
for 38 points; draws: TIROSIA; scores: [135, 168]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDL
DLDLDLI1DL
TWTLDWN1TW
DLDLDLC3DL
DWTLC3A1I1R1D2
TLDLDLD2TL
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1F4E1T1U1S1
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWT1O1A1D2Y4
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack RGAEESA makes Play(start=49, dir=17, letters='GREASE', rack='A')
for 36 points; draws: AERGQPG; scores: [171, 168]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDLG2
DLDLDLI1DLR1
TWTLDWN1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1F4E1T1U1S1
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWT1O1A1D2Y4
TWTLTLTW
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack TIROSIA makes Play(start=267, dir=1, letters='SOAR', rack='TII')
for 26 points; draws: TIIEANA; scores: [171, 194]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDLG2
DLDLDLI1DLR1
TWTLDWN1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1F4E1T1U1S1
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWT1O1A1D2Y4
TWTLTLS1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack AERGQPG makes Play(start=262, dir=1, letters='GAPE', rack='RQG')
for 21 points; draws: RQGENYJ; scores: [192, 194]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDLG2
DLDLDLI1DLR1
TWTLDWN1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
DWB3U1T1T1E1
TLDLI1DLN1TL
DWTLO1F4E1T1U1S1
DLDLM3DLDL
TWTLE1O1L1O1P3I1lE1
DLDLF4A1X8DL
DLDWT1O1A1D2Y4
TWG2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack TIIEANA makes Play(start=176, dir=17, letters='TAENIA', rack='I')
for 24 points; draws: IIKRZDH; scores: [192, 218]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDLG2
DLDLDLI1DLR1
TWTLDWN1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
DWB3U1T1T1E1
TLDLI1DLN1TL
DWT1O1F4E1T1U1S1
DLA1DLM3DLDL
TWTLE1E1O1L1O1P3I1lE1
DLDLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack RQGENYJ makes Play(start=205, dir=1, letters='GYRENE', rack='QJ')
for 36 points; draws: QJLLEHE; scores: [228, 218]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWDLG2
DLDLDLI1DLR1
TWTLDWN1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
DWB3U1T1T1E1
TLDLI1DLN1TL
DWT1O1F4E1T1U1S1
DLA1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLDLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack IIKRZDH makes Play(start=45, dir=17, letters='KHI', rack='IRZD')
for 25 points; draws: IRZDIIO; scores: [228, 243]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWK5DLG2
DLDLH4I1DLR1
TWTLDWI1N1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
DWB3U1T1T1E1
TLDLI1DLN1TL
DWT1O1F4E1T1U1S1
DLA1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLDLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack QJLLEHE makes Play(start=138, dir=17, letters='JELLY', rack='QHE')
for 30 points; draws: QHEBMNO; scores: [258, 243]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWK5DLG2
DLDLH4I1DLR1
TWTLDWI1N1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLDLDLD2E1
J8DWB3U1T1T1E1
TLE1DLI1DLN1TL
L1T1O1F4E1T1U1S1
L1DLA1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLDLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack IRZDIIO makes Play(start=123, dir=17, letters='IODIZER', rack='I')
for 34 points; draws: IVUTLON; scores: [258, 277]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWK5DLG2
DLDLH4I1DLR1
TWTLDWI1N1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLI1DLDLD2E1
J8O1B3U1T1T1E1
TLE1D2DLI1DLN1TL
L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack QHEBMNO makes Play(start=154, dir=17, letters='HE', rack='QBMNO')
for 28 points; draws: QBMNOVS; scores: [286, 277]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWTLTLTW
DLDWDWK5DLG2
DLDLH4I1DLR1
TWTLDWI1N1E1
DLDLDLC3DLA1
DWTLC3A1I1R1D2S1
TLI1DLDLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack IVUTLON makes Play(start=22, dir=17, letters='VOLUTIN', rack='')
for 50 points; draws: _UWEARW; scores: [286, 327]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWV4TLTLTW
DLO1DWDWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
DLI1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " 'V',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'O',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack QBMNOVS makes Play(start=239, dir=1, letters='MOBS', rack='QNV')
for 29 points; draws: QNV; scores: [315, 327]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
TWV4TLTLTW
DLO1DWDWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
M3O1B3S1I1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " 'V',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'O',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'M',\n", + " 'O',\n", + " 'B',\n", + " 'S',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack _UWEARW makes Play(start=21, dir=1, letters='AVoWER', rack='UW')
for 63 points; draws: UW; scores: [315, 390]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
A1V4oW4E1R1TW
DLO1DWDWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
M3O1B3S1I1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " 'V',\n", + " 'o',\n", + " 'W',\n", + " 'E',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'O',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'M',\n", + " 'O',\n", + " 'B',\n", + " 'S',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack QNV makes Play(start=39, dir=1, letters='ON', rack='QV')
for 6 points; draws: QV; scores: [321, 390]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
A1V4oW4E1R1TW
DLO1N1DWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
M3O1B3S1I1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " 'V',\n", + " 'o',\n", + " 'W',\n", + " 'E',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'O',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'M',\n", + " 'O',\n", + " 'B',\n", + " 'S',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack UW makes Play(start=38, dir=1, letters='WON', rack='U')
for 11 points; draws: U; scores: [321, 401]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
A1V4oW4E1R1TW
DLW4O1N1DWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
M3O1B3S1I1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " 'V',\n", + " 'o',\n", + " 'W',\n", + " 'E',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'W',\n", + " 'O',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'M',\n", + " 'O',\n", + " 'B',\n", + " 'S',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 0 with rack QV makes Play(start=0, dir=1, letters='', rack='QV')
for 0 points; draws: QV; scores: [321, 401]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
A1V4oW4E1R1TW
DLW4O1N1DWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1DLN1F4A1X8DL
M3O1B3S1I1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " 'V',\n", + " 'o',\n", + " 'W',\n", + " 'E',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'W',\n", + " 'O',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'M',\n", + " 'O',\n", + " 'B',\n", + " 'S',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Player 1 with rack U makes Play(start=225, dir=1, letters='RUN', rack='')
for 7 points; draws: ; scores: [321, 408]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
A1V4oW4E1R1TW
DLW4O1N1DWK5DLG2
DLL1H4I1DLR1
TWTLU1DWI1N1E1
DLT1DLDLC3DLA1
DWI1TLC3A1I1R1D2S1
TLI1N1DLD2E1
J8O1B3U1T1T1E1
H4E1D2DLI1DLN1TL
E1L1I1T1O1F4E1T1U1S1
L1DLZ10A1DLM3DLDL
G2Y4R1E1N1E1E1O1L1O1P3I1lE1
DLR1U1N1F4A1X8DL
M3O1B3S1I1T1O1A1D2Y4
TWA1G2A1P3E1S1O1A1R1
" + ], + "text/plain": [ + "['#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'A',\n", + " 'V',\n", + " 'o',\n", + " 'W',\n", + " 'E',\n", + " 'R',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'W',\n", + " 'O',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " 'K',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'G',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'L',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'H',\n", + " 'I',\n", + " '.',\n", + " ':',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '=',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " 'U',\n", + " '.',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " ':',\n", + " '.',\n", + " 'A',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '-',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'C',\n", + " 'A',\n", + " 'I',\n", + " 'R',\n", + " 'D',\n", + " 'S',\n", + " '#',\n", + " '#',\n", + " ';',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'D',\n", + " '.',\n", + " '.',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'J',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'B',\n", + " 'U',\n", + " 'T',\n", + " 'T',\n", + " 'E',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'H',\n", + " 'E',\n", + " '.',\n", + " 'D',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " ';',\n", + " '#',\n", + " '#',\n", + " 'E',\n", + " 'L',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " 'T',\n", + " '.',\n", + " 'O',\n", + " '.',\n", + " 'F',\n", + " 'E',\n", + " 'T',\n", + " 'U',\n", + " 'S',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " 'L',\n", + " ':',\n", + " 'Z',\n", + " '.',\n", + " 'A',\n", + " ':',\n", + " 'M',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'G',\n", + " 'Y',\n", + " 'R',\n", + " 'E',\n", + " 'N',\n", + " 'E',\n", + " '.',\n", + " 'E',\n", + " 'O',\n", + " 'L',\n", + " 'O',\n", + " 'P',\n", + " 'I',\n", + " 'l',\n", + " 'E',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " 'R',\n", + " 'U',\n", + " 'N',\n", + " '.',\n", + " '.',\n", + " 'F',\n", + " 'A',\n", + " 'X',\n", + " '.',\n", + " '.',\n", + " ':',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " 'M',\n", + " 'O',\n", + " 'B',\n", + " 'S',\n", + " '.',\n", + " 'I',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " 'T',\n", + " 'O',\n", + " 'A',\n", + " 'D',\n", + " 'Y',\n", + " '.',\n", + " '#',\n", + " '#',\n", + " '.',\n", + " '.',\n", + " '.',\n", + " '=',\n", + " '.',\n", + " 'A',\n", + " 'G',\n", + " 'A',\n", + " 'P',\n", + " 'E',\n", + " '.',\n", + " 'S',\n", + " 'O',\n", + " 'A',\n", + " 'R',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#',\n", + " '#']" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[307, 422]" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "play_game()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "That was an exciting game, ranging to the four edges of the board, with three bingos: INCIDENT,\n", + "EOLOPILE and \n", + "VOLUTIN (yes, those are actual words). \n", + "\n", + "But that was just one game; Let's get statistics for both players over, say, 10 games:" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "min: 278, median: 389, mean: 378.15, max: 447\n", + "CPU times: user 26.7 s, sys: 313 ms, total: 27 s\n", + "Wall time: 29.1 s\n" + ] + } + ], + "source": [ + "%%time\n", + "\n", + "games = 10\n", + "\n", + "scores = sorted(score for game in range(games) \n", + " for score in play_game(verbose=False))\n", + "\n", + "print('min: {}, median: {}, mean: {}, max: {}'.format(\n", + " min(scores), scores[games], sum(scores)/(2*games), max(scores)))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Tests\n", + "\n", + "I *should* have a complete test suite. Instead, all I have this minimal suite, plus the confidence I gained from seeing the game play." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ok'" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def sames(A, B): return sorted(A) == sorted(B)\n", + "\n", + "def test():\n", + " \"Unit tests.\"\n", + " assert is_word('WORD')\n", + " assert is_word('LETTERs')\n", + " assert is_word('ETHyLENEDIAMINETETRAACETATES')\n", + " assert not is_word('ALFABET')\n", + " \n", + " rack = 'ABCHKNQ'\n", + " \n", + " assert sames(letters(rack), rack)\n", + " assert sames(letters('ABAC_'), 'ABCabcdefghijklmnopqrstuvwxyz')\n", + " \n", + " assert dict_prefixes({'HELLO', 'HELP', 'HELPER'}) == {\n", + " '', 'H', 'HE', 'HEL', 'HELL', 'HELP', 'HELPE'}\n", + " \n", + " assert rack_prefixes('ABC') == {'', 'A', 'AB', 'AC', 'B', 'BA', 'BAC', 'C', 'CA', 'CAB'}\n", + " assert len(rack_prefixes('LETTERS')) == 155\n", + " assert len(rack_prefixes('LETTER_')) == 1590\n", + " \n", + " DOWN = WWF.down\n", + " plays = {\n", + " Play(145, DOWN, 'ENTER', ''),\n", + " Play(144, ACROSS, 'BE', ''),\n", + " Play(138, DOWN, 'GAVE', ''),\n", + " Play(158, DOWN, 'MUSES', ''),\n", + " Play(172, ACROSS, 'VIRULeNT', ''),\n", + " Play(213, ACROSS, 'RED', ''),\n", + " Play(198, ACROSS, 'LYTHE', ''),\n", + " Play(147, DOWN, 'CHILDREN', ''),\n", + " Play(164, ACROSS, 'HEARD', ''),\n", + " Play(117, DOWN, 'BRIDLES', ''),\n", + " Play(131, ACROSS, 'TOUR', '')}\n", + "\n", + " board = Board(WWF)\n", + " for play in plays:\n", + " board = make_play(board, play)\n", + " \n", + " assert len(WWF) == len(board) == 17 * 17\n", + " assert all_anchors(WWF) == [144]\n", + " assert all_anchors(board) == [\n", + " 100, 114, 115, 116, 121, 127, 128, 130, 137, 139, 141, 143, 146, 148, 149, 150, 154, 156, 157, 159, 160, \n", + " 161, 163, 171, 180, 182, 183, 184, 188, 190, 191, 193, 194, 195, 197, 206, 208, 210, 212, 216, 217, 218, \n", + " 225, 227, 230, 231, 233, 236, 243, 248, 250, 265, 267]\n", + " \n", + " assert crossword(board, 141, ACROSS) == '.MUSES'\n", + " assert crossword(board, 148, ACROSS) == 'T.E'\n", + " assert valid_crossword('.MUSES', 'A')\n", + " assert not valid_crossword('.MUSES', 'B')\n", + " \n", + " assert sames(prefix_plays(rack_prefixes(rack), board, 141, 1, rack),\n", + " [Play(start=141, dir=1, letters='', rack='ABCHKNQ'),\n", + " Play(start=140, dir=1, letters='C', rack='ABHKNQ'),\n", + " Play(start=140, dir=1, letters='K', rack='ABCHNQ'),\n", + " Play(start=140, dir=1, letters='B', rack='ACHKNQ'),\n", + " Play(start=140, dir=1, letters='A', rack='BCHKNQ'),\n", + " Play(start=140, dir=1, letters='H', rack='ABCKNQ'),\n", + " Play(start=140, dir=1, letters='N', rack='ABCHKQ'),\n", + " Play(start=140, dir=1, letters='Q', rack='ABCHKN')])\n", + " \n", + " assert sames(extend_play(board, Play(start=140, dir=1, letters='B', rack='ACHKNQ')),\n", + " {Play(start=140, dir=1, letters='BA', rack='CHKNQ'),\n", + " Play(start=140, dir=1, letters='BACKBENCH', rack='Q'),\n", + " Play(start=140, dir=1, letters='BAH', rack='CKNQ'),\n", + " Play(start=140, dir=1, letters='BAN', rack='CHKQ')})\n", + "\n", + " assert len(BAG) == 100\n", + " \n", + " assert replenish('RACK', ['X', 'B', 'A', 'G']) == 'RACKGAB'\n", + " assert replenish('RACK', []) == 'RACK'\n", + " assert replenish('RACK', ['A', 'B']) == 'RACKBA'\n", + " \n", + " assert score(WWF, Play(144, ACROSS, 'BE', '')) == (3 + 1)\n", + " assert score(board, Play(140, ACROSS, 'BACKBENCH', 'Q')) == 116\n", + " \n", + " return 'ok'\n", + "\n", + "test()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Conclusion: How Did We Do?\n", + "\n", + "We can break that into four questions:\n", + " \n", + "1. **Is the code easy to follow?** \n", + " - I'm biased, but I think this code is easy to understand, test, and modify.\n", + "2. **Does the strategy score well?** \n", + " - Yes: the mean and median are both well over 350, which is enough for [the elite club](https://www.facebook.com/WWF350Club) of high scorers. \n", + " - No: this is not quite world-champion caliber.\n", + "3. **Is the code fast enough?** \n", + " - It takes less than 3 seconds to play a complete game for both players; that's fast enough for me. If desired, the code could be made about 100 times faster, by using multiprocessing, by caching more information, by not building explicit lists for intermediate results (although those intermediate results make the code easier to test), by using PyPy or Cython, or by porting to another language.\n", + "4. **What's left to do?**\n", + " - We could give players the option of trading in tiles.\n", + " - We could explore better strategies. A better strategy might:\n", + " - Plan ahead to use high-scoring letters only with bonuses.\n", + " - Manage letters to increase the chance of a bingo.\n", + " - Use blank tiles strategically, not greedily.\n", + " - Play defensively to avoid giving the opponent good chances at high scores.\n", + " - Think ahead in the end game to go out before the opponent (or at least avoid being stuck with high-scoring letters in the rack).\n", + " - In the end game, know which tiles have not been played and thus which ones the opponent could have.\n", + " - The display could be prettier.\n", + " - The game could be interfaced to an online game server.\n", + " - More complete unit tests would be great.\n", + " - We could compare this program to those of the [giants](https://www.cs.cmu.edu/afs/cs/academic/class/15451-s06/www/lectures/scrabble.pdf) whose [shoulders](http://ericsink.com/downloads/faster-scrabble-gordon.pdf) we [stood](http://web.archive.org/web/20040116175427/http://www.math-info.univ-paris5.fr/~bouzy/ProjetUE3/Scrabble.pdf) [upon](http://www.gtoal.com/wordgames/scrabble.html).\n", + " \n", + "Thanks to Markus Dobler for correcting one bug and making another useful suggestion.\n", + "\n", + "
\n", + "*[Peter Norvig](http://norvig.com)*" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Sicherman Dice.ipynb b/pytudes/ipynb/Sicherman Dice.ipynb new file mode 100644 index 0000000..35ab0de --- /dev/null +++ b/pytudes/ipynb/Sicherman Dice.ipynb @@ -0,0 +1,2087 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Sicherman Dice\n", + "\n", + "*Note: This notebook takes the form of a conversation between two problem solvers. One speaks in* **bold**, *the other in* plain. *Also note, for those who are not native speakers of English: \"dice\" is the plural form; \"die\" is the singular.*\n", + "\n", + "Huh. This is interesting. You know how in many games, such as craps or Monopoly, you roll two regular dice and add them up. Only the sum matters, not what either of the individual dice shows.\n", + "\n", + "**Right.**\n", + "\n", + "And some of those sums, like 8, can be made multiple ways, while 2 and 12 can only be made one way. \n", + "\n", + "**Yeah. 8 can be made 5 ways, so it has a 5/36 probability of occurring.**\n", + "\n", + "The interesting thing is that people have been playing dice games for 7,000 years. But it wasn't until 1977 that Colonel George Sicherman asked whether is is possible to have a pair of dice that are not regular dice—that is, they don't have (1, 2, 3, 4, 5, 6) on the six sides—but have the same distribution of sums as a regular pair—so the pair of dice would also have to have 5 ways of making 8, but it could be different ways; maybe 7+1 could be one way. Sicherman assumes that each side bears a positive integer.\n", + "\n", + "**And what did he find?**\n", + "\n", + "Wouldn't it be more fun to figure it out for ourselves?\n", + "\n", + "**OK!**\n", + "\n", + "How could we proceed?\n", + "\n", + "**When in doubt, [use brute force](http://quotes.lifehack.org/quote/ken-thompson/when-in-doubt-use-brute-force/): we can write a program to enumerate the possibilities:**\n", + "\n", + "\n", + "- **Generate all dice that could possibly be part of a solution, such as (1, 2, 2, 4, 8, 9).**\n", + "- **Consider all pairs of these dice, such as ((1, 3, 4, 4, 5, 8), (1, 2, 2, 3, 3, 4))**\n", + "- **See if we find any pairs that are not the regular pair, but do have the same distribution of sums as the regular pair.**\n", + "\n", + "\n", + "That's great. I can code up your description almost verbatim. I'll also keep track of our TO DO list:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def sicherman():\n", + " \"\"\"The set of pairs of 6-sided dice that have the same\n", + " distribution of sums as a regular pair of dice.\"\"\"\n", + " return {pair for pair in pairs(all_dice())\n", + " if pair != regular_pair\n", + " and sums(pair) == regular_sums}\n", + "\n", + "# TODO: pairs, all_dice, regular_pair, sums, regular_sums" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Looks good to me.**\n", + "\n", + "Now we can tick off the items in the TO DO list. The function `pairs` is first, and it is easy:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def pairs(collection): \n", + " \"Return all pairs (A, B) from collection where A <= B.\"\n", + " return [(A, B) for A in collection for B in collection if A <= B]\n", + "\n", + "# TODO: all_dice, regular_pair, sums, regular_sums" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**That's good. We could have used the library function `itertools.combinations_with_replacement`, but let's just leave it as is. We should test to make sure it works:**" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pairs(['A', 'B', 'C'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# TO DO: `sums(pair)`\n", + "\n", + "\n", + "Now for `sums`: we need some way to represent all the 36 possible sums from a pair of dice. We want a representation that will be the same for two different pairs if all 36 sums are the same, but where the order or composition of the sums doesn't matter. \n", + "\n", + "**So we want a set of the sums?**\n", + "\n", + "Well, it can't be a set, because we need to know that 8 can be made 5 ways, not just that 8 is a member of the set. The technical term for a collection where order doesn't matter but where you can have repeated elements is a **bag**, or sometimes called a [**multiset**](https://en.wikipedia.org/wiki/Multiset). For example, the regular pair of dice makes two 11s with 5+6 and 6+5, and another pair could make two 11s with 7+4 and 3+8. Can you think of a representation that will do that?\n", + "\n", + "**Well the easiest is just a sorted list or tuple—if we don't want order to matter, sorting takes care of that. Another choice would be a dictionary of {sum: count} entries, like {2: 1, 3: 2, ... 11: 2, 12: 1}. There is even a library class, `collections.Counter`, that does exactly that.**\n", + "\n", + "How do we choose between the two representations?\n", + "\n", + "**I don't think it matters much. Since there are only 36 entries, I think the sorted list will be simpler, and probably more efficient. For 100-sided dice I'd probably go with the Counter.**\n", + "\n", + "OK, here's some code implementing `sums` as a sorted list, and definitions for regular die pair, and sums.\n", + "By the way, I could have used `range(1, 7)` to define a regular die, but `range` is zero-based, and regular dice are one-based, so I defined the function `ints` instead." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def sums(pair):\n", + " \"All possible sums of a side from one die plus a side from the other.\"\n", + " (A, B) = pair\n", + " return Bag(a + b for a in A for b in B)\n", + "\n", + "Bag = sorted # Implement a bag as a sorted list\n", + "\n", + "def ints(start, end): \n", + " \"A tuple of the integers from start to end, inclusive.\"\n", + " return tuple(range(start, end + 1))\n", + "\n", + "regular_die = ints(1, 6)\n", + "regular_pair = (regular_die, regular_die)\n", + "regular_sums = sums(regular_pair)\n", + "\n", + "# TODO: all_dice" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's check the `regular_sums`:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "36" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(regular_sums)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 12]\n" + ] + } + ], + "source": [ + "print(regular_sums)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**And we can see what that would look like to a `Counter`:**" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 5, 9: 4, 10: 3, 11: 2, 12: 1})" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from collections import Counter\n", + "\n", + "Counter(regular_sums)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Looks good! Now only one more thing on our TODO list:**\n", + "\n", + "# TO DO: `all_dice()`\n", + "\n", + "\n", + "`all_dice` should generate all possible dice, where by \"possible\" I mean the dice that could feasibly be part of a pair that is a solution to the Sicherman problem. Do we know how many dice that will be? Is it a large enough number that efficiency will be a problem?\n", + "\n", + "**Let's see. A die has six sides each. If each side can be a number from, say, 1 to 10, that's 106 or a million possible dice; a million is a small number for a computer.**\n", + "\n", + "True, a million is a relatively small number for `all_dice()`, but how many `pairs(all_dice())` will there be?\n", + "\n", + "**Ah. A million squared is a trillion. That's a large number even for a computer. Just counting to a trillion takes hours in Python; checking a trillion pairs will take days.**\n", + "\n", + "So we need to get rid of most of the dice. What about permutations?\n", + "\n", + "**Good point. If I have the die (1, 2, 3, 4, 5, 6), then I don't need the 6! = 720 different permutations of this die— that is, dice like (2, 4, 6, 1, 3, 5).\n", + "Each die should be a bag (I learned a new word!) of sides. So we've already eliminated 719/720 = 99.9% of the work.**\n", + "\n", + "One other thing bothers me ... how do you know that the sides can range from 1 to 10? Are you sure that 11 can't be part of a solution? Or 12?\n", + "\n", + "**Every side on every die must be a positive integer, right?**\n", + "\n", + "Right. No zeroes, no negative numbers, no fractions.\n", + "\n", + "**Then I know for sure that 12 can't be on any die, because when you add 12 to whatever is on the other die, you would get at least 13, and 13 is not allowed in the regular distribution of sums.**\n", + "\n", + "Good. How about 11?\n", + "\n", + "**We can't have a sum that is bigger than 12. So if one die had an 11, the other would have to have all 1s. That wouldn't work, because then we'd have six 12s, but we only want one. So 10 is the biggest allowable number on a die.**\n", + "\n", + "What else can we say about the biggest number on a die?\n", + "\n", + "**There's one 12 in the sums. But there are several ways to make a 12: 6+6 or 7+5 or 8+4, and so on. So I can't say for sure what the biggest number on any one die will be. But I can say that whatever the biggest number on a die is, it will be involved in summing to 12, so there can be only one of them, because we only want to make one 12.**\n", + "\n", + "What about the smallest number on a die?\n", + "\n", + "**Well, there's only one 2 allowed in the sums. The only way to sum to 2 is 1+1: a 1 from each of the dice in the pair. If a die had no 1s, we wouldn't get a 2; if a die had more than one 1, we would get too many 2s. So every die has to have exactly one 1.**\n", + "\n", + "Good. So each die has exactly one 1, and exactly one of whatever the biggest number is, something in the range up to 10. Here's a picture of the six sides of any one die:\n", + "\n", + " 1  <\n", + "2-10 ≤\n", + "2-10 ≤\n", + "2-10 ≤\n", + "2-10 <\n", + "2-10\n", + "\n", + "The bag of sides is always listed in non-decreasing order; the first side, 1, is less than the next, and the last side, whatever it is, is greater than the one before it.\n", + "\n", + "**Wait a minute: you have [2-10] < [2-10]. But 2 is not less than 2, and 10 is not less than 10. I think it should be [2-9] < [3-10]. So the picture should be like this:**\n", + "\n", + "\n", + " 1  <\n", + "2-9 ≤\n", + "2-9 ≤\n", + "2-9 ≤\n", + "2-9 <\n", + "3-10\n", + "\n", + "Good! We're making progress in cutting down the range. But it bothers me because it says the range for the biggest number is 3 to 10. But if one die has a 3 and the other a 10, that adds to 13. So I'm thinking that it is not possible to have a 10 after all—because if one die had a 10, then the other would have to have a 2 as the biggest number, and that can't be. Therefore the biggest number is in the range of 3 to 9. But then the others have to be \n", + "less, so make them 2 to 8:\n", + "\n", + " 1  <\n", + "2-8 ≤\n", + "2-8 ≤\n", + "2-8 ≤\n", + "2-8 <\n", + "3-9\n", + "\n", + "**I can turn this picture into code:**" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def all_dice():\n", + " \"A list of all feasible 6-sided dice for the Sicherman problem.\"\n", + " return [(1, s2, s3, s4, s5, s6)\n", + " for s2 in ints(2, 8) \n", + " for s3 in ints(s2, 8)\n", + " for s4 in ints(s3, 8)\n", + " for s5 in ints(s4, 8) \n", + " for s6 in ints(s5+1, 9)]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I think we're ready to run `sicherman()`. Any bets on what we'll find out?\n", + "\n", + "**I bet that Sicherman is remembered because he discovered a pair of dice that works. If he just proved the non-existence of a pair, I don't think that would be noteworthy.**\n", + "\n", + "Makes sense. Here goes:\n", + "\n", + "# The Answer" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{((1, 2, 2, 3, 3, 4), (1, 3, 4, 5, 6, 8))}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sicherman()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Look at that!**\n", + "\n", + "It turns out you can buy a pair of dice with just these numbers.\n", + "\n", + "\n", + "\n", + "Here's a table I borrowed from [Wikipedia](https://en.wikipedia.org/wiki/Sicherman_dice) that shows both pairs of dice have the same sums. \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
23456789101112
Regular dice:\n", + "
(1, 2, 3, 4, 5, 6)\n", + "
(1, 2, 3, 4, 5, 6)
1+11+2
\n", + "2+1
1+3
\n", + "2+2
\n", + "3+1
1+4
\n", + "2+3
\n", + "3+2
\n", + "4+1
1+5
\n", + "2+4
\n", + "3+3
\n", + "4+2
\n", + "5+1
1+6
\n", + "2+5
\n", + "3+4
\n", + "4+3
\n", + "5+2
\n", + "6+1
2+6
\n", + "3+5
\n", + "4+4
\n", + "5+3
\n", + "6+2
3+6
\n", + "4+5
\n", + "5+4
\n", + "6+3
4+6
\n", + "5+5
\n", + "6+4
5+6
\n", + "6+5
6+6
Sicherman dice:\n", + "
(1, 2, 2, 3, 3, 4)\n", + "
(1, 3, 4, 5, 6, 8)
1+12+1
\n", + "2+1
3+1
\n", + "3+1
\n", + "1+3
1+4
\n", + "2+3
\n", + "2+3
\n", + "4+1
1+5
\n", + "2+4
\n", + "2+4
\n", + "3+3
\n", + "3+3
1+6
\n", + "2+5
\n", + "2+5
\n", + "3+4
\n", + "3+4
\n", + "4+3
2+6
\n", + "2+6
\n", + "3+5
\n", + "3+5
\n", + "4+4
1+8
\n", + "3+6
\n", + "3+6
\n", + "4+5
2+8
\n", + "2+8
\n", + "4+6
3+8
\n", + "3+8
4+8
\n", + "\n", + "We could stop here. Or we could try to solve it for *N*-sided dice.\n", + "\n", + "# Why stop now? Onward!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "OK. I know 4-, 12-, and 20-sided dice are common, but we'll try to handle any *N* > 1. My guess is we won't go too far before our program becomes too slow. So, before we try *N*-sided dice, let's analyze six-sided dice a little better, to see if we can eliminate some of the pairs before we start. The picture says that (1, 2, 2, 2, 2, 3) could be a valid die. Could it?\n", + "\n", + "**No! If a die had four 2s, then we know that since the other die has one 1, we could make 2 + 1 = 3 four ways. But the `regular_sums` has only two 3s. So that means that a die can have no more than two 2s. New picture:**\n", + "\n", + " 1  <\n", + "2-8 ≤\n", + "2-8 ≤\n", + "3-8 ≤\n", + "3-8 <\n", + "3-9\n", + "\n", + "Now we've got [3-8] < [3-9]; that's not right. If a die can only have one 1 and two 2s, then it must have at least one number that is a 3 or more, followed by the biggest number, which must be 4 or more, and we know a pair of biggest numbers must sum to 12, so the range of the biggest can't be [4-9], it must be [4-8]:\n", + "\n", + " 1  <\n", + "2-7 ≤\n", + "2-7 ≤\n", + "3-7 ≤\n", + "3-7 <\n", + "4-8" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def all_dice():\n", + " \"A list of all feasible 6-sided dice for the Sicherman problem.\"\n", + " return [(1, s2, s3, s4, s5, s6)\n", + " for s2 in ints(2, 7) \n", + " for s3 in ints(s2, 7)\n", + " for s4 in ints(max(s3, 3), 7)\n", + " for s5 in ints(s4, 7) \n", + " for s6 in ints(s5+1, 8)]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I'll count how many dice and how many pairs there are now:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "231" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(all_dice())" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "26796" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(pairs(all_dice()))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Nice—we got down from a trillion pairs to 26,000. I don't want to print `all_dice()`, but I can sample a few:**" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 5, 5, 5, 7, 8),\n", + " (1, 6, 6, 6, 7, 8),\n", + " (1, 3, 4, 6, 6, 7),\n", + " (1, 3, 3, 7, 7, 8),\n", + " (1, 3, 5, 5, 6, 8),\n", + " (1, 2, 2, 4, 4, 5),\n", + " (1, 2, 5, 6, 7, 8),\n", + " (1, 3, 4, 4, 4, 8),\n", + " (1, 2, 3, 5, 5, 6),\n", + " (1, 2, 2, 3, 3, 8)]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import random\n", + "\n", + "random.sample(all_dice(), 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# `sicherman(N)`\n", + "\n", + "OK, I think we're ready to update `sicherman()` to `sicherman(N)`. \n", + "\n", + "**Sure, most of that will be easy, just parameterizing with `N`:**" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def sicherman(N=6):\n", + " \"\"\"The set of pairs of N-sided dice that have the same\n", + " distribution of sums as a regular pair of N-sided dice.\"\"\"\n", + " reg_sums = regular_sums(N)\n", + " reg_pair = regular_pair(N)\n", + " return {pair for pair in pairs(all_dice(N))\n", + " if pair != reg_pair\n", + " and sums(pair) == reg_sums}\n", + "\n", + "def regular_die(N): return ints(1, N)\n", + "def regular_pair(N): return (regular_die(N), regular_die(N))\n", + "def regular_sums(N): return sums(regular_pair(N))\n", + "\n", + "# TODO: all_dice(N)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Good. I think it would be helpful for me to look at a table of `regular_sums`:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "N: 1 {2: 1}\n", + "N: 2 {2: 1, 3: 2, 4: 1}\n", + "N: 3 {2: 1, 3: 2, 4: 3, 5: 2, 6: 1}\n", + "N: 4 {2: 1, 3: 2, 4: 3, 5: 4, 6: 3, 7: 2, 8: 1}\n", + "N: 5 {2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 4, 8: 3, 9: 2, 10: 1}\n", + "N: 6 {2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 5, 9: 4, 10: 3, 11: 2, 12: 1}\n", + "N: 7 {2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 7, 9: 6, 10: 5, 11: 4, 12: 3, 13: 2, 14: 1}\n" + ] + } + ], + "source": [ + "for N in ints(1, 7):\n", + " print(\"N:\", N, dict(Counter(regular_sums(N))))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**That is helpful. I can see that any `regular_sums` must have one 2 and two 3s, and three 4s, and so on, not just for `N=6` but for any `N` (except for trivially small `N`). And that means that any regular die can have at most two 2s, three 3s, four 4s, and so on. So we have this picture:**\n", + "\n", + " 1  <\n", + "2+ ≤\n", + "2+ ≤\n", + "3+ ≤\n", + "3+ ≤\n", + "3+ ≤\n", + "4+ ≤\n", + "4+ ≤\n", + "4+ ≤\n", + "4+ ≤ ...\n", + "\n", + "**where [2+] means the lower bound is 2, but we haven't figured out yet what the upper bound is.**\n", + "\n", + "Let's figure out upper bounds starting from the biggest number. What can the biggest number be?\n", + "\n", + "**For a pair of *N*-sided die, the biggest sides from each one must add up to 2*N*. Let's take *N*=10 as an example. The biggest numbers on two 10-sided Sicherman dice must sum to 20. According to the picture above, the lower bound on the biggest number would be 4, but because there can only be one of the biggest number, the lower bound is 5. So to add up to 20, the range must be [5-15]:**\n", + "\n", + "\n", + " 1  <\n", + "2+ ≤\n", + "2+ ≤\n", + "3+ ≤\n", + "3+ ≤\n", + "3+ ≤\n", + "4+ ≤\n", + "4+ ≤\n", + "4+ <\n", + "5-15 \n", + "\n", + "There's probably some tricky argument for the upper bounds of the other sides, but I'm just going to say the upper bound is one less than the upper bound of the biggest number:\n", + "\n", + " 1  <\n", + "2-14 ≤\n", + "2-14 ≤\n", + "3-14 ≤\n", + "3-14 ≤\n", + "3-14 ≤\n", + "4-14 ≤\n", + "4-14 ≤\n", + "4-14 <\n", + "5-15 \n", + "\n", + "\n", + "Let's start by coding up `lower_bounds(N)`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def lower_bounds(N):\n", + " \"A list of lower bounds for respective sides of an N-sided die.\"\n", + " lowers = [1]\n", + " for _ in range(N-1):\n", + " m = lowers[-1] # The last number in lowers so far\n", + " lowers.append(m if (lowers.count(m) < m) else m + 1)\n", + " lowers[-1] = lowers[-2] + 1\n", + " return lowers" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 2, 3, 3, 4]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lower_bounds(6)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 2, 3, 3, 3, 4, 4, 4, 5]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lower_bounds(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And `upper_bounds(N)`:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def upper_bounds(N):\n", + " \"A list of upper bounds for respective sides of an N-sided die.\"\n", + " U = 2 * N - lower_bounds(N)[-1]\n", + " return [1] + (N - 2) * [U - 1] + [U]" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 7, 7, 7, 7, 8]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "upper_bounds(6)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 14, 14, 14, 14, 14, 14, 14, 14, 15]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "upper_bounds(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now, what do we have to do for `all_dice(N)`? When we knew we had six sides, we wrote six nested loops. We can't do that for *N*, so what do we do?\n", + "\n", + "**Here's an iterative approach: we keep track of a list of partially-formed dice, and on each iteration, we add a side to all the partially-formed dice in all possible ways, until the dice all have `N` sides. So for example, we'd start with:**\n", + "\n", + " dice = [(1,)]\n", + " \n", + "**and then on the next iteration (let's assume *N*=6, so the lower bound is 2 and the upper bound is 7), we'd get this:**\n", + "\n", + " dice = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7)]\n", + " \n", + "**on the next iteration, we find all the ways of adding a third side, and so on. Like this:**" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def all_dice(N):\n", + " \"Return a list of all possible N-sided dice for the Sicherman problem.\"\n", + " lowers = lower_bounds(N)\n", + " uppers = upper_bounds(N)\n", + " def possibles(die, i):\n", + " \"The possible numbers for the ith side of an N-sided die.\"\n", + " return ints(max(lowers[i], die[-1] + int(i == N-1)),\n", + " uppers[i])\n", + " dice = [(1,)]\n", + " for i in range(1, N):\n", + " dice = [die + (side,)\n", + " for die in dice\n", + " for side in possibles(die, i)]\n", + " return dice" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**The tricky part was with the `max`: the actual lower bound at least `lowers[i]`, but it must be as big as the previous side, `die[-1]`. And just to make things complicated, the very last side has to be strictly bigger than the previous; `\" + int(i == N-1)\"` does that by adding 1 just in case we're on the last side, and 0 otherwise.**\n", + "\n", + "**Let's check it out:**" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "231" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(all_dice(6))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Reassuring that we get the same number we got with the old version of `all_dice()`." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 2, 2, 3, 4, 6),\n", + " (1, 3, 5, 5, 6, 8),\n", + " (1, 3, 3, 6, 7, 8),\n", + " (1, 2, 3, 3, 3, 7),\n", + " (1, 3, 5, 5, 7, 8),\n", + " (1, 2, 4, 5, 6, 8),\n", + " (1, 3, 6, 6, 7, 8),\n", + " (1, 3, 4, 5, 5, 7)]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.sample(all_dice(6), 8)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Running `sicherman(N)` for small `N`\n", + "\n", + "Let's try `sicherman` for some small values of `N`:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2: set(),\n", + " 3: set(),\n", + " 4: {((1, 2, 2, 3), (1, 3, 3, 5))},\n", + " 5: set(),\n", + " 6: {((1, 2, 2, 3, 3, 4), (1, 3, 4, 5, 6, 8))}}" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{N: sicherman(N)\n", + " for N in ints(2, 6)}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Again, reassuring that we get the same result for `sicherman(6)`. And interesting that there is a result for `sicherman(4)` but not for the other *N*.\n", + "\n", + "Let's go onwards from *N*=6, but let's check the timing as we go:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 304 ms, sys: 2.73 ms, total: 307 ms\n", + "Wall time: 519 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "{((1, 2, 2, 3, 3, 4), (1, 3, 4, 5, 6, 8))}" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time sicherman(6)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 18.2 s, sys: 209 ms, total: 18.4 s\n", + "Wall time: 21.4 s\n" + ] + }, + { + "data": { + "text/plain": [ + "set()" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time sicherman(7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Estimating run time of `sicherman(N)` for larger `N`\n", + "\n", + "OK, it takes 50 or 60 times longer to do 7, compared to 6. At this rate, *N*=8 will take 15 minutes, 9 will take 15 hours, and 10 will take a month.\n", + "\n", + "**Do we know it will continue to rise at the same rate? You're saying the run time is exponential in *N*? **\n", + "\n", + "I think so. The run time is proportional to the number of pairs. The number of pairs is proportional to the square of the number of dice. The number of dice is roughly exponential in *N*, because each time you increase *N* by 1, you have to try a number of new sides that is similar to the number for the previous side (but not quite the same). I should plot the number of pairs on a log scale and see if it looks like a straight line.\n", + "\n", + "I can count the number of pairs without explicitly generating the pairs. If there are *D* dice, then the number of pairs is what? Something like *D* × (*D* + 1) / 2? Or is it *D* × (*D* - 1) / 2?\n", + "\n", + "**Let's draw a picture. With *D* = 4, here are all the ways to pair one die with another to yield 10 distinct pairs:**\n", + " \n", + " 11 .. .. ..\n", + " 21 22 .. ..\n", + " 31 32 33 ..\n", + " 41 42 43 44\n", + " \n", + "**To figure out the formula, add a row to the top:**\n", + "\n", + " .. .. .. ..\n", + " 11 .. .. ..\n", + " 21 22 .. ..\n", + " 31 32 33 ..\n", + " 41 42 43 44\n", + " \n", + "**Now we have a *D* × (*D* + 1) rectangle, and we can see that half (10) of them are pairs, and half (the other 10) are not pairs (because they would be repetitions). So the formula is *D* × (*D* + 1)/2, and checking for *D*=4, (4 × 5) / 2 = 10, so we're good.**\n", + " \n", + "OK, let's try it. First some boilerplate for plotting:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import matplotlib\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "def logplot(X, Y, *options):\n", + " \"Plot Y on a log scale vs X.\"\n", + " fig, ax = plt.subplots()\n", + " ax.set_yscale('log')\n", + " ax.plot(X, Y, *options)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Now we can plot and display the number of pairs:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2: 1,\n", + " 3: 1,\n", + " 4: 55,\n", + " 5: 496,\n", + " 6: 26796,\n", + " 7: 1274406,\n", + " 8: 17502486,\n", + " 9: 823794345,\n", + " 10: 37613250675,\n", + " 11: 1688821500366,\n", + " 12: 25925418283128}" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "def plot_pairs(Ns):\n", + " \"Given a list of N values, plot the number of pairs and return a dict of them.\"\n", + " Ds = [len(all_dice(N)) for N in Ns]\n", + " Npairs = [D * (D + 1) // 2 for D in Ds]\n", + " logplot(Ns, Npairs, 'bo-')\n", + " return {Ns[i]: Npairs[i] for i in range(len(Ns))}\n", + "\n", + "plot_pairs(ints(2, 12))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "OK, we've learned two things. One, it *is* roughly a straight line, so the number of pairs is roughly exponential. Two, there are a *lot* of pairs. 1014, just for *N*=12. I don't want to even think about *N*=20.\n", + "\n", + "**So if we want to get much beyond *N*=8, we're either going to need a brand new approach, or we need to make far fewer pairs of dice.**\n", + "\n", + "\n", + "\n", + "# Making Fewer `pairs`\n", + "\n", + "Maybe we could tighten up the upper bounds, but I don't think that will help very much.\n", + "How about if we concentrate on making fewer pairs, without worrying about making fewer dice?\n", + "\n", + "**How could we do that? Isn't the number of pairs always (*D*2 + *D*)/2 ?**\n", + "\n", + "Remember, we're looking for *feasible* pairs. So if there was some way of knowing ahead of time that two dice were incompatible as a pair, we wouldn't even need to consider the pair.\n", + "\n", + "**By incompatible, you mean they can't form a pair that is a solution.**\n", + "\n", + "Right. Consider this: in any valid pair, the sum of the biggest number on each die must be 2*N*. For example, with *N* = 6:\n", + "\n", + " ((1, 2, 2, 3, 3, 4), (1, 3, 4, 5, 6, 8)) sum of biggests = 4 + 8 = 12\n", + " ((1, 2, 3, 4, 5, 6), (1, 2, 3, 4, 5, 6)) sum of biggests = 6 + 6 = 12\n", + " \n", + "So if we have a die with biggest number 7, what dice should we consider pairing it with?\n", + "\n", + "**Only ones with biggest number 5.**\n", + "\n", + "**I get it: we sort all the die into bins labeled with their biggest number. Then we look at each bin, and for the \"7\" bin, we pair them up with the dice in the \"5\" bin. In general, the *B* bin can only pair with the 2*N* - *B* bin.**\n", + "\n", + "Exactly. \n", + "\n", + "**Cool. I can see how that can cut the amount of work by a factor of 10 or so. But I was hoping for a factor of a million or so.**\n", + "\n", + "There are other properties of a feasible pair.\n", + "\n", + "**Like what?**\n", + "\n", + "Well, what about the number of 2s in a pair?\n", + "\n", + "**Let's see. We know that any `regular_sums` has to have two 3s, and the only way to make a 3 is 2+1. And each die has only one 1, so that means that each pair of dice has to have a total of exactly two 2s.**\n", + "\n", + "Does it have to be one 2 on each die?\n", + "\n", + "**No. It could be one each, or it could be two on one die and none on the other. So a die with *T* twos can only pair with dice that have 2 - *T* twos.**\n", + "\n", + "Great. Can you think of another property?\n", + "\n", + "**Give me a hint.**\n", + "\n", + "Let's look at the sums of 6-sided Sicherman and regular pairs:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "42" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum((1, 2, 2, 3, 3, 4) + (1, 3, 4, 5, 6, 8))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "42" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum((1, 2, 3, 4, 5, 6) + (1, 2, 3, 4, 5, 6))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**They're the same. Is that [the question](http://hitchhikers.wikia.com/wiki/42) that 42 is the answer to? But does a Sicherman pair always have to have the same sum as a regular pair? I guess it doea, because the sum of `sums(pair)` is just all the sides added up *N* times each, so two pairs have the same sum of `sums(pair)` if and only if they have the same sum.**\n", + "\n", + "So consider the die (1, 3, 3, 3, 4, 5). What do we know about the dice that it can possibly pair with?\n", + "\n", + "**OK, that die has a biggest side of 5, so it can only pair with dice that have a biggest side of 12 - 5 = 7. It has a sum of 19, so it can only pair with dice that have a sum of 42 - 19 = 23. And it has no 2s, so it can only pair with dice that have two 2s.**\n", + "\n", + "I wonder how many such dice there are, out of all 231 `all_dice(6)`?" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{(1, 2, 2, 5, 6, 7)}" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{die for die in all_dice(6) if max(die) == 12 - 5 and sum(die) == 42 - 19 and die.count(2) == 2}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**There's only 1. So, (1, 3, 3, 3, 4, 5) only has to try to pair with one die, rather than 230. Nice improvement!**\n", + "\n", + "In general, I wonder what the sum of the sides of a regular pair is?\n", + "\n", + "**Easy, that's `N * (N + 1)`. [Gauss](http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/) knew that when he was in elementary school!**\n", + "\n", + "# More efficient `pairs(dice)`\n", + "\n", + "**OK, we can code this up easily enough**:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "\n", + "def tabulate(dice):\n", + " \"\"\"Put all dice into bins in a hash table, keyed by bin_label(die).\n", + " Each bin holds a list of dice with that key.\"\"\"\n", + " # Example: {(21, 6, 1): [(1, 2, 3, 4, 5, 6), (1, 2, 3, 4, 4, 7), ...]\n", + " table = defaultdict(list)\n", + " for die in dice:\n", + " table[bin_label(die)].append(die)\n", + " return table\n", + "\n", + "def pairs(dice):\n", + " \"Return all pairs of dice that could possibly be a solution to the Sicherman problem.\"\n", + " table = tabulate(dice)\n", + " N = len(dice[0])\n", + " for bin1 in table:\n", + " bin2 = compatible_bin(bin1, N)\n", + " if bin2 in table and bin1 <= bin2:\n", + " for A in table[bin1]:\n", + " for B in table[bin2]:\n", + " yield (A, B)\n", + "\n", + "def bin_label(die): return sum(die), max(die), die.count(2)\n", + "\n", + "def compatible_bin(bin1, N): \n", + " \"Return a bin label that is compatible with bin1.\"\n", + " (S1, M1, T1) = bin1\n", + " return (N * (N + 1) - S1, 2 * N - M1, 2 - T1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Let's make sure it works:**" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{2: set(),\n", + " 3: set(),\n", + " 4: {((1, 2, 2, 3), (1, 3, 3, 5))},\n", + " 5: set(),\n", + " 6: {((1, 2, 2, 3, 3, 4), (1, 3, 4, 5, 6, 8))}}" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{N: sicherman(N)\n", + " for N in ints(2, 6)}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Good, those are the same answers as before. But how much faster is it?" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 24.9 ms, sys: 1.23 ms, total: 26.1 ms\n", + "Wall time: 153 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "set()" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time sicherman(7)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Wow, that's 1000 times faster than before." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**I want to take a peek at what some of the bins look like:**" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "defaultdict(list,\n", + " {(12, 4, 2): [(1, 2, 2, 3, 4)],\n", + " (13, 4, 1): [(1, 2, 3, 3, 4)],\n", + " (13, 5, 2): [(1, 2, 2, 3, 5)],\n", + " (14, 4, 0): [(1, 3, 3, 3, 4)],\n", + " (14, 5, 1): [(1, 2, 3, 3, 5)],\n", + " (14, 5, 2): [(1, 2, 2, 4, 5)],\n", + " (14, 6, 2): [(1, 2, 2, 3, 6)],\n", + " (15, 5, 0): [(1, 3, 3, 3, 5)],\n", + " (15, 5, 1): [(1, 2, 3, 4, 5)],\n", + " (15, 6, 1): [(1, 2, 3, 3, 6)],\n", + " (15, 6, 2): [(1, 2, 2, 4, 6)],\n", + " (16, 5, 0): [(1, 3, 3, 4, 5)],\n", + " (16, 5, 1): [(1, 2, 4, 4, 5)],\n", + " (16, 6, 0): [(1, 3, 3, 3, 6)],\n", + " (16, 6, 1): [(1, 2, 3, 4, 6)],\n", + " (16, 6, 2): [(1, 2, 2, 5, 6)],\n", + " (17, 5, 0): [(1, 3, 4, 4, 5)],\n", + " (17, 6, 0): [(1, 3, 3, 4, 6)],\n", + " (17, 6, 1): [(1, 2, 3, 5, 6), (1, 2, 4, 4, 6)],\n", + " (18, 5, 0): [(1, 4, 4, 4, 5)],\n", + " (18, 6, 0): [(1, 3, 3, 5, 6), (1, 3, 4, 4, 6)],\n", + " (18, 6, 1): [(1, 2, 4, 5, 6)],\n", + " (19, 6, 0): [(1, 3, 4, 5, 6), (1, 4, 4, 4, 6)],\n", + " (19, 6, 1): [(1, 2, 5, 5, 6)],\n", + " (20, 6, 0): [(1, 3, 5, 5, 6), (1, 4, 4, 5, 6)],\n", + " (21, 6, 0): [(1, 4, 5, 5, 6)],\n", + " (22, 6, 0): [(1, 5, 5, 5, 6)]})" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tabulate(all_dice(5))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Pretty good: four of the bins have two dice, but the rest have only one die.**\n", + "\n", + "And let's see how many pairs we're producing now. We'll tabulate *N* (the number of sides); *D* (the number of *N*-sided dice), the number `pairs(dice)` using the new `pairs`, and the number using the old `pairs`:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " N: D #pairs(dice) D*(D-1)/2\n", + " 2: 1 1 0\n", + " 3: 1 1 0\n", + " 4: 10 3 45\n", + " 5: 31 9 465\n", + " 6: 231 71 26,565\n", + " 7: 1,596 670 1,272,810\n", + " 8: 5,916 6,614 17,496,570\n", + " 9: 40,590 76,215 823,753,755\n", + "10: 274,274 920,518 37,612,976,401\n", + "11: 1,837,836 11,506,826 1,688,819,662,530\n" + ] + } + ], + "source": [ + "print(' N: D #pairs(dice) D*(D-1)/2')\n", + "for N in ints(2, 11):\n", + " dice = list(all_dice(N))\n", + " D = len(dice)\n", + " print('{:2}: {:9,d} {:12,d} {:17,d}'.format(N, D, len(list(pairs(dice))), D*(D-1)//2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "OK, we're doing 100,000 times better for *N*=11. But it would still take a long time to test 11 million pairs. Let's just get the answers up to *N*=10:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 26.2 s, sys: 129 ms, total: 26.3 s\n", + "Wall time: 26.6 s\n" + ] + }, + { + "data": { + "text/plain": [ + "{2: set(),\n", + " 3: set(),\n", + " 4: {((1, 2, 2, 3), (1, 3, 3, 5))},\n", + " 5: set(),\n", + " 6: {((1, 2, 2, 3, 3, 4), (1, 3, 4, 5, 6, 8))},\n", + " 7: set(),\n", + " 8: {((1, 2, 2, 3, 3, 4, 4, 5), (1, 3, 5, 5, 7, 7, 9, 11)),\n", + " ((1, 2, 2, 3, 5, 6, 6, 7), (1, 3, 3, 5, 5, 7, 7, 9)),\n", + " ((1, 2, 3, 3, 4, 4, 5, 6), (1, 2, 5, 5, 6, 6, 9, 10))},\n", + " 9: {((1, 2, 2, 3, 3, 3, 4, 4, 5), (1, 4, 4, 7, 7, 7, 10, 10, 13))},\n", + " 10: {((1, 2, 2, 3, 3, 4, 4, 5, 5, 6), (1, 3, 5, 6, 7, 8, 9, 10, 12, 14))}}" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "{N: sicherman(N)\n", + " for N in ints(2, 10)}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Not bad; we solved it for all *N* up to 10 in just a few seconds more than it took for just *N*=7 with the old version. Interestingly, there are solutions for all composite *N* but no prime *N*. So I have some questions:\n", + "\n", + "- Do all composire *N* have solutions?\n", + "- Do no prime *N* have solutions?\n", + "- Do some *N* have more than the 3 solutions that 8 has?\n", + "- Could we handle larger *N* if we worked with [generating functions](https://en.wikipedia.org/wiki/Sicherman_dice)?\n", + "\n", + "\n", + "**Good questions, but I think this is a good place to stop for now.**\n", + "\n", + "Agreed!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/Sierpinski.ipynb b/pytudes/ipynb/Sierpinski.ipynb new file mode 100644 index 0000000..d076716 --- /dev/null +++ b/pytudes/ipynb/Sierpinski.ipynb @@ -0,0 +1,335 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Chaos Game with Triangles\n", + "\n", + "John D. Cook [proposed](https://www.johndcook.com/blog/2017/07/08/the-chaos-game-and-the-sierpinski-triangle/) an interesting \"game\" from the book *[Chaos and Fractals](https://smile.amazon.com/Chaos-Fractals-New-Frontiers-Science/dp/0387202293)*: start at a vertex of an equilateral triangle. Then move to a new point halfway between the current point and one of the three vertexes of the triangle, chosen at random. Repeat to create *N* points, and plot them. What do you get? \n", + "\n", + "I'll refactor Cook's code a bit and then we'll see:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import random\n", + "\n", + "def random_walk(vertexes, N):\n", + " \"Walk halfway from current point towards a random vertex; repeat for N points.\"\n", + " points = [random.choice(vertexes)]\n", + " for _ in range(N-1):\n", + " points.append(midpoint(points[-1], random.choice(vertexes)))\n", + " return points\n", + "\n", + "def show_walk(vertexes, N=5000):\n", + " \"Walk halfway towards a random vertex for N points; show reults.\"\n", + " Xs, Ys = transpose(random_walk(vertexes, N))\n", + " Xv, Yv = transpose(vertexes)\n", + " plt.plot(Xs, Ys, 'r.')\n", + " plt.plot(Xv, Yv, 'bs')\n", + " plt.gca().set_aspect('equal')\n", + " plt.gcf().set_size_inches(9, 9)\n", + " plt.axis('off')\n", + " plt.show()\n", + " \n", + "def midpoint(p, q): return ((p[0] + q[0])/2, (p[1] + q[1])/2)\n", + "\n", + "def transpose(matrix): return zip(*matrix)\n", + "\n", + "triangle = ((0, 0), (0.5, (3**0.5)/2), (1, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_walk(triangle, 20)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OK, the first 20 points don't tell me much. What if I try 20,000 points?" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nuV1N3FrZAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_walk(triangle, 20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wow! The [Sierpinski Triangle](https://en.wikipedia.org/wiki/Sierpinski_triangle)! \n", + "What happens if we start with a different set of vertexes, like a square?" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiAAAAIXCAYAAACl9uUJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvbuuHcmSNrYoyJBDQ+by6Y8loLdLmiQgQ5r/Bch2/u5x\nJD3DPIQMAXqTAeQLB8TGGJscp+c39ATN5mYfpozadSovcb9k1mavBRTOae6qvERExuWLyMwXpZTL\n7Xf73X633+13+91+t9/M33+3egC33+13+91+t9/td/v99X43B+T2u/1uv9vv9rv9br/pv5sDcvvd\nfrff7Xf73X633/TfzQG5/W6/2+/2u/1uv9tv+u/mgNx+t9/td/vdfrff7Tf9d3NAbr/b7/a7/W6/\n2+/2m/67OSC33+13+91+t9/td/tN/90ckNvv9rv9br/b7/a7/ab/bg7I7Xf73X633+13+91+0383\nB+T2u/1uv9vv9rv9br/pv5sDcvvdfrff7Xf73X633/TfVAfkxYtLOZ7/8m/Ei3eXFy8eLy9elMuL\nF18vL178xDT88vLixd+evvnb5cWLl4LB1N88XF68uBJ//3h58eIN2e72/p2ob35c9na032tp3fZT\n0/yNqR28PR8d27bfXF68+AaOzdqvXkbzZdr7PSc7Vlmx/sb+Xg9zypSbqJ+Gbivnk83fWfITpYvP\nNo5WNn4fZEQqOyMfPoj4Us3nxYv/8m+1PTfPqZQy7blcSjmef/439N3L5WW5XP5WLpevT//7kmz7\ncrkrl8vjU8Nfy+XyQflNKZfLQ/NN+/fv5XL5ho7lGO+jaLz8vG3tWL7X0hqn+Wu0na2PO7Ltsb2f\nQuRu6/vjEw+/P/1/jM/yfvUy6pVpHT2030Oy0/PNKis+3tX9vRnm5OMfLZN589CsA16XrRhnPh1s\n/InSxdgYZLrs5ZOsflSPg2p/tFm7jPyEyA68FkY+XFm+dHT97y//y/9TD8NK43yhrjtr6EY4IMeE\nfxIxriXo7yKmb988gIw8/r4bLvgdWDDsxtOrfKBxyBeMjNa4EL8E25EqhCzl19LksVwur8P63Rbu\nh3K5XBU0s8i0xxm1Ojy7Q9nyzSIrPv4d/eEyp6NTpJGSz+HNE001jqpMl2XRe1X7Hv7E6WLMIafH\ndbzzrRy2QzYOrv3DJj0+yUYr85s++v2pz99JvdTzAdfdd9X//oOu/+Plf/5/n6ED8s//djw//Z8J\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "square = ((0, 0), (0, 1), (1, 0), (1, 1))\n", + "\n", + "show_walk(square)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There doesn't seem to be any structure there. Let's try again to make sure:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiAAAAIXCAYAAACl9uUJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvT2vXFmWJRYUIMjKHxCmBPrpjZIQNN0gTdISmF6XxSwn\nyTSmspxuOeNUNaCuAWbGGI05A2l+iQDZCYJgVj9+ZIvMbHS33AGTLx7zbRk3Vp2111773PvisXJU\n0gvggnwR9+Pcc/bn2h/nVkTsbj43n5vPzefmc/O5+dx8fs7Pf/VfegA3n5vPzefmc/O5+dx8/v/3\nuTFAbj43n5vPzefmc/O5+fzsnxsD5OZz87n53HxuPjefm8/P/rkxQG4+N5+bz83n5nPzufn87J8b\nA+Tmc/O5+dx8bj43n5vPz/65MUBuPjefm8/N5+Zz87n5/OyfGwPk5nPzufncfG4+N5+bz8/+uTFA\nbj43n5vPzefmc/O5+fzsnxsD5OZz87n53HxuPjefm8/P/rkxQG4+N5+bz83n5nPzufn87J8bA+Tm\nc/O5+dx8bj43n5vPz/75WQ2QW7d2geO/vvXw/1g5+c7u1q3D7tat2N26db67desz+f3e7taty+Pv\nl7tbt14d/73c3br1dHfr1icr9//k+IxP5Ltvjs/9hs7BOC52t27dtddefTL2u1u3zo73fnf89+nx\nvT6Rc+u4xvf37DX+ur29z2njn6/Px/yM+d5fad7r+9+TMX/x0d9heebTI61UOpy9i5vTLbTmr+Pv\n4khroJt7x/Hl987zdba7dWt/7bH5d18//7q0u1x/Ru9/eXzn/trxzIvdkC141/3u1q1fpjk55dPx\n8vKbrtnpdMlzne+LeTgjGqw8UOXrfTtuXdP8fi93t249oN+uLzOWMb873uOd0GhPX1t/q2N8IvPw\npJmvfl3XxrDl2u3zM+exj/GsW7c++e9v3fvPrM9PHm9E/GzHbheB45/t7v7n2O0+ac/f7T6J3e6b\n2O3Oj/9+Ir/fi93u8njDy9jtPsR4wCF2u89W7v00druL47+fHL+/c7wW97hL514ej2fHvw92XFuO\n5Z5nwRMy3uOi3DeP6zx2u8+O93hG43paxlKv+4L+vojd7u5kfHeutT7b56E+h78fzznEbvdu87wv\n1/1S3vehjHl/7Xeoz1W6vCtj0nd5erxmf/z3qRnf4Ugv+81rUWmM6Ubp2dF/HK//pHkGj23revD5\n+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\n9OP/Aay0DeKUwjGKAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_walk(square, 20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I'm still not seeing anything but random points. How about a right triangle?" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "right_triangle = ((0, 0), (0, 1), (1, 0))\n", + "\n", + "show_walk(right_triangle, 20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We get a squished Serpinski triangle. How about a pentagon? (I'm lazy so I had Wolfram Alpha [compute the vertexes](https://www.wolframalpha.com/input/?i=vertexes+of+regular+pentagon).)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nY2pqh67egNTUxXVcXOl5Hy9Aq+YZOzdH8897GTGU2bBdIssVcQOIpvb29R9nBtaPJWjt0ue68Pra\nEjH4lsskxnzVzxQLQJ52nVjVYw8QlevT866ugR/QmJraoas3IDX1ICozRbQD4ZYJmrTva7tEepkJ\nahxaTM68fjuekZ83pnKXfvysqJ5sHjpefW3Ur9n/rAW4S/dLDKxHAEz7gMbU1KB+AABDSsqx5YMP\nTv/jMPztvys/eXsO8D//1QI3+HAYhv8xDMPfH4bhT/Z//XvDMPx0GIbfGAD+inzv14dh+GP2t38x\nDMO/H4bh14ZhuBmG4Z8NAP+r8771vfTv1vf2r/kPhmH4ZhiG39h/0v5tr3zwwekwDP996H3uY0jp\nh18fhuGvD8PwwUDb2NP3y7UnNgblu386DMN/nd3GKc+qzaN6ztvX65kX47X++TAMfzgMw699Ovyd\n7//L8I9e/J/hb/7f+osLvesp91fWRkipD1OH4ZM/qrNGUT/5o8XuQ3eeUTeFHZTYGyexnEtkC8zA\nVlTu0jXma3131DHmx7w4EYsl8U5X7mX8voZhuP7Hw6P/d/B3PfVe6t9YGyClpBxMxh0g3eVFmIB/\nOIw7zF8bhgGGYfjxMAz/eejZ5cr7zpWXw7jjxd3tHy947VoA/mr44IPfGA7BziwhY3v+2/DBB/9k\n0Nq4fN8vL0u1sf86/jzyrtc7L8j3//fwt35vGIZ/2tHOlJRhGIYEKCkpTPgi3gdODiHHBg0Pycg/\nJJk7j3r7fP/99x/85vdd90lJ2UsClJQUKltlENIgpywhOY9S7pAkQElJ4ZKLeEpKSsrqkgAlZSV5\nez4Mv2n8PSUl5f5Ivusp0yTTjFNSUlJSUlI2J39t7QakpKSkpKSkpHBJgJKSkpKSkpKyOUmAkpKS\nkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKS\nkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKS\nsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5\nSYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmA\nkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKS\nkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKS\nkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKS\nkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKyOUmAkpKSkpKSkrI5SYCSkpKSkpKSsjlJgJKSkpKSkpKy\nOfn/w7HqK+VSVlwAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pentagon = ((0.5, -0.688), (0.809, 0.262), (0., 0.850), (-0.809, 0.262), (-0.5, -0.688))\n", + "\n", + "show_walk(pentagon)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To clarify, let's try again with different numbers of points:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_walk(pentagon, 10000)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nIkdJI4lhsH/Ik3QDsZVuBUlQBAyjBwFCElBIjmA1CUSkDM8MjKEMz8gWpXhGhpVAil5QIglIEEES\n7MiSBQUKAieDTqm6WVVdRfaDjyaHM5qRuureW32//Njnm/3ttdc+59zqat5u9i1goe4995x99nPt\ntdf61lp26tRjPeV9u5l9W/feU2b2za4Op8zsH9mpU2tm9j1m9u901yD3fLSjj5jZXanbT5jZ95vZ\nGTP7YfdeBN9Pmdl3mNm/ZWZvm9l/ZGZ/1cy2gvv177aZvR6061915V+w3N+tvw8P/K5/71qq8y+Z\n2Tc17jly32cWt13v3wmeY93+Qnf/95nZ95rZ75rZH1qaF4fdc7fN7FWL59LEzP4bM3tZ3jt37/B/\np8zsu7p3/Ub3nne6tuyY2RetbD+6+hxZmhOwvB4+3F1/173j7e6ZHTP7S3bq1JqdOvWYnTp1pvv9\n0PI8NTN7sfv/G2b254I6m6W5+IJrn5nZvyL1bI033/MxM3svuN76ey+49ufN7O9YPKYfMrNvNeAP\nuu+/Z4nHfEzuuWFm13ve+VZXr4+a2Q+Y2S/Lu7imD4Lnvt3S+PA+30/vWVpXUzO70n3+PUt9/rfN\nbNvMvtpTL5jZvjz/zy2t6e/rfv/7FvfnXctzE2b2N+UZ8tm7ZvYFM/stS2MY8YePWeKJf7d7P/vk\nI2b23Wb2N8zsz1jmfd9iqQ+/y9Jc+2h3339seZ58qPvNOh7+vWb28e7/6m/ZEtIHgUaYeKgNoNp1\nC5quG9BwzLxOtTT/+4zDZxHjJVgGo3mOBS76e7w2hqQ21/L9uQ6Rbd3TNpJmpg8Yq6c+daWOgtK1\n3uOfewwpXsMQiDWKQbPt7nkO6TR0Ce1suH193HcPNRz6zCHMvtDzLD2ivPaB0WbVxdKrx73L+1mk\nEzTvOUCcNFAD6mnfDLVzL3huijQnopgXX3Plei2Ex17RXKXjQkzADhLoU8sfY965gsXwNu8gm1uo\nibjTvYfYoqE50fe7/kagvHqgRe2ZI2nCTiODbyPzp373gd2ovaDmSmMFacJSPw84TsR7eJOQd3H2\ndZ8gaW7OyvOtlAEzlJo5mjR91uXLKOOjeO1Sy4xGs2ZLU+z7zydjHXQ1/jP2n69MPMuuwAeBetHW\naQH5fB+1+rmMHaHqT3pyXEBp2qmDudVlMD+EDyIEDAf28otNVeG6wKONfAv1puHLbIEbeZ/3jiCx\n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\nSdT+IU1k33UKFGPTbOg9FBY3kYWJTZSaOh+UkuPhA1U+iXLu+lAR71+agQ8gfchWfw/a3ykz+/Nm\n3xgbmNms+w8z2zKz/7v77bWOpmZ2y8yOuuf17wfN7K+Z2Z5c+zfM7JfM7F0z+7ONeqyZ2V0ze9rM\n5t21uZn91e7z75nZ75rZ75vZf21m394o52Nm9nfM7CNd/T/avfMjZvbNZvZhM/suM3vczH7HzL6j\nu+e7zezfDcr9TjP7U2a23ZX3YTP7X7q6/J6dOvVYox7695rlfrvS0d8ys5cb98PMXunq/FEz+9ct\n9edRV85+9/mKmX2lu8+6un3E4j8/TrfN7FUz+zdH1N///ctmds3SPHnd/fYRS/37bd3n77TUtx/t\nrpmZvdHVf2KpT7bM7IfM7N83s4+b2ROW5oJZnocf7t43NbNNS3Psew34+jfeDHzdgD8orvnr/p70\n/+NdeyDv3Jc6fJtcn0rJ32Rmf9fMrnbXd83sD7vPcxv+O2VmP2CnTp0zsz9n9dz7sqV+Gvr7JqvH\n138f8/chS/PhPzOzG5bb+uGuvP/KzP5tM/s+S+N13cwumNlnLPeVWZqrr1tqz6+a2b8mv93oyvqL\nVq47/7dlaX5Y9//3u3F7U8Zvs7tv2t0zszQG329m/4GZfVHaMJXyor9Wf53qyr1iaWxbf+Sb/Kxz\n6UOW2v0hS33yYUv9+EuWeJKZ2bdY6vvbUubHzOzfs3IOfE0+f4+l/jvV0bqZ3anm/+pv/N+yJaQV\ndRSfPqZIIeOn8j1y57yO7KbIUxVPBZTu1SPobnDqiDwgJkjAtu3umSuoT0rzxrP8bezJ0d+33b1L\n3Y1ZhyniDLfeg4ko+pYn0zbKrLGtNnizCNXZjyNnSdXAbtddGe9huE9eRY4T0+qz3+nG4wuu7QT8\nadRgfd+ryFqdAyR7P0+Q6uFzGmWCxCgEuPZ7eYI82fVAc9B5ZM1ApOXyGsBp98xTyGr6x7u2/QKG\nT+2kd3ru4XsmPWVFc3oMHaH2xOF4+PnOTMLUOqp3FEHBN5E0mKpxVE3IeSnDm+MuILnyem+YuYxJ\nMofkMTsnv3EtsnyvCe4zoe0gBtTOwaCA+X00ueg9bw70/1BkZUaxveiuKxiWpKZn5SU3kbQyKw3K\nMWnpFVhRR7X3A5lFnHMnDh2umxQFFLq7tfKpoFtMvxpci+zodMHsC+xFmiJ2yWT5nmmR3v7Gwu6P\n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\nKTP75u7zN5vZt3Tl/SMz+3r33tbfV933v2lm32dmL7j6HPfvY2b2p83sipn9dTP755b6y/99uPu/\nZ2kMftfM/tBS30+De7+t+8wx6mtj62/bzL7srn3/yLJOdfWAme2Y2V8zs18zs9+zU6ceM+DNrqxZ\nd/9dM3vXTp06033/ePfc1FJ/TM1s18wmZvYbZvYv7NSpNTP7HjP7zu5d325m/5uZ/b6ZmQF/YKmf\nNs3syPL8HPM3795/ZGb7ZvY3zOx/sjRvPtLRTdcXH+ra+LHu+8fM7O2g7I+Y2d8ysxtdu7bM7Ocs\nHnetj/69aamPvr2r00ctzeuPmtl3mdk/tHpe6N/HgjL1D2Z2qytj0n1Hz/1mecyH/mCpX/nn9wpY\n6tdTltrj33FX6rNnZv+pmf2Kpb543cyesLhtty1uw9zM3nHXvmpmf9ly336rmf1flsZo29K8fbV7\n3+9bmnc/aWa/ZadOrdmpU2c6vmWW+MXHpOz/0YA3DfiDjj+u/pbxt2wJaUX3kWpf/ydQY00YvEqD\nszEUuuJFFPehyHhVn/qT6C6GPRNap7m3EavYo3tpMyaQU3EyQ8/yN+Jcot/vdv2okXJvoO1FdAk5\nLgjziPj3l9FY6xNci+iaSXNQFIJ9hnZwLm+CIH1axk9PnWrmUbMbsRUaZfdx1KaLXSTtk2+beiup\n+YOaFj9HonkyQc51w/HzHlMvIeFj7so1b5r6BGKTEudUCqee6qog8yHtxovSPh2nObIm5SaOD4C+\njYQn0xxKUbTmRYgg6qGgf7dQmlL5DLWz7GOa3H4UpVZDvb98v7fe6wHXjKRLzeshcu4mdR/2Afz8\nPH4MiTfquzaWzr9XZEuvwIruE8XYk8uI42bsoA6PrwxEAZPMw0HgZsuMNEcCynl7/M+7+15HEkb8\ns76OgNkfoa3+nyLHOTjTc19Es45hPYF27IlfbDw7h9nvI6u57yDbv68EbeP7zrrx8kC/Vh8o5udC\no758Xsds2tVFzRtKCrRkvJEoGBrHmZFZI0C2xypEQFJ6ijHA37QrjxF8KWwQj6LCsuJlVJ3f6ofL\nSHPiZ7r3aaA/DVQ46foowk/QvPf0wPuUdpGzSWuUVI+xOUQSonwQMz9n1HzKsVAz0Ficjm8b58an\nR7ZtgjIg3ibKgHh7yHGPtqTe3rsmyqwdgWl5YNpEDGzuO4gQY6fAfp8k8jkkPJK+8+z7zrNXVNHS\n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\nOXqiZ7ZybksTUFqZU3m4EcIvVr5vpZVWzk5p73orJyvNxNNKK6200korrSxc+ci8G9BKK6200kor\nrbRiSxNQWmmllVZaaaWVhStNQGmllVZaaaWVVhauNAGllVZaaaWVVlpZuNIElFZaaaWVVlppZeFK\nE1BaaaWVVlpppZWFK01AaaWVVlpppZVWFq40AaWVVlpppZVWWlm40gSUVlpppZVWWmll4UoTUFpp\npZVWWmmllYUrTUBppZVWWmmllVYWrjQBpZVWWmmllVZaWbjSBJRWWmmllVZaaWXhShNQWmmllVZa\naaWVhStNQGmllVZaaaWVVhauNAGllVZaaaWVVlpZuNIElFZaaaWVVlppZeFKE1BaaaWVVlpppZWF\nK01AaaWVVlpppZVWFq40AaWVVlpppZVWWlm40gSUVlpppZVWWmll4UoTUFpppZVWWmmllYUrTUBp\npZVWWmmllVYWrjQBpZVWWmmllVZaWbjSBJRWWmmllVZaaWXhShNQWmmllVZaaaWVhStNQGmllVZa\naaWVVhauNAGllVZaaaWVVlpZuNIElFZaaaWVVlppZeFKE1BaaaWVVlpppZWFK01AaaWVVlpppZVW\nFq40AaWVVlpppZVWWlm40gSUVlpppZVWWmll4UoTUFpppZVWWmmllYUrTUBppZVWWmmllVYWrjQB\npZVWWmmllVZaWbjSBJRWWmmllVZaaWXhShNQWmmllVZaaaWVhStNQGmllVZaaaWVVhauNAGllVZa\naaWVVlpZuNIElFZaaaWVVlppZeFKE1BaaaWVVlpppZWFK01AaaWVVlpppZVWFq40AaWVVlpppZVW\nWlm48v8DHyzlqLKk1CIAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_walk(pentagon, 20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I definitely see a central hole, and five secondary holes surrounding that, and then, maybe 15 holes surrounding those? Or maybe not 15; hard to tell. Is a \"Sierpinski Pentagon\" a thing? I hadn't heard of it but a [quick search](https://www.google.com/search?q=sierpinski+pentagon) reveals that yes indeed, it is [a thing](http://ecademy.agnesscott.edu/~lriddle/ifs/pentagon/sierngon.htm), and it does have 15 holes surrounding the 5 holes. Let's try the hexagon:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAIXCAYAAAC2IaX9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvUuMZkl2HhYlkKZhoVcyLP8wBBJyUiKpAWZFogvEgEDW\nxuPKjY0er6RV9Wgx1Q2LHC5M7UkBEm35AXhBL+y1N14Z1MrwmCBEkDAwKCR7yKzseVQ3YQ4BLyQa\n9cisquPF/WPixHlEnHjcGzfzjwAOZrryv/eeeJ3Hd06ceAAAbrbZZpttttlmm21P7W+MZmC22Wab\nbbbZZpuNtmmgzDbbbLPNNttsu2vTQJltttlmm2222XbXpoEy22yzzTbbbLPtrk0DZbbZZpttttlm\n212bBspss80222yzzba7Ng2U2WabbbbZZpttd20aKLPNNttss8022+7aNFBmm2222WabbbbdtWmg\nzDbbbLPNNttsu2vTQJltttlmm2222XbXpoEy22yzzTbbbLPtrk0DZbbZZpttttlm212bBspss802\n22yzzba7Ng2U2WabbbbZZpttd20aKLPNNttss8022+7aNFBmm2222WabbbbdtWmgzDbbbLPNNtts\nu2vTQJltttlmm2222XbXpoEy22yzzTbbbLPtrk0DZbbZZpttttlm212bBspss80222yzzba7Ng2U\n2WabbbbZZpttd20aKLPNNttss8022+7aNFBmm2222WabbbbdtWmgzDbbbLPNNttsu2vTQJltttlm\nm2222XbXpoEy22yzzTbbbLPtrk0DZbbZZpttttlm212bBspss80222yzzba7Ng2U2WabbbbZZptt\nd20aKLPNNttss8022+7aNFBmm2222WabbbbdtWmgzDbbbLPNNttsu2vTQJltttlmm2222XbXpoEy\n22yzzTbbbLPtrk0DZbbZZpttttlm212bBspss80222yzzba7Ng2U2WabbbbZZpttd20aKLPNNtts\ns8022+7aNFBmm2222WabbbbdtZ8azcBsp9kePHj4e879nb/H//LFFcC//sfbczTbbLOt0eZen622\nTQNltkHt7/w95/7XX+P//l9sz8pss822Ypt7fba6NkM8s80222y4PXjwgXvw4KF78OCD0azMNtsp\nt2mgzLar9jPu3b8zmofZTrgtRskfOOe+45z7gyojpcXAyT07jafZTqhNA2W2XbX/0L3+90fzcGfa\n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\nOsj5DevezCo3XTFdOi3uHytFmzLMK1Xe4jH5Q/fgwaPNDZXAw+8f/8VX0OVhrlSfWg0t6XlJQYdw\nxNddqbHRamzVr2FvBPzU8b/fOueeuyXMlOIFGw/Ljdr918e80Xi2+jYawpl0whTD4lfg3JkZbqZQ\neI+TMn368xDx5MNR5xCOez5i4akSWL8EMh95WkbmQZ6X/JFkPmZ16yx+nh+hvW76zhZjle6fPwlk\nO8a+hFdfoP733zdh/vodrZ90MjScgUknTryOR6sSGpOnoStBb7ScHY2w26OxAFUKoUSJxTzVf7PP\nuOjzks5P+e4qYybnbNCaJNsauS1ruDR3JV4br1fZNzP/ZFIjzRDPbOs0KyTvYfEl1FMfq+6bA1DT\ncpcLXroFRvcw/K3rdXxXa8sYfN0tp53GwOy2eUnl8eDQRa8x+5ELYafXzrnP0d++52josDWHp2Qv\n1K7h8vASXq8PnHPfKv5m2Tdm/slsxW0eM56tf6u5i2ONO0a2bPnLBXH73Dn3jx097pk6jpm6IyjP\nky+p/k/YN2396lHu3nKEnF4hgMf0C+fcf+mc+78a+PBHnvG83Drn/jPn3P/rguGjHY3O37xM+7rX\ne2m22G93fU/PNr6NhnAm3UNqi6WXwtTrHZEs7zfNi5GqcF6BcwflWUtpeDtU3l4NtiTfhc9F6/PL\nv5cdQ7f3Cx8BvwYp/6k+nKbluYwIr9GcKPrf6x7xnhVlJzXQcAYm3UPaIh8kn/PRS5G1vSvOsamr\nvbHWHUH5523fLVXOsqLUjDMtf6R1Xmj599fKWrKNXz6PZtvcKD6mbTlekyYNoJmDMlv/tk0+SC7n\no+2occu7eM7BA+fc/+fCDbFSPkIqt6TuqGbNPNQcgeZz8cukpL12HHw5+rxU2+W5CnL9lB+5PnP8\nx865H6D//hn2/bLxk8eqdS/U58DgOfkl59x/7tbIB9lDnZ3Z7m8bbSFNuue0VhhG8kx7etvtqIW/\nqRcfW017sRocvtVRTQnJsED0/Jgr7bN2HNwffcYX5uHv8hugY+SjLWQSwkf8IryaddM7nNFyCoaH\nsf4cnPuiK5IzT+lMWpmGMzDpHtPaAiyd8+GV4zOkBCXFr90+WwfNxwqYHlv9uNjo2VIJtN/k++HR\ngNDfIR8dvgHnHicMGWxs5q8PyPMp5WEc0Df2oXjbc4guwLm3EMJYAEso6xudDJTxtYcm3WsazsCk\n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\nlic+xt+yF3ELz9sNurrqt+uHBcJ3bGvWul5q1kU6lKN9o/W4dy48OkMzk8w0nIFJJ0Q2mFoK05TC\nzesJwdL3534vjQlHYloSH1tRHEtY7SH63/IibnwsLGjZeI+8ZV5q1kvJ2suHI63GbSnyVu8krDGe\nk+40DWdg0glR+fX2AGsXIhtN5SdWrMqpDJGRv+lzRuS6JXLOBFZOX4VUUqf+bR0B0H67/bxRtGjd\nejS911VZ/0qTZi9gqd9SumbXT/yedKfob4y+TXm2O9b4VeolzXKV/A9duNr+jXPuP3U1V7G38Vnf\nyr+Lx+TPnXN/kzz7FefcLznnfto594vOuX+Q/b5zf+Cc+87xf51z7muu5Fr75Tdfc859/fgvv++c\n+wOhT5S3nz0+8yPn3M855/61c+5/dM79vnk8lm//qXPuV5xzf/iTfkjPA/y1A/ijovWRmx/7/OG+\n/7xz7jubr7V0y62rXJPXXWp8wtr735xzf5c9W/O90jZq38+2ThttIU26Q1SWxKgdx82FPNqz/Ud5\nY21eJz5t5NGIsiTh1PjVwfX0XXGJcQmd6XeSxVYzpef8lK9vWyhyVOhCXlcla7LsVFrpcfLc93rP\n76Q7R8MZmHSHqKy0fJ2g0ASVVcgvv/umic9R42N79gXExkpp7oFdsaTf5ZXbpajo5HyZXidZapRc\nKiSUC6eVJt76ZO7UqRl7KKhsjXvjlRqM/Y738rnNGb/YmE4fJ7d8b8v9N2mXNJyBSXeIrF5On/g3\nzkOoKZGeVo7rJThqtUBKTvy8htgz/7hJ0KcrnqaUmzdQbsG5z8F67Dh8v/Uki13JWYyw3Pqtz9eR\n7uWREocBtJwqqxHJ1zjN/2k73ptarzbjt3bO2/diDxRm0q5oOAOT7hhZvJxegqIU7rfUEInfa0tw\nzHvmNCm1pLgWfRZfTgewGCttkDWfD6rMNOVG0Yw+963YxrNUyZWge7lTVbUXIWqGQz4UZOdfC6Hx\nSw1L+5Rar7Hx1Vbrx/rN+rU1jzLfExrOwKR7SilBYUcVyuD+OoQHIHVSKCdA00K9/ITOUuLcIyg3\nGaVj9zpjw4nyJSs32UBMHzu28dE/T2CE9xwbl3ruTVkoyCNHuZNTNIRWlquU3xfSOtAMF8ue03LS\nZlhmkkrDGZi0c9IFSx0sW6KgauB+O8JjTXCsz1vIhxTos+eEL4/wSPk49UpeR1Q4n8tvfaJlu/K3\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "hexagon = ((0.5, -0.866), (1, 0), (0.5, 0.866), (-0.5, 0.866), (-1, 0), (-0.5, -0.866))\n", + "\n", + "show_walk(hexagon)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAIXCAYAAAC2IaX9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvc+PXUmWHnbLGhmW7foDnoGBBDghWPIAhG1YKMIQBJPL\npDcGy6vqVVV50WQZnqpeuLsBa7ToGkDdA6tHkEeQZWAEQ4ZGkOyNYRvwaiwI1s4FIp1VnZkkq0hW\n/6juGck/QPK9JPPz4t5v4osvTsS9L5lVL0lGAAeZ771748avG+fEOd855w0AQy+99NJLL7300stl\nKv/SrhvQSy+99NJLL7304qULKL300ksvvfTSy6UrXUDppZdeeumll14uXekCSi+99NJLL730culK\nF1B66aWXXnrppZdLV7qA0ksvvfTSSy+9XLrSBZReeumll1566eXSlS6g9NJLL7300ksvl650AaWX\nXnrppZdeerl0pQsovfTSSy+99NLLpStdQOmll1566aWXXi5d6QJKL7300ksvvfRy6UoXUHrppZde\neumll0tXuoDSSy+99NJLL71cutIFlF566aWXXnrp5dKVLqD00ksvvfTSSy+XrnQBpZdeeumll156\nuXSlCyi99NJLL7300sulK11A6aWXXnrppZdeLl3pAkovvfTSSy+99HLpShdQeumll1566aWXS1e6\ngNJLL7300ksvvVy60gWUXnrppZdeeunl0pUuoPTSSy+99NJLL5eudAGll1566aWXXnq5dKULKL30\n0ksvvfTSy6UrXUDppZdeeumll14uXekCSi+99NJLL730culKF1B66aWXXnrppZdLV7qA0ksvvfTS\nSy+9XLrSBZReeumll1566eXSlS6g9NJLL7300ksvl650AaWXXnrppZdeerl0pQsovfTSSy+99NLL\npStdQOmll1566aWXXi5d6QJKL7300ksvvfRy6UoXUHrppZdeeumll0tXuoDSSy+99NJLL71cutIF\nlF566aWXXnrp5dKVLqD00ksvvfTSSy+XrnQBpZdeeumll156uXTl13bdgF5ez/LGG1f/zjD8+p8v\nf3l4BPwf/+k336Jeeunl6yj9Xe/lvKULKL3sqPz6nx+Gf/hXyu//k2++Kb300svXWPq73sv5Sjfx\n9NJLLy9neeONN4c33rg6vPHGm7tuSi+99HLxpQsovbx85VVhTC97P3bZ/vGZ/2QYhj8chuGfvLRj\n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\nBe0chYISFBQUFBQUtHMUCkpQUFBQUFDQzlEoKEFBQUFBQUE7R6GgBAUFBQUFBe0chYISFBQUFBQU\ntHMUCkpQUFBQUFDQzlEoKEFBQUFBQUE7R6GgBAUFBQUFBe0chYISFBQUFBQUtHMUCkpQUFBQUFDQ\nzlEoKEFBQUFBQUE7R6GgBAUFBQUFBe0chYISFBQUFBQUtHMUCkpQUFBQUFDQzlEoKEFBQUFBQUE7\nR6GgBAUFBQUFBe0chYISFBQUFBQUtHMUCkpQUFBQUFDQzlEoKEFBQUFBQUE7R6GgBAUFBQUFBe0c\nhYISFBQUFBQUtHMUCkpQUFBQUFDQzlEoKEFBQUFBQUE7R6GgBAUFBQUFBe0chYISFBQUFBQUtHMU\nCkpQUFBQUFDQzlEoKEFBQUFBQUE7R6GgBAUFBQUFBe0chYISFBQUFBQUtHMUCkpQUFBQUFDQzlEo\nKEFBQUFBQUE7R6GgBAUFBQUFBe0chYISFBQUFBQUtHMUCkpQUFBQUFDQzlEoKEFBQUFBQUE7R6Gg\nBAUFBQUFBe0chYISFBQUFBQUtHP0/wHwcDbRGjkZQAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_walk(hexagon, 20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see a little of the six-fold symmetry, but it is not as clear as the triangle and pentagon." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Snobol.ipynb b/pytudes/ipynb/Snobol.ipynb new file mode 100644 index 0000000..19e9147 --- /dev/null +++ b/pytudes/ipynb/Snobol.ipynb @@ -0,0 +1,276 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
Peter Norvig, Nov. 2017
\n", + "\n", + "# Bad Grade, Good Experience\n", + "\n", + "Recently I was asked a question I hadn't thought about before: \n", + "\n", + "> *As a student, did you ever get a bad grade on a programming assignment?* \n", + "\n", + "I've forgotten most of my assignments, but there is one I do remember. It was something like this:\n", + "\n", + "# The Concordance Assignment\n", + "\n", + "> *Using the [`Snobol`](http://www.snobol4.org/) language, read lines of text from the standard input and print a *concordance*, which is an alphabetized list of words in the text, with the line number(s) where each word appears. Words with different capitalization (like \"A\" and \"a\") should be merged into one entry.*\n", + "\n", + "After studying Snobol a bit, I realized that the expected solution was along these lines:\n", + "\n", + "1. Create an empty `dict` (Snobol calls these \"tables\") whose keys will be words and values will be lists of line numbers.\n", + "2. Read the lines of text (tracking the line numbers), split them into words, and build up the list of line numbers for each word.\n", + "3. Convert the table into a two-dimensional `array` where each row has the two columns `[word, line_numbers]`.\n", + "4. Write a function to sort the array alphabetically (`sort` is not built-in to Snobol).\n", + "5. Write a function to print the array.\n", + "\n", + "That would be around 40 to 60 lines of code; an easy task. But I noticed three interesting things about Snobol:\n", + "\n", + "* There is an *indirection* operator, `$`, so if the variable `'X'` has the value `\"A\"`, then `'$X = i'` is the same as `'A = i'`.\n", + "* Uninitialized variables are treated as the empty string, so `'A += \"text\"'` works even if we haven't seen `'A'` before.\n", + "* When the program ends, the Snobol interpreter automatically\n", + "prints the values of every variable, sorted alphabetically, as a debugging aid.\n", + "\n", + "That means I could do away with the `dict` and `array` data structures, eliminating steps 1, 3, 4, and 5, and just do step 2! \n", + "\n", + "# The Concordance Solution\n", + "\n", + "I ended up with a program similar to the following (translated from Snobol to Python, but with `'$word'` indirection):" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "program = \"\"\"\n", + "for i, line in enumerate(input):\n", + " for word in re.findall(r\"\\w+\", line.upper()):\n", + " $word += str(i) + ', '\n", + "\"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's just 3 lines, not 40 to 60! \n", + "\n", + "To test the program, I'll write a mock Snobol/Python interpreter, which at heart is just a call to the Python interpreter, `exec(program)`, except that it handles the three things I noticed about the Snobol interpreter:\n", + "\n", + "* `$word` gets translated as `_context[word]`.\n", + "* It calls `exec(program, _context)`, where `_context` is a `defaultdict(str)`, so variables default to `''`.\n", + "* After the `exec` completes, the user-defined variables (but not the built-in ones) are printed." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "import re\n", + "\n", + "def snobol(program, data=''):\n", + " \"\"\"A Python interpreter with three Snobol-ish features:\n", + " (1) $word indirection; (2) variables default to ''; (3) post-mortem dump.\"\"\"\n", + " program = re.sub(r'\\$(\\w+)', r'_context[\\1]', program) # (1) \n", + " _context = defaultdict(str, vars(__builtins__)) # (2) \n", + " _context.update(re=re, input=data.splitlines(), _context=_context)\n", + " builtins = set(_context)\n", + " try:\n", + " exec(program, _context)\n", + " finally:\n", + " print('-' * 79) # (3)\n", + " for name in sorted(_context):\n", + " if not (name in builtins or name == '__builtins__'):\n", + " print('{:10} = {}'.format(name, _context[name]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can run the program on some data:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "data = \"\"\"\n", + "There she was just a-walkin' down the street, \n", + "Singin' \"Do wah diddy diddy dum diddy do\"\n", + "Snappin' her fingers and shufflin' her feet, \n", + "Singin' \"Do wah diddy diddy dum diddy do\"\n", + "She looked good (looked good), she looked fine (looked fine)\n", + "She looked good, she looked fine and I nearly lost my mind\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-------------------------------------------------------------------------------\n", + "A = 1, \n", + "AND = 3, 6, \n", + "DIDDY = 2, 2, 2, 4, 4, 4, \n", + "DO = 2, 2, 4, 4, \n", + "DOWN = 1, \n", + "DUM = 2, 4, \n", + "FEET = 3, \n", + "FINE = 5, 5, 6, \n", + "FINGERS = 3, \n", + "GOOD = 5, 5, 6, \n", + "HER = 3, 3, \n", + "I = 6, \n", + "JUST = 1, \n", + "LOOKED = 5, 5, 5, 5, 6, 6, \n", + "LOST = 6, \n", + "MIND = 6, \n", + "MY = 6, \n", + "NEARLY = 6, \n", + "SHE = 1, 5, 5, 6, 6, \n", + "SHUFFLIN = 3, \n", + "SINGIN = 2, 4, \n", + "SNAPPIN = 3, \n", + "STREET = 1, \n", + "THE = 1, \n", + "THERE = 1, \n", + "WAH = 2, 4, \n", + "WALKIN = 1, \n", + "WAS = 1, \n", + "i = 6\n", + "line = She looked good, she looked fine and I nearly lost my mind\n", + "word = MIND\n" + ] + } + ], + "source": [ + "snobol(program, data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Oops! The post-mortem printout includes the variables `i`, `line`, and `word`. Reluctantly, I increased the program's line count by 33%:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-------------------------------------------------------------------------------\n", + "A = 1, \n", + "AND = 3, 6, \n", + "DIDDY = 2, 2, 2, 4, 4, 4, \n", + "DO = 2, 2, 4, 4, \n", + "DOWN = 1, \n", + "DUM = 2, 4, \n", + "FEET = 3, \n", + "FINE = 5, 5, 6, \n", + "FINGERS = 3, \n", + "GOOD = 5, 5, 6, \n", + "HER = 3, 3, \n", + "I = 6, \n", + "JUST = 1, \n", + "LOOKED = 5, 5, 5, 5, 6, 6, \n", + "LOST = 6, \n", + "MIND = 6, \n", + "MY = 6, \n", + "NEARLY = 6, \n", + "SHE = 1, 5, 5, 6, 6, \n", + "SHUFFLIN = 3, \n", + "SINGIN = 2, 4, \n", + "SNAPPIN = 3, \n", + "STREET = 1, \n", + "THE = 1, \n", + "THERE = 1, \n", + "WAH = 2, 4, \n", + "WALKIN = 1, \n", + "WAS = 1, \n" + ] + } + ], + "source": [ + "program = \"\"\"\n", + "for i, line in enumerate(input):\n", + " for word in re.findall(r\"\\w+\", line.upper()):\n", + " $word += str(i) + ', '\n", + "del i, line, word\n", + "\"\"\"\n", + "\n", + "snobol(program, data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looks good to me! \n", + "\n", + "But sadly, the grader for the course did not agree, complaining that my program was not extensible: what if I wanted to cover two or more files in one run? What if I wanted the output to have a slightly different format? I argued that [YAGNI](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it), and if the requirements\n", + "changed, *then* I would write the necessary 40 or 60 lines, but there's no sense doing that until then. The grader was not impressed with my arguments and I got points taken off. \n", + "\n", + "Still, I was happy with my program. I felt like the\n", + "purpose of the assignment was to get familiar with a new programming language with some different idioms/paradigms. By using the indirection operator I learned more about \"thinking different\" than if I had written the expected program.\n", + "\n", + "# TFW you flunk AI\n", + "\n", + "Here's another example that I had completely forgotten about until 2016, when I was cleaning out a filing cabinet and came across my old college transcript. It turns out that *I flunked an AI course!* (Or at least, didn't complete it.) This course was offered by Prof. Richard Millward in the Cognitive Science program. I certainly remember a lot of influential material from this class: we read David Marr, we read Winston's just-published *Psychology of Computer Vision*, we read a chapter from Duda and Hart which was then only a few years old. The things I learned in that course have stuck with me for decades, but one thing that didn't stick is that, according to my transcript, I never completed the course! I'm not sure what happened. I did an independent study with Ulf Grenander that semester; my best guess\n", + "is that when I started doing the independent study that would have put me over some limit, and so I had to drop the AI course. \n", + "\n", + "So in both the concordance program and the Cognitive Science AI class, I had a great experience and I learned a lot, even if it wasn't well-reflected in official credit. The moral is: look for the good experiences, and don't worry about the official credit.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pytudes/ipynb/Sudoku IPython Notebook.ipynb b/pytudes/ipynb/Sudoku IPython Notebook.ipynb new file mode 100644 index 0000000..6ca53a9 --- /dev/null +++ b/pytudes/ipynb/Sudoku IPython Notebook.ipynb @@ -0,0 +1,1275 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "\n", + " \n", + " \n", + " \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
Peter Norvig, Nov. 2016
\n", + "\n", + "# Solving Any Sudoku Puzzle, Quickly\n", + "\n", + "Sudoku is a logic puzzle game. Given a grid like the one on below left, fill in the blank squares so that each column, row, and 3x3 box contains all the digits from 1 to 9. The solution is shown below right:\n", + "\n", + "
\n", + "\n", + "In this notebook I develop and implement an algorithm to solve any\n", + "Sudoku puzzle, quickly. It turns out to be straightforward using two computer science ideas: constraint\n", + "satisfaction and search. \n", + "This notebook is an expansion of my\n", + "previous Sudoku essay; that\n", + "one emphasized simplicity; this one emphasizes\n", + "efficiency and covers everything in more detail.\n", + "\n", + "\n", + "\n", + "We will use these definitions:\n", + "\n", + "- A **grid** is a 9×9 array of **squares**. We can partition the grid\n", + "in three ways: \n", + " - as 9 rows (of size 9×1) stacked on top of\n", + "each other; \n", + " - as 9 columns (of size 1×9) placed left-to-right; \n", + " - as 9 boxes (of size 3×3) arranged in a 3×3 array.\n", + "- A **unit** is a row,\n", + "column, or box: a collection of 9 squares.\n", + "- A **puzzle** is a grid in which some squares have been\n", + "filled with a **digit** and some are **empty**. \n", + "- A **solution** is a grid where every unit contains\n", + "all the digits from 1 to 9, and the filled squares of the original puzzle remain unchanged\n", + "in the solution. \n", + "- A **well-formed puzzle** has exactly one solution.\n", + "- A **peer** of a square is any other\n", + "square in the same row, column, and box.\n", + "\n", + "## Sudoku data structures\n", + "\n", + "Here are the choices I made to implement these concepts. I represent a grid as an 81-element list, with the upper left square being element 0, then going right-to-left and top-to-bottom with the lower-right square being element 80." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "Grid = list # an 81-element list, left-to-right, top-to-bottom\n", + "Unit = tuple # a 9-element sequence\n", + "Square = int # an int from 0 to 80; index into a Grid\n", + "Digit = str # a character from '1' to '9'\n", + "Digits = str # One or more digits\n", + "empty = '.' # a square that has not been filled by a digit\n", + "\n", + "puzzle0 = Grid('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')\n", + "answer0 = Grid('534678912672195348198342567859761423426853791713924856961537284287419635345286179')\n", + "\n", + "def is_solution(solution: Grid, puzzle: Grid) -> bool: \n", + " \"\"\"A solution to a puzzle is a grid where every unit contains all the digits 1 to 9\n", + " and the filled squares of the original puzzle remain unchanged in the solution.\"\"\"\n", + " def unit_contents(unit): return {solution[s] for s in unit}\n", + " return (all(unit_contents(unit) == digits for unit in all_units) and\n", + " all(puzzle[s] == solution[s] for s in filled_squares(puzzle)))\n", + "\n", + "def filled_squares(grid):\n", + " \"All the squares in a grid that are already filled with a digit.\"\n", + " return (s for s in squares if grid[s] in digits)\n", + "\n", + "def empty_squares(grid):\n", + " \"All the squares in a grid that are not already filled with a digit.\"\n", + " return (s for s in squares if grid[s] not in digits)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Utility Functions and Displaying Grids\n", + "\n", + "Here is the code to set up all the units and peers and related data structures, alog with the imports and utility functions we will need later on, and code for displaying grids in a pretty fashion. Although we will mostly use 81-square grids, the function `use_grid_size(n)` can be used to work with `n`-square grids, where `n` can be 1, 16, 81, or 256." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import itertools\n", + "import time\n", + "from IPython.display import HTML, display\n", + "\n", + "def use_grid_size(n=81):\n", + " global N, D, B, digitstr, digits, squares, all_units, units, peers\n", + " N = n # Number of squares in the grid\n", + " D = isqrt(N) # Number of different digits\n", + " B = isqrt(D) # A boxis of size B x B\n", + " rows = range(0, N, D) # Squares at left of each row: (0, 9, 18, ... 72)\n", + " cols = range(D) # Squares at top of each column: (0, 1, 2, ... 8)\n", + " digitstr = '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_'[:D] # E.g., '123456789' for D=9\n", + " digits = set(digitstr) # E.g., {1, 2, 3, 4, 5, 6, 7, 8, 9} for D=9\n", + " squares = range(N) # Al1 the squares\n", + " all_rows = [cross(rows, [c]) for c in cols]\n", + " all_cols = [cross([r], cols) for r in rows]\n", + " all_boxes = [cross(rs, cs) for rs in chunk(rows, B) for cs in chunk(cols, B)]\n", + " all_units = all_rows + all_cols + all_boxes\n", + " units = [tuple(unit for unit in all_units if s in unit)\n", + " for s in squares]\n", + " peers = [tuple(union(units[s]) - {s})\n", + " for s in squares]\n", + "\n", + "def cross(rows, cols) -> Unit:\n", + " \"A unit of all the ways we can add one of the row numbers to one of the column numbers.\"\n", + " return Unit(r + c for r in rows for c in cols)\n", + "\n", + "def union(collections) -> set: \"Set union\"; return set().union(*collections)\n", + "\n", + "def isqrt(n) -> int: \"Integer square root.\"; return int(n ** 0.5)\n", + "\n", + "def chunk(sequence, B) -> list:\n", + " \"Chunk sequence into subsequences of length B.\"\n", + " return [sequence[i:i+B] for i in range(0, len(sequence), B)]\n", + "\n", + "def first(iterable) -> object: \n", + " \"Return the first item from iterable, or None.\"\n", + " return next(iterable, None)\n", + "\n", + "def show(grid):\n", + " \"Display the Sudoku grid.\"\n", + " use_grid_size(len(grid))\n", + " CSS = ''''''.replace('3', str(B))\n", + " table = '' + D * ('' + D * '
{}') + '
'\n", + " display(HTML(CSS + table.format(B, *grid)))" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(puzzle0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can how the numbering scheme for squares works; I'll display a grid that is filled, not with digits, but with square numbers. Then I'll show the units and peers for square 20:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
012345678
91011121314151617
181920212223242526
272829303132333435
363738394041424344
454647484950515253
545556575859606162
636465666768697071
727374757677787980
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(range(81))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((2, 11, 20, 29, 38, 47, 56, 65, 74),\n", + " (18, 19, 20, 21, 22, 23, 24, 25, 26),\n", + " (0, 1, 2, 9, 10, 11, 18, 19, 20))" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "units[20]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(0, 65, 2, 1, 9, 74, 11, 10, 18, 19, 21, 22, 23, 24, 25, 26, 29, 38, 47, 56)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "peers[20]" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
BBC......
BBC......
RRXrrrrrr
..c......
..c......
..c......
..c......
..c......
..c......
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# A grid where 'X' marks square 20, 'r' marks squares in same row, 'c' marks squares in same column,\n", + "# and capital letters, 'C', 'R', and 'B', mark squares in the same box.\n", + "show(Grid('BBC......BBC......RRXrrrrrr..c........c........c........c........c........c......'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need a test suite:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'pass'" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "puzzle0 = Grid('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')\n", + "answer0 = Grid('534678912672195348198342567859761423426853791713924856961537284287419635345286179')\n", + "wrong0 = Grid('532678912672195348198342567859761423426853791713924856961537284287419635345286179')\n", + "puzzle1 = Grid('4.7.6.8.5.3....9.....7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......')\n", + "answer1 = Grid('417369825632158947958724316825437169791586432346912758289643571573291684164875293')\n", + "wrong1 = Grid('427369825632158947958724316825437169791586432346912758289643571573291684164875293')\n", + "\n", + "def tests():\n", + " \"A suite of unit tests.\"\n", + " use_grid_size(81)\n", + " assert N == 81 and D == 9 and B == 3\n", + " assert len(squares) == 81\n", + " assert len(all_units) == 27\n", + " for s in squares:\n", + " assert len(units[s]) == 3 \n", + " assert len(peers[s]) == 20\n", + " assert union(['feed', 'beef', 'cafe', 'face']) == {'a', 'b', 'c', 'd', 'e', 'f'}\n", + " assert isqrt(16) == 4 and isqrt(81) == 9 and isqrt(256) == 16\n", + " assert cross((0, 9, 18), (0, 1, 2)) == (0, 1, 2, 9, 10, 11, 18, 19, 20)\n", + " assert chunk('abcdefghi', 3) == ['abc', 'def', 'ghi']\n", + " assert units[20] == ((2, 11, 20, 29, 38, 47, 56, 65, 74),\n", + " (18, 19, 20, 21, 22, 23, 24, 25, 26),\n", + " (0, 1, 2, 9, 10, 11, 18, 19, 20))\n", + " assert set(peers[20]) == {0, 1, 2, 9, 10, 11, 18, 19, 21, 22, \n", + " 23, 24, 25, 26, 29, 38, 47, 56, 65, 74}\n", + " assert is_solution(answer0, puzzle0)\n", + " assert not is_solution(wrong0, puzzle0)\n", + " assert is_solution(answer1, puzzle1)\n", + " assert not is_solution(wrong1, puzzle1)\n", + " return 'pass'\n", + "\n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solver 1: Generate and Test\n", + "\n", + "Here is a simple (but very inefficient) algorithm to solve Sudoku puzzles:\n", + "\n", + "> **Generate and test solver:**\n", + "First fill in all the\n", + "squares with digits. Then check to see if we have a\n", + "solution. If not, then fill the squares with a different\n", + "combination of digits. Repeat with different combinations until a solution is found.
\n", + "\n", + "\n", + "

Sometimes generate and test is the best you can do. Herb\n", + "Simon, in his classic book [The Sciences of\n", + "the Artificial](http://books.google.com/books?id=k5Sr0nFw7psC) (page 194), describes the task of opening a\n", + "safe that has ten dials, each with 100 numbers on it. If the safe is\n", + "well-designed there is no better approach than to generate-and-test\n", + "with all\n", + "10010 combinations. The generate-and-test solver is simple:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def solve(puzzle): \n", + " \"Find a solution to the puzzle.\"\n", + " return first(grid for grid in generate_all_grids(puzzle) \n", + " if is_solution(grid, puzzle))\n", + "\n", + "def generate_all_grids(grid):\n", + " \"An iterable of all possible ways to fill in grid.\"\n", + " values = [(digitstr if d is empty else d) for d in grid]\n", + " return itertools.product(*values)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
...4
4.3.
.4..
.241
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
2314
4132
1423
3241
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.210 seconds\n" + ] + } + ], + "source": [ + "def do1(puzzle):\n", + " \"Do one puzzle; showing puzzle and solution and printing elapsed time.\"\n", + " show(puzzle)\n", + " t0 = time.clock()\n", + " solution = solve(Grid(puzzle))\n", + " t1 = time.clock()\n", + " assert is_solution(solution, puzzle)\n", + " show(solution)\n", + " print('{:.3f} seconds'.format(t1 - t0))\n", + "\n", + "use_grid_size(16)\n", + "tiny = Grid('...44.3..4...241')\n", + "do1(tiny)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "That works fine for a 4x4 array. But on a 9x9, with say, 64 empty squares, there will be 964 combinations of digits.\n", + "Suppose we have access to a secret new custom 10 GHz\n", + "GPU capable of doing 1024 generate and\n", + "test operations in a single clock cycle, and let's say we can fit a million of these units\n", + "in a data center, and we could afford a hundred data centers,\n", + "and while we're shopping, let's say we also pick up a time\n", + "machine and go back 13 billion years to the early days of the universe,\n", + "and a fleet of starships with which we visit a trillion galaxies and\n", + "in each galaxy convince the inhabitants of a billion planets to each\n", + "buy a similar setup, and we all start our programs\n", + "running, managing to distribute the cases perfectly so that no\n", + "computation is duplicated or wasted. Then we can [estimate](http://www.google.com/search?aq=f&sourceid=chrome&ie=UTF-8&q=10+GHz+*+1024+*+1+million+*+100+*+1+trillion+*+1+billion+*+13+billion+years+%2F+9**64+in+percent)\n", + "that we'd be only 3% of the way through with the first puzzle.\n", + "\n", + "

Generate and test is not the algorithm you're looking for. Move along." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "# Solver 2: Combinatorial Search\n", + "\n", + "In Simon's safe example, he next supposes a defective safe, in which a\n", + "faint click is heard whenever a dial is set to the right position.\n", + "With this safe it only takes 100 × 10 trials to discover the\n", + "correct combination, not 10010. The moral is that if we have some selective\n", + "knowledge of components of the safe (or puzzle) that tell us if a\n", + "partial solution is on track, our search will be\n", + "much easier.\n", + "\n", + "

Fortunately for us, Sudoku is like the defective safe. To be\n", + "precise, it is like a safe with 81 dials, each with 9 numbers,\n", + "and sometimes if you put one of the dials in the wrong position you hear a sound,\n", + "but sometimes not (depending on the positions of the other dials and\n", + "on how carefully you listen). For\n", + "example, in the lower-left corner of the tiny puzzle above, if we try\n", + "1, 2, or 4 we would immediately get feedback that those digits won't\n", + "work, because they already appear elsewhere in the bottom row.\n", + "Therefore, the lower-left corner must be filled by a 3. There are\n", + "262,144 ways to fill in the 9 empty squares, but right away we can eliminate\n", + "196,608 of them; we need only consider the ones that have a 3 in that position.\n", + "\n", + "

Unfortunately for us, Sudoku does not give up all its secrets so\n", + "easily. Sometimes, when we consider a square, we can't immediately\n", + "tell what digit to put there. For example, in the upper-left of the tiny\n", + "puzzle, only 4 can be eliminated as a possibility. That's ok--we're\n", + "allowing ourselves the use of an eraser, so just guess one of the\n", + "remaining three possibilities; if it doesn't pan out, erase it and try one\n", + "of the others. This gives us:\n", + "\n", + "\n", + "

Combinatorial search algorithm: Start filling squares with digits, one at a time, always making sure\n", + "that the digit we put in a square is not the same as any peer. If there are several possible digits, pick one, but remember the others. If we\n", + "reach a square where every digit conflicts with a peer, back\n", + "up and consider a different digit for the previous square. Stop when\n", + "we successfully fill every square, or give up if we tried all\n", + "possibilities without finding a solution.
\n", + "\n", + "The progress of this algorithm can be described as a search\n", + "tree, where each node represents a partially-filled (incremental) state of the\n", + "puzzle, and a branch corresponds to filling in a square with a\n", + "digit. (We display the new digits in red.)\n", + "Here is a search tree for the tiny puzzle:\n", + "\n", + "
\n", + "\n", + "

A few things to note about this particular search tree:\n", + "

    \n", + "
  • Each successive level fills in one square, so with nine empty\n", + " squares, the solution must appear on the ninth level of the tree\n", + " (counting the root as the zeroth level).\n", + "
  • This is a well-formed puzzle, so there will be exactly one solution,\n", + " and thus exactly one node at the ninth level.\n", + "
  • A rectangle with a black X indicates an\n", + " inconsistency: there is no way to continue because the next\n", + " unfilled square\n", + " already has all four digits taken by its peers.\n", + "
  • When we hit a X we have to pull out our eraser, or in\n", + " other words we have to backtrack--go up a level in the tree and\n", + " try the next possible digit for the previous square. On the far-left\n", + " branch of the tree we have to back up three levels---erasing first the 2, then the 3, then the\n", + " 1--before we can pencil in another possible digit \n", + " (the 2 in the upper-left corner which we\n", + " see in the middle branch of the tree).\n", + " \n", + "
  • The rightmost branch of the tree remains unexplored--the search\n", + " proceeds left-to-right and has not got to that brnach yet. (But since the\n", + " puzzle is well-formed and we have found the solution, we know the\n", + " unexplored branches cannot contain another solution.)\n", + " \n", + "
\n", + "

The code to implement combinatorial search is straightforward:" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def search(grid) -> Grid:\n", + " \"\"\"Select an unfilled square, try each possible digit there, recursively searching.\n", + " When all squares filled: success; when no more digits to try: return None for failure.\"\"\"\n", + " square = select_empty_square(grid)\n", + " if square is None: # No empty square means the grid is a solution\n", + " return grid\n", + " for digit in possible_digits(grid, square):\n", + " result = search(assign(Grid(grid), square, digit))\n", + " if result: \n", + " return result\n", + "\n", + "solve = search\n", + "\n", + "def select_empty_square(grid) -> Square:\n", + " \"Return the first square that is not filled with a digit; or None if all squares are filled.\"\n", + " return (None if grid is None else first(empty_squares(grid)))\n", + "\n", + "def assign(grid, s, d) -> Grid:\n", + " \"For now, simply assign grid[s] = d.\"\n", + " grid[s] = d\n", + " return grid\n", + "\n", + "def possible_digits(grid, s):\n", + " \"A square can be filled with any digit that is not already taken by a peer.\"\n", + " peer_digits = {grid[s] for s in peers[s]}\n", + " return digits - peer_digits" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "The key function is search. It obeys the convention that if\n", + "it is passed Inconsistent (to indicate an invalid grid) it returns\n", + "Inconsistent, meaning that no solution can be found. Otherwise it\n", + "selects some unfilled square to work on. If select_square\n", + "returns None that is actually good news: it means that all\n", + "the squares are already filled, and we are done: we have a solution,\n", + "so we just return it. Otherwise, for each possible\n", + "digit that could fill square s we try to assign that digit to\n", + "s and search for a solution from there. If some call to\n", + "search succeeds, return it; but if a digit assignment causes\n", + "the search to fail, just keep going with the next digit assignment.\n", + "If all digit assignments fail, then the whole call to search\n", + "fails, and we back up to the previous recursive call. \n", + "\n", + "

We call this type of combinatorial search a constraint\n", + " satisfaction search: think of each square as being a\n", + " variable that can take on a value (a digit), and the\n", + " rules of Sudoku as being constraints on the possible values.\n", + " A state in the search tree is then an assignment of values to some\n", + " subset of variables in a way that does not violate any constraint.\n", + "The constraint satisfaction\n", + " approach has found many fun applications in puzzles and serious\n", + " applications in problem solving.\n", + "\n", + "

Here we see solve (and therefore search) in action:\n", + "\n", + "\n", + "\n", + "That's all there is to it! The only reason we don't stop this article\n", + "now is that the program is still too slow for some purposes. We're\n", + "not talking billions-of-years slow, but it did take 3 minutes and 45\n", + "seconds to solve this puzzle (a rather hard one). On a benchmark of\n", + "50 easy puzzles the program was fast enough, taking a total of 9.5\n", + "seconds (a rate of 5\n", + "puzzles per second, or 5 Hz). \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
534678912
672195348
198342567
859761423
426853791
713924856
961537284
287419635
345286179
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.024 seconds\n" + ] + } + ], + "source": [ + "do1(puzzle0)" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
4.7.6.8.5
.3....9..
...7.....
.2.....6.
....8.4..
....1....
...6.3.7.
5..2.....
1.4......
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
417369825
632158947
958724316
825437169
791586432
346912758
289643571
573291684
164875293
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "17.216 seconds\n" + ] + } + ], + "source": [ + "do1(puzzle1)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 63904089 function calls (62617098 primitive calls) in 30.046 seconds\n", + "\n", + " Ordered by: standard name\n", + "\n", + " ncalls tottime percall cumtime percall filename:lineno(function)\n", + " 52321162 8.946 0.000 8.946 0.000 :17(is_filled)\n", + " 1286992 0.444 0.000 20.602 0.000 :36(first)\n", + "1286992/1 3.380 0.000 30.046 30.046 :1(search)\n", + " 1286992 1.496 0.000 22.374 0.000 :14(select_empty_square)\n", + " 2573983 11.162 0.000 20.108 0.000 :17()\n", + " 1286991 0.238 0.000 0.238 0.000 :19(assign)\n", + " 1286991 1.272 0.000 4.055 0.000 :24(possible_digits)\n", + " 1286991 2.783 0.000 2.783 0.000 :26()\n", + " 1 0.000 0.000 30.046 30.046 :1()\n", + " 1 0.000 0.000 30.046 30.046 {built-in method builtins.exec}\n", + " 1286992 0.326 0.000 20.159 0.000 {built-in method builtins.next}\n", + " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", + "\n", + "\n" + ] + } + ], + "source": [ + "import cProfile\n", + "cProfile.run(\"solve(puzzle1)\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solver 3. Arc Consistency" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def solve(puzzle: Grid) -> Grid:\n", + " grid = Grid(digitstr if d is empty else d\n", + " for d in puzzle)\n", + " return search(grid)\n", + "\n", + "def possible_digits(grid, s) -> Digits: return grid[s]\n", + "\n", + "def assign(grid, s, d) -> Grid:\n", + " \"\"\"Assign grid[s] = d and eliminate d from the peers of s.\n", + " Return the updated grid, or Inconsistent if inconsistency detected.\"\"\"\n", + " if d not in grid[s]: return Inconsistent # d is not among the possibilities\n", + " grid[s] = d\n", + " if not all(eliminate(grid, p, d) for p in peers[s]): \n", + " return None\n", + " return grid\n", + "\n", + "def eliminate(grid, s, d) -> bool:\n", + " \"Remove d from possibilities for grid[s]. If checking finds an inconsistency return None.\"\n", + " if d not in grid[s]: \n", + " return True # Already eliminated d\n", + " grid[s] = grid[s].replace(d, '')\n", + " return all(constraint(grid, s, d) \n", + " for constraint in constraints)\n", + "\n", + "def arc_consistent(grid, s, d):\n", + " \"Return true if s has multiple digits left, or one that we can consistently assign.\"\n", + " ndigits = len(grid[s])\n", + " return ndigits >= 2 or (ndigits == 1 and assign(grid, s, grid[s]))\n", + "\n", + "constraints = [arc_consistent]" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
4.7.6.8.5
.3....9..
...7.....
.2.....6.
....8.4..
....1....
...6.3.7.
5..2.....
1.4......
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "TypeError", + "evalue": "'NoneType' object is not subscriptable", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdo1\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzle1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Should be 0.2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mdo1\u001b[0;34m(puzzle)\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0msolution\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mt1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0mis_solution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpuzzle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msolve\u001b[0;34m(puzzle)\u001b[0m\n\u001b[1;32m 2\u001b[0m grid = Grid(digitstr if d is empty else d\n\u001b[1;32m 3\u001b[0m for d in puzzle)\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mpossible_digits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mDigits\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msearch\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mdigit\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpossible_digits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdigit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msearch\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mdigit\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpossible_digits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdigit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msearch\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 2\u001b[0m \"\"\"Select an unfilled square, try each possible digit there, recursively searching.\n\u001b[1;32m 3\u001b[0m When all squares filled: success; when no more digits to try: return None for failure.\"\"\"\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0msquare\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mselect_empty_square\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msquare\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# No empty square means the grid is a solution\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mselect_empty_square\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mselect_empty_square\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"Return an unfilled square with the fewest possible digits; or None if no unfilled squares.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0munfilled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msquares\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0munfilled\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0munfilled\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mselect_empty_square\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"Return an unfilled square with the fewest possible digits; or None if no unfilled squares.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0munfilled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msquares\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0munfilled\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0munfilled\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: 'NoneType' object is not subscriptable" + ] + } + ], + "source": [ + "do1(puzzle1) # Should be 0.2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Benchmarking" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "puzzles = \"\"\"\n", + "4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......\n", + "52...6.........7.13...........4..8..6......5...........418.........3..2...87.....\n", + "6.....8.3.4.7.................5.4.7.3..2.....1.6.......2.....5.....8.6......1....\n", + "48.3............71.2.......7.5....6....2..8.............1.76...3.....4......5....\n", + "....14....3....2...7..........9...3.6.1.............8.2.....1.4....5.6.....7.8...\n", + "......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.\n", + "6.2.5.........3.4..........43...8....1....2........7..5..27...........81...6.....\n", + ".524.........7.1..............8.2...3.....6...9.5.....1.6.3...........897........\n", + "6.2.5.........4.3..........43...8....1....2........7..5..27...........81...6.....\n", + ".923.........8.1...........1.7.4...........658.........6.5.2...4.....7.....9.....\n", + "6..3.2....5.....1..........7.26............543.........8.15........4.2........7..\n", + ".6.5.1.9.1...9..539....7....4.8...7.......5.8.817.5.3.....5.2............76..8...\n", + "..5...987.4..5...1..7......2...48....9.1.....6..2.....3..6..2.......9.7.......5..\n", + "3.6.7...........518.........1.4.5...7.....6.....2......2.....4.....8.3.....5.....\n", + "1.....3.8.7.4..............2.3.1...........958.........5.6...7.....8.2...4.......\n", + "6..3.2....4.....1..........7.26............543.........8.15........4.2........7..\n", + "....3..9....2....1.5.9..............1.2.8.4.6.8.5...2..75......4.1..6..3.....4.6.\n", + "45.....3....8.1....9...........5..9.2..7.....8.........1..4..........7.2...6..8..\n", + ".237....68...6.59.9.....7......4.97.3.7.96..2.........5..47.........2....8.......\n", + "..84...3....3.....9....157479...8........7..514.....2...9.6...2.5....4......9..56\n", + "\"\"\".split()[5:6]\n", + "\n", + "benchmarks = {}\n", + "\n", + "def benchmark(label, puzzles=puzzles):\n", + " \"Run `solve` on these puzzles; record and verify results for this label; print all results.\"\n", + " n = len(puzzles)\n", + " t0 = time.clock()\n", + " results = [solve(Grid(p)) for p in puzzles]\n", + " avg = (time.clock() - t0) / len(puzzles)\n", + " for (r, p) in zip(results, puzzles):\n", + " assert is_solution(r, p) \n", + " benchmarks[label] = '{:.3f} sec/puzzle ({:.1f} Hz)'.format(avg, 1/avg)\n", + " for L in sorted(benchmarks):\n", + " print('{:10s} {}'.format(L, benchmarks[L]))" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(puzzles)" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3. AC 11.219 sec/puzzle (0.1 Hz)\n" + ] + } + ], + "source": [ + "benchmark('3. AC')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Dual Consistency" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def dual_consistent(grid, s, d):\n", + " \"\"\"After eliminating d from grid[s], check each unit of s and make sure there is some\n", + " position in the unit for d. If only one possible place left for d, assign it.\"\"\"\n", + " for u in units[s]:\n", + " places_for_d = [s2 for s2 in u if d in grid[s2]]\n", + " nplaces = len(places_for_d)\n", + " if nplaces==0 or (nplaces==1 and not assign(grid, places_for_d[0], d)):\n", + " return None\n", + " return True" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3. AC 11.219 sec/puzzle (0.1 Hz)\n", + "4. AC+Dual 26.392 sec/puzzle (0.0 Hz)\n" + ] + } + ], + "source": [ + "constraints = [arc_consistent, dual_consistent]\n", + "benchmark('4. AC+Dual')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# 5. Naked pairs" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def naked_pairs(grid, s, ignore):\n", + " \"\"\"Look for two squares in a unit with the same two possible digits. \n", + " For example, if s and s2 both have the value '35', then we know that 3 and 5\n", + " must go in those two squares. We don't know which is which, but we can eliminate \n", + " 3 and 5 from any other square s3 that is in the unit.\"\"\"\n", + " vals = grid[s]\n", + " if len(vals) != 2: return True\n", + " for u in units[s]:\n", + " for s2 in u:\n", + " if s2 != s and grid[s2] == vals:\n", + " # Found naked pair: s and s2; remove their two vals from others in unit\n", + " for s3 in u:\n", + " if s != s3 != s2:\n", + " if not all(eliminate(grid, s3, v) for v in vals):\n", + " return None\n", + " return True" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3. AC 11.219 sec/puzzle (0.1 Hz)\n", + "4. AC+Dual 26.392 sec/puzzle (0.0 Hz)\n", + "5. AC+D+NP 29.821 sec/puzzle (0.0 Hz)\n" + ] + } + ], + "source": [ + "constraints = [arc_consistent, dual_consistent, naked_pairs]\n", + "benchmark('5. AC+D+NP')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 6. Variable Ordering" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def select_empty_square(grid):\n", + " \"Return an unfilled square with the fewest possible digits; or None if no unfilled squares.\"\n", + " unfilled = [s for s in squares if len(grid[s]) > 1]\n", + " return min(unfilled, key=lambda s: len(grid[s])) if unfilled else None" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'NoneType' object is not subscriptable", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mbenchmark\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'6. VarOrd'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mbenchmark\u001b[0;34m(label, puzzles)\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzles\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 30\u001b[0;31m \u001b[0mresults\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0msolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mp\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpuzzles\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 31\u001b[0m \u001b[0mavg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzles\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresults\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpuzzles\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzles\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[0mt0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 30\u001b[0;31m \u001b[0mresults\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0msolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mp\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpuzzles\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 31\u001b[0m \u001b[0mavg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclock\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mt0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpuzzles\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresults\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpuzzles\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msolve\u001b[0;34m(puzzle)\u001b[0m\n\u001b[1;32m 2\u001b[0m grid = Grid(digitstr if d is empty else d\n\u001b[1;32m 3\u001b[0m for d in puzzle)\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mpossible_digits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mDigits\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msearch\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mdigit\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpossible_digits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdigit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msearch\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mdigit\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpossible_digits\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msearch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGrid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdigit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36msearch\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 2\u001b[0m \"\"\"Select an unfilled square, try each possible digit there, recursively searching.\n\u001b[1;32m 3\u001b[0m When all squares filled: success; when no more digits to try: return None for failure.\"\"\"\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0msquare\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mselect_empty_square\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msquare\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# No empty square means the grid is a solution\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgrid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mselect_empty_square\u001b[0;34m(grid)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mselect_empty_square\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"Return an unfilled square with the fewest possible digits; or None if no unfilled squares.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0munfilled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msquares\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0munfilled\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0munfilled\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mselect_empty_square\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"Return an unfilled square with the fewest possible digits; or None if no unfilled squares.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0munfilled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msquares\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0munfilled\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrid\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0munfilled\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: 'NoneType' object is not subscriptable" + ] + } + ], + "source": [ + "benchmark('6. VarOrd')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "

However, if you want to solve a million hard puzzles, you probably\n", + "don't want to wait a few years, and you would prefer a\n", + "faster algorithm.\n", + "Look again at the search tree above, and consider how we can find the\n", + "solution faster. Here are four general strategies:\n", + "

    \n", + "
  1. We could try to move the solution to the left. Since we go top-down,\n", + " left-to-right, this means we would find it sooner. This can\n", + " potentially be done with better value ordering, the order in\n", + " which the function possible_values considers which digit to\n", + " try next. If we were able to choose right every time,\n", + " there would in effect be no search--the solution would be in the\n", + " lower-left corner of the tree and we would arrive at it directly\n", + " with no backtracking.\n", + "
  2. We could try to move the solution closer to the top. If we only\n", + " fill in one square at a time then the solution will always be at the\n", + " same level (the number of empty squares in the original puzzle).\n", + " But if we could fill in several squares at a time, the solution gets\n", + " closer to the top and we can find it faster. Filling in multiple\n", + " squares at a time can be accomplished with constraint\n", + " propagation--using the constraints imposed by the rules of Sudoku to\n", + " conclude that an unfilled square must take on a certain digit,\n", + " thus sanctioning us to fill in several squares at once.\n", + "
  3. We could prune branches (mark them with an X and backtrack)\n", + " earlier. This can also be done with\n", + " constraint propagation, but in this case rather than filling in\n", + " squares, we would notice that some\n", + " square has no possible digit, and thus that we can backtrack immediately.\n", + "
  4. We could consider the squares in a better order, a process called\n", + " variable ordering, which in our program is implemented by the\n", + " function select_square. At each node in\n", + " the tree we pick one square to branch on. The current\n", + " implementation of select_square just considers the squares\n", + " in order from 0 to 80 and chooses the first unfilled one, but it\n", + " could be more clever. A\n", + " different ordering could be better (or worse) for any of the three reasons above.\n", + "
" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/TSP.ipynb b/pytudes/ipynb/TSP.ipynb new file mode 100644 index 0000000..7e75acb --- /dev/null +++ b/pytudes/ipynb/TSP.ipynb @@ -0,0 +1,4651 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Traveling Salesperson Problem" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consider the [*Traveling Salesperson Problem*](http://en.wikipedia.org/wiki/Traveling_salesman_problem): \n", + "\n", + "> *Given a set of cities and the distances between each pair of cities, what is the shortest possible tour that visits each city exactly once, and returns to the starting city?*\n", + "\n", + "In this notebook we will develop some solutions to the problem, and more generally show *how to think about* solving a problem like this. [Elsewhere](https://research.googleblog.com/2016/09/the-280-year-old-algorithm-inside.html) you can read about how the algorithms developed here are used in serious applications that millions of people rely on every day.\n", + "\n", + "\n", + "
An example tour.
\n", + " \n", + "# Understanding What We're Talking About (Vocabulary)\n", + "\n", + "Do we understand precisely what the problem is asking? Do we understand all the concepts that the problem talks about? Do we understand them well enough to implement them in a programming language? Let's take a first pass:\n", + "\n", + "- **A set of cities**: We will need to represent a set of cities; Python's `set` datatype might be appropriate.\n", + "- **Distance between each pair of cities**: If `A` and `B` are cities, this could be a function, `distance(A, B),` or a table lookup, `distance[A][B]`. The resulting distance will be a real number.\n", + "- **City**: All we have to know about an individual city is how far it is from other cities. We don't have to know its name, population, best restaurants, or anything else. So a city could be just an integer (0, 1, 2, ...) used as an index into a distance table, or a city could be a pair of (x, y) coordinates, if we are using straight-line distance on a plane.\n", + "- **Tour**: A tour is a specified order in which to visit the cities; Python's `list` or `tuple` datatypes would work. For example, given the set of cities `{A, B, C, D}`, a tour might be the list `[B, D, A, C]`, which means to travel from `B` to `D` to `A` to `C` and finally back to `B`.\n", + "- **Shortest possible tour**: The shortest tour is the one whose tour length is the minimum of all tours.\n", + "- **Tour length**: The sum of the distances between adjacent cities in the tour (including the last city back to the first city). Probably a function, `tour_length(tour)`.\n", + "- **What is ...**: We can define a function to answer the question *what is the shortest possible tour?* The function takes a set of cities as input and returns a tour as output. I will use the convention that any such function will have a name ending in the letters \"`tsp`\", the traditional abbreviation for Traveling Salesperson Problem.\n", + "\n", + "At this stage I have a rough sketch of how to attack the problem. I don't have all the answers, and I haven't committed to specific representations for all the concepts, but I know what all the pieces are, and I don't see anything that stops me from proceeding." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are the imports used throughout this notebook. I'm assuming Python 3." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import random\n", + "import time\n", + "import itertools\n", + "import urllib\n", + "import csv\n", + "import functools\n", + "from statistics import mean, stdev" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# All Tours Algorithm: `alltours_tsp`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's start with an algorithm that is guaranteed to solve the problem, although it is inefficient for large sets of cities:\n", + "\n", + "> **All Tours Algorithm**: *Generate all possible tours of the cities, and choose the shortest tour (the one with minimum tour length).*\n", + "\n", + "My design philosophy is to first write an English description of the algorithm, then write Python code that closely mirrors the English description. This will probably require some auxiliary functions and data structures; just assume they exist; put them on a TO DO list, and eventually define them with the same design philosophy.\n", + "\n", + "Here is the start of the implementation:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def alltours_tsp(cities):\n", + " \"Generate all possible tours of the cities and choose the shortest tour.\"\n", + " return shortest_tour(alltours(cities))\n", + "\n", + "def shortest_tour(tours): \n", + " \"Choose the tour with the minimum tour length.\"\n", + " return min(tours, key=tour_length)\n", + "\n", + "# TO DO: Data types: cities, tours, Functions: alltours, tour_length" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**: In Python `min(`*collection*`,key=`*function*`)` means to find the element *x* that is a member of *collection* such that *function(x)* is minimized. So `shortest` finds the tour whose `tour_length` in the minimal among the tours. \n", + "\n", + "This gives us a good start; the Python code closely matches the English description. And we know what we need to do next: represent cities and tours, and implement the functions `alltours` and `tour_length`. Let's start with tours.\n", + "\n", + "\n", + "Representing Tours\n", + "------------------\n", + "\n", + "A tour starts in one city, and then visits each of the other cities in order, before returning to the start city. A natural representation of a tour is a sequence of cities. For example `(1, 2, 3)` could represent a tour that starts in city 1, moves to 2, then 3, and finally returns to 1. \n", + "\n", + "**Note**: I considered using `(1, 2, 3, 1)` as the representation of this tour. I also considered an ordered list of **edges** between cities: \n", + "`((1, 2), (2, 3), (3, 1))`. In the end, I decided `(1, 2, 3)` was simplest.\n", + " \n", + "\n", + "Now for the `alltours` function. If a tour is a sequence of cities, then all the tours are *permutations* of the set of all cities. A function to generate all permutations of a set is already provided in Python's standard `itertools` library module; we can use it as our implementation of `alltours`:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "alltours = itertools.permutations " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For *n* cities there are *n*! (that is, the factorial of *n*) permutations.\n", + "Here's are all 3! = 6 tours of 3 cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cities = {1, 2, 3}\n", + "\n", + "list(alltours(cities))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The length of a tour is the sum of the lengths of each edge in the tour; in other words, the sum of the distances between consecutive cities in the tour, including the distance form the last city back to the first:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def tour_length(tour):\n", + " \"The total of distances between each pair of consecutive cities in the tour.\"\n", + " return sum(distance(tour[i], tour[i-1]) \n", + " for i in range(len(tour)))\n", + "\n", + "# TO DO: Functions: distance, Data types: cities" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**: I use one Python-specific trick: when `i` is 0, then `distance(tour[0], tour[-1])` gives us the wrap-around distance between the first and last cities, because `tour[-1]` is the last element of `tour`. \n", + "\n", + "Representing Cities\n", + "--------------------------------\n", + "\n", + "We determined that the only thing that matters about cities is the distance between them. But before we can decide about how to represent cities, and before we can define `distance(A, B)`, we have to make a choice. In the fully general version of the TSP, the \"distance\" between two cities could be anything: it could factor in the amount of time it takes to travel between cities, the twistiness of the road, or anything else. The `distance(A, B)` might be different from `distance(B, A)`. So the distances could be represented by a matrix `distance[A][B]`, where any entry in the matrix could be any (non-negative) numeric value.\n", + " \n", + "But we will ignore the fully general TSP and concentrate on an important special case, the **Euclidean TSP**, where the distance between any two cities is the [Euclidean distance](http://en.wikipedia.org/wiki/Euclidean_distance), the straight-line distance between points in a two-dimensional plane. So a city can be represented by a two-dimensional point: a pair of *x* and *y* coordinates. We will use the constructor function `City`, so that `City(300, 0)` creates a city with x-coordinate of 300 and y coordinate of 0. Then `distance(A, B)` will be a function that uses the *x* and *y* coordinates to compute the distance between `A` and `B`.\n", + "\n", + "Representing Points and Computing `distance`\n", + "---\n", + " \n", + "OK, so a city can be represented as just a two-dimensional point. But how will we represent points? Here are some choices, with their pros and cons:\n", + "\n", + "* **tuple:** A point is a two-tuple of (*x*, *y*) coordinates, for example, `(300, 0)`. **Pro:** Very simple. \n", + "**Con:** doesn't distinguish Points from other two-tuples. \n", + " \n", + "* **class:** Define a custom `Point` class with *x* and *y* slots. **Pro:** explicit, gives us `p.x` and `p.y` accessors. **Con:** less efficient.\n", + " \n", + "* **complex:** Python already has the two-dimensional point as a built-in numeric data type, but in a non-obvious way: as `complex` numbers, which inhabit the two-dimensional (real × imaginary) plane. **Pro:** efficient. **Con:** a little confusing; doesn't distinguish Points from other complex numbers.\n", + "* **subclass of complex:** All the pros of `complex`, and eliminating the major con.\n", + "\n", + "\n", + "Any of these choices would work perfectly well; I decided to use a subclass of `complex`:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Cities are represented as Points, which are a subclass of complex numbers\n", + "\n", + "class Point(complex):\n", + " x = property(lambda p: p.real)\n", + " y = property(lambda p: p.imag)\n", + " \n", + "City = Point\n", + "\n", + "def distance(A, B): \n", + " \"The distance between two points.\"\n", + " return abs(A - B)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here's an example of computing the distance between two cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "5.0" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A = City(3, 0)\n", + "B = City(0, 4)\n", + "distance(A, B)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Random Sets of Cities\n", + "---\n", + "\n", + "The input to a TSP algorithm should be a set of cities. I can make a random set of *n* cities by calling `City` *n* times, each with different random *x* and *y* coordinates:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{(193+375j), (427+384j), (497+585j), (179+546j), (224+543j), (245+643j)}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{City(random.randrange(1000), random.randrange(1000)) for c in range(6)}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The function `Cities` does that (and a bit more):" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def Cities(n, width=900, height=600, seed=42):\n", + " \"Make a set of n cities, each with random coordinates within a (width x height) rectangle.\"\n", + " random.seed(seed * n)\n", + " return frozenset(City(random.randrange(width), random.randrange(height))\n", + " for c in range(n))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are three complications that I decided to tackle in `Cities`:\n", + "\n", + "1. IPython's matplotlib plots (by default) in a rectangle that is 1.5 times wider than it is high; that's why I specified a width of 900 and a height of 600. If you want the coordinates of your cities to be bounded by a different size rectangle, you can change width or height.\n", + "\n", + "2. Sometimes I want `Cities(n)` to be a true function, returning the same result each time. This is very helpful for getting repeatable results: if I run a test twice, I get the same results twice. \n", + "But other times I would like to be able to do an experiment, where, for example, I call `Cities(n)` 30 times and get 30 different sets, and I then compute the average tour length produced by my algorithm across these 30 sets. Can I get both behaviors out of one function? *Yes!* The trick is the additional optional parameter, `seed`. Two calls to `Cities` with the same `n` and `seed` parameters will always return the same set of cities, and two calls with different values for `seed` will return different sets. This is implemented by calling the function `random.seed`, which resets the random number generator.\n", + "\n", + "3. Once I create a set of Cities, I don't want anyone messing with my set. For example, I don't want an algorithm that claims to \"solve\" a problem by deleting half the cities from the input set, then finding a tour of the remaining cities. Therefore, I make `Cities` return a `frozenset` rather than a `set`. A `frozenset` is *immutable*; nobody can change it once it is created. (Likewise, each city is immutable.)\n", + "\n", + "For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "frozenset({(172+20j), (234+40j), (696+415j), (393+7j), (671+296j)})" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# A set of 5 cities\n", + "Cities(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[frozenset({(172+20j), (234+40j), (696+415j), (393+7j), (671+296j)}),\n", + " frozenset({(172+20j), (234+40j), (696+415j), (393+7j), (671+296j)}),\n", + " frozenset({(172+20j), (234+40j), (696+415j), (393+7j), (671+296j)})]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The exact same set of 5 cities each time\n", + "[Cities(5) for i in range(3)]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[frozenset({(414+310j), (776+430j), (41+265j), (864+394j), (523+497j)}),\n", + " frozenset({(814+542j), (29+476j), (637+261j), (759+367j), (794+255j)}),\n", + " frozenset({(439+494j), (211+473j), (585+33j), (832+503j), (591+15j)})]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# A different set of 5 cities each time\n", + "[Cities(5, seed=i) for i in range(3)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we are ready to apply the `alltours_tsp` function to find the shortest tour:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "((6+546j),\n", + " (199+147j),\n", + " (350+65j),\n", + " (737+26j),\n", + " (847+187j),\n", + " (891+465j),\n", + " (554+374j),\n", + " (505+548j))" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alltours_tsp(Cities(8))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2509.307587720301" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tour_length(alltours_tsp(Cities(8)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quick, is that the right answer? I have no idea, and you probably can't tell either. But if we could *plot* the tour we'd understand it better and might be able to see at a glance if the tour is optimal.\n", + "\n", + "Plotting Tours\n", + "---\n", + "\n", + "I define `plot_tour(tour)` to plot the cities (as circles) and the tour (as lines):" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def plot_tour(tour): \n", + " \"Plot the cities as circles and the tour as lines between them.\"\n", + " plot_lines(list(tour) + [tour[0]])\n", + " \n", + "def plot_lines(points, style='bo-'):\n", + " \"Plot lines to connect a series of points.\"\n", + " plt.plot([p.x for p in points], [p.y for p in points], style)\n", + " plt.axis('scaled'); plt.axis('off')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nRK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_tour(alltours_tsp(Cities(8)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks much better! To me, it looks like the shortest possible tour, although I don't have an easy way to prove it. Let's go one step further and define a function, `plot_tsp(algorithm, cities)` that will take a TSP algorithm (such as `alltours_tsp`) and a set of cities, apply the algorithm to the cities to get a tour, check that the tour is reasonable, plot the tour, and print information about the length of the tour and the time it took to find it:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def plot_tsp(algorithm, cities):\n", + " \"Apply a TSP algorithm to cities, plot the resulting tour, and print information.\"\n", + " # Find the solution and time how long it takes\n", + " t0 = time.clock()\n", + " tour = algorithm(cities)\n", + " t1 = time.clock()\n", + " assert valid_tour(tour, cities)\n", + " plot_tour(tour); plt.show()\n", + " print(\"{} city tour with length {:.1f} in {:.3f} secs for {}\"\n", + " .format(len(tour), tour_length(tour), t1 - t0, algorithm.__name__))\n", + " \n", + "def valid_tour(tour, cities):\n", + " \"Is tour a valid tour for these cities?\"\n", + " return set(tour) == set(cities) and len(tour) == len(cities)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nRK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 city tour with length 2509.3 in 0.110 secs for alltours_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(alltours_tsp, Cities(8))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## All Non-Redundant Tours Algorithm (improved `alltours_tsp`)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We said there are *n*! tours of *n* cities, and thus 6 tours of 3 cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(alltours({1, 2, 3}))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this is redundant: `(1, 2, 3)`, `(2, 3, 1)`, and `(3, 1, 2)` are three ways of describing the same tour. So let's arbitrarily say that all tours must start with the first city in the set of cities. We'll just pull the first city out, and then tack it back on to all the permutations of the rest of the cities. \n", + "\n", + "While we're re-assembling a tour from the start city and the rest, we'll take the opportunity to construct the tour as a *list* rather than a *tuple*. It doesn't matter much now, but later on we will want to represent *partial* tours, to which we will want to append cities one by one; appending can only be done to lists, not tuples." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def alltours(cities):\n", + " \"Return a list of tours, each a permutation of cities, but each one starting with the same city.\"\n", + " start = first(cities)\n", + " return [[start] + Tour(rest)\n", + " for rest in itertools.permutations(cities - {start})]\n", + "\n", + "def first(collection):\n", + " \"Start iterating over collection, and return the first element.\"\n", + " return next(iter(collection))\n", + "\n", + "Tour = list # Tours are implemented as lists of cities" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can verify that for 3 cities there are now only 2 tours (not 6) and for 4 cities there are 6 tours (not 24):" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[1, 2, 3], [1, 3, 2]]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alltours({1, 2, 3})" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[1, 2, 3, 4],\n", + " [1, 2, 4, 3],\n", + " [1, 3, 2, 4],\n", + " [1, 3, 4, 2],\n", + " [1, 4, 2, 3],\n", + " [1, 4, 3, 2]]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alltours({1, 2, 3, 4})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note:** We could say that there is only one tour of three cities, because `[1, 2, 3]` and `[1, 3, 2]` are in some sense the same tour, one going clockwise and the other counterclockwise. However, I choose not to do that, for two reasons. First, it would mean we can never handle TSP problems where the distance from A to B is different from B to A. Second, it would complicate the code (if only by a line or two).\n", + "\n", + "We can verify that calling `alltours_tsp(Cities(8))` still works and gives the same tour with the same total distance. But it now runs faster:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\ngg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 city tour with length 2509.3 in 0.018 secs for alltours_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(alltours_tsp, Cities(8))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's try a much harder 10-city tour:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2291.8 in 1.636 secs for alltours_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(alltours_tsp, Cities(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Complexity of `alltours_tsp`\n", + "---\n", + "\n", + "It takes about 2 seconds on my machine to solve this 10-city problem. In general, the function `TSP` looks at (*n*-1)! tours for an *n*-city problem, and each tour has *n* cities, so the total time required for *n* cities should be roughly proportional to *n*!. This means that the time grows rapidly with the number of cities. *Really* rapidly. This table shows the actual time for solving a 10 city problem, and the exepcted time for solving larger problems:\n", + "\n", + "\n", + "
n expected time for `alltours_tsp(Cities(n))`\n", + "
10Covering 10! tours = 2 secs\n", + "
112 secs × 11! / 10! ≈ 22 secs\n", + "
122 secs × 12! / 10! ≈ 4 mins\n", + "
142 secs × 14! / 10! ≈ 13 hours\n", + "
162 secs × 16! / 10! ≈ 200 days\n", + "
182 secs × 18! / 10! ≈ 112 years\n", + "
252 secs × 25! / 10! ≈ 270 billion years\n", + "
\n", + "\n", + "There must be a better way ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Approximate Algorithms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What if we are willing to settle for a tour that is short, but not guaranteed to be shortest? Then we can save billions of years of compute time: we will show several *approximate* algorithms, which find tours that are typically within 10% of the shortest possible tour, and can handle thousands of cities in a few seconds. (**Note:** There are more sophisticated approximate algorithms that can handle hundreds of thousands of cities and come within 0.01% or better of the shortest possible tour.)\n", + "\n", + "So how do we come up with an approximate algorithm? Here are two general plans of how to create a tour:\n", + "\n", + "* **Nearest Neighbor Algorithm**: Make the tour go from a city to its nearest neighbor. Repeat.\n", + "* **Greedy Algorithm**: Find the shortest distance between any two cities and include that edge in the tour. Repeat.\n", + "\n", + "We will expand these ideas into full algorithms.\n", + "\n", + "In addition, here are four very general strategies that apply not just to TSP, but to any optimization problem. An **optimization problem** is one in which the goal is to find a solution that is best (or near-best) according to some metric,\n", + "out of a pool of many candidate solutions. The strategies are:\n", + "\n", + "* **Repetition Strategy**: Take some algorithm and re-run it multiple times, varying some aspect each time, and take the solution with the best score.\n", + "* **Alteration Strategy**: Use some algorithm to create a solution, then make small changes to the solution to improve it.\n", + "* **Ensemble Strategy**: Take two or more algorithms, apply all of them to the problem, and pick the best solution.\n", + "\n", + "And here are two more strategies that work for a wide variety of problems:\n", + "\n", + "* **Divide and Conquer**: Split the input in half, solve the problem for each half, and then combine the two partial solutions.\n", + "\n", + "* **Stand on the Shoulders of Giants** *or* **Just Google It**: Find out what others have done in the past, and either copy it or build on it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Nearest Neighbor Algorithm: `nn_tsp`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a description of the nearest neighbor algorithm:\n", + "\n", + "> **Nearest Neighbor Algorithm:** *Start at any city; at each step extend the tour by moving from the previous city to its nearest neighbor that has not yet been visited.*\n", + "\n", + "So now, instead of considering all *n*! tours, we are generating a single tour. It takes O(*n*2 ) time to find the tour, because it has *n*-1 steps, and at each step we consider each of the remaining cities.\n", + "I implement the algorithm as follows:\n", + "\n", + "* \"*Start at any city*\": arbitrarily pick the first city. \n", + "* \"*extend the tour*\": append to the end of a list of cities.\n", + "* \"*by moving from the previous city*\": previous city is `tour[-1]`.\n", + "* \"*to its nearest neighbor*\": I will define the function `nearest_neighbor`.\n", + "* \"*that has not yet been visited*\": I will keep a set of `unvisited` cities.\n", + "\n", + "That gives us:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def nn_tsp(cities):\n", + " \"\"\"Start the tour at the first city; at each step extend the tour \n", + " by moving from the previous city to the nearest neighboring city, C,\n", + " that has not yet been visited.\"\"\"\n", + " start = first(cities)\n", + " tour = [start]\n", + " unvisited = set(cities - {start})\n", + " while unvisited:\n", + " C = nearest_neighbor(tour[-1], unvisited)\n", + " tour.append(C)\n", + " unvisited.remove(C)\n", + " return tour\n", + "\n", + "def nearest_neighbor(A, cities):\n", + " \"Find the city in cities that is nearest to city A.\"\n", + " return min(cities, key=lambda c: distance(c, A))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note:** In Python, as in the formal mathematical theory of computability, `lambda` (or λ) is the symbol for *function*, so \"`lambda c: distance(c, A)`\" means the function of `c` that computes the distance from `c` to the city `A`. \n", + "\n", + "We can compare the the slow (but optimal) `alltours_tsp` algorithm to the new fast (but approximate) `nn_tsp` algorithm:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2291.8 in 1.681 secs for alltours_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(alltours_tsp, Cities(10))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2381.4 in 0.000 secs for nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(nn_tsp, Cities(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So the nearest neighbor algorithm is a lot faster, but it didn't find the shortest tour. To understand where it went wrong, it would be helpful to know what city it started from. I can modify `plot_tour` by adding one line of code to highlight the start city with a red square:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def plot_tour(tour):\n", + " \"Plot the cities as circles and the tour as lines between them. Start city is red square.\"\n", + " start = tour[0]\n", + " plot_lines(list(tour) + [start])\n", + " plot_lines([start], 'rs') # Mark the start city with a red square" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAVgAAAEACAYAAAD2sW7aAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAG2dJREFUeJzt3XmUnVWVxuHfhkCAkAIFY1IMBgIhiYWiNmqjoEhoENCg\nKGiDtiLSiGADLYhQiC4rIEPbilOM6FIZbbUFGSMRBAVFcGgoSBhCgmAlAUEIKRkM7v7jnErd1L1V\nqeF+93zD+6yVVasqSd0dMW++u885+5i7IyIizbdB6gJERMpKASsikhEFrIhIRhSwIiIZUcCKiGRE\nASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhIRhSwIiIZ\nUcCKiGREASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhI\nRhSwIiIZUcCKiGREASsikhEFrIhIRhSwIiIZGZe6gMH8s9n8SbD7M2w+wxk/znh+zURWL34M7vi1\n+9Gp6xMRWZ/cBuwk2P1K2A1WE34wDthtTtqyRESGLbctgmfYfMZIvi4ikje5DVhnfMOn68G+LiKS\nN7kNWOP5NSP5uohI3uQ2YCeyevFIvi4ikje5fbv9GNwxB3iGiTP/wabjjRfWtPFU92NwR+raRESG\nw9w9dQ1DMmMH4CHgSncOTl2PiMhw5bZFUGPj+HFm0ipEREaoKAF7P/AKs7VhKyKSe0UI2PGEkwYP\nAzsnrkVEZNiKELAbAy8Ai1CbQEQKpCgB+zxwLwpYESmQIgTsePQEKyIFVISAVYugwMzapprtcbHZ\nITeGj21TU9ck0iq5PWhQo69FsBiYbsYG7vwjcU0yDCFM5yyEedNgAtALHPNGs7bZ7quWpa1OJHtF\neIIdD7zgzmrgCeAVieuRYevo6g9XCB/nTQtfFym/IgRs3xMsqE1QMFPa+8O1zwRgcnuKakRarQgB\n27fIBQrYglneE9oCtXqBFT0pqhFptSIEbN8iFyhgC6bnTDj9+f6Q7QWOWQLdnSmrEmmVIi1yQQjY\nDyasRUZk2SGw6A7Y9+HQFtj5VXDoee4XLUtdmUgrFCFg61oEZpg7+R4DVnFm7AScAjNf737bQ/Fr\nc4AzzZiv/35SBYVqEbjzOPAP4OVJK5IhmWHAfOAsdx6q+amrCP+oH5CkMJEWK0rAPl/zufqw+Xck\nsDnw5dovxv3LXcAZMYRFSq0IAVvbIgAFbK6ZMQU4GzjKnRcb/JIfA1sC+7S0MJEEihCwtbsIQAGb\nd18F5rtzV6OfjKE7FzijpVWJJFCUgFWLoADMeDfwSkIbYCiXAduasVf2VYmkU4SAVYugAMzYEvgK\n8FF3nhvq17qzhtBG0H5YKbUiBOzAFsEjwBZmbJGoHmnsXOCn7vxymL/++8AMM96QYU0iSRUlYNe2\nCOJK9H3AjGQVyTrMeCvwduBTw/097rwAnIOeYqXEihCwA1sEoDZBbpixKfAt4OPurBrhb/828Doz\nXtP8ykTSK0LADmwRgAI2T84Efu/OT0f6G2Ov9nzg9KZXJZIDRQjY8ay7iwAUsLlgxmsJhwo+MYZv\n801gTzNe2ZyqRPKjCAGrJ9gcMmMccCFwijsrR/t93OkFvgSc1qzaRPKiqAH7ILCdGZskqEeCk4C/\nAN9rwvf6GvAvZuzchO8lkhtFCNi6FoE7fweWgv5CptA/KYt/b8ZUrLg49jXg02P9XiJ5UoSAbfQE\nC2oTJDFgUtbSJn7rC4A5Zkxt4vcUSaooATtwkQsUsKl8hAaTssbKnScJwT3svbQieVeEgG20DxYU\nsC0XJ2WdxeCTssbqi8BhZmyTwfcWabkiBKxaBPkx5KSssYoD1b8LnJzF9xdpNXPP980dZqwCth14\nSsiMCcDjwMSMnqakRpyUdRaw2/qGuYzxddqBbmDmWLZ/ieRBEZ5gG7YI4v7Jx0GLIlkbyaSssXKn\nhzDO8KQsX0ekFXIdsHHFerAWAahN0CrnAleOYFLWWJ0DHGXGVi16PZFM5DpgCRfkrYkTtBpRwGas\nZlLWqa16TXf+BPwv8B+tek2RLOQ9YAfbQdBHAZuhMU7KGqsvAMdq7q8UWd4Ddqj2AChgszbqSVlj\n5c4S4FrguFa/tkiz5HoXQdx3+Qd3Jg/y81sBS4CXNOPIpoBZ21To6IJp02HqrvD4nu7z7kxTCzOA\nW4Ad3VmdogaRsSj0E6w7T8SfbxjAMjIhXOcshBsOh4t2h1M3gd7Lw9dbz53FwE3Ax1K8vshYFTpg\no0XArBbUUgG7dsG8aTAhfj6B8HnH+m6JzdJc4KTYDxYplLwHbKNh2wOpDztGZmxmxsfgLe/qD9c+\nE4DJ7SnqAoinxm4HPpqqBpHRynvADvcJVgE7Cma0mzEXeBjYDxbfCr0DflUvsKKn9dWtows4xYzx\niesQGREFbAWZsZsZ3yMcSW0D/tmdg2Hh0XDMkv6Q7SV83p305ld37gTuBj6Usg6RkRqXuoD1UIug\nSczYADiAcAR1OuHo6wnu/LXv17ivWmbWNhuWdIW2wIoe6O50X7UsTdXr6AIuNuM7ceC6SO7lPWCH\n8wT7KLC5GVu681QLaioUMzYD/g04AVgN/Bfww8FCKobpES0rcJjcudWMpcDhhIlbIrlX+BZB3P+6\nGD3FrqO+v8pHgX9y59ICPwF2AaeZsWHqQkSGI+8BO5wWAahNsNZg/VV3binBYYybCBPUDk1diMhw\n5D1gh9MigIoHrBkbmHGQGTcCVwP3AtPcOd6dBxOX1zTxH4jPA6fHnrJIruX9/6TrG/bSp5IB279/\nlUXA54ALgR3cOad28apkFgDPAgenLkRkffIesINdeDhQpQK2pP3VYYlPsV1AZ5wXLJJbRQjY4TzB\nLgHay36csuT91ZG4irAD5oDUhYgMJbcBGwaMHHkkfOIgsz0uHmrgiDtrgIcI+ztLpSr91ZGIA9i7\ngDP0FCt5lstxhf1TnfoGj/SdKLpy9mCb3s34EfAjdy5vYamZGen+1aqJW7XuAY5zZ2HqekQayekT\nbMdopjqVog9b5f7qSMSbhOcCZ6SuRWQwOQ3YKe2Npzrt9kYzOgZ5W1jogFV/dVQuA7Y1Y6/UhYg0\nktOAXd7TeKoTLxIWOB42Y54Z7zBbm8SFC1j1V8cm9t7PBpIOoxEZTOF6sLDqYWAGYQX5AOD1wG3A\nL4CzgI3iX7zcUn+1eczYGHgQeK87t6euR6RWLgMWau+GGnqqkxltwGxC2H4kfvnLhAvzbnYf1j7a\nljCjHfg4cDRwK/BF4JdqAYyNGR8H9nfnHalrEamV24AdDTOuA35NaCUcAHQQnmyvBa5z50+J6toN\nOBF4B3AJ8GW1AJrHjE0I2/QOdOcPqesR6ZPTHuyo3Qs8785cd94E7AhcDuwJ/N6Mu834ghl7mbFR\nloWov9o67jwHnA+cnroWkVple4I9Cnize/3k+7hvcnfCk+2BhPC9AbgGuN6dlU2qQf3VBOJi50PA\n29y5J3U9IlC+gH0T8EV33jCMXzsF2J8QuLMJCyXXEgL3znhaaCSvrf5qYmZ8Guhw5/DUtYhA+QL2\npcBSYMuRBFtsF7yJ/p0Jk4DrCYG7oG8yVf/C25T2sJWsuxNWbYn6q7kQFzyXAHu480DqekRKFbAA\nZqwEXuvOn8fwPaYCbyeE7VuA/4Pbfg0Xvg++sl3/1rHTnoVPPA3TvgTML/GIwMIw47PA9u4cmboW\nkTIG7C+ArmadT48r1G+FY78E5+2y7gmzXmC/S91/pbekORHfxTwAvM6dZYnLabpG76JycimlNFC2\nXQQQTnTNatY3c+c5d66HlT2Nj+9OmtKs15Kxc+dJYD7wqdS1NFv/AZwbDocf7x0+zlk41KQ5Saus\nAZvBkdnBju+u6Gn+a8kYfRE4zIxtUhfSXKMagiQJKWCHrbszHNftC9m+47vdOgefM+48Trja++TE\npTRNuIPsla9p/C5qcnuKmmT9xqUuIAOZBKz7qmVmbbNhyXqP70ounA90m3F2s/Y4p2LG3sD58JJJ\n4R/2gesAz2hxNafKuMhlwNPA1NiPk4oy42vAavdi9mPNmAWcS1hT+DS03V4/BOmTT8B/9sJOe7vz\nUNKCpU7pAhbAjN8CJ7pza+paJB0ztgf+AEx354nU9QxXPATzOcLNuWcDX+8bWtRoCBKs2p8wsnF/\nd7qTFS51yhqw3yOcorowdS2SlhnfApa785nUtayPGZsDnwSOB74DnDXcvdVm/Cthce+d7vw2uypl\nJMq4yAVhsEqhhm9LZr4AHGvGFqkLGYwZ48w4Grgf2Jmwh/fkkRxccedSwvVCV8eereRAWQO2cLcb\nSDbcWUI48nxc6loGMsPMOAi4C3g/4enz8NEekHDnKuBQ4Admmo2bB2VtEewM/MydHVLXIumZMQO4\nBdjRndWp6wEw43WEnQ4vB04BrmnWYCAzdidcrXRSfLKVRMr6BLsUmBxHB0rFubMYuAn4WOpazJhq\nxiWEALwMeJU7Vzdz6po7dwD7AOeYpf8zV1kpAzbeyfUgsEvqWiQ35gInmbFpihc34yVmnAf8jjAr\nYbo787O6Py7OxH0L8EkzTs3iNWT9ShmwkfqwspY7dwG3ExaCWsaM8WacCNwHbEGYV/vZVrQq4r7Y\nPYEj4k0eja67lwwpYKVKuoBTzBif9QvFBazDCDta9gH2dudod5Zn/dq13OkhPMm+DfhGvNlDWkQB\nK5Xhzp3A3VB/pVAzmbEn8BvC4tVR7hyU8hqbeMhiH0LL7KKs76OTfgpYqZou4NQsQsaMXcy4ArgI\nuADY3Z2bmv06o+HOM4QB8psDP0nVi66aMgfs/cCOZqUcaCOjFI9PL4Xm3dtlxiQzvg78inAf2wx3\nLhnpvW5Zc+dZ4BDCrI7r4hU7kqHSBmz8P1MPMC11LZI7XcBpY+1HmrGZGZ3E6+IJwXpevEY8l+Lt\nxh8gvMP7uRlbJy6p1EobsJHaBNLITcDjhFNPI2bGhmYcSXiXtCvwBndOLMpAmfhkfSzh2vpbyjeY\nPD8UsFI5cVP/54HTwyDr4TNjP8KErg8Dh7hzWDyOWyjuuDunQRiMZKZ3ellQwEpVLQCeJYwEXC8z\ndjPjZ4TFq88Ae7lze4b1tYQ75wDnADeb0ZG6nrJRwEolxafYLqBzqA34ZmwXx19eD1xBOChwRTOP\ntqbmzjcJ1+ssNOP1qespkyoE7AydYJFBXEW4NumAgT9hxhZmnA38EXiEcLT163GRqHTcuQw4Co07\nbKpSB6w7TwGrgW1T1yL5ExZ7rv0mnPJds0NuNNvjYrPpO5lxHGEB6+XAq93pdGdV4nIz587V9I87\nfGfqesqgCntE+9oEj6QuRPIlXL8y50SYtzVM2DvccdV5KNx7G8zaN84vqBR3fmHGgcBVZrS5c3Hq\nmoqs1E+wkfqwMoiOrv4LBCF87NoIjnq0iuHap2bc4dlmHJu6niKryhOsVkelgSnt616BDeHzye0p\nqskTd+4xYy/ghnjdzhfKtLDXKlV5gp2VugjJo+U9oS1Qq5dwW6u4s5Qw7vBw0LjD0ahKwKpFIA10\nd8IxS/pDtpfweXdnyqryJI5XfAvwVmCexh2OTCnv5KoV/9V9Cpjmzl9S1yP5Eha6OrpCW2BFD3R3\nuq9alrquvDFjInAlsBL4YFm3qzVb6QMWwIzfACe788vUtYgUlRmbAP8DbAi8152/JS4p96rQIgC1\nCUTGLE4JOwT4Kxp3OCwKWBEZttga+CDQDdyocYdDU8CKyIjEcYfHEQbmaNzhEKqwDxYUsCJNFffE\nnm7G08CvzNjXnQdT15U3VVnk2pAwk+BlrbguWaRKzDgaOBPY3527U9eTJ5VoEbjzIvAA4VZNEWki\nd+YD/0kYd/iG1PXkSSUCNlKbQCQj7lwOHEkYd7hP6nryQgErIk3hzjXAe4DLzJiTup48UMCKSNO4\nczNhgPk8Mz6Qup7UqrKLABSwIi3hzp2xTbAgzpT9WuqaUqnELgJYe8zvKWCizlGLZM+MHQhXg38H\nOLuK4w4r0yKIx/weAXZKXYtIFdSMO3w/cG4Vxx1WJmAjtQlEWqhm3OFewPyqjTtUwIpIptx5EpgN\n7AhcasbGiUtqGQWsiGTOnWeAA4FNgCvM2CxxSS2hgBWRlojrIO8BngSuj3d9lVrVAnYxsItZ5f7c\nIrlQM+7wLsK4w5clLilTlQoad54Gnga2S12LSFXFcYfHA9cRxh1um7ikzFQqYCO1CUQSc8fd6STs\nkf2lWTm3TypgRSQZd84DzgJuNuNVqetptiodle2zCNgtdREiErjzLTNWATeYMced36SuqVn0BCsi\nybnzA+DDwFVmzE5dT7NUNWBnVfHYnkieuXMt4dbaS804OHU9zVDFgF1J+HOXenuISBG5cwvwduAb\nZRh3WLkerDtutrZN8FjqekRkXe78zoy3EcYdbunOV1LXNFpVfIIF9WFFcs2dRYQBMf9hRmdRW3oK\nWBHJJXeWEcYdHgacV8SQVcCKSG7VjDt8M/Ctoo07VMCKSK7VjDvcgXChYmHGHVY1YB8GtjJjYupC\nRGT93FlNGHe4MXBlUcYdVjJg3XkRuB+YkboWERmemnGHjxN2GOR+3GElAzZSm0CkYNxZA3wI+CNw\nkxmT0lY0NAWsiBRKHHf4CeAawrjD3I4fVcCKSOHEcYdnABcSxh3unLqmRip3kquGAlak4Nw534yn\nCeMO93fnrtQ11TJ3T11DEmaMJ9xu0ObOC6nrEZHRM+Mw4ALgYHd+nbqePpVtEbjzPPAnyOdbCxEZ\nvppxhz/N07jDygZspDaBSEkMGHf4rtT1QLV7sKCAFSkVd24x4+3A1Wa0ufO9lPUoYGG/1EWISPPE\ncYd7Az8zYwt3LkhVi1oEeoIVKR13FhPGHR5vxhmpJnFVdhcBgBltwHJgYty8LCIlYsZk4GfADcAn\n3Wlp4FX6CdadVcBfgVekrkVEms+dFcBbgT1IMO6w0gEbqU0gUmJx3OG+wFTg8rgHviUUsApYkdKL\n4w4PAjYijDuc0IrXVcAqYEUqoWbc4Upggdkhu5rtcbHZITeGj21Tm/2aVd+mBXAvcETqIkQke+6s\nMePD8Ptvw3Z3wPfHwwSgFzjmjWZts91XLWvW6+kJNj7BFvFCNREZubBj6LiNYG4MVwgf502Djq5m\nvpYCNkxHd8j34F4RaaYp7dS1YScAk9ub+SqVD9i4L24RMCt1LSLSKit6QlugVm/8evNUPmAjLXSJ\nVIQZ4+Abm8Fpz/aHbC9wzBLo7mzqa1X5JBdAWDl8z49h4iS442bo7mxmk1tE8iNe+X0psDnseQK8\n2BnaAit6svi7X+mADeE6Z2Fobq9dSVwCVzZ1JVFE0jNjU+BHwAvA++JM6ExVvEXQ0dUfrtC/knjg\n982YEd5KiEjRmbE5cDXhFpNDWxGuUPl9sIOtJG4zk/Afo92M+4Fu4O74sRv4U6uHRojI6JixBXAt\nYa3l3915sVWvXfGAXR5XEmtDthe4bYE7R8TjdDOBXYEOwlXBHcBEM+5hQPC681hLyxeRIZmxNbAA\nuBU4odVT89SDHUUP1oyXEoK29seuwN/pf8rtC9574tQuEWmhOKpwIXAVcFqKd52VDljoC9mOrrGu\nJMaTYFPoD9u+4J0F/IX64F0cz0aLSJOZsR0hXC8C5qZq6VU+YLMW509OZd3Q7QCmAQ9TH7xL3FmT\npFiREjBjGiFcL3Dnv5PWooBNI+7Hm0598E4B7qN+Ye0RLayJDM2MGYTbC+a6My95PQrYfInbSWoX\n1vp+TICGC2uPJypVJFfMeDVwHXCqO99PXQ8oYAvDjK2AV1IfvC/QeGHtmUSlirScGa8nLGYd584P\nU9fTRwFbYHFhrZ36hbWZhClhA9sMi1u1wVqkVczYE/gxcKQ7V6eup5YCtoTiwtoO1AfvjsAyGi+s\ntWzztUizmLEvcAnwfnd+nrqegRSwFRIve5tOffBOBhZT/8T7qBbWJK/MeCdwIfBud36Vup5GFLDS\nt7A2i/r+7mbUP+12u/OXRKWKAGDGYcCXgYPcuTN1PYNRwMqg4jHDRgtrz1EfvPdqYU1awYwPAWcB\n+7lzd+JyhqSAlRGJC2vb0HhhbSX1wXufFtakWcw4FjgV2Ned+1LXsz4KWGmKuLC2I/XBuwOwlPr+\n7kNaWJORMONk4GPAPu4sTV3PcChgJVNxYW0X6oN3Eo0X1v6shTWpFd81fQZ4PzDbnUcTlzRsClhJ\nwoyJhIW1gcG7CY0X1p5IVKokFMP1HGB/QltgZeKSRkQBK7lixssIC2sDg/dvNF5YW52oVMmYGRsA\nXwF2B/Z358nEJY2YAlZyLz7FbMu6s3c7gBnAChovrL2QplpphtjTvxDYCTiwqDOVFbBSWPEv4TTq\ng3cq8BD1/d2lWljLPzM2Isxx3Qo42H3t3dqFo4CV0jFjExovrL2McC/TwODt0cJaPsT/dj8gXMj6\n3qIPpVfASmWY0Ub/wlpt+G5M44W1wvX8isyMzYArgKeAw935e+KSxkwBK5VnxiQaL6ytpvHCWmHf\nsuZV/MfvakJr56iy3OqhgBVpIC6sbUf90+4uwHLq2wz3a2FtdOIlotcBvyPMc23pza9ZUsCKjIAZ\n42i8sPYKYAmNF9ZKExjNFt893BB/nFy2XrgCVqQJ4uLMDOqDdysaL6wtL1uYjJQZ2xAuJ/wB8Lky\n/u+hgBXJkBlbUL+wtiuwIY0X1v6aqNSWMmMq8HPgm+6cm7iczChgRRKIb41rR0DuSlhoe4b6p91F\nZVpYM2M6oSVwnjtfTV1PlhSwIjkRF9a2pz54dwH+TP0T7/1F28pkRgewADjDne+kridrCliRnIsL\naztR39/dHniQ+ifeZXlcWDPjdcA1wAnuXJ66nlZQwIoUlBmb0nhh7aXAvdQH74pUC0lm7AH8BDja\nnStT1JCCAlakZOLCWt/BidqFNaO+zXBP1gtrZrwNuBz4gDsLsnytvFHAilRA7O8OtrD2NI0X1v7W\nhNc9APguYa7AzWP9fkWjgBWpsDhztdHC2nTgUeqD94GhFtbM2qZCRxdMaYeNx8HcmbDjQe7cnvEf\nJZcUsCJSJ44MrF1Y6wve7YAHqA/eh6Fte5izEOZNgwlAL3D8I/CjvdxXLUvwx0hOASsiwxYX1mZS\nH7xbwinPwZlbh3Dt0wvse4n7bUe0vtr0xqUuQESKw51ngd/HH2uZsSWs/DlM2Hrd3zEBmNzesgJz\nZoPUBYhI8bnzFDywiLoDZ73Aip4UNeWBAlZEmqS7E45Z0h+yvYTPuztTVpWSerAi0jT9uwgmt4cn\n1+7Oqi5wgQJWRCQzahGIiGREASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhIRhSwIiIZUcCK\niGREASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhIRhSwIiIZUcCKiGREASsikhEFrIhIRhSw\nIiIZUcCKiGREASsikhEFrIhIRv4fFiVKSewtlOQAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2381.4 in 0.000 secs for nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(nn_tsp, Cities(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that the tour moves clockwise from the start city, and mostly makes good decisions, but not optimal ones.\n", + "\n", + "We can compare the performance of these two algorithms on, say, eleven different sets of cities instead of just one:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.0,\n", + " 1.0,\n", + " 1.0,\n", + " 1.0,\n", + " 1.0118279018107388,\n", + " 1.0121039193389436,\n", + " 1.107851821362778,\n", + " 1.139713084817861,\n", + " 1.1531140497779002,\n", + " 1.1972133336642432,\n", + " 1.2160497559961319]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def length_ratio(cities): \n", + " \"The ratio of the tour lengths for nn_tsp and alltours_tsp algorithms.\"\n", + " return tour_length(nn_tsp(cities)) / tour_length(alltours_tsp(cities))\n", + "\n", + "sorted(length_ratio(Cities(8, seed=i*i)) for i in range(11))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ratio of `1.0` means the two algorithms got the same (optimal) result; that happened 4 times out of 10. The other times, we see that the `nn_tsp` produces a longer tour, by anything up to 21% worse, with a median of 1% worse.\n", + "\n", + "But more important than that 1% (or even 21%) difference is that the nearest neighbor algorithm can quickly tackle problems that the all tours algorithm can't touch in the lifetime of the universe. Finding a tour of 1000 cities takes well under a second:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEACAYAAABfxaZOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXecVcXZ+L8HsIWixhgVfSNGU/RVQ4xBwFVAWWxIV5cO\nUkU6liiLkkSTmORNTPJLNFWTYIlGV6OxiyViN4ogRdqClAXp7AJSfH5/zL3cc8+ZOWdOu0vizudz\nP7D3njPzzDPPPPPMUx0RoaE1tIbW0BraZ6M1qm8AGlpDa2gNraGVrjUw/YbW0BpaQ/sMtQam39Aa\nWkNraJ+h1sD0G1pDa2gN7TPUGph+Q2toDa2hfYZaA9NvaA2toTW0z1BrYPoNraE1tIb2GWoNTL+h\nNbSG1tA+Q62B6Te0htbQGtpnqDUw/YbW0BpaQ/sMtQam39AaWkNraJ+hVu9M33Haz3CcOnEcXJ86\ncZxh7zoOv3EcHnMc3nMcNjoOOxyHDx3nuo3quZs97+U/vWbW97xK0cy4+2aV4wxcXPhtvjhO+VbH\n6fGqeqdFq2zg6T0z7no4TotWxTDXifrbD2uScT6LTa17/eIryvrG6x/HcTjYcTjccTjGcTjBcTjF\ncTjDcWjvOJznOFziOPR2HPo7DsMch7GOwzWOQ6XjcIvj8H+Ow68dhz86Dvc4Dg87zuRV+j3W+e/h\n820/Q9Fq8Z5znE4P6PtsPyMNXIS1JqUYJLgd0xKaer5rCnzu88A84Gngo9xnvQjiOK/MgLr+6syq\no/j9OmBnbdpQqkU79RYF75rVMLdSZGt12uOEw4EDtAJawxln63F3fFe4s4n6/3Lgj8AjzaFpO6hr\nB6PbOk6LzmnBX8DNQafo16NZU8ehsQh7zb2cegvceWLh3aaov5fcAgwofnbNav04NauTzuW/rTlO\nqxPhf79V//gyrW/jBxyHB4CDc59DXP+P8vdBwCfATtdnR8S/N/t/33wiNG1ZPJemQNvujsNq4F3g\n367PCmhxPHR/rjDfOuCqdo7zxM/g4nIo66rft6ee4Tg0F2FbpvxGROr1A+1mQK2AuD61Au1mmN9p\n3goGLIZ5AlOk8H6twMi1sGQDyAgQJx0Y8+O5xxmwGJq3Mj/fbgb0mqn+1T8XPq4cCNIaZAjI7SAv\ngWwGWQnyOIyYo8ddj48Lf0+XIPwmhbUYN9UCkzzrMXQFzH8D5F2QMnM/vWYWw5j/9JzpH691FQz4\nxHY9slqfaDgq3Xgu+jkMJq/W75OKraWCI3h9x68E+T+QW0EqQa4BGQsyHKQ/SG+QS0DOB2kPcgbI\nKSBfBjkG5HCQQ0AaZQO3mT+BHA/SA+R7aj/KapANMHmN/p3Jq0GGQse/6X8fsRqmfQJD10L/7XHp\nO3ROpVr04A1hz1D9G6l8FrRbCt1m5TcUyMkgs0EeADksy4UPnk+1QKVAn+3QpipoTmqDSgeQCSB3\ngbwHsgPkA5B7QK4FKQf5Yjju2lQVvrtJs9FEoOfMuLgPxk1+zl1rXOvhgFSAfJSby7HFa9hrJnT+\nWN/Ppa5+dLit2BOG2zTordT0nXxcOQlkPoz/qIDP6Tl6mC5QPqu0+zy6cLc/fKILfHI0DH0vSIDR\n99mvGnpUq/8HC2qJ51TfSC0god0MhazrN8ERJyTvUw4G+RXIMpB2Cfo5EEbOt9k4IE2h25MFpuSV\nrhSxgHwJpBvITSAP52CsBXkN5DcgI0HagHzOHnc9Z+qZo5mA0tiIthJ6AT9yC8h6mPVjGLikMP48\ngYG7zTeGQUvhopeTw2ua8xUvgfRK/3PFS6VmdiCdQGpARu0vzFbP6K7emsZeLw3sxXssHo0VcO7v\ns7WVoJbGfPYDnT7kdFUDcvrqN+FH3wSWJeuTncA4x+E54BHH4RfAbRKoVy40x+FAYBAwFZodBPNR\nuvHvUtDTLfqm47xxO5z1P8DpwLFw8l71+09dz0JBh9lqAbAFpQt8F/gbcAOw2Ba24nkq3Pnhb9FZ\n6cObnQALToObmsMDwG7gpVrYfSQce5Zet3jkCTZjOw6fh/850VZfLEIdUOk43AUPvgh3HFd472Tg\nhiZQvgwO+hw8flQx7n5zAow8Tg/v0R6da1Az2ZCOPRkNHpO3Y09ODrN9cxxGoQivrwgvOM5BL8O0\nCvh+4wLdjl4CcyuzGN/URLZWF2jy6JawYS389svw/65xHMaKIKWEJ0oz7TFzm1sJo9sW6/SLce7t\n03F6zyzQiclWmZINpr5PUf8pKd1R+t9U9PG5Po9D6cOfB2kZ8uyBKH3iMpBnQM5Wp3LnrQY93ByQ\nK1AqpSaFU950Wl/xr3qQVMqgX61fiu5lugUstcBpJ5CP4O0/FEvstuo58w3B/FvHmsI4+VvXVFHq\nPVv1TjzJN65e3jzesPdADk/St2c9moD8EmQByFdc34+BuU+aJNVS2hv8Y3U9FeQtkB+lud+zWMf4\n49jeDs65r5i29VqCVGArBaKjIUsclD770pT7bYxSp9SAXOJf/FO+4mX2xe93f9XmylW4xlaaGGrJ\ndZjFjMet7pmgIa4pEqTvzR2KPwJZBXJhHAL3w1SMH/NvrasUbp8VuDTH8KeLUg3ZbQqDPnUHnLEC\nuszSwZ9EL69/d8hyeO8BkA3w5h0weFkyu4ocBvJ07nNYYdz2M+CG7dDjaV1/pbQ3mMca0BpkLsiN\ndn2k5XSQ7XyjwSWNYM4TMNYlWM4TJWh209JkovHqc7IBSOgD8mYWpz/IObB4JYzZVLz4E3fDvJe9\nzL7wXlRjbuuqLC3w0ebslpzdN5A8w3TbKebtm5N/k93aCeRtkMdAjkwGk3kDhvxWBhW7/QfVPO1a\nmMduUwW9t6vDuTrXz1CBcaIMas1b5ZjpGVCRyJZgOhRBjoerFibrO2+wlV+ANAnDbRSaTs8LrXkr\ndRszesEcA7IYZFwcerGHY/+wb2jW8McgL8M3vhpVeIo1Xn1ONgAJjVBeKxdk03/HB6IufhyiiyMB\nZzNfk6Svu0ZeudLMeCftgRenpXUYB+HHzChNG3e6RDF0mfupFKX+Gv8JyDaQ2TDl4+Ln8p/L/5Vc\n+rQ3hGv2yT6Drd3ciunbPPaQd6HzKWlIxQU6mqoZR81TPdOlCm7cCf1f1d9KsnQ6uOyl+tiXuTUc\nDbIQ5IiSjVlfk7VARj+QV7KR9uNttCyYeCl0jMG+9O5r5Ig58OZv1DvpSUVpztG8dlNTYgA35eZ5\n3to87ZlxccleGLQnG+mz+1NBuAMZlWP4neLSt3nsa9bCTbvjrL8f3rz7sMmLrGKhX701Yo3/VhL/\ncAyf79TtKO1C5naFYvz0eR6WrAM5Ketxi2Ao5WDRkCONQT7UEXXyvvePa54igH7VHv1ydXaMP39g\nta5Sm9ErRf+uG3xnsyLIS2uSbrLCuOnpUeH8v+vXrnOkYKMCDbjdcCsFJub67FoTModdShWUVPrU\n9T2iBpashXfvUa6q7t8GLoZ37sJjsI1D32rsMZv1arQ+L/rXvlqUMV1/eBfmklcZThXotqfwrvdW\nOaQaei1XeM+rF6tFvd+paJzi2JM0cT1gMdzVC6UiqyLE0SP5HvSOf+VHpdYAlGygeEiSITB/VtqS\n8P5i0DETcpuq0uPai5N0DNHp3hikAyyugdEbiteuYis0N0b7mufbo9ofDzA+x3SK18Bzy1uqnknH\nn1ofayGHwRiDvn/yagKCDpXdY8Au/yFVjCMQBxZVQ9d/hqvRdLETxXtGveON/nXTkc/jqsxv9xqR\nWwP3dz2qodtH/vGjC0jFkvaNtfCzLjlcHISKrF1HitH8We2FRHCUcrDoSPrKScrAmj5z3h/07WZp\n+tJPijegnXpEbaJ2S6Hnxvymik+Quk3ev87k4WLu13Qtn7QWZCjIceF9iIOKSK4B6ZLW2pkP3c61\nwbaa/JwyjpzU4i5Y2i6spdlAX6CpCx9VenQbjyWvEOCNmD7+RBi10I8T82GhZ4KV4oc9/773VtY6\nkXAEb92pVJruG4WchnIieQHkpNKoJvu9lgV/McJRysGiI+nse/aHkzG7+XXZpJ9fT/fmKLPzxLCT\n7jzvuAi6Y43aVHk4qkWpOjp9Apesgwt2qs1ohkE/hkm6GfAayP0g61FG+5+DXATStBiuDn+DuU+B\nvAHypXTxb9qE3QJTFBSrhuz9qaMykPCDOG+P6f5qsZAQrP+29+5xH65uAUU37wk7YfTHeoNt/qDy\n3iZ0cOrciC/X9FlYpziMWb0zdIX+MJLGIJNgyUYYvT491aTReWAHKndPuRJwsrXzpdZRdAQYDVTN\nQS4DmQFTdxeIpv7yhmQzf2kL43b6paBJUtAr14rSbeoI5bIXQC5HJWMbA+Ub9M/pA60M3jk5XHs3\ndXxVj36cketc690Y5EyQG0FegqW1MN5z5R+zGb7x1fTXIEmgljcHUO/A/Erxvb9GrjOrSkxpPsJc\nMaPP2+wB5n6/dZU5iFHn2qyDo4emb913tQLl6+H+/nHiHGxwABc8kqbQaaaBtl8DGQbyPnz4YfGa\np696TnUTRUOAjhF88CLIVpAnQUZD54f2hwyB6c05vyH7vaY8Bm6+Rukr84asSlE6TbfE3XeXXsqZ\nsh6VUO5ukDugYqdButsYjegrNZs6me66WGK85HFYsh7kC/pnO9yvh6v/LJBj0l8PnVvqraHOA4U5\nXf4vqNwJ3+sQ/HwU42q7GdD7BbhqATxXrdQwXmk7KKfSG/8Pxu8wMQ7zTaBrjd2hFZjEr0ztz3Cm\nVbCruOn/Ag0dm4IIh6yBKQahKOzgDvcGsnsm6u0tyE1ZHOj1bNbajSbUW/Pm1v7ZkTC8Edx3rAjb\nABznjadgfHkuF7zr2T80h/JbyCRXSjZN5cf25tgePRqeHwBrR8MRnaH1UTAVOD73Vh1QvRLqTvDn\n4Xj1KRF37o7lF+ifq9msh8iUg+a9tXDAgdD08ML3yXKB+POMcDvwA2Ck/+kjvqiH66ivAPMch4+A\nZ3Kff4mww/1klDzkhXwwn86Ao06C15+Dn62DtoOBF2zn5DjcAEwAXjK/YcJ3IQePnkbGLINZExSs\n7WeoOhJNgU/R93f6t6GNA3eeDeWTVf81HjyY6hG0PgoOe05Xa6E4d85BnaHuKB09iGx9xXFaXAzl\nf4GjD1P0N3dI7v1WxWvDnfA54DsU5jusMYwDvgB0Bp4DNgBHApVACxQ9DgOGPZ/D61FBeNW3PZ+E\n03Rw3QbDng6sVRGUx0cEcRwaZ56rKUvJNvjECz5BC8/ZpT/Y3z/hV27j9T8TnX4QPFE9NzTSTlmQ\n9ANyKCr3+FnR4JImIG1R6TReQQVPPQMyBeS0uF5ZID1BHsn9/zCUneHLEWj5YJBqkI7R1398Nbno\n5mg0kpf0vcbNsTvCYNfjaYoUIpOjqLeK8RyNjiu2FuxE7vnmDc+DPTQ3yQWjnSrLsF4nKpfY4auD\naMV8E5w2WY3bMdYtIwmfSIUX1R8TTKL3SxcJ2c9VHOXZIOL/6K6KXoOXnbeK2liX1MJltWHeO9E3\nbo9qvW+/yYc92OgLMhCV0qFxOFyT9sCUthq8HooqYnEHyFKlMotz1ZcuIM+6/v4+yO8jrvEVsHCu\nynfjP+z08xq4RHmQSA3IZdHUCeWz4NJt/sN48Gp7Q2bHmmL/eP94we9HiZi+aIv+++ma+eZh0j1/\ncS1cux66nhpGx35Ye82ETg/CoqUgo2z2lf+ZKVcpegxWc8XnFdm7k6fSSbzJ2U0sTSRkbRXXjylH\ngTwO15kMrakeXiB/BhkSDR/2aRD8fQSlRTDPUx2E8i88KQT0Y8+6DRa8A2X3Brsq9nst6iZUY3V/\nCq7b7HLbOwJkAxG8hdR7Zj168bym7YVz73cZs9uCLFBSf7CrZfGYyQKW0haoQL4KE1bp1+DyOv33\nXm+fWtf8dc9P+9T19wMg34PnroNJK5Wdq+ze8MP2qo3peOBk47JboJMBb6pYgmOsb51W/afZWfSJ\nTV6t8nwEM2BbBhQ+XmkDskAuBVkDcovK4pn9+KjCMeNLt45B6Qzcf2uLqpyOCobRGnWL125cbbiK\nKxoTC77tvPkblQwtrnuleWyQJXiiaUEOgRkz/CqNIBVdstQE+vnHCXSTM0EeBPkYhr9vwIMh4Vpn\nj9E3r2YyMdSye9XhIqtz3/9AZSzNHxQ3782lNnhDwTRqXroHmxvnOg+qibvzAV8p7ee3QC5Odc+m\nzQQiTmg+yP9m07dXqm8dKBXpbgFxbwaoClF3otI0n+OHKbuAMFSt0aklWr+mSjqNLum7+ridEFVK\nNM8XLxMbvT76LaV1lT/9QZh7ZaQKYq+AnBt3nnGfN+yTMsV4zWmq9XtDHFTd2mdRZTAngjSLYZvK\n2X+6zVJw5NWC80Rjo3LZkaQJSBXM+adKTVGk4loGf+oJUgFXLU5yMIbj3Fse9KmJ6vB7ZHgaWgWQ\nK0EeS3XfloI5GCbjoEoEHpp+3zrCG7S7WG+Z/4ythqcnqRwY7ufdNSv9ROcfL7/Alz6R0xn+OYu5\nWeD1epDbsunbPc8LHoEP58N7D2qKqITq9F3wHqqMat2eNBt+ozBU98Fa/nDOPbS1fmxTvz32RDcO\nRpL0HwCpsIdHz6DSuL3GczAYvgYWzs4JbUNADjSvgb1tSvN7WfDzcpDSFgTBn7YKy8aG8IceMCmV\nTAI5AXIDyPGp7eMsmIPlZA4D2apf9KSnY5APuve74bNh/DL750fPB7kGVS3rbLjhbL+k4c8SWEK8\nXgVyR/r96oh91MfFNyL3Zr3iJZWS2EZ1N6ImeBPF37ggg0DeBznInk66G1Iph9kGvIKDSUiQX4BM\nsocnLOV3/NtjePSuCabLXwRpVB80Xgy/LjGcG/701brhh1faB807d3nTRSTCWf0tlpwGMq8YkWkZ\nbE2E3Ftb1MReLy0CoxeB/Aylw3wNptaVwkAbAa8DQO5J1ofuOl92bzTVg7QFeSN8LJvISC9tzBMo\n3+ZNP2CAwwF5BOQH+nnqaC6egRQevwomrAg3fsv1ID+xh8dWrRgnHUHwXKF3IFOt7489/WSrVnWt\n7YFw9bK0cKZg96eLSARj/S2WXATydJTFS04IbaqiuZnpJH3bQhSmqL18WuOM8mog3UigA9QznjFb\nYKwhMtikeri+vToQw5LE2eZ+d7sqDjLqeg04OQrlFqlx+/QzhLjMF2QyyO3BuG03A0Z8AOOW2rkI\nRmH4cdI86DKN9t2pykdWLIbusfLql+pTHw4aAev/bZA5ypMoW16WCM76WywZAfLHwt89Zus3f3Dy\nqzQIQf+8nU4/mk40PD1t8g3Q8xm4dlN8LyfTfMpW2BKygsOr8jKpOqJIar1caY3D4fDQWx9YtATO\nvc/mwI3DfDGobeLQZHrrZmOH0NUUqBXlmfKs+A2qBQ+foNtFWura4PVxC1KjP1TzeHFaWuOEj91u\nBpR9HeQnOcGiXym0FongzxI5wZMZ8b66BrWbAbfeCB0/NRCtNmGY/cKMrYZh74VLaSaJzyZ4w7zA\nxZvR3q836oZJTzXQc6M/WEdEeVfYBsHYRyrmrq9GXbh+XlM08NlUPRu7LUuJEFWEo7f+t3T1vP7+\no7tvhqs1a6Xg0XPOLo2HjzFaPMtDztz3KV8pHGAj5mVzk9aNPXEXvP8PkC8G8ZN44/1XSfpupA3Z\nq/yTdUmVkmXUROVs/2u2cwkKcjIVJXd/dKqMqFd1M1MJO0DCGau3H20wV1kh0Va0SEW4+09wwWZv\nHQAQBy5+TD8vO5dQG/ykRwfyDsiZ+t+6zCoOusrj9srZIAcX01FQAJrvmbzL49pCkXf3/CavQWWt\nPVDzvuHW5MZtfi11QVSdP9bj9KoFMHZJVHyb51bkKnqACqbT9d26SgVeZXmwZ09HNrwgUZ9ZAGq5\nQTxI6yVRohEjjNMe5M36m+elT0SV9ONd1U1S28Q6f6Wpwcvg9gtQftYVMPgtM2O11Q27g2yi3mgm\nflIM37BV8M7dIMvgxh36eU11PW+jb09eY9WC1ta7pb3iOXozT07J0fc1a0E2wewq5QoZdpMKS3nh\nzk8zcAk8MQ5kJshaePMOGLLcQwtS/L73sJ/u+teLO1Nm19EfKknbHt92cxu3HZZug+u36fvO3v6Q\nBR3ZCWXtZsDoNSqFepdkgnCWDC9kg3iQNkWySKEMA1rDtF2lTL3gmuMpKjowv5ntdPrxruqmg6Kj\nwY/5+k2o6kAPwPiVhvE22qmW2s0olgRfEZvIUkXM53xUUBu4mc2wd0FODTgAl0bTt2etXpGmINvR\nlNkzj92lNie9HgOD39Q/c81aVKrxh5Tx1+bW07HGfxOTr8KoD8y49AZHuQ8mU2I0U5RtuxlR8W1+\n3je3B8zP9livp+PB76S3p5PREb7qds362NzqFZ0UhIJEcygVA9RsEg/SLpXigsqdA6s+hSA2dzJ2\nf9VPyNlZ9otP7AsegcWrQQYUq0XyRqfJ62Dg6/orvPt2YEdYZpVQl1lhB0hyQr7s5WLpPn9LCyvX\n54V3qCgjYvU++OJ7pXjVAlkbUuVkkIX630yHeN854c8MfgfkYpA+Zul5oNgkTLOrqNVuhjoA2i1V\nnlJ5NUukKNvI+LZ3m+42y9y3yf20cgfIt9Pb4/pi8hbvlvmN4uV79TCfez9Is8Ln3KI6E4nmkAXz\ns0Oe96r7iodJxNPl2+qn05+PbtxChSj/8w8MhOs3aiqHHa+Kfwdf9c0weI3Rcfzgwzaom6l2fgjG\nbikudhOu0zfDVSnqNlSofxrFKBY0l0I/l7ytom57vpHW7Q/kApBn9Dhqt1R5wXgPwb7/CseHe52C\ncBaeGjnJ4W5agxA7T+636zYrr7I4NimvpN95q8nJwrz2VcNQnjWnJtvf7WaopH6TPoG2vmLy5j2y\nby9qbka68pIiULkHlbEg96nc4/49Ea2myfiiIXHfgsVywYtHPHnLvp3aIp1xTXpsHXH2Og1kLsjE\nAtFc/rKSVH5xYXxitb0+hm3evHtcv+ri/vpvVN/lpXtTeTs3AwuS7GoF2sQqem1ehyv/DXIZ/PbS\nqHl17MaVkSB/CMC5FN84B+2FO38ZZZ2CBZo884/qmpy9Tzsq9XVgEkA9bP336tVNZucE8+EkfUFW\n4Ul0l+Ye0j+fz83TZzv00MS6xLPzJVqPLBc7C4QWL6zON9jETHQl19K83kfJD2NiTJPXgPwSj14Y\nlVrhX97vo+E4nvuYf31M9XJbuwLfdAeDbWqF6Ua8JVuHcStAHla3q/iqLDOORsyBq5eqeZ35qJ3U\nOuqDqOuknjHlwTeXO0yDFuLj54VKuHpReKCeF7ayt/UeT2M+jncTlhGoYjf/Ew3+qPaJ8ocLDN/N\nc3TC0DyBitA8Pd59mGg9sl5w+03TboaqNzppF5z1z2juhSa/ePcC9TIwq+SqHpCmKg2vraSfZ0ze\ngu/DN+ApKpLrvzHKHXBA9mvgyzLquZJGcTs1M5dwqTXtm14+WC5d7wv9PIaIPrmfF3eTamKu01K9\n8fubVUFeIPW3t+1yEtmvZafYBzfIJJCFIEfZzyHMFiJfBLkc5Lcgi2DqLr0Ub3JwaNbH5iB276lE\na1LfROGf1NVbggjETAj9XwVpB32/4d+EFVuh++Y0NrufOd7VSy307Ids1QbqPV3B977bzAsubVE5\nxEuUlbRHtZLWvTrH9ApHqHHbVKmcSHkf82Q3MNXnsFXRhYK0DxldCg+vpD8lkOlrDmKN4TSv8hi6\nE0YG7p362dNJ7Qi6SPmLDW68tnUE5GaQ2SCfTzaH0fNRyfw2g/wDlV76dFU9rVb0AtIrAmdv98ak\nlHRN6pMg7JHbxmXUM526k9aAvAmyBZZsUK5uE1fD0HeUIedCw5U7Uu5xDRFO2gP/GFX43fbEdvu1\n28ED8geQn5cG73k1jpfJp59KIm2VA/zrVhUgZLJPpKfXjpDcz+NzPmQ5LDIG2ejh7LvN7DpZ9nhW\nN9lka5FGoRc3bbSuMqsYbb3NxAH5KcjrIM2D1MXq+bKv+wWJcdth1o9BzgJpol+7ZHBmtib1OXi0\nDRQqqS1VyBYH5GiQjiCjQH4O8gQsWg6TPy1euJFrc5J6whM/jpQbveA7yJEqP/zFj6VxhXdtqI1+\nOPJSiq46kL5ebnZ0ER6p6sHT/SCDLOadAg7NgopnjLLivy8/HWRL9H51QVI9Z6ahtoqK56T4iddf\nr5l6muy/PQq8OT7xO5j/qr8exMDF8Oc+IDeBvAhSCwveUircm8RbktGMy9ZVCq797PZVn4PbE0jl\nPsZq1gX7K/74+//WVxXDHLZe6fivWqeKLC/dCvIxylj6B5BrUaUOv+o+xc0bK05SuOgHiJr7yHVp\nEFExHnUqG7c0n7c9TN13uJaOJuIY+mURGVVkSwO+HIwOyA6QpvrfTbSmS4fQbgacfU8y6Tcbzx7V\nr9eoPyknOCRJCOhNEtc68iEC0hjGLdPj7boNID8GuRCkmWvN6kBaRJt/aQ3noTDVOwA+d8D+O/XG\nPV+qYoMxKywHS/NW+gyQV53pvx3IEpCdqApBj8DIuXoC6Rw5cjgeM4t309Abad19eSWneQJ9xK/G\n6efbqFlIh0nmDHKoksz8BvHsaThqOmRZAnJStHl7a8rmYxBevx3G1cVl2mnbOor7zqtk3F44SexA\n3n0zeFl89VzvF6LckEDmkcDff3/4NKEem+O0aAXdn4M7T4SmQB3Q/VP4EdAo9xkHfAGoWZ1/T2Rr\nteP0roZbTijusSlwdMvgUU+9Be7IjZd/584ToXyiCAOAF4th5GDgJODrMOQsGPM1+E2TArw3A79s\nDj952HG4GVgILBVhTxAUag4tOsOSWxTMNathbqXI1mrzW8e0LMDtnnO7Lo7DD4HFwKLcv2tEED2O\nry6DAxoV+joeheefArM3Qc1mePYEWJ/77tPcZ967bvj0fQ/v5jgtLhbZ+krQ/O2bac7GdT4DeE+E\nvUlHVvM79RYFwxrj+uS+GxBjiDVAS9R6edrcShjdthi3Y5bBG4OgfLSbZmBrS6ACZnSE8gn29ORu\nkfEc2Ipx9z+nwPc1Tx3d0hbHhefKW8LcOXDeHDj2UDjyi3DNcpG7fe/YtdWrFG7dc6/DzW+KYRhx\nKGy6x3FkUGfvAAAgAElEQVQWzImG3/2o1eeJo5cu8rk+giWW+FJvUsOSKVviuBW528HS4tuB/AiV\n6bM9lraDaPiqFaj4F0glyN0gs0DW5aTd2TBhuf6dC7eY8OfHkT6oreCl4O0j+s1HP19pq2IXIkn6\n14L8IvnYWadtaN5KFZUfPtdUWKf4BjFoBVT4SuaBtMjRXPdsaOviOuj4t2xiO9pU2QcOmqKs5RCU\nOq9bvHk/ey1M2JkEhjTooZSf+h3cyIDzOT/i57GPTty2us9LQr0kQA4GORWkD8hUkL+wz7NIPgZ5\nBb/t4IDom8k855ya41uKqZhwbNpIQaqfWlG1cec8WfBH9n6mWuNTP0/5JsjjICvguettC7Lk3g00\n4trDkKW6wxuxGewNFeTrDvJnkN+mAJMmL4w7Y6d93Wc/7kxzbG0s1ehRGwZG7YOcp/Jcdbg/WqlI\nOU4JSL+8SL1z2UsqeO91n9CQJT2E00rKxvUsAQ4nDPtiGwGb5zXlrmnj1ZH3C79sZxy/cMXMP1yg\nvH6in/goQ9Ax+G0H1reDqPrjIGI19RVu5K0V6PeKyruj+2262BU18doZ5BRU7eHVIOPIFTMvPHvZ\nyzDtE+h1mrm/G7YrY31SA2SvF/QHWvJUzMVrEh734D+E80b189aqamB6Y3B0mPJpNAaKPjf/pJUg\nx5sYUY6+28CEVX68VYva7+5cOUZvvbeC82cVrwUW8T2GvfgEyE2e74/M7cNrPfSQeWpuPU1nYFzP\nCuDwCdlJOeH9yJkgs+MhsP92JW1YZchrBaPnqeyY+et4ehZ59oPbgf89kzuniJp781bmPPFRM4KO\n3arcUeVakM8F4OlBkNFpb45iRlZ2Lwz7KIwZx1/raIV1iiO4vbeuKz9Kh/5sYBqzBJZshFHri2EY\ntBRemo4KVFqi0mKH484skPQ0ZJ70Brcpt894nnAyFORd3R4CORYliI0OhzU7ST+rMTMB1m5C+Unk\nExJ19eUAt+znEJTr24FpI7DACLq/ChfUlSpFs2d+treD2yjcDo7QzyNO7p2wtAbNy5QO311Kb+QW\ndTCagl1MfXa43wIfF4O8kebm0B8aQ+qg//I4B0nYlTy+pJ9eNHTwOpvHMQc5jlsG0gmkke0hrJ7T\nVbrqYohhcRfOKWRijSqFs0+tI98IoLMvg3xELvVJfej0s7pdZAKs3YTSmwjKjcq4gHoEBmfcNMcD\nZJuiOeK8vbeDv2K+HXTD8nZQPMYT42DCJ0HEXnyolD0Ow3YFPx+fmEGaoLIlnhLe36Sa3GHpmFUS\nuvxCebjzSeQmroYhb5vtCF6347Bkc2VfLzA7W53+gMXmNLxpqJzs7Ay2axcmaBR+n1gLHVa5cve3\nMh/ivaTYgSKv3gk/9IvXaNIqeO1nFrR2CsgakJ7FfUz9RKk2494kbW0O6Qa27eu3VAxKg1DjAsXo\n6z5CjHfhxsmoWSD9hL6/fCi+HYwmxu0g18+hisHe3dv2pmC3AZNK5vIjkJ+E9zf4LZAPlN7bq5IY\nsJh9uWyCmSlIFzy3i8LYtp4q+4yO3UCq4f1H4Py/FxfWCc3Pbjic0qr+1byVqs41Yp4JpjRUDmFS\ns/73vFFZh1Pd81dthzMeUUy2TZUKBnP/PtDWDncG6lbQxfXdSyDnpzVfzxq7D4YyU2BbonUuFSPy\nIyK9axLId0D+zx7xNlfqsEo+9S/px8RVlNvBMpCXiXA7sJEEDZt6j0rBG54+GuRrOQmsibm/fd4t\njrmQdp6JBtMD6naxFuTLfli8TNCkD6+YBfIoyIIoDMNMw8XzTJE+7gepyBKGaJJ5TwPTDrptnvUI\nDNnuZ5b6Q8MCJ2fnGH9Zzmi8CEYtTC6xlz9MLojQjNfTn9IFtiVa47SIJTpxXTYTpqxPwxAKchHI\nc3abJtg4Gb5QdsXC/9M++G8HL+XmvYVIt4Pism6mDea//t/SEeR9la303PvCc6/LqyBdzf1ZqZNy\ndGBz85Nfg9zgh8Pbt+kAqdypDtlvfDWJC14S+4y+H58HThVIryxhiFcDOj/myFXQZaOKlzHdimxu\n6fn1t3bvLFeOBkMjp4k2z/fGnbm9tQgmG2pZD9irezfRXs+CgdgtvPQDuS+lvlqipFSrIiNmV8Ow\nEoIVW5WR6boN8Px36gt3JVibxijp/8rc3xFuB4vXwPgdwVd3PdNTuu6xHm+gftU6ozCqIMZDdvMx\n5qVxqUuC8wuBnAPyvr9vG5/0cXUwrcxGSo6j+42+voE3o3+6D9Po/YbDHldFpPoftjqM6drV240u\nwMHlL+rhbh8Ct2m+HWvgnPvgtvNh6Ht6mDut1b2baP1LxUj8iJCrQO5MqS8Hdf1qaUeQI1bBgNDi\nxiaJBuR/c8zuhNLjrRRMQa7KMfJGFnh33w5yhbuXbIKb9sANdTDxI3jzDpChKqOpueaAeXNU+p4H\nORSWboFODwYX3Gk3AwZ9CJfs8Xtf/fqnMDG0apHq64gTYGod9H+jmBaa9VFl/dx99NwN3Wqgp8Dl\ntUo9EWSgdHtChUejJ1/foNgNeRakPB5d2gYOavPn1Omikm3htnvOTUfRnTICkuDtRt2CJ6NcyL2p\nljXr6g58G7DYXNS9dRWMqPHiNdH6Z8mgQhjGd0BuS7G/Z0EusifI/ssVQuNeUeVaVNrVQMaYLs5K\notM9KnegBQRA+apr5QKnptbBff1y/WhuB9euD2Z6thJafmzvrSDMGFixteAl8vRkkI/g5nPCVBUB\neM+5q+aDmvJ612cFBmo8nkzptIfNgeHfilNjId4am9UrKBtOh+h9RpPeiwWqbz0CVwd6fIXBHb5e\nIzbl9vtGf5lJfx/R5tj5IZArUCrAOagb8FMgN6oUzQOXFGhkgOgD31obU1LAk+Nh/LLU6k2UimFp\nmMsPQW5Msb+fgmhVLml4HGjGawzz31SufKUpT5fFPDTz+ivIj/3f6zZSvrqW3SEUnnbDFKHt08XO\nDJeaA6XZ3ihD8MnJ8N51u97zx2gYNnjfTFqpIo2zc8ksnk/ZvQG4eR2kbfQ+k7jhJpXgdSVJ84fK\niHkqtcLRHdTf56+Lu4f0e2CQThV4BEh3kP+D6zyCjjkYT6dZUJ++ryj343R4TGqEFIO5/Abk6mjv\nBOmDZSAGG0EWQQ4KliHWDC8dnGUbCo4KrllOLn948W+6DRetMpC+j3kCA3MJr3T6cL3XBQx5NwgX\nxbhy514v3whLPgZpnRzvfbbpGbyJeZ/9NvQ1pEbu9UKWwVfF83lpuj8N88i1ObXZv0HOiN6niSGf\nE2i3AzkERs4PXsv8vr/0HRjyqb2QIceBfKxy69jnOgrf93nGPPx9+PADkMPtacd+jbO62adGSNGJ\nZNwyGPGBvfU8zLdXTgeZp3+30wPpS/rZS90eAj4gSvH1GP0fiPLQ6WFHvCK2RdKD17B8W/GcXhHo\nIdDjE2izArp5vCWGLIe5z8AN24JwUVif5KkLzGt9/jp9rePOu/zPzxMYvLtwzZ8quWykZYUxdH1V\npJKx1LXOh4KshdsvKDCvix9T6RXkBJAPiJEvXq2tNzHe2G3w4Tz44Xl+taAcC3IryDp10zHdPLw0\nMy+Ht25G753cPPfl1tEb2+NnASge4+0/wLUfQ5+X9HYlG0O/yfaRDY9JhZDiISza6RV+nZcDQbaD\nHOIn8oXv68O9k8QGlC4BE8gXQF6AD573G0LHbE7lyofcCPIYBg+oNCR91Y/3CuvWcweVZhy1UDHL\nJRtBrleujzYBPsnrlOoPq/Hb4ZmF6gDxMvJmfTSHW6C+vjCG/lBIkZZuBblL8/11MP81dZj2ey2e\nnevBwYoButUTz9+gYjC8h8HSzSC/AvlqsDdRXE+fQm6dzNIZWHtj6dSi4bm7/svTMNQKtNtm8r0F\nOcycItjtWy/vgZzp+rsZKr/8L9Pyby70ndEp7FNh3X4BKpL2hyCNi+fR8QFYsg6kTbKx+r6q/Min\nGhlMGjr9cDyarr4DXoNle9XvFa5wfZtQ/0tr0tg4qq9z74Ox1QpXL97kXw+3V0/Q4Wai3/w7oxbA\nmA/TkvAL/V7xioL92nb+Z475cpCrreWe/jPIRLt90vFvehi9eIzj059X66jULNntVVtbRDze818o\n6XsXcaoU17q97XyQa1AeMtuCroAeohuW+/8hIM+D/JEMPGzg2WtgYmBOmuh9miJVnxwfgMcBOYmm\nSfKxwtLR5ol33Aq48l0bxhsNDpO6aILo3Nbs1IJJfMLdh+8jw0GqQe4BOSb62kYxQspVIHekQ6e2\nKQCSMZjcftuEx206edGiqF5BxSmT1fzbVEGf7cXp1Cftht/+ymQjtIPNNLdeKdwg2s2Anq/DpZ+m\nnegxMVHFn5h3EXuKWpSJub+n1oHcCdIV5HNmhvjSdHIqCZSf7C9Rqp5/gtxLBrVSQU5SksTPutT3\n7UER+bxZUb2IkmxykL4gD6eHzzyRm7x3Lg7U34f3Hedw874zcVfeHTX+HE1unz59d4pM31Yajcec\nC2s3bA5MqUn/MPnHKL96KMj/v/+rcP02FZCXz63kfjefTv2SnmpNk9xsLnhEP7cRq+IeJuGuxv/R\n3jtFzNt1Ag8VbyF0P4Hlmez0c0HeAnkUBrSGXs/CdZtVicC5TxExo6Qdcfd+Qfmbv3Rz+jiJG54+\nJFIKYJDGapNGG8v1/pdBVqU//7Kvw+gN/rmEq0bs1i554Zl0aGgfHBqm1K8aerwLE1ZGUwWY0irY\n+rbHETji6rRtb2lSDrIOfnNJuBqvTRVctqNYmu+71VRxK4Ub4Atw1cfQz0Ovo7bBCIl7mJTCQSSV\nTuJtgHZLzYEKldaTVFL9W79T1zU3ogcuSVcnmn0u7XgbL5La4CBU+oJFcG0Cf2Vx1E1HjkuGUzeT\n+ufVIMthzuPQparYGFhqT6nSGOnN8/JHIMelz2h656g3onR12sU00f0pWLIBJNCQrYc7H21bK/4Y\nD7WO8QUs382hujjI01wCcn+hvdQIODrBN2+l9Gy6Cfbeno5LXVopZ0vDdOJtPJusltICFUG8CqX2\nOieZBNa8lbKxDJuTXI+fH3vCTvjr5WnhJf4aiAMj55Zmve0jkOPSZxTcRb8Rpceg9HAOWxX/VpZn\n9t6YiTBJv6PRjdOGD6Rjw/BGeAdXoouM67Q3TbSFNuWbiFYkILvgq7zUkY4HiP24/V9VhTtsNp4J\nh+2WwqgzUS5661EGyG/o52hvk0iDAZs3T8XLqDS2X8bnepuu95UeLmkE8ivl4mvOEZTeWEPfCWZY\nfjrTqXGg/+sm+sypPh6Hnp8qOm5jVR402TpGZ1Dx1S1BB2etFKe2qBXlEJB3QPDZCKU4H8717UE6\ng4wBuV1lBdbjOS2coC1QP2AXKbruptJJfKJJR4JLWxL3w5Xc1zva+DIUjS+1Hs4e1f5gj0Gi8r9M\n3gv//guaPPDxYTMeMhH83k0bdfI6kNdQXjI7QTajAsZm5g6tn4JMQWVo7QTydVSwkVV21RCcNwG5\nG+Rfqs/sDhlU8e0nYME7MLhaz3j8uNXvl/HbYewO/ZqY87mkMw9d4FT5NmWDKcaZ2eawD8+h6c71\nMASpyNyG8p4zoes/c3WYTygeu2uNXs08tS5He3eCTIbLXgiX9E3qpr89ZGPc/a/W6fuJIf7mSvv6\n70d88gLu0ca3Zfp5ON1pBioFxolNgfJ4eDap5OxvPXbXZHFAPo/KaNoZlWbjOlQVsPtR+f4/BNmG\nCspbgsoM+iDKg+sGkCEgF6CitY/E47rrMs6/qIz/814CaZotvUsHVO3V20AOKKb/4GIhZrwNWwFj\nNhW/N3w1XPRyFgykmIG3qVKHS/ksGKj1hgn2XMp/Hy8FhUHPnvPQ0aloZBIqv9ABhe+SJHKzyc57\nx+1h9RqiwpJo/bIk8FJ+Coju9zrckCh0XY/4alH6vuzUCy7CtGT6YVfb6ekSC+1mZBfhmuSQlmYg\nXwE5F5XtcGKOqf4FlX11LsgGkF05hvumSuUwZksxDFeuhIlnETHmIZwme81ULoSv/RyV6O3C8Hei\nFIMZshh6z1Fuz30/UYfABzOVJ5vu+aRqT+/aDV+jxjfZFUyHVRdXlHx4IZs4ONPQSiOUH/8Piuna\njqbjqUSj9N8l8U06FJ60OtpfPqhreh1I8/h9JFdhJJxDREnfC6fbiJWmpN9rpn5z9o9keFd9Za+j\n1+D1IJDjQdrCFS/pcTd1O8huVHnE90CeBPkTyjYyFpWhsz0qT83BwfPTqWLGx4qeDl5vr946WQqD\nYBhMBWkurjUdMObD6oodfsFqukSpaBWTDr6Icmo437xWaarBbG8ScggsnAujPs7UnpT1RquPD8p3\nv328d0168oraoBJt6cFub8gNd1frnHKyLpM6qbW14d2k2y09jQTmlG+CKg5zBsglIMNBpqEyw1ah\n1APLQT5BRaHOQ0V/zwD5CchklQ43bYZrCtwx+aInibr2VSpzQHqowjg6vHU1BNYF+sQbUk1nL1yh\nVIYrQY4snncWNpw+z9vME5U94P6sBaJMEVtfH1TpvqvivRukJ88vVlbugkH+1kGGsDZVys3VHZhS\nkUGyruHfUsbheFJIKV0v7dY5mWtcjhEegSoWUw4yCOR6kNth8lo9c7xuM8gDIL9AFRIaDNIF5DRU\nYr1Ao7SfIXSZFSRFRlN9NG/lz6VUUQsTRqEM3O+bGVibgCIgNjr9ePSQRIgA+RHI42E4T0ZncqzK\nj3XlyuJ5TtoDPz6/AP/I+fCdzdD5lMxpv9SbrRQfkHHELMWYlu90vLFNEtG5z9pFPqYjHQRIe9Ph\n3XvjjlMKz4QIc8zUNc48157PgFSgDIo/RhWteQ6V0nhj7vawAuQNVAm+O0BuQgXVdQX5FqomdJO4\nODWvr0mtecFeePZa9iWYCxNMdPaI5mVQvgEqdioJP59SOj7dhgkRYQcCyAEKzy99N83bp8tB4AW4\nZi28+lP/PJ+eBItXl7omh8h/L9M/F+S1eO+G6cnznyx89E0HTvc9pWKW5o3U9msoPffX05/fZS+V\nnkayDuhr3krp8KNtaFSZyVYg7UB6gVwNcgvq6v8EKrleDcruUKN0wN6CKMPXwJ965vo52A+XiWmb\n4lEGFOElKqPO6oZnXsN+r8CvL1ZR+cFjqlQudrl9ku0fnafOoDeKDdn5lNrtlmaqQi71ZivFB+Qw\nlCtfo2IiDT/J9Ytm9p1OF24TEZs2Y8WsqPOLDkO+4ESfLSoK12aDe9358nBd+rZ+ftN2gTyak4Cb\npj0nPZy9X9DjNI0c6+1mwJWzYdxWOOORjHz9myiJ/46u0PXNXBH2OhiyFOY+nbsprEB5LG3M3SSe\ng3FGPbo54V3PRHixPWBt19x16Bh8+yethes32Y2Z/PD3wG1lp1DvdKxRGoRrJEm+nsjrkUWn+8MH\nFeDzlWTGLJPv9IRP4P1HSNmn2wyr6dpduRPmPqnC1dOSVLxlBu3d6IIPzFqBsbuhjwbW7qeh9OFP\ngmyG9x9V0qrXYJmW6kW+AddtSLrZ7dcvKy8UKxvQC9DpwVxdhi6qZqyI/9NzpjqgdeUqxyXEi02q\nkCg+8OG+/fYeM0nTJnjhDq9zXJ+Cpch/N9N/FKRPuid5XmJr+zWQu1D+319LF27/1dm8ITqfAgPf\n0M+vdVUcSbn4gIkWMBOuGssb/MyqAZAjzXNK5o2Ectn8Psg6eO66tBl0Gt5N8cbz4inIqGreD+r3\nbh8pmPOwDxfoVav6jJt33iYYz/TMyLkgPyh83HmRzEKJ/e2i/OEk/ME/TvieqU8Vssh/N9O/A2Q2\njF2e5CQ399+8FQx8HabugkveSLIp7MfzM0tzIFn/yPpk1Z9b2jMVNenqy5tuhkU8/dikbjb1Ez/u\nAOVbPw/lctkyCKfx1yi9OAb78XR4GrA3mLGHGT/bVKk17lgDpz2rbmjxyzjaSPHmuYxZgirlmfuM\nWeKndb9vv0Ga3g1PjHPRxCGwcA6MWh9vr8i34dpNfniCb8f16Swi8h/E9IP0fSCNUaH2o1HVsxYV\nkDf8/Wyv8dFSNKStq9ZLDfGjZguMa7ooXa5WraSdox6WeQK9JIrUGywJRS1zKM1Q7pGrQfqQqXte\nuxmlzNNkxtN5BndRrxvnsDkweXWwqjPv2pqsYLuL7t+EnnvhgteLmXR7S8k8SfTs7ReArIWqYerv\nSWtg/DKK8vPobp/ePXvzOahUIKuU4Kej+XZL9V5M4sCV/zbvq/z/B362dfr6U3vYanj9dlSY/RZU\nHpa7QUaifJ6/CrJc/+6gWNbxwuK7DV72KpAsdL7+A6hSoFeunmy1By4bKdu9qXRSS77IjW5D6hJw\nDfa836/azhhc4YkyjZ5LCOX/vixHF0eUhk6T5yZKti8GLLbN6U6hxKGx/KNidPHy4kShf3hqgkqv\nHUWnb37ODMPvu0fx1tGPN3kvvPZ/IE2jeevIISAzVBbXwcv8+6J1lXIwmLQyZzNMvcyryH8M0w/U\n911KLqrOg+BGKA+ew4tP/KsXw+u/TLbB3NcwkwpEV/krihdDmyrltdOxxpQ8qvj51lV+lU4+Olc/\njh2RzxO4NNfXpQKvuGDvNktzc3FJTe1XxmUWqp/OW5U6IR84ZdpMXhj6fgNlc6kGuaA0NJqHoevH\n+oyNWWVktbUBjauFY3zZVnMH4oTgvRdunEy2j8vuVYfzjCts1G1J1HJmGPQ2MAVbmI7epHp102Xn\nh2Dhe7kbwueC5pA7HF5AZfdM/Waa+WawI9gwF6249TvlVZAOnu9aoZJvfSE+wbolnyiSvq0Xgzcq\ncpIoD6I4VYzy8EWNnG03QzH1dkvhvHV6RtZ5D5RtKy7cPHQFzPoRyEtQuScJsyjAce0mVQrTxPB1\nutt37iZB/qUotBrutVQ6dZ+/354zFeOaNwve+bN3rNxt6I3gfi7YHvfwtqP/0R+CPJ7GeoThEyo0\nEczVAgN2FK/f8DUwuwqm7o7He3Q0MXq9/R6U5ii325+mzfhT6ygeUdpei+J54KCMueMN398Wn2Dd\nag97nb55HoVqPeZngktIBhwoiZNXBatbKsV/o7hqIcjFcO596TAL+RXIJP1v2QZZ2dCqzbom3QPJ\n59D9NOVq7B3r+BNRwV4nafDeGORWmLkG+tclhTPEa+X8FNYjMK2DkqB1rromO8ygN5SEHof3pOE1\nKJ8HmQ0yLVVaSJu4khNAerpwlGH3j5rvj0NJ+0fFhzevPx8o0HYnnPm03bU0SCIcvAz6LdMz75vE\nJF2AnKT0gNkxP5XjxZ2nptoF176NK24pKC2mhkpBcJf+txLkHw+h1fg30ewPLJuxUIbuacXPy+dB\nnkIVEfliGp5OenoYsylHSzXw+FV2N3/TXDqvD5ijA/IXpSv3wmC2w8TnPba3+uD5ghwF8iG8/D33\ns0looQn11o5pCU093zUFjm7pfVJka7Xj/Goc3PoALHgLalbD3EqRrdUhg8wGhvv7Y6XjMAP4DjDJ\nDt65lTC8G/yhuYLzC8AO4Abg+oOg8dfguY5BMKl5tOgMe/8KciacdDBMAI7PPfHrVnDZNqijGDd1\nwKfAqi2O036Gwt2a1XDQrfDCQGAk9P49XHUZ3HGiercOGL1EwZ1G27YMLm8PD+RguRu4HGiUg/VT\nF6w1q4vnu+QWta7W6+Ztc4DR+p/WrNbjS8EQtzlOi1Zw6i1wxMnw+W8E02pcGOz3QPIWNNYf/w6L\n/+w4H3ZSc+l7D4z7NfAw8B0R9sBWgAFhoxTwlqfRwnr76WHbJvjteXD8l+BPZ8Kcv8GzB7jot63j\ntOjspxfTXL7QLACf44HT4bT28OgXi2lyb1Oo66Fbv/g0HEwTCk/dn4M7TwyarwhrHec7Q2DXS/Bs\nk8Kz4WthbGlLFMkljwsf1T8vN4JEMsCi3PW2oymKAXI0Kjy9ZQRJpQw67yo2LrrVHLYBHTJCpU7W\nSQLdZul1+lds8kcGT9qds/IfWyw5ZBH2r0tQNliUYTee7cB+7M6nwE27lWeDjT49TY8okTA3zPjS\n4P4g6Q/7SFOycY/bnz0+3sLsGfJ7cmrWaDd/47OGFAiXvaBuEqpMYlK47XFhrrOcdL6JaCFt4kpG\nIKM+hiUbQa4BaVJ8/bl2HTw4KPo4sghEm64UZST5f9H6C1Jz2BooZRKMnm++inoDZM5+ylwHtVSF\nXYJsDRVbVbm89APT9HRSnJKhmE6mbocfnpfuXMPtNi7vnXegx25dnVjN3MriBtGlg8eBS+ByIx2m\nRyM6RiangHwMcrj6215FFk2nP257bo8aPZSK1y+tQL3mraDXWyqrqN8DL9p8/c8mgi1t4oqGlLMf\ng4GfupECciLITFg4W3mCeIk0sj747yB9Db8didLtfyk5YUeS9G+C138ZTSoa9HaBAbkPnfJZpVkv\nE5F2W2uzJnG9VAL0t9rgIFUI/sp/J/GGMUc598zhvdNeXUGdaM4J+WfjR7rG23Ne9870bCIqz49d\nX6i00deEr7Mp5UfzVjD0HRi3Qu+903MmnHOfiriV93MHTGShMT6ewyKQP5OSfqCV3dFHutVKmEeE\nhrimgfwo4PcfgPwu2oLq1C/dt9tW1kLlUb8+inShfk8WGZnEPdBMpNN2gTyNMrb64iVsN4F53MCU\nDEv9TDd58rlw99cevv5BGsEFj6SgoihpbYG04AA5WkX3hvcFcjaq8tjBhe90NDLxEzjlKwFjDgL5\nq+G3nOFW7s39/1SQBSiV0iFZucoG47TsXtd8y2CQtpC8zf5JBF8pCax4IsHEEV702zo/RjeQJwN+\n/zzIehBf4Ir5Hbf6pcM66LCz2Fc9LIun/AZkTDR8NW9VXAtVj7fg95NEMjZvBWM2+9/vfArIZaig\nk80ob48xuKI8zZugTcKUDFPdTNeJ615nh6u87WawFAeo1YoqlCFb4Mad9pKuib4n1aCKu7cohicr\nBpVcnw1yIchqdXsd6Onryo+KD2ZxUPEzPqnbLwQ99goMey+gCMrFIE8ZYJqAqnH8Odd3zUHugw8/\ngF+B+/MAACAASURBVCHLg1SGyXBqWtvKPUpAeuWHMPSjKLc8+GlnuLE2j5tE8KVFPNERo0OK250p\n0Kc3v5mXhrt3yfEgq0NgmQ5yd7x5RJeUUNWSYtgnur9qy1TSgNMD88mwZD10eiAgQ+YhID1y89uE\nKrE3QR8QI6JKPCZJyZCXvKfUgGxQye/i4Uc/bl5H32E3XFIHZ28vZvj5z+B/gxyRjjFy4BuoYilb\nFYN4YZo/ZD9dvX9hrhWzVLrub3w1/NleuaCvt34H8hFIx+Lfe86EfrNUkZeCI0WOPt4HaRwOU/C8\nQb4N8o6GVjthMNyqQ2dQJllcw9e24wMgPeGqBTF4xlQiOrIY+0qLcKIjJkzSN0lb7qjQqa7f9Dld\ncpLFJgyqh9wzh8KSDXDho9F1ztF1oqhMjz3TIybbRGrR4PTA/DiGACnD8wehior/STESHdzjxO7g\n1qVkcNPCkHdBjkp+sPklapDDcwz4c+H++ja63PwY/eZC172mGyJKKu0dVPQkm30pL4F0M+NHl95h\n8DcNfTmogvETc383AZkPclEatI6Krl/hGfNLIGtAOkffC/GzuIbjyb22sXjG2yCJHBT29ZUF4dgh\nxpdAbZVfcmzeCkZ9AJfV6tMATPf8rVcX5Ag5gAiat1Ih0tGkqdwGjrwpUTVRy9MmpnibqOMD4e9K\nOcoL6sB4a/2Vk2CAJxp0hMB4sZ1LAdd5xu/PKZQMPyYvoSs+hIkfqd+jMHVtnVjDGGbPp1IEnxWP\nN/NGGF+tTzcR61b7NeWR1/khGLlA3cqS2HLc2gBpCrLd9fchIO+ATIm3F6JncQ2mJxMdRDVay5dQ\nKmif63ks2LIgnOhI6fUsLK5BEyELMhf+0CNc6heBrjUGpP0yiBD0i5BPj2rSJ7q9L+yrS+XgeR2k\nbdrEFP6eLhrywwUExCqgQvHfJ8bNpLif1lWF4hzTRZWIi8pAkjHdYPjCjLd520EWyb6C5lxKX/4w\n3/I4EmrzVjB6Q5T9YTvv3E1iR475Fxluw+dZUatXGWZrSFdjn/UI9JWCIBsm8Mg4Yqqftf1lOcFo\nyJBbUWHfjVzftQJZB9KoeLOdvb1wLXYTREcT0x8G8hfz2F5itimE4CZK+6LGah7f2Qz938jCrz0Y\nx2O/rVQtbpc9+Q7IUhCtlwTI8NxNKVHSJzXWCFcJxHiZG5Mw3eB+wwpbhDPaMINrfKZZqvw8Yeqr\n0h1a9gf8jbXQ91UY/JYy0BYMt8F9l3+kssa6VYbhab+T7wHvnPpvD8+iKzNBuqcGR1YTjI4QOQBl\n1b/W9d3VuhPOXMtTX6AD5EyQ2faEaVPybP/ewAY8XIrG2wHlbrka5Jue75vnvv9WOuN/kDPu9ZwZ\nRy2WLW7CHAeSr61/jHz+pvPXKXzoA7oKh8nI+Ur1klFxjRCajkO/SdRTypZz9nIY8GlOmPIE5Hlh\nGWKFm8I6pF/WMujgj6keOwJVL+SQ1Na5PjZYwATzkn2b3N9PgFymJ4ZLtxXX8jSnHkbp+nZg0En7\nCcimuHFQKLhJ0qtf32yQ74LcYvitt8J9Pqd5r5kwYg7MfiilsY9GGdSb6nFe2gNQTwMj15lViMkl\n2uI556N87dWDMPibKi6iz4vRVXvhLp/siwVxB//N08yh3QzlntolUEJNQvPhxtD6c2qID7N5XNMa\ngQwBSWUP7oOzPjZYMOKkDyxaDuf/Xfm1dvib3hgWLZIRVR/1G+EbY8i70GNPtA2c/32wBPnrl9oo\np8HBP0F6mH+/r5+/qtDgZem4sckUkD/pcW6vqrFlYPFgnD8LKl5W+Y86b40We2G3tgX489XX7Oox\nmI3AwQGBUQ5XtPmVBuzS7S2QR0Eut1uv9PMSJbtBpCd8eehxqV7tPPhNkMuV7VI37qhNMHy1Dkc5\nPA9Ii8ZF9kum37wVXL0l7RMe5D5CfONB+oKshbt6+Qk1X87M7c5XxLQMC+4+KOpP0kcZutaCHFeK\nzaAZ+308BW3i0UY2twOQlrmbyCGFsewPJCX12uOuwLTsKq/ZGpr9eD//77ZwRVl/kEqQn9ivW9TD\nPUzVlOQGceajMESS0pGeHnUOJhNWgjwI819TUcbu5yfugms+1c/l3PtQ7sKHJ6XvIrjT7CwVgDI6\n4VEGy58F/D4eFWRyqp9Q21T5M1xGl+LrU6VBwX/ZaJBN+yZSwOGAN5XB7QhtlsO0aCMcjsC85RNB\n/hxtXvn+HhkBSz6GUdZuv4W52Er6Nobm7k+hakT/ClVub32UgLVoScDkApAX49FD+C0tnA/EsS94\n1WuVogIE24SqqaLB6HUl16nHes1UgY63nQ+D39Hj/cr3QZ5NnRek3WFigML1XrEMgCAXgTyv+d4B\n+T7IQpDj4xCg7TOFRR/2LoytLqX3DkgvkMfiEXHca28Sn3mdftOY9G2W2XgWpmfNj3XdFujzfLhE\nr+tv0m74Y89CXwPfghu22DEgr05/nkCXOq9R147BXL8VVRt4Miq24uho0nskSf+InBRqVbw7aB00\n612mbtWDdgcLWlFvY+neZIODvOxp3gzXuKVETNdiBXfaHSYGyIiANlVx/eJzRNpSST4FSRflg/5b\nkLdg6Bn+YuTdTwPpB5PXhUlA8MBAdVWz0Z1Kf5D7SotX+QHIzcHPpHcTSdeAl9ddd6rRq9Au8lyZ\nh61SQUbyExVYpYcjnrRo7T++AkNK7+K5tpuRC85aCue/7U+1PGy1qjk8u8pf7jDc0GyY4xZF67r6\nslEyv8pSkJOT0cMZnkpW86RgV0gujRfDkPZNNsiZI6qdypf2ejEs3UyuVkaqvCDtDhMDZCS81i6d\nqb1fvGcjrmNfwRE5GOQhkOfgwv/VZ84cvhc+eB4GvKZf3DP/UZBQrlsPt02zkTxAykBeKy1e5RmQ\nS+zwn9wPPv0Sgnk1yMDdxQbWfrX6g+DqxSA3wLA5JjjMY7WuMt8cbA228guQymg4M8Ezeh7IUPjt\npUrPG83QXHy4tF0JFZ+aAoNc3jk7wrxzQP6GZQ6pALx59Nl26q54NJm2pP/4GL+OPq6Q5N13fxsA\n8nomvCCLTpMvjp/xBF3t7fuVZ1GZ+VqgdJ4PgBxkJgaVI19/EA3aBmMDr58BcBxHSBK4dPEpDqpK\nmHVN4ORjmnDaPkTSv+xl/ToXBUm5JKkuhmRu4QY/c978ATtN62qvxrunQhXhtvcyil5IZMoalezN\nRrURZHTUwS8fgPxvcH9D34HxH9mN38Zg6O76sX6dw3EQnSbTvMnK4SCr4U890xCSNP3/BuT6TPZm\nFp1mAqhxs4VnxiscIuNWqIpVC+fmkNpY/R5kJHMHprgX9/SnitMKFG+etvC7bvBuJ5rt6MgRuzvR\nbEc3eLct/A6lVvoE5KDS4E5OxJOYKvsxdRts/A649z69vl6+CfIHmPaJfp31QVJJDH76d02lEfPS\nf5dZ/qyfxVGVqm9viuF0Ug941vV5kPOT7Z88Xr0OB9d+rAr3tK7yqoJsmKdfT3/6U/qAyjYriuHK\nTtIvhus7dcrwHfcmK38gYtW9CH03UgeKGLOdJuq/VEwgncUypdiNmq9l9IZiAg2W9PV9enWvealJ\nbZ5u8K7mFJFu8G5uYZeCnFQa3MkVIA/Xz5q5D8pvX+jXS4+ogQXvoDynpsKoM4Pd4Lz6c1sGNKXG\nKxXr3+2zPVz6nyfQsRYu26VTk6RrzwjUqUdg+mH1KXSHpKlMZPvHoh+0fbb7q75Vi1I5mXT64ThI\nsCcq4zJtVOrmFbhqHqQMW1uQeZnty1Js/vSQYapP29WYuc/O8Na8lV6nr4/ytTkkOtFsh47pd6LZ\njtzCvmCzYaO4uZnfHbdceQzVT7RrON4uf5GinOt5uO1012F2CPX7pJVw5Wy9d4/7XZ0aQif9m4ul\nJ0w9YGVTKah3hrybzHOlUszqK5PUPeDToPkV+nAz+R4B+PLNuSwLlUkxPuTLKBvfARHfOwSVcbZr\ndvtEfgRya2b9Z9VxNsiwI9zid6wjJcvgvM3QfQ902K6uo6YNZ+qz9/Y8wXbgiE91TL8jR+zOLexd\nIMOC55vU7XH/SXMQZS388whj6OZDMbr0bCv9m3XPaRsM01hb9c6ImiC1lH+NTHPsVKOfX5ucCqzn\nRn/Swnm5w2J/okd5FeTiiO/8EORvGcLkoNzHz8xsjPpCeDyERDNGqXdsJf0ojMHU55lP5/vpwPEi\nmh3jkvSng3wveL6mca7fhMob/hoqA+YzqCInD6PKFv4Frl6UBeNJdvNI23vCRrVjMiCGqQTjSP9u\nydVbji89BhdffbTgXbjshSAJ2k7Sb12lj1jPBzBON+Ann648Owk+Gh7lapB7IjzfOnc7yMwhAuQU\nlOooUVbbwDHqE+nxkNK8lfKj96p4RMxeDl4CHbnWTqdvMqCFu5V24CzxdCiC0unnbAKvwqQ1wVd4\nk2Tc/w2Qb4G0A+kA0gWkKyoAqy/IYFWwQvdufC+IpLeHtG8fdkZcnZQeDQ96uHtU+1WCbjXJM1Ng\n/LIsGFzMyktngSzBqkxhmE7fl4Jkht+lup+O/BPRX9ofkC+i6jo3s3i2CchbIFdmDFNqZRFNnyb8\nhzWRrdWO0/45uK4/NHX9UgfUrNY/36IzLLkF2pbDIU1h1JMiv60uPHVMy+K+QP19dEszDPk+j26p\nxp1bCeV/yvezgtPpCEANajNAM7YvqGHHfOj+HNx5onq2rj+Mbus4LTqLbK0uHmnNajUv7zybNwfm\niLDLhCfHmVMOdV+zwZG5jxZlcOpf4OjDoGYzHPdhAW5ycN15osIDA8L6M+HNP2/b5l235cDdwNEX\nO077GXByU/j6IXoc2uPBvN4A5Ya5lJ8A5b8S4Wc2YzhOi1Zw6i1qTmtC8GKiC/+cCv227QybV8Hf\n/wfM+PbPddkWOA849lDNeu1bc8fpPbMAz/FAS5LiPesmwjrHmfdvuOUpx/lkVwjexwNbgbsyBqsn\ncG2mI9T3aRvvNLTPBug5RdvnJI6Xi79PR+1Q3I83gOzt34N8N8pYhviApfDBc6jqW8cH4EjzbiSp\nXIdj0RcGrx/pzY9vb6R23mPE+33/0ILsyWGTN0DOscR1pLVSz3vTQJsM3Lobij8aN921yK+H/pZQ\nH7RixqPXzqELVOv7qio+9L0OGdPMl0ixLKJxnPpGfHwCC877bUCqAwvfV77g0fyO7YnInSrCnf65\nSx08t9x8Nb9qEcgx+j69gWrSCORaVNZMoxeBrSeIAceGHEc9NN9d9I8gXX/c38Ln1WVWIT+LTv+c\n1yunXywjGLaye6Fyr4qejVLUw4vXILvD3Geg7yv2+nnJlBEHHzD7hw4/Ct5L6QhRoOfRH8LYJZkL\nJPWN+HhIihvi37yV0ucH6Sj7vaZO9VGxrOe5fpbqcwQN2QvlM/WENnYxKrXvEyi/+kPCPVPkbJTR\n58dEdD0Ln0fvLQYc7/XbR17cFIzXoERbSTIlSu5g7bwNem72w1ot/niK7KTNuIzCTM/D5ngFAdeh\nsgc6PhCMK2+/pQh86v4UXL9tf2TyGhp/UY/3brlcSPlSinaFdEpJM4nGrG/Ex0NUXO8F2xB6+RnI\nnXYLposu7TXTvMEqFpqZoDQFGQDyrEq2ZK4r4IL1CyBPgswiIFe+PW6lMchEcyGZtiv8N4+LjcE6\nwdJUHM8aY3+Gm0nrqlxN4tezZkTp0+WklSAbUIF8f4WZU2HoClsG4e83uxQHLvo5CKQOpHl984kQ\nOB0lVevw3lkTBFqdOq6S0EyiMesb+fEQNfxbMHmvLfEX3rNOlnU4yjXrNHNfYeH9ppKLN+ywUbtA\n54fsdf/SCOQGkBqQixJshJNRvssvwxUVtnaT4HTY3V81SFOL4njWmMfKR3b6K6qhbkPHZ0+XJtiu\nfD9cxWUUBBrl1mW4mUnZepmZ3UzTxYO8Avf3j+vaW4oPyM2wcDYMXFKM94qt+gR+0zPCVRA9Z4O/\n/zjvHdV+3x/+PQPKG0fzArHzehBhk+O8/Gt49GnHqV6gt+qffqvZk2VuJRzaB+oO8o8lu2DrUSJh\n3i4tDlfv5j1SPgUaAc1O8D4pwqfADx2HWcC9jsNfgJtE2BM8hmqOwwHANcAU4CbgTpH7P3WcFith\nict7Z+4gka2v+HtYuyYAr+31v239MpQ1KvyWn+duoKaV47RopV/PlVv0/dUug9evh71PwO+b5zyj\nmsPou2FZCzih1gYXyZqJvg78Ely5AG7N0UMdbo+tgsfMhz+Hr3RVuN4wB/at7XxgvuOs7gdNv1w8\npq2X2ZeOhyNaw4Rd8IvPu+BYUvBESqu9NQde/CU86xpneDfHuWAObFuWzGMruNl4QTkOg4Ah8NV2\n8MjBsNjlgdX8BDi5fXGvTVF0mQWu1qxWy/sAhT1+NnDEaVDVXkcviYes7xM3xgl9XO7K6zN6hr9r\npz9Tz3kTZg1bBS9/H+RukH8rQ53uhO6ay/Eyaid0r/OP9frtID8PhzVvrPbaBSoCE8yhfI+fQQVt\ntbTAZ2s1H3k6rjQMb94B47W6c2Vs9c5hikD3zQXPGrsaCaq/HtV+Y2S/avVb6yp9Eryb91KC5HZm\n+gpXY9kFmsWJJ2k3Q2UuvX4TvPZ/SYz79ni46DX9OuSl5YrcDSx+oF/c/Q3SMXeLP6UYR71mKhvJ\nYFP9BasU7sGw6VTBOi+58r1R1jkyLFlvhPQJSn4Lclty5Efxesgj/aqFICNAzlKeGbpnKj3MqHWV\nx/PmZJBVhFQcUs+6dYv2i4/Sy09DlUcsNzxzEKpi2DqQocSMAAS5HGQZDP6mDq8BnlY5HXy1QC+x\nmWdhXfzeOLmAN0MSvGmfxp1fGvRlV0oz3cjx+jAQusbdoV8Hd3rszrX+EqS6bKX2hwKcfU8QDnN7\nby3IearvNlVKxehOmjdyC/RMNZpaMfbOWwuG4XkCg5epamsV//LDbFINp2NPyHwTpLuR8p41A1pn\nO17cereTpDhC2KiDnw1ybjgcJn243eKjsgGuAvkurkhMdWjJByCP2NwGAvo/HeRjEON6BDCfssL3\n4QZGdZCZo4zNTLNSYNon9Uu/NgzdOkeUlaSud9esFFUZLjsde/A6uNNjT5WCgOR9zksfRXTTCmXn\nOBGkOyqC9T6QOTDNcPvuORPkKJRBfLCeJt3pXPblEEp8A1FjmbIDX7deX5UvYy+r+twM9kgrsUuT\ntZePewN2rClm+AWCK36+TRVctg0uqfMmu/LD0fWfSRcf5GiQmag0vCeA/BRl8L2CGNJvYc6Xvww3\nbIMnx1u8UwbnrYW+u3LX5LLivjq6AmT8VdGUZCaz4Zq1fnzsy+ey0Z+WQwT67IDFa/Y/Gh60rThI\nKronU/CY7kNEF6CWlc+56fDqJ8Wuj/mbmve5fameDd5Y161HeQctB/knyG0gA0HOgHMMt+9z70MF\ny31Xv7/zB+LAHFzl1oWZ4vOS6WIWVuaJ/6BIMXdTfW6GZEjL0KUplv+4TR6YKOmbpRUsroHha5Iu\nPkrd80IOrjUgR5YOLzZ6Vm9Qm/vZcbWweAVIb72Pvlcf6s29f/6zIAvqn47dAsKZj/qrruly+Qxd\nEXejF9NjtpKj3T6Y5FmjeaKX9PcVddmoPzwGvQ1yaDRam/skyF/zQk74gRhsN7Nb514zof0MGLhC\nP4+pEhIEVpaV7aVeN4IdEtMtZhx98eyQHsbcgq+9+cV3G5QWLQIZn9TwBtIc5NcoNc+vckx/GiGJ\nt/R9xYkcDfKr90ZFm6S7snsN62J4Ps/kBixWBczk7fqmYzuc5KtUda2B87fB+duVii/OurvpMXv/\n/OB90HcllG0r1mm7s3LmnyvKmGtYW5tCNIPehAkrFd7e+h3Ii7gM+WkciDp7g37ug/foXUALFf9K\nYVwvgr2+N0D8DZKdpJ+M4PWLF1y5qPdbagPkPR4qBQZuSe7NIBegrsF/BDk8911L9qVjPrdrQTVS\nULuY+4uT3dH0zlTXWuZ1tdH6D3h+o8tw3gnkxfqmDTu43bEGydUxevWZuPrMZg/pjdna78pUBbK+\nUmxM7VcdpNMPH3vEHLh6KQx+ExYtztN+8TPxD0SzgNfaoKLzBnsp76V6o7/63gB2BORF8OhaheD9\nM/BDP48gSf+SPfr6ofFyxKCCy/4EUg3SRfN7E/jL3TDYy1gCk9alK+lP9/UR3SXRxkAql4I8Xt/r\nbwn30uKbij2e9fsmL4lWzIFhu6My0NLhQZ8bqTCH3i+qfFnj24TP2csrhhjUp94D0Q3DOFG1e03p\nT0zr17FGf4B0m1VKST4U7/W9AaIRcM+Z0O4f+yMB281h1FY/Y79iLZy93kRE0ceR7ihVzv8jIBQ+\n4Pq8NHgO+hw7we+YPCXcY/ecGdVmkJPqAm0eqPoC99f3+utx4o0e7ru0cPsTzcfWa0uHx4Efed2H\n6x8P9jc7VKW5ScH9xRFKvLEf4UnpzHB33alX5exfWon/iIjcXBTaAACVJ/0XTeLmdK+/tnUjLPsU\nLnkKmn8TaoHDa2D6Mqhsp8/n38y6d8fhSOBXwBlAXxFeDn7j6MMMNQQO8/edj3Isbwm7dqvgs0+3\n2ERCF0ebfrEdbGoBvz9E5VzPNxW9Gz3f/tYVsGgzDJkPezE83wyF7P2m5eY5BPY+Cb9vVogermiq\ncNGIoMjx8KjTU2/xR4vfcRyUvyTycM/MJ2jdAiO5Pe3BmfDWzx1nyaXmvPfR6mJAfi3OehdmHK+e\n/SnwfYL5iynyuvVB8MO9cENjOJnsIp4Ttvo+dbKUDvanD6o024Oe744C2QztHtVLKG1C1TuompoV\nKDfMH4McYgePSdLvsEr97k5f7HUfG7wsiqRYLHmml94XpBsqmtjoegoyCeT2+l5/Df4DXPXMOn07\nb6j9a4/ojZ7iwL//DONCs6Cq570R8rrn4ia8s6kLHBaj4zVC7z83Kt986xuAdDZLelcoHYEm71Mc\nkPkgHTS/PQePjfa766nUAiH9tgR5FGQuSKC+UzNPTfj3wD0wcxXMf02lnYivX/bg0XPA5P2iu8YO\nFMrh9E2Q3iHPTQO5pb7p1g9XWKKt8lx637w+OMwLzG3H2H+cH/wHfqWoKNiKOfDhfOh6api+2zaG\nIW5MTxxvHjWWfdnW/elT7wAkIyL7ha3PvkHO///tnXe4VcXV/z/HkoaYxGgSjb+Imh6NGhMiQhQV\nxEIHpVyKSJFexAJyNSSa9iZvisa85k3TN9gTiZpiBRtEjV1EI8Uril4B6Zcu6/fHOpuzy8zes8u5\nl4Qzz7MfOOeePWXNmpk1q3wXyIsmiRRkBMhtady2yhve+Wg07LcJuKO5H1plX+CA9w7IPjDwsQoN\n0umX2RWA5g9vLz6sHKQzyEIS4SzkhyDT4ue8+dEgi5FKzbSs5hrJPk6TP3zyjVHH4o7GmsX9MetN\ndHc6XFPNSUt3IBsjtW4Dl2+Dvg8XuVCrNYkgd4BcYPnbASDrcMQfB2mDAqo9DXJMlC5xCUtcDwP/\nxuL5VSdnKbNfey9ykp5S0vRhkDqH310LMt7OR1mCzdIdEu4+3S5SaRqpd8iTMGl52jVS5EFY4aWs\nN8Z2s6oBCW0YY4fK5/GboNMDyVAXrdvA2DW7w+Gaauwt3YFsEyYlkPcIBRjlZVa7FHXJWpDRIAdk\n6OunUVTQ/WJ+81eQgQn17IXaBVaBTMOQR9N+aH3jz+m8Yvz1PCaurp329icLTAzVkay+iqHFSSCL\nTTQw/PZ6kGHJ4/T31xWfPqv3UvggThMAaEcZjf7+pgEKXZH2gAr3N+hXnk6A8KARsnkkaRvF5jmO\nmZMO0Os+mLbRnV5/mwCTl+3OOvxIn1u6A9kmTT4AssVxIp0nwb4JnDMX5NayRD4bpDeOUL0g3yPB\nkAgyBOTOmL9/DuQRNMHJF+y/sx1ag1JJSkFaukto9vYnCYyQYPCZGX7C3Bdvg2k7W90OL3oXBv3D\n7X35I8g57vRqENXVRqKFMwU5FXl7TPJrj9Jt6Gv59Nv+/moEaZp1psLZ83fA+A1ZpfU0Y86/zjtv\nSE8vORLkzax9aYmnxTuQfsJat4FTboMZ24MGrjMsHjBpAlr+MhYmb7VNPMiHQYajODarQK4D6YDF\ne6R8OL0D8rkExvlw+UAJRQ7KPmgC9FUgk0iATkgfNJIUddhulh0DxaRPtbXfM+OCN20wHpKp86K8\nB0s2sWh//frcBtEgnRO3w8AdWaXVIj1p0vm1F20zmCGal+BbzljvIBeBPAMdvqCHdfp8xWaHg/gg\nwux0DNueXOglJTLm92ip59/CT98r6p/c44GKD3JTHUw+rVR6eTEc/420PrrBuvkInD0DVg6Azr1N\nfuIirAN+C/y2VJp2Iqy6Fg4aDKWdpVKP38E3fiHCIl+15wDPivBqXNsirCuVeBDoCfy+3J+jgN8B\nG4C2IixNHsWCeph0Kvz84GBmpLUvQlNPN39or08aG6FxEU11bu8uqIfRJ/jmB5gAfJBsc2PyN78S\n9aX+Fo7xGTF++t//F8zYWslo9Zty/auA75ZfPXUfmFZuO95/3lzcsrW5lTR1pfdZj29jX+CFR6AE\ntOqYVG+pxBnAhcAJIo8uA3rp+l3qGIPhlaNGw2X76px7maUu2xeWjAYei383yxjjxxUuIkipxFPA\n14G7svWnmUtLnzrpTmib9DLgMehwU3Zpst0sNXiN/Vd2veeodTB+M1yyDs59Hr7xV/3/OXMd1RD9\nylLp+0CuQD1zRtpuEfZ6Hv8ZjFoQxT2JAEE1ZB9rUpRsu6UVcC3vWl6k1OmXuJN0wvIcyHGG778O\nsgK+c3JFr96tfCOaKRV1hL+t9BDFduP2c7eD7Jtubn/dw7V9e5Ifp9vVlmh/1Xjv5jIqn1faipM0\nbvHjPxBkiBlvPnne0/P0gA1Zo2lBrgK5Mmt/mvtp8Q6km6y4BNzFGtni+xGHo+P936+GGLzEQQ3R\nqlzXctSwe2h6Rm43C6augnMfCrcXNBoOfw5emuN6oGQzOCZBIOeh80xxXZSowfezwY2l421lAdi1\n5gAAIABJREFUuObe5vau8G324QPL8zXvuQrGNamR3IbR4g9w83zu298ILz9eViW9CX0fcjcayjP6\n3km3mEH9/GMc1gBDU+uotZ67HoUum4KomG7BYaiq8hWQEe68Fa5v4iZYuh7kDqibX5RNxM7Tk9+A\n667OahNEgwTvydOf5nxavAPpJipeytCJ7HGPStgum1NWachFAg1vTuMWgZxM2a88uEA73ARPXlt+\n99H00n1aaVz2VQn43inV8lHXPrW/UbMZnXQzGfDB9Z3OIUje1Dr9Rhj/9Sh9xq41b9KDFuum7kn6\nVum+A0zaYv4+HMnsD0pqOxs6dYcpO9IJKNK2zB9/cOeButfT4u2UeWMdDPuqbb60rXGL4IJXgnY1\n2RvkbyDX5F/TCqddhIOGw5iPgiUr4cS79bbXsTEpwVHo/YNRvX6zpOTMPd6W7kC6yXEJQZcDQNbH\nTQAKf3AlzNiW5eqYLIF6j/8QGLMI5AWQ1+GJX8B5oTyc4zfAnMtA5qanSxagqV+enXbjyTZn8gIG\n9YrbXIfhprs1wRfvSbmJbYSTb3E3PrZuowu+5+agUbdeoM9m3bS9Aztcpz/j0UyxHxrpcx+XN1MB\naVcUD5jH3uMeuHRDsium3EvIQI4Gws0hhdrKLkB1nxfsV/VQKrX+8bkyVYG8CXJkkf2q1tPiHcg2\nQUlh29KIQT0C8iWQ34CsAfmfrB4/8V4l/nqiagiQr8AFL9mkm3LfUuWtzYZz3zzRhCC3g/RP/96x\ns6Ob7gBRyFtnCWwvkJ3Qe256+nibf8dGhYtoOzsoXJho7lcF2dRDIvYI5brHLePwpPzFNmEmr5dQ\nhtviKyBf9n2uQ3PQfizdPFtdRHPBp6eLJSjiwJTZWfi8JZ7dynsniB745jrYBhzxYT+qnh9x017H\nKODdu0ulf72kHiXrDwemohb2a4HPibCyVJrXBkZ/OehtkoyKF0WD3LovHHwCHFimZxNwOTApUqcI\nL5RKK9+BVl8K1toKOOiTqAdAX+Bqd8pl8RD5+BFm746DDndv16m8Anwh/WsfaVfxpLkGGA7cBhzx\n/2D/F0ql/c8SWZ/kvfEhYDPI9rT0KfNZDCKliebbfZ89T581BD1PzkO9REz9OfyYUon2IswLNfat\n8r+/FEHc+5PGS8jkKRX1jqqs0dM+C49cXio9Ow3WHwT8DDhVhHfd2vPKgnoY0R1+07qyBr8FXN0K\nbuqpPNAEjD6hVNq/U7K3j9HLL+F9k6fTKuD9nUqlPnPsqJ6B8k90f7klqX8tXlr61ImXNNLqb011\nTNpSzp4zEgMCZVFXR3jyl2oQ6uULIjLXGSdZgJwJMj8/7YYsTZBuUuPpZ6OL1JEBzz7oSeNHndyl\natkRlr6D89l7jt7kGgQWv11EruF4mi8U+Oa2iv3hMYGRAudJsN2pAveLOfH1bYNBVsDs4RW7wMnL\n4aIdcMV2GPbVdDzgPsbsmD5DX4PFb4H0yk7L0+cFYT68G3PYRuYmeaePtI6L1/DmttP6uNSVcOug\ntNHPZp6tflRv1SpOP/FFeGrY6jix6gBIqKvl01gwdqKTbAvNl33RYKzD0rXvP7zGLYInYo1putDC\nuuapAp3npWnXgS7HgzyX/j0PY8bbCGKNqm3sdJ0q0PvoauiFK3V2NsBPTxWNQjaqLtbbDNua03fK\njiwpEyv92WU8dx6jmyum7Tcjns9HR1cbWRzAmt/dM23azTDf+KOHk9109f0hS9PMlcteUOQ6DLRZ\nrYrTT3wRPtktiyMO8gVY8q5KmPGndtwmBPK/IBfn6MfhqDeBVb+qbboBqeWkyX4gTSSgYZrpM7BB\nF6CnA7f5+1+4HOQxuHR1c9gpzLQ0tXuqxVGgu/VgrdSVB9K6fjP0eyzN4abvjV0bv7nZ1lfvXOvL\n3UbmAqVctwmOfyOtz31wPXbzRbAnz0Mem0Bz2db8z26k07fpJPfy/T9JP1lk9GOWsv8WGPAe/LF7\nki4xwTZxC/Cj8pO6iPBaqcQdwBTAYp9YUA/fC0XP1m+HupuSMzOl6svGUok1wP8DXnd/b31DqbR/\nRzjyp3BgV2jaR/XiJjvEmpXANFj+E2j19ejf3aKysxdb9OuHVkPTJ1Q/fD3a/53AshXJddnGah9L\nRZc97QPQqj00tXfVhSu9F6+E/vNg3w+aI2Zt6+vtXOsraiNbvg4OOQ4OPKzSRv126HtD8E2THeJX\nH4QfHAo/2AnT9qpksJqxFfa9RSPMo3wdzc7nRaG7zMOnDs2OBpA1cjpHqaYElO60nz0cpmw3n/Z5\ndPrNB3WazXXSGI24N+qB9NnsfZHDYckaxSlKCh7ybht/n6g3lXR5cB368gBIl+zvt+6g6pN40K6W\nkJri2z3/dei73BUVM1hXeklf4yKy3g46/UldmE9MuJ1Gcu8mBh5mnPMQb943FWSl8qi3Xk5dEc21\nLKI3V7VPVd6//rcwOTFAUNv154OYbJ0HFHdnAFy28d9J0q/aQkg3sf3nwYxNcOHoykR7xtBL10Pv\n+9NdU6vt02s2uqR1DTQvov7rVd8+5hWY/+N8/Ry3Lu3mDWfeVTQToknaJ+UxWFVcKO2gXWZ6jt9Y\ndcOY1ZA+779g0qY09KzUZdLpD2wwuTGirsg/hMu2puE/e9/jXDW/c7Kqj4Y+DSOXQ6/nms0AydVn\nRjfuOFdpvxHaurkuDWLqR+AZNkM3Q2Tz/3QFeQzkGfi/c7LnZejwFNS9F3o3F6BcIh2rOUnpF4rp\n5JVpIL9sqX669hmkFUx6Pd0CjzNgbRRF/MzqTVQ0ymKuLFfj4Zk/FHELSzrUg3+vmw/P/6n5eMNk\nmO3zUPqN+Nc9VHo8fT674BvaztZgNT/9Rq2AV54FeUs3/fQHdho+AdkfzVY2Rsd7/pvNaoC09tUP\nfxLIVevTuycha24UGLjRbAtoO7ssrMxVyX/MSlUXDX4cDj7ChS/t+4h7kqLC6NgcCyIPs6F41Y0k\nwAq3bJ9P/jvI0/D8n/S66yo1JRmvNwqcdXe2vmbbvKtx3YRb6qDrpiAIm1dvx8x5cpPblXEmgaE5\nXeSyqfzkryBj3Orp+yDlZDJZ1JuufIIGut0Fcl21+CQ7T3ddAX186TlNRmgXD6Hw5wotQN4Hj16V\n1qMqmSeyJZfJ87SgIdfNgCHCklKJ5cBJwNzm6p252Pp8SBeY/yM4cRr8+TBYfJUbfGyS8boVcPhR\n2fqa1ahtgkdODlizFTUu9r4KbvlgMPhmAnAYcNIn4JK6NME30fqtRucIrHL6wJ28JR09SyXaAkcD\nvYN/sfHeeyURdgBEDaIu8MV2PgnS9mMHwYWb4At94/tTTaO5ra/v3qf0fOsqeMkybhvs94dR/4LD\nyvVuD7XZBOwN8CLcsZ8Gi4UD2Bb8tFQ6scnd8cEfGJkFrjtnqdZpUqQExG6i4om/XmbJhNS6TTRo\nyLueep9nCsj7stWdx3e43SwY9CTMaIIv5TAoJ6mwPMm/XtRVLq2bYSzi45UgV2Tlu+L4Js3VPyrl\nV7PfMTQ06LcrAX+uuXqLp2OeALRdRtrNwVuBXyXUKRRvMaEJFi0BOcueaa3nZtescGWjua8NUxzA\nhe/BYVXD8alKpe4TMNhpAmHmSWo86j03y3Xc7CGT/oqv74QNiR7DZLuOwQt3qW6w+zxlhoW+uoct\n8xmpzk7bZ/jJ6TBtbR6jNsj9IOdln+c4XepU0cjVbFdm+0bo6WAnLINhT5dtLq1BBsDUlZbr9Orm\nMEYm0LotyDIMqTh1DMPeqIYOXes++Vao36EeQDZAOd3U9e/uuXqLpZH/APWcPdKs4TjBzTvsOt6q\nvDNT4F8LPKHL/O4EidJhitjSOVbiY/w8v1Cg0zbdA46dDePWqKG8SmrPlmJwJcB/nQbT18eDpxVx\nuoff79mgDBr+rm0iA+mkeKe6J6Wml3C0XyfdrAvtlNuDB5E/AYp8D2SBQklMcE43p+/2fVDzyYa9\njNKAUclpqPEuVXBV8iLrKcEEK+lzoNoPlHNCKS8nbCzjs//Vjs/u9aP5XHyj8zF1FQx5wr4OznkW\n+m1KC/3r3odpa/V2124W9PmnTddcmdPi8tZm62+WXBhWu0AjHHwECtfSCPJrkO6w5B09EL0czWFj\n+qnbzfzUsTG+fT/tZopGdTePy3mzMbaZANILJNZQmXStTdrAzO+H/b3DWBtxt47WHaDrDlOCiWow\nLMhXQF5Pkxks3ssoNZpiCeQpkB7FLc6BW+Ccnfr/K8R8xa3blLyAk7w5/N91vM3en7BKrbp+/Wl5\nwf03WW6u7WYppkz4ltltp13Sb9nId5d9If17Pe8FeQZ1wzy+Qp+w27PnNusdfl0tN8dulk3/tD/a\n6Rrum1/teexsv1Cai3bNNUlmAsh0kB/F/8bGYGMWwx/OTfKWMb8ftpi7BcKYF1//9Wl9alPaM0oq\naQ952nWh2eu/eKU+6aQ0kL4g/yBjkoiKLtXvYeGBWJ28IinoKr7eiN55uzlgJwwc1m6WqnT83kR2\nmlZvDeTBvPELPkVkjfMffv7cAME6i7IvuB5U0d/9/Ay9Fbmth+Rxj99QBo0b4Odxt7mx2TYmbQKZ\nCXJopf995sKIFTDSCHcR3Kv8glBUKM3Fc83F3OYJkOtBhmdbFGNegYtXZVsw4U3GkzbDSH9ht7Wi\nmD0p7aPH4N7pPm4p9BbXtu31D3lKn3SSNcjesGgp9LovO765jXbHlqMfzfRw3zh6zVFd7NgN7nRK\nsgk0h0unC7pl/G+yuYW6uDB2nmeOPcivhnCtw/y7KTug1/NZ12JFtTpuKdRv0bzS0irb3HgYUeHb\nwM+6gFwLS9eqetH/d0+VHKarf078/vu9Ims/F89Vi5ndJl4eB2mflTnskzL5bZA+IPupOiZsfA3r\n9N2MMUVda+M3G2+sJnjXQdtdFlq8Ea7drLSStdJ61Ip8izzuoCvOE0SlQA+lcqaoGq6T8TZm5q0J\n70H/XGMthhf8gks8vEK2JDouMSJxh8bPumgAmYtdyORIERch67+pn3J78lpxnyf05nwuyOsgt4HE\n9Ns1ligOPDFt1jZvTJOkIphFfflz8Vw1GNmN2aUEshaHTDs2otonZeiTIPfB0g3qchXeAPbrq0zj\n5cM8ZrmNscxMkM+AVfZcCqmlBjbAV5cFT/pwnxaWF0W8N06yTj+dZB13SLmPOckbpDgDFvzkSjgv\nHNpus9GEeOvEeUUdQO68YE7VV+nbeYvh7O1BnfuuSPCPa4L1IiV9F/WQfB/kB27jM83t6fPMPDhD\nFKP/4W+BzFFHBzOvVugzdone/BM3/ONAHgF5DuTk5L4f/zmNiq+OsBO/17XfFLcX5OK5ajCyGzHk\nkyCr8i+YOD/tk281b5wDm4LvDN2RpAeutFeMqxr8uBNMX1eRdHs2BNPo5YvUi5c+0knWdsbtk2hs\ndZ+r4jCTshv50h+IBayDfVUF0OlPQa8tE726bYBvrlBhpe3sctKV5fDktRX353AS9jSCQf/1FZWO\nh/cfxvnx5umyzXD2X7Ib221JfLwNbvwSkB6qhkm6CcnRIK9hTSUpB6Fw5e+AXIBjdD/IT+DFv+Th\ny+y82GN+5fdRdWwunqsGIzsStCPIY/nridvckvKY+ifB5PFhuoIVo4pAM2TdF2QMf99s/Wx/YzE0\nS+PBU0xQWtA1sd/DZv1tfl16PgiKbEblHOvgFJB/JtPc5GE2ZTvcPKBCu3hAOte1E8MfhoCtrDAP\nXZ+GzhuCXnB+Q7Jnr3D1XLpsAwx6IjgO2RdkCpqU6GcgH005L8tJmfM371qLn/96UdfSf1PvnfKJ\n+5vqtmHarGxJqfs4LZbi9PqV8Qd9d+0We5i4GW4fUgxtWreBcx/SYCUXnawtKK37vPSugvIdkCuL\nWBzu8+4iXfWek9V9tDKG1LT4GUh9Mp9VN5mHG/26b01bv72us0NomcNEA/VM44o7nGwH3e1DQV4G\nuRfkSynX5odRnf+Zxa21dLcF83oYtqwI21LuAWUnhPwU5KLqttG6jer0/YTzh0D7mdDz2EjSl9uY\nuNvf0vVr1AL1Hmg3SxnXq9OzF8wQ6CLQcWNlY33kSpDfuTGYU+CVcypDe1BaF2fJ0tduL5C/uNE1\nK7xFHukqS6CYq/rKD+PbbhZMN6pJovRIVvfFZLaam45+VnXeurQCj4574uYgXQZsMKNZugfIVeht\nu5lNXw/SjQxuxiA3KCps83hwJa/lcx6By7d5iJ65623ugfgI+3eQrtUl1sDHYcIWaHenbzNPfUU1\nM5v//VErYHEjyK0gnwn2waQTjQQrNUQj/aIQsSCfAlmNIUzfXrc9jgDk4yDvZh/3wKa0aenK7bYB\nWR78rt9jRdygojyQVrpKn0AGZC/ocY9586mbB7882xBPss1kmLXTO1ntZD84L14JcqSrQJBeDx+L\nGHqAOlR0uKkyFzYjrjsURqWPtsOwz9z0vNJ7DvR/BB5clgYtt9oPyNkgDxRWX0sMQgcyfTN0+XPR\nhNQJNPnNmqIXsxpnjHAJrUBmgKyCp6+3gZ3FecKoJ5Ffkvb+7pfm5GGQ7vELIVx3p/VmVZWUQLaA\nfCj9uNvOhtNWZNmotZ7Lt0K/R7W+e6cotpKp72fc2bx8+fQNitfTKySRRxKXfKC8GP8XpBGmbTTT\nYkojXLrGPLYwrG+cK+Cxs6N87Rq5+8h3XDKiVdo7/R8W76cMOn0ZAHKXG5+msQ95t5FsuYTjadZ/\nO4wPrcNst85ieFK+C/KdwupriUGUB1L4CaoT2HaZbVNtpnEdBKNftjFiXHJpl8UAMhbEaMyNBzez\neebIIpDPu9PXk9SS0xfa6wgvsklb4YJh0e8vWAVLVqP4Q5HgmSrN3z9AOtr7OrIRXvwbyDrU/W8q\nyGfiXVKTfOK9x+WwjBdW7Prvs+6Om6voWL2IaU+1mM3LCmQWyAXJPOASQew/fL9yT0UVlx3j3j5v\n3mESNS439wMyh4LsCyItvukHGS9ffR4jDTIsLhHoasTCqM7YwuHUnn64Y6Pd+2f6OvjlTwwBWIHU\naahKZq1JOo9nYL83hH/xvDwPpLM7ff0LIv2Ci98cjTeoQ0D+gKJP9gMpFeXlY+DJfUCaQPaP72vd\nfJCD7PQJ0iJ+XopdB2486X+yR/Um80v7GzXvbuc77J5aaTNN7aLtdhjh48N6gQGiQl8RfvT+IDWP\n35svUjvEkxtI4XmUWGe1Ox0zGB+BL14DUgfygShTuMIIe0wbDVnWz2bUu+qMzW8QDG+KJoTPQYvh\n+j6abjE5dRoKd3xO6LtPw3O3wXk7g3VP3VWHefGMWw8PXOI+JpGghBo+1LKiHCZJufJNkOfg5fnq\nxVCsvlVpc9bdML2pQqusgTVOLpCxOv3q8WR4XWSP6o2nZZHBdra+XxRaK+khzt0O5BkC47dB3Zrg\nmNLjbqUfuxwHsrDQOqvZ4YTB+IjX72GQe0BWgvxUIZez+gNPljT41tUZW5JnwbFGT6FkaczbVEa9\nrAdE6zYgHwP5Mci7IFfBsV30Wh5FATUz+EKB01cnG/f8fcuuR80jUarUM+TJIiXS4HyF+e3YAuEh\nIgdChzx2pWztT4xJKl+k91TRt4ak/LbZ2zDPfQR1dSm0+5t5TGZ7WXHzJuMo2LW9akzmMBgD48nh\nIN+FGZvSMk1Quh4pwUw2vaqaXT7IQN7tpO1s6GRL2JES7uDS1XDf1KhHwZjVZZ33dSCHmPsxeh10\nm6//79YYrDt8E/H0uD3mhzeiICRsdj1qXimwOonb44zrfiyk5EjX3e0JerJN3gLH/9kcyGial7Fr\nsoyz6DmKcVAIAZllS+JSoZEpkVESzpfdXlbMvE1phEH/KJLfWpAZ44xRfeamZZog03oLdKDoFbC6\n2eWj7XsMc97ONC6N9g3xj+fBhRZ8ILt3i9Y30peOMXzz8Evs9o0c5KPw6kIY/W70gAga+tIxdHop\nt2gpUutMQj09djYM2pz1oIqO3Y/7VGwylGhbPRvSpfLz5uWU22HJSpBj0rdrm6PzniJDMh7tV9gb\nbmADdH7DdWx5edPFXlbsvBWnHovUXw1myz/oEzMtbCVWsttjvskwL9h4d8k0aqqhx2kgRjA1ZDYk\nxXCfwlG+M3zf95aKSsh/tT3pFtSj5Sd5XV2LWxD5QLCi9cX7nxd10GhbYXvOFOtmlddgrfyZXdUJ\nMgJFwnXCqgn2OyIAvQ4vPwnyEMjh6efpb+MVWM7jveJUb+5jCucXqNjLim2reMEmUH81CJR/0A9c\nApO2mKXO+IVQLYIlLVj7ptzdiElub0f6YcgmZh+XZoQy12VL5NyxsdyfpdF8nRtF1WMXiR6e3bbC\ns7eQMYFKcTzhzfuQp2HMehMeebY6By0206CiKqg+pHa9QIebkvktnfpC59nIM05ODSB7oZmkIona\n3ecr4Im1N+riuhJkVJpDDeQ3IBPjeTv9nKQcU4eovWzyNuh6VLHtVHdsVSFORoKWGaDfoxqoM+q8\nKNO4gi+FfzO4AO+OuAXbbpYZ0TOLNBhk7vhxjd8Y53mT7LHRuk0UlsI9dWTz8kYcVHQ2aThIHz/8\nRU/xS9/FSfpx7oGX7wTZhIJ8vQhjVtrsDO7thW043uPuvgzy5fIm/cni5lO+DP96IQqRYsO7khKK\nhfPFZN72p8Wshltv+DB7ZhbI7UUKRXuEpO+qw3IlRnBiLnwLHvt+/j7GLdheq2H4GzA4lSrH3OfL\ntsCZd8Vf9z2G+8tYykidWekahHAVyRvhGO1r/kVnn/fT7q+OUfiK8OHYIYoImf4gTBYcpBXIoSBf\ngV7vmvt29mb38dliQvq/CIcdmULK/j7IzcWu+fjEMKH2PwfyJoFUhibeHrMGXn0Fxn+9mjrxUN8+\nAPI0yOTi6nxwut4g/oN1+u6beRa9thyhHi5d/pwtaXTvOZr9Zogl0rfet1HWvR5MmlwM1nzM2D6E\nBmp9PHkc5j5FaZ8Pxz/PeOz12ea9bkeeA0rHboqL8Hy0RyyAyw3QA/3LiXjSHWppdPp21UxPZ1qa\n2xv8Jvz1nzb1qZ3PFi+DPg8UJTm7pyJsNwsu+Jfi6ycHeIHMULA1c7xLNW4AqNfhOyAnFlDXaVrX\nVR2rZT8rpJL8A3XbzLNce3SSR69KZ0w1bVoXrIceb0YX7EjJi8+R5zoHchMZdK7BsY5bV2k/P558\n8X7a1qu8VX3huCl20CAp/5wOFYX43SgwaZnZfdieNNyN3p4zQM8dcOpc863OZoSdnIqW5o0x3fzo\nO8PfKlLydFM9ZhMcYODSqI1mqkCnZ6p1A0ARPd8gFKntPj+958AZd5Y9pjrm7U9sm9WsvCgGCBJo\ncGjSRsYu8GwHRZzfdtvZuqmcslUXYDjjlit+ij9f6DmPZJWuQbqDPJyP/vN/rFDPbsBeyfXVPeF2\niLtJXfYNwObBUR/b50q73Rr1tw3W99Ml4kltvxmLwWivf9uvL/TYGXRJ7CsVzHl/usB0UisM/Eca\nfotRr/0xSlc3d9SkTT2fIGTzxjplZxHzFjOf30ej5R0zc5loMOqdatvPqlZxOmK5n+pw6yC4eJUy\nfbe/wZJVIIfa6y4yabT/6pn11hEe5+hVMGVLdgaX96Nwy5/KwaxDQRKTVjjWNQzqE8eTVpIL9qnt\nbN1QPOA3fx3DRJNKm3Hwze36IzBF/DcF8zzbEvFcISCXg3wTTvh80oaM6oPfIuQLX3EP9Od27iZw\nv1QOnP4vRgUg25rxHw5n3Q3jUwU/2tdD/XY0TeHN8PC3Yejbwf5MEei52dv8g/1oOxuOuRcG7YRT\n3gkfEHk8WKJ2Ku/pYckHUIFh1ttfu6VlmOelpAjqRHFy5oJ82+331TXYWtutZuWpOoIH0FS/Qz1h\nrPrF34Fc6Pt8Bch9WII+ipX0s29a8fWelNMgKb8nhyEJTQ2X87YgrUBuAHkJ/ruz2dPosCPzMnyU\n7gsFOu2Ei8sboz+aMprxyt7uTGMfdBPosiloxLUl4vHqMAW6DY3o7bX+x74HExuCN7+4Ps4Q9Xk/\n/20X+pn59PyV0fwNcQeurT8nzgL5vAoNY1+137rqxZwzYkqZVuFI8JknqQNGZknfxluWG8DlW0Fm\nwfdmJAEeOqyDT6IeWGck/7b53U5Fm6he5Rk3j3+AnGT5W0SqLZ+uT4CMc9skXDZnV2+idBJxcuRn\nZun6DJDHc9D8MyBL070Tlh5fXVQ+fFpFadPhJnjpIXjudt0oes+BHhmx+E0L2ttYXDbB0+dFQbpE\nKh47fhWDiQ88I67NhVQ+pXj8pr7M2AQyG+QSdt0GTHkXbElGZpQ3rri4EFc7mFumONf1EO8J5dHW\nlId6skQPyCk74Ne/cL3JpOivwSg/aDFMbAsyBrrabkAp14acBNII8mn7uukzVzGv0ichyvtUreIc\nG9AvQSZZ/tYD5CHD959Hkx8bceGDhK7fDN89xY1xjp2txraeK4vAW6nWdQ5NAL2SDJGO+v7xn4Nv\nvReOAo6nTTpdJHT8YjBtnm2THvx4nK7aHnDW972kTTBebdKxMdqWfb60rktXw6An3fooAv3ngfQH\n+TnIk3DFdtsmY/6+Au5l71u/h/HdeosLLEvrBeb1p1400E/E7BlmQ8X133qyCEI2OAV7narSMdJq\ndYY1eTEqjL4vft0M2t6caKsiu+emPxLkBvMETnkHBj9h0Y+OLxN5n4T6fwDy325Mk8/Sb9i8OsD5\nb+apM2Zc14Fcmr5fbWenuerr+0WozExBYOe9DvcvhvFGzxiQj8PkNyySq8WlNpxO0BR9O2Cn6Qof\nfzOTEopz/pGs9IG+D5nr7z7PfMPw51Uw8eeIt+Ffz4O8iEZ27w3nzG0OvXH5QA0BoE0Rxbz3PI5M\nkv5gw/iVxs2x34TmzQbHkUrSL6/HEsifQa524IulzQlt0qxEdSPW/3TV9HL+jdJF1SJ7oZbzyxMm\n4wj0VvDBBAbIJZXbD427HtWDq9hJRvXyz2Trl6dbdRtnccbxACREWbI76WZtP5ycvMsp582wAAAd\nt0lEQVQ8kLfgyWst1/5EPtE+uHvexEv6ciDImnRz7x5s6CLlmn6jT98H4ZJ1OtbHBM5/I6kvOXmv\nBPIJ6LVApfrBohK85902Q2B0EwxaG+W7i5zno/p7j8mFN51OP0SXj4AsBumfdd1UZZzNTdgEoreJ\nwgd32uC+SOVQkBUgx8e389JczX4U51mRb4JirrubccxJm5LB9gZ5G5+Ky+weevIt5n7NdB4nnJ4a\n7Mpd+u09x2wIPW8nzOoXHJf71b3SBy/3aVinHx2v5YDcAT+5Sj3HLl2fvCFfttWWC7qI22RyfRfu\n1ETfdfNd1XcxPLYPGh3bHbVL/B61wa0BWQ0Xr7BLsn7vHb8HVmeDB1bLwX5UvHf6rIMe27Nu+D6a\nHYeqXr/YUt46kT61BGHtBErjHmfzKZY6kIU2SV4Zb8TbSUyW3btESiBfg4lvBiVab6M5c0O1GBrV\nFV9RGWfEg2YDTNhhpucVseOsLNi+D8EFa2DE6nQqoTTSb/4AMUsfOsCAUMLveKTE6EEypA4mhz08\n4qJZ/49Qjtj4+vMGPN0vipg6uPzv/QK97gN5EHWvHIVPz2zp84dB2oIMQfMT31FeU1tAloD8FeS/\nUVXsN0EOYlcayyyR5cXRoMC1VAJZCvKVAuoaAfKS2rXy0KegaOiWJm5wcPkDYcqTdRvIT81/d7lS\n954DXR6CETtSLO6Pg1yI6lOXwPDnKmqK7ImbUzLXieXFWbKPs32D+ft6a//Mi7lnQ1qkS3eVRd9N\naQ56d/rYaOKe/SitMAAyGOSPefrtPr4OT2lEsX+ehgq0f6rcl/ZohrplqA3ssyCdQSaAXIsm4H4L\nZCOKJ3MjGndwDsjR+NKZ5pnjf5cH5GqQy/LV4dFj8lswYal6fp2xFvptwiEOwHaQ5upTSxM2OEDT\ngkof8o6mEFwOEvHSsattxq6M3gCGvROHpYN6zfRADTZrQK4HORlkr8pkVUdqtYx7LxSN8Gj7OM8x\nhKIPbLCNUw+QM+8qegzxHjo2oLAkaTxNykf/032ee7/T5s0d/3X1A8+nWnFcPxZV6IlN5Y378vJG\nHu7/9fDwTMXW6T9P3Wr/fTfr4ugpp4PMz8fjEcTfHebMXNIKpA16w+oKcj7IpTB6oWlOc42rpQmb\nTCTPSJdOegA5s7wBfjj4vVXas0DZGm0HR6PX20aQR8sT1No8Hhu8bUHY2JEN75+/AvlujE1hCzxx\nDXztTjWidmv0u6PqJi9fBBkDcivIOzB9c5FjSFIDpFETpPttfp1qmjqK1tkn8PuB0GejeZ4GvIeq\naL6Hqmzaoiqcr+r3S1bABanwqfaEB40LWkdKPJ1kXvFsSZ7bcK/34LUtIA0gT6Lqs9+D/BDGLDLN\naa5xtTRho4QqUscp14FcH63ftBBtATFeUnI5AE1S/BQK8/pdkM9mn/j8kr55LMPegEUN9nFObAsv\n3BnVS49aAS/crZu8vFZmuqEqfRQ7Bpf6XPkg/yY8eRuc2ctVZ9rch0yIn/dBA+m6glyE5l54DPVG\nWwvdbPAXsS6HGlzX8gbG3fEB+RPIkGzv2m6FF0s0j7cte5qZh3KNqaWJWuUJ2w91meoV/N7k6mZb\noH0fLEu8a0FuAelCivRxVfL3b6Pfn3Kbuc/T14N8ze7lYhtr3XwQA+MV7WVSnOtaenWLR5MJy2D4\ns/Dra/UA9AdsdQr4xNvrSDqQso2zzLfHo04JV4L8EWQByObygfx3kJ+CXICqEz+BGlJDLocLBTq/\nB12fju+nDaum+X3ld7cHZBiINTtd/Lu2ddZVXNNY/sfr9Ks0ae1RNcwn4n9ndM/bXg52GQvy0ex9\nyBtZaArCWXBPGfDKsFjHvQbyI3udWfzsi/YyMS2GtsvSI0Zm9rJ6CuSb+r4pYKu/s3E3S990k5ZP\nofjp40CuQeNM3kAzaD1XFjJmolG8x+Dg6ltxOeyyNuqpZIMSsWEJ1ST98oG6hgSPJ8tctIm6oA/a\nBl3ETG9zGkut56y7YdrG/zjvnSpO3PdB7iImpRlIa83Ne9EKmLFNDSg/Ob3l+27bOAb9w+5zf9bd\nqIdGYSB07v1NNqrqb0zJRM4RDehxz0xlPhTHrE4w9LcGaQL5QNqArXS0mHkSXBjaeMetLwsS68vC\nyEOoGnIyiqHUxjZvxfBN2BW3eofef8oDrzwLve/PlpLzZ11g2lqfsNRBs5+JRB97GksUaubVQsbT\n0gRtnkmT95Ulp/ND3+8F0hFFh1yLeuH0ANm3pftc6WMSSJsV+OslkPbmOqtjYEyn7z52dkWn6Rm2\nNop+F+87b263fguc+wicejssWgRycQw/dAZ5VP9/9l/SxoJY6jwAdZk9H+S/QO7VOhoEpq+DqSvh\ngpfg/otBTiDHzTEb33iGw16rg6o+73f+WJKZAp2dPZr+kx/lrdHvZl0rID0J5Uywe6fZ8x+jSAKv\nFTGmfdgDigjbSiUGw9KHSqUx3eCAj8N++8G0j8KR64DfAxeLsKKl+xotq1ZAE9DK910T0PiWyPqG\nUmn/TrDkKjjuBGAn3Hm6fs8tQD9gXrjG4HufPAQa34IF9SLrG/L19air4LojK31thX5echUwKPjb\nIz4MVxrq2Av4NvBjtG8uZf3r5Rc7i7C1VOJQ4JFSae77YMYX4eBD4G3/GDsCHy+VeAh+/nmYsBWa\n3m+isb+VUom9gU8DXyg/X/T9//3AK77ny8BCOOw4ke9tcxtHkeXttyp88zpwDUrXVh+FpjoYfYLy\nwFHl3x0GfKv8bhNw72tF9aRU2r+N8sauebgOjhptmJfdsBx1Ffz4ADeeNpYjgSXBr16eAgO/Bl85\nVNl2J/Dicv3eWnZAQft1S5+kzXdin/D5aF7Q89/Y3a+w8OwtqhJI0s3KoSDvUg6gQcPl3yaF0Tl/\nX223kolvoLYVH/pjnDubSBlG2FHSlw+AbA1+N/Mktcn46TZkKcz7ga/Nc0H21St3JBnLG/D3iSDf\nRg35z6O69mVo/oarUbfWU0AOZldEartZMPxFmL4Behzdcnzjv3WZ1FcLRXX/A5fCUOcgxHz98NqN\n4Ns0e1SqI18dDhNez3MLRFGDJ0THElZvjlqXoJI8GMSq/kk1rpZiyuZ4dCHKCSC/0gCZfw9jVWjz\nWA9HdXbzFpH7Qc71fX4G5NTm67dtIx/+HOp9sgzkRyDH6xh7NgTd1rx8wxsFOu9QN9rkBY7CAKx0\n68uE18qfP4ImvOgIMhqe+q0m7rhsM1yxA159GY3s/g7IQNSnfb/4OWsen/z0fBSGDA5HiXtJTLo7\n0TsfT6S3nzRzvMNeqG3lLyCr4AJjcFQKgeRekLPceLOfNZERCvD3biFjbCmGrOZTPhUvQSEJXgW5\nTCMNw3rLBucTuzr9NAGiZWdwNOT/r77Pl4D8qnnHExd0JUeBXAWyGBYthZEh1MWJ5Q1owE7FjHEb\nP8iRIEuC39luHdObyv9fiwJhPQryaxRC4yyQI+DgI9JKldU0juefl/wbb3Z+CAcnmjD1JXYdFh/v\nYFp38lGQKSCLQJ4FGQ7yobwHjvJ6MM+HnTdnbAP5jKWej4CsK2ReWpohi2MweR9In/IJvQYNXGlP\n2WNHDYduvrHN018TM53/BvRfkJXBFdDp8q3Q7zFl5hkdyhtbsxmmy25qjyvWiM17R0qKUmkc54a0\n2YRQJMPXQL6BBpT9wI67P30degM60H1eKlj20Q3j4CNAzoVLN6TdzFqO1/Ibrt3bDMOQZJH0bZtk\n77nFrLtx62DpOhSi4kRCXn5Z3ZXRYLqtIO8Pfm87xIY+iTqcRMAiUZiGTYXMTUszZH7mkmNRdMkV\naFLiIZRT9gV/l95iXt1+W694TWYGTwrosUkkrzyNQ77OgudkBMhv4n9j9UqyZS+ag169D0MD5CaB\n/E95zr3fPQXyB5AZcPdoGLYsSo8FARWY+7xowJY5oveVp5orWUm6efAfUB6Uca850GlVtftaoaNJ\nlTRoZ5CGk7bA078Lb7bJc3LJu4SSymdfd6cVDooHcjjIMve12roNyE2mtYMKtdsL6VdLMaQbo1ol\nxQNBJqLXsNdRY9sR8fXuHgkMkvvTsTHLgoyRHv5JCIqi+mNz2fStV3ZL9qJLV6O+9W+CPADyCxQp\nshNqUP1rtI2whPaxw1Fj9yF23uvYGMXaF1Hp+ExrEFO19c5pDZn2/ow6D6ZsgQGiUnhD4X2N8rdf\nrdpTNLFLvUCfTXoY9T4axZz5uWnjh5sHRI3ygxZrXI2sQKOW359EI/372SvN684ddC/FOugEMtc+\nPxNfgxELgi60sh+qlh4Wqmuvcl+tsUbO/Sp6oPkZ22PUhjJj9C0zxmFHgpyNhqSvBZmFRjM6BbJU\nglD8Ov1kX3A7BEI+bwL7pvfVZVC3Ke3mYT9E+j2GqrsSYXELZHaHTb91m2hS8AlNMKsxCg88eAeM\nHY4V1G7AYzAlkuPW0K+jCOn+zbzntTvVtynOFDg39hZWZNRyct+yprTsGgoWq9ukN4BijaLJ3lne\nZ11/qM46svGjkOXL4dZBZkgROQTkz/Dqq3EZwio07CmWgzt1SkSHdXBB3DpAVdAjDN9/CVXLHhP6\n/j0S0sE69avogRbDKCYM+inby6qKUYSQMx0XTmpcErNr1cAG8zU/C55OuI4hO7Vf3oHnSUL5DIlo\n1GeP5pnDsE7/sCNR3PZuaLLo34LMB1kNS9dqtqXJb8GwZ2D2cDjjTtfDOe1mWL4RXJ+OfoFgMVsO\nVUvf8rkYVupIf/uLMRamqicfH9gOUX/7/sT13sb/9O/KtJsLFy6HJ34R35aUoP+jcTSqzO8kw94y\nVaoRjIYG6U2P+fs1IBMtfxuIGpU/7PtuCwlpXp36VfRA8xHJY9TivQuCi9qa2KRDcKF+7d5oPxYK\nnLAxWJcH1KVp4dItjF3Sy2tpDZjJi2z0qrKecDTIzdWdO9kf/rc7jGwM9uHCnbDodSzZluw8EH5M\n6QzTeXWg+tLh8bwXfgaLDxbC6bAvQtUTrKNIj5dwWsz4evLxRIC/l7rwt6p6wvE0g3PcdL1bmH9v\nSX/jzzb2Sa+H1TchfvwhyLSYNXUtivJZdkaRjRhuu6n7Vo3Jzk4oj1HTM3ly3X6msAWrhAN0uu8I\n/sY7LGaEPufX4xZhcwgusjPuhCWrUfvHQSgueMTAHX031pZSQoPAOqH69GvRNHzLQZrUsJbvsE6z\nkbvSrDK2y7YoXdLAIHcMqI1cVDj2usYtQm0RPy0v+KtArgCZDjIVtVONARkOdfMqdRTl2z5wYx7B\nIt/adjsIs7pnJr0Xr0UY2FCsPSN5rPqbEc8rOKJ1vb0fVXldWP68BuSA3P2r9mSnJ9bIxmpkmwoy\nhelQMS2ssP7P+0343/z9rIafd3mD+Xn5//di8VoxM+mwZfCXMSD1qP3kKZANaDq9OWik4UQ0u9Cn\nQfaGYc8Vc3C5bA7SCsYvSaKZe32m3416p9gDfNQraGrCC0EuRTNZfQfkB+gt6BoUfO23aqPw3ssm\nXOiYTrpZ+f3Ct4tQS+Zf3yffAvXvQfsbzRtdVjjqpBgRv6rWU58OEDhDoHOhkfn2tdz7fpAD09wE\nUW+1d+CGvlC/Gfo9mveQrvpEpyfY83+CHs9mMWaaGcHvstazwb5Zm3yXJ0vQtz8s4dv8nfs+lG1B\nFLsgUQl/FapTHwZyRzomnbwMRSgdyq5sS+EbwdDj0CCwJephk//g0jZmNMGA+cGgNa/dM+6EV19R\nXolA14YkqjQ3B78U3/3vsLiRmCjc9Is+z43H26iCgGkOPPD7ch3XRsfYPHAGhj4tADm+SNrpuE64\nU9VxHRtNxul4kL+kW1MazynbwXXJWpC1MGNTmjHCn84Ley/lon9zT3gCM+yFws0enpc5LdfbBp34\nzvOiqhwTpvhCgW4bKozil/wbBHobDo+NooiPcjXIF9L3ucNNUL8DTr61iAUJchnq8fRRVMWzvzuT\nmtQkYZpe+B48dzvIN4o6uMqH1Rp26TKNUviK4GFgy2OcXW2G+vxflZ7mtsC7vIb+8Rvh7tEp6DgE\n5GX1fLnk3ebFrbFvlHqTkbHu407yVHK9zdl44QrRpDoyAqQdAeOp1Zkjpj+xThUlRQdw50lTfbnm\nptqTn45R5FiKwoxO1PFFNgvb1bdD5XfHzg4ygA086uJ2qL72HRQPpyfIPq4SA+qH3i3/Yms7W3Ph\nXrYFetxTDkwanJZWaX5XzGHd5wG4eE1Fys8uOed7Vw6FJWvg9Nnpk7v46TDgUbh/kao00kA7hGn5\nwp9BBjmupS+ArFQ89/jbUAYe66CG2V6ry84LHaL9joXjGAVyg/u4Tao4/zo61hJ46cq/9aLeY3ID\nyD9Rg+mbIPfCkEXmd+JgkJPGn9YBIXpYZZ07kd1v058GcnUxdVUnO5T5sDC/gxpi6kDmw+I31ZvG\nSY83HeRndia3HRYmZpsilWvsyEZ4yeAFc+5XYEoi0mK1A9zsiyU+f3G2Ol033exY6sF6JjQVcAP6\nDchIh999EOQFkJFF24qIuD5vFP1c2fj1cIsTuOQYkJeL45Eh26OuoFH+MEvtUyScnxbVOLQBORvO\nscBr2BOeJO0laXnyP13SnwtydjF1fePPaU/o6o6t61/ddcvSFuTFtAyS7Ka3UaDXe5psxH9gTXwD\nzltaCdNP65VSjPdHTP3O/vHmelu3UVyTiW+mk9aL0M23bpO3/z6+uIYQTK/ld9eB3AxSKvqg1uBB\nk178pDdRw/6d9jSenvvkYUfC5dvgnEdc56OyiXZrrEQS+2lZ77i2WrfRG3DXRpvuP/h7W4yEObVh\nSr5wuhGb9oBcbed5ucgHDT/eQIxbYUpiboBuUnFR8071lgJYS+N/LvugUcefKMaF0e+tNMNXx6Bt\nQfrYDhOPpgNe0IjO5HeKpVH3efn93mUoMSqFvHNm58VBi4vJzNW6jWbeGrM4QTXYDw3q2V8/F3dQ\nlyXlUESvF3BV9x6KVtofTvujXaddlM4+HOjVJ7fjh7nt3QOoMXxI5KqrOTsePyjpBvJgdJBpdaAR\n10PRKDxPKhn0BIGEF81j3Eqvx5M7QQYUE6w00/B/2+ewHtRE0/7r1RheLN3s/W87G068CwbvdJHO\nLPTsg8V7yc5L7V7TDduPw5PmhuGNJ59rr7uhUj6Dhu9/Nf7dCRvhmM8VNz/1gg/GINhmGE7lhDvT\n0sKNrz1AuY6Nehtwi2R3o30470NQHfTv9rR4B3wM+wuQS9IweTbmmL4BFi+DsWvT1p+feVJBBkxU\nyck2prGvEorOi7axUPS2c4kEk5T46wrHLIT1oNVV6YT63wEGbQ7SaGBDxdU221wpXfo+CBe96+Zy\nZ5Ms3RO2az3+/LPZg/jcDOjyfpCnQcabx+NJie1vhAV/B7kLjvlcMa6IfQWOmxPNC3Hs7Kjr9YCd\naW898TfYXbQ0OGL0bCgDuuUS7KDH0XDF9pZ0cy10nbV0B3xMu4gywFB2X10n5mgDnR9sro0s2D//\n4rt4Jcw2QgKU6fFlkKUWw9VSeO4WkAaQ06IeO55bal0onH2CRHWhSZJ+86CTVsbphcjPEHWj/eI9\nzSElB9+Jsy2kOWz89eSB60ieA9RFeFfIfsJa21c3/gkbi6HLKcb0h+bfpw+8jNJxsqj79NnvQdtl\nuuGfEbpBNEhQLeNlB+sxP+3GjQL1Lazm3tCcT4t3oEzUI9B8rqV4Ju/zUHw9yaH0ZalvU3NsZPF9\nvXeKgknZYGClxK6Yhd5Hq+Grz1z/b0HOgMXLYey66KKzubHV+3+XqNO30/SSd1FQqH2LUJXFz132\nucoiQBR10Cldhi/Pe6OETn+KGwNIbxUQ5CPudcZ72NjHY1L1maEdzHRskLSBl0GBYKREdexjNsHU\nbcF2/Cq1vDctORvknubaG6r9tHgHykQdQ9nIBvIRGPsvy4a1GcXOjsFDj4COvRt0l2o3qxowD8lj\nDEvjvV530NHehAaMnI3P3hH8zcm3msfSw+JB0bURBi/TwLJeL6jUadfP2yXlO4aBzFVX1AtWJo8l\n/mCwb7RdM+UXSK43C1jZOXPTHnDwxDUw8sX0WZe8dvo8BGPfhbo1ZmlaDkcx5dum48c8cAd+rxO7\nO62djsfOdvVcCbW71L52T3wt+L1fbZnXpiJjaMa0o9V+WrwDZaLeWZYa60DegmdmRbHWBy2GH56G\ngnytRlObRRg9yJSn/VH19/dfVFmoHRs1iUP45K/bVC1dXbz/vJ0J0TydN6PYLN8y121bvD1X2Rec\nibZJkpbN59ia9jAV/k28ETeNLSS8KZuQUrNItOe/CXPeTmsLQmGkT8vPL3UNYZdaNJvSE5QBudK1\nUYytRuEqzPVktc3Z2+o9xw7G2Dnk4eU/HPIBOKJQJDOqsTe0xNNyDe9amB1uKm9+z6P5IU+oML41\n6OkjKCrha+VF1Q9LHlg9KMKBR1NEN34PXrVeoMO96cfgGjSVZGA2M6HmuK3fDJesU7CmNL7zts3S\nljYya7COi77Z1scTEw6GKdvh7F7Q4S8wKNFzx2zI7rUtqg5IRlU08R90vC0N7UBao9GdqTDQXTdk\nkB+D3E2GbEoWeu+AufVJ9flceOfD+M0w7B3bxp7GH92NLvZberAtf/R8bkn/RgyR7P+uT8s1HGCS\nqQKPXEnKrDAge4P0QpOEvIFGsn4syihJuu0LVsKSFWkksjgpBs3mc3r5YPo9XLrevDFeYWVCdze9\nuH6YNq6ig3XiNyido/NfMLdZvwPkUdQIOQyuPlN1zV5/f3WN5qB1lfLDffEWuz9dX71k9bFOSztU\nLZcFGnt1NF1jsB2Qrmiq0I9lGUuovTK9r+qIgqH9DkumNTO/eV4y1fVuqbhPuh3ilfGZsLaSEVQr\n71+yFnrd9+/utbNrXC3WcEELsVKfHKsbrKxBg0SO0u/jdMWBq3JH1Jg8uTLZPearHvH0iM7bvtld\nvhXVsT6Ipn4bqbg3SQdPUeiQSdF9hYfltzGnqet9NLtuYxevNLfZ8TaQU8u/uxHNDboJhXH+NQx5\n0k115N22uoWMvv5D1c9vHRuLNTZPbQQ5gwBAXLtZCuI1/Dl3nXVcAJKXuav3HOh8R1lIaV/8upT9\nQG5FMWg+Hb3NFntTzMZvnj9+V2d//OAa6fY3eGgVdLzVngb1dMNB0Xww1FWlYYs1XCWdOppT83IU\n9/0BNb65SXsgbeDVl2Dc+ujiWyiawec3PUEuVZ9vMRwm5z5qZjgb4mfx6JDJzF+MnrWyQEa9CV3W\nqER1xp3wzA3lw/dGkLZp2gRphSIdjtU0iiYaDH0G5KPResNXf7+knz/ZjXkcgxfDPZNRrJsX1Ctr\ncMExJiZgP82KVp21KSWQi/RgCXsf9dtRDb5szkfncZzB483v61989r7d5WlBwleXoKiRqw7+9RwM\nd9bratIJ2+LbKIoZLz+Hfg+n0++m020WLZHn6Yu9jkikZxMsWYnBwypLm3YaXLQCZIMG2vn/bvLN\nHrStSG8t2zjKG2UXTVaSvi37IT9oJ3Tf2hIbkNqRwu02v+db8eOy8dXpvnwQxWfv212eFiR88xBU\nF+MZzht0Mn6NBxpVrGdCtB/VrT9//2wLp8NNxbURazfZGwY+Hp2nBtGrvx8FNaz2qSa/ZXWFtNGz\n/Y0w5KmW2ICK8rPf3R77HPXfXPn/f66kvw8tVpqAVqHPjW8V3YoIUip96L1gW5Tb/uQh0Tfefsvc\nt70CfRRZ31Aq7d8Jllyl9TS+BQvqRdY3FNPv6tafvxx8iJmmB32yqBaSaFAqvbYYmr4R7MeBwNYH\nRO4Y5H1TKp34ADTVNQe/2fknqa0F9TD6BLjuSH23CRi9BF6YATuvgqbjm6f//mIay4HAS/dC56bd\nky9dim2OXn8bmg7X788DvgV8m+B8LKhv7t4WXcqGp1qplVqplVrZE8peLd2BWqmVWqmVWmm+Utv0\na6VWaqVW9qBS2/RrpVZqpVb2oFLb9GulVmqlVvagUtv0a6VWaqVW9qBS2/RrpVZqpVb2oFLb9Gul\nVmqlVvagUtv0a6VWaqVW9qBS2/RrpVZqpVb2oFLb9GulVmqlVvagUtv0a6VWaqVW9qBS2/RrpVZq\npVb2oFLb9GulVmqlVvagUtv0a6VWaqVW9qBS2/RrpVZqpVb2oFLb9GulVmqlVvagUtv0a6VWaqVW\n9qBS2/RrpVZqpVb2oFLb9GulVmqlVvag8v8BHo6MOq6wR2sAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1000 city tour with length 21275.9 in 0.145 secs for nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(nn_tsp, Cities(1000))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Can we do better? Can we combine the speed of the nearest neighbor algorithm with the optimality of the all tours algorithm? \n", + "\n", + "Let's consider where `nn_tsp` can go wrong. At the end of `plot_tsp(nn_tsp, Cities(10))`, we see a very long edge, because there are no remaining cities near by. In a way, this just seems like bad luck—we started in a place that left us with no good choices at the end. Just as with buying lottery tickets, we could improve our chance of winning by trying more often; in other words, by using the **repetition strategy**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Repeated Nearest Neighbor Algorithm: `repeated_nn_tsp`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is an easy way to apply the **repetition** strategy to improve **nearest neighbors**:\n", + "\n", + "> **Repeated Nearest Neighbor Algorithm:** *For each of the cities, run the nearest neighbor algorithm with that city as the starting point, and choose the resulting tour with the shortest total distance.*\n", + "\n", + "So, with *n* cities we could run the `nn_tsp` algorithm *n* times, regrettably making the total run time *n* times longer, but hopefully making at least one of the *n* tours shorter. \n", + "\n", + "To implement `repeated_nn_tsp` we just take the shortest tour over all starting cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def repeated_nn_tsp(cities):\n", + " \"Repeat the nn_tsp algorithm starting from each city; return the shortest tour.\"\n", + " return shortest_tour(nn_tsp(cities, start) \n", + " for start in cities)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To do that requires a modification of `nn_tsp` so that the `start` city can be specified as an optional argument:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def nn_tsp(cities, start=None):\n", + " \"\"\"Start the tour at the first city; at each step extend the tour \n", + " by moving from the previous city to its nearest neighbor \n", + " that has not yet been visited.\"\"\"\n", + " if start is None: start = first(cities)\n", + " tour = [start]\n", + " unvisited = set(cities - {start})\n", + " while unvisited:\n", + " C = nearest_neighbor(tour[-1], unvisited)\n", + " tour.append(C)\n", + " unvisited.remove(C)\n", + " return tour" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nFBH/D6i9NWsGaMGjAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 city tour with length 6734.1 in 0.002 secs for nn_tsp\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 city tour with length 5912.6 in 0.157 secs for repeated_nn_tsp\n" + ] + } + ], + "source": [ + "# Compare nn_tsp to repeated_nn_tsp\n", + "plot_tsp(nn_tsp, Cities(100))\n", + "plot_tsp(repeated_nn_tsp, Cities(100))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that `repeated_nn_tsp` does indeed take longer to run, and yields a tour that is shorter. \n", + "\n", + "Let's try again with a smaller map that makes it easier to visualize the tours:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2381.4 in 0.000 secs for nn_tsp\n" + ] + }, + { + "data": { + "image/png": "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\nSEoUsCIiKfl/otWLcOBvkAEAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2297.7 in 0.000 secs for repeated_nn_tsp\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2291.8 in 1.619 secs for alltours_tsp\n" + ] + } + ], + "source": [ + "for f in [nn_tsp, repeated_nn_tsp, alltours_tsp]:\n", + " plot_tsp(f, Cities(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This time the `repeated_nn_tsp` gives us a tour that is better than `nn_tsp`, but not quite optimal. So, it looks like repetition is helping. But if I want to tackle 1000 cities, I don't really want the run time to be 1000 times slower. I'd like a way to moderate the repetition—to repeat the `nn_tsp` starting from *a sample* of the cities but not *all* the cities.\n", + "\n", + "# Sampled Repeated Nearest Neighbor Algorithm: revised `repeated_nn_tsp`\n", + "\n", + "\n", + "We can give `repeated_nn_tsp` an optional argument specifying the number of different cities to try starting from. We will implement the function `sample` to draw a random sample of the specified size from all the cities. Most of the work is done by the standard library function `random.sample`. What our `sample` adds is the same thing we did with the function `Cities`: we ensure that the function returns the same result each time for the same arguments, but can return different results if a `seed` parameter is passed in. (In addition, if the sample size, `k` is `None` or is larger than the population, then return the whole population.)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def repeated_nn_tsp(cities, repetitions=100):\n", + " \"Repeat the nn_tsp algorithm starting from specified number of cities; return the shortest tour.\"\n", + " return shortest_tour(nn_tsp(cities, start) \n", + " for start in sample(cities, repetitions))\n", + "\n", + "def sample(population, k, seed=42):\n", + " \"Return a list of k elements sampled from population. Set random.seed with seed.\"\n", + " if k is None or k > len(population): \n", + " return population\n", + " random.seed(len(population) * k * seed)\n", + " return random.sample(population, k)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's compare with 1, 10, and 100 starting cities on a 300 city map:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def repeat_10_nn_tsp(cities): return repeated_nn_tsp(cities, 10)\n", + "def repeat_100_nn_tsp(cities): return repeated_nn_tsp(cities, 100)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "299 city tour with length 12752.7 in 0.014 secs for nn_tsp\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "299 city tour with length 12070.6 in 0.127 secs for repeat_10_nn_tsp\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "299 city tour with length 11598.6 in 1.285 secs for repeat_100_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(nn_tsp, Cities(300))\n", + "plot_tsp(repeat_10_nn_tsp, Cities(300))\n", + "plot_tsp(repeat_100_nn_tsp, Cities(300))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we add more starting cities, the run times get longer and the tours get shorter.\n", + "\n", + "I'd like to understand the tradefoff better. I'd like to have a way to compare different algorithms (or different choices of parameters for one algorithm) over *multiple* trials, and summarize the results. That means we now have a new vocabulary item:\n", + "\n", + "# New Vocabulary: \"Maps\"\n", + "\n", + "\n", + "We use the term *cities* and the function `Cities` to denote a set of cities. But now I want to talk about multiple trials over a collection of sets of cities: a plural of a plural. English doesn't give us a good way to do that, so it would be nice to have a *singular* noun that is a synonym for \"set of cities.\" We'll use the term \"map\" for this, and the function `Maps` to create a collection of maps. Just like `Cities`, the function `Maps` will give the same result every time it is called with the same arguments." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def Maps(num_maps, num_cities):\n", + " \"Return a tuple of maps, each consisting of the given number of cities.\"\n", + " return tuple(Cities(num_cities, seed=(m, num_cities))\n", + " for m in range(num_maps))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Benchmarking\n", + "\n", + "The term *benchmarking* means running a function on a standard collection of inputs, in order to compare its performance. We'll define a general-purpose function, `benchmark`, which takes a function and a collection of inputs for that function, and runs the function on each of the inputs. It then returns two values: the average time taken per input, and the list of results of the function." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "@functools.lru_cache(None)\n", + "def benchmark(function, inputs):\n", + " \"Run function on all the inputs; return pair of (average_time_taken, results).\"\n", + " t0 = time.clock()\n", + " results = [function(x) for x in inputs]\n", + " t1 = time.clock()\n", + " average_time = (t1 - t0) / len(inputs)\n", + " return (average_time, results)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: Each time we develop a new algorithm, we would like to compare its performance to some standard old algorithms.\n", + "The use of `@functools.lru_cache` here means that we don't need to to re-run the old algorithms on a standard data set each time; we can just cache the old results. \n", + "\n", + "We can use `benchmark` to see the average call to the absolute value function takes less than a microsecond:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(5.00000000069889e-07,\n", + " [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "benchmark(abs, range(-10, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can see that `alltours_tsp` can handle 6-city maps in under a millisecond each:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.00032370000000003785,\n", + " [[(574+214j), (236+141j), (556+348j), (677+277j), (833+33j), (578+224j)],\n", + " [(433+6j), (396+143j), (527+431j), (167+227j), (113+100j), (127+105j)],\n", + " [(571+206j), (724+42j), (703+269j), (797+331j), (543+474j), (310+248j)],\n", + " [(12+30j), (344+45j), (693+77j), (548+186j), (279+508j), (171+229j)],\n", + " [(243+271j), (379+72j), (859+331j), (840+411j), (651+478j), (8+369j)],\n", + " [(672+502j), (820+460j), (887+489j), (853+65j), (422+69j), (433+135j)],\n", + " [(38+119j), (644+90j), (622+288j), (602+511j), (509+424j), (275+536j)],\n", + " [(18+208j), (832+456j), (483+477j), (314+533j), (314+539j), (23+596j)],\n", + " [(274+560j), (213+594j), (248+84j), (550+317j), (508+577j), (377+575j)],\n", + " [(813+467j), (438+216j), (270+118j), (71+18j), (125+320j), (199+578j)]])" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "benchmark(alltours_tsp, Maps(10, 6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Benchmarking Specifically for TSP Algorithms\n", + "\n", + "Now let's add another function, `benchmarks`, which builds on `benchmark` in two ways:\n", + "\n", + "1. It compares multiple algorithms, rather than just running one algorithm. (Hence the plural `benchmarks`.)\n", + "2. It is specific to `TSP` algorithms, and rather than returning results, it prints summary statistics: the mean, standard deviation, min, and max of tour lengths, as well as the time taken and the number and size of the sets of cities." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def benchmarks(tsp_algorithms, maps=Maps(30, 60)):\n", + " \"Print benchmark statistics for each of the algorithms.\" \n", + " for tsp in tsp_algorithms:\n", + " time, results = benchmark(tsp, maps)\n", + " lengths = [tour_length(r) for r in results]\n", + " print(\"{:>25} |{:7.0f} ±{:4.0f} ({:5.0f} to {:5.0f}) |{:7.3f} secs/map | {} ⨉ {}-city maps\"\n", + " .format(tsp.__name__, mean(lengths), stdev(lengths), min(lengths), max(lengths),\n", + " time, len(maps), len(maps[0])))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How Many Starting Cities is best for `nn_tsp`?\n", + "---\n", + "\n", + "Now we are in a position to gain some insight into how many repetitions, or starting cities, we need to get a good result from `nn_tsp`." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def repeat_25_nn_tsp(cities): return repeated_nn_tsp(cities, 25)\n", + "def repeat_50_nn_tsp(cities): return repeated_nn_tsp(cities, 50)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " nn_tsp | 5668 ± 488 ( 4674 to 6832) | 0.001 secs/map | 30 ⨉ 60-city maps\n", + " repeat_10_nn_tsp | 5232 ± 374 ( 4577 to 6172) | 0.006 secs/map | 30 ⨉ 60-city maps\n", + " repeat_25_nn_tsp | 5159 ± 394 ( 4620 to 6069) | 0.014 secs/map | 30 ⨉ 60-city maps\n", + " repeat_50_nn_tsp | 5118 ± 386 ( 4512 to 6069) | 0.029 secs/map | 30 ⨉ 60-city maps\n", + " repeat_100_nn_tsp | 5113 ± 384 ( 4512 to 6069) | 0.034 secs/map | 30 ⨉ 60-city maps\n" + ] + } + ], + "source": [ + "algorithms = [nn_tsp, repeat_10_nn_tsp, repeat_25_nn_tsp, repeat_50_nn_tsp, repeat_100_nn_tsp]\n", + "\n", + "benchmarks(algorithms, Maps(30, 60))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that adding more starting cities results in shorter tours, but you start getting diminishing returns after 50 repetitions.\n", + "\n", + "Let's try again with bigger maps:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " nn_tsp | 7789 ± 458 ( 6877 to 8632) | 0.002 secs/map | 30 ⨉ 120-city maps\n", + " repeat_10_nn_tsp | 7316 ± 334 ( 6646 to 7870) | 0.021 secs/map | 30 ⨉ 120-city maps\n", + " repeat_25_nn_tsp | 7242 ± 287 ( 6725 to 7870) | 0.053 secs/map | 30 ⨉ 120-city maps\n", + " repeat_50_nn_tsp | 7189 ± 295 ( 6646 to 7742) | 0.106 secs/map | 30 ⨉ 120-city maps\n", + " repeat_100_nn_tsp | 7173 ± 289 ( 6646 to 7736) | 0.213 secs/map | 30 ⨉ 120-city maps\n" + ] + } + ], + "source": [ + "benchmarks(algorithms, Maps(30, 120))" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " nn_tsp | 8668 ± 485 ( 7183 to 9636) | 0.003 secs/map | 30 ⨉ 150-city maps\n", + " repeat_10_nn_tsp | 8220 ± 364 ( 7290 to 9197) | 0.033 secs/map | 30 ⨉ 150-city maps\n", + " repeat_25_nn_tsp | 8117 ± 326 ( 7222 to 8918) | 0.083 secs/map | 30 ⨉ 150-city maps\n", + " repeat_50_nn_tsp | 8086 ± 300 ( 7237 to 8676) | 0.166 secs/map | 30 ⨉ 150-city maps\n", + " repeat_100_nn_tsp | 8062 ± 284 ( 7174 to 8603) | 0.331 secs/map | 30 ⨉ 150-city maps\n" + ] + } + ], + "source": [ + "benchmarks(algorithms, Maps(30, 150))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The results are similar. So depending on what your priorities are (run time versus tour length), somewhere around 25 or 50 repetitions might be a good tradeoff.\n", + "\n", + "Next let's try to analyze where nearest neighbors goes wrong, and see if we can do something about it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Problem with Nearest Neighbors: Outliers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consider the 20-city map that we build below:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "outliers_list = [City(2, 2), City(2, 3), City(2, 4), City(2, 5), City(2, 6), \n", + " City(3, 6), City(4, 6), City(5, 6), City(6, 6), \n", + " City(6, 5), City(6, 4), City(6, 3), City(6, 2), \n", + " City(5, 2), City(4, 2), City(3, 2), \n", + " City(1, 6.8), City(7.8, 6.4), City(7, 1.2), City(0.2, 2.8)]\n", + "\n", + "outliers = set(outliers_list)\n", + "\n", + "plot_lines(outliers, 'bo')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what a nearest neighbor search does on this map:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "20 city tour with length 38.8 in 0.000 secs for nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(nn_tsp, outliers)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The tour starts out going around the inner square. But then we are left with long lines to pick up the outliers. \n", + "Let's try to understand what went wrong. First we'll create a new tool to draw better diagrams:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def plot_labeled_lines(points, *args):\n", + " \"\"\"Plot individual points, labeled with an index number.\n", + " Then, args describe lines to draw between those points.\n", + " An arg can be a matplotlib style, like 'ro--', which sets the style until changed,\n", + " or it can be a list of indexes of points, like [0, 1, 2], saying what line to draw.\"\"\"\n", + " # Draw points and label them with their index number\n", + " plot_lines(points, 'bo')\n", + " for (label, p) in enumerate(points):\n", + " plt.text(p.x, p.y, ' '+str(label))\n", + " # Draw lines indicated by args\n", + " style = 'bo-'\n", + " for arg in args:\n", + " if isinstance(arg, str):\n", + " style = arg\n", + " else: # arg is a list of indexes into points, forming a line\n", + " Xs = [points[i].x for i in arg]\n", + " Ys = [points[i].y for i in arg]\n", + " plt.plot(Xs, Ys, style)\n", + " plt.axis('scaled'); plt.axis('off'); plt.show() " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the diagram below, imagine we are running a nearest neighbor algorithm, and it has created a partial tour from city 0 to city 4. Now there is a choice. City 5 is the nearest neighbor. But if we don't take city 16 at this point, we will have to pay a higher price sometime later to pick up city 16. " + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZ\nJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVw\naTYRSWsl/ULS3ZKulLRP2ZmstUlaLuk+STskHVzz2Ofyx+6S9NKyMrYal2ZzWRsRL4iI44DZwHvK\nDmQtbx1wKvBA9aCkNwJdEfEnwF8Cq0vI1pJmlh3AxkTEt6vu3g4cWVYWaw8RsQFAkmoeWgysyde5\nTdKBkg6PiIeLzthqvKXZhCTNBM4Fvr27dc320BHA5qr7D+VjthsuzYJIlV6pZxAuQuoZlCq9E6x+\nGfD9iLilqHzWeqRKp9SzVlrSl91WOsvONB1497wAWUEu7oPVs6ADuPBoWNYnVRZGDK/beV39PXBo\nRLyvnLTWCrKCXHwTrO7K5tQIsOxkqbIoYnjTOE+JmvsPAc+pun9kPma74S3NQnSvGStMyG5Xz8rG\nx0h6D/B64O1FJ7RW071yrDAhn1Nd2fi4lC+jvg4sBZB0MrDNxzMnx6VZiHlzxyb3qI58fCeXA4cB\nt0q6U9KKQuJZC5q/oM6cWlA9IukCSZvJjldukHQFQET8N7BR0v3AvwN/VUDotuDd80Js3QYjB+08\nyUfy8TERMavYXNa6tgxlc2iXOTVUvVZErAJWjfcdIuL9jcvXvrylWYj+pbBsezapIT/+tD0bN9sT\n/Stg2UDNnBrIxq2RFFF7fNgaITsZ1L0GTjsabtwI/UtrTwKZpchOBnWvzHbJtw5B/4o6J4FsCrk0\nCyYREdReaGxmLcK752ZmCVyaZmYJXJpmZglcmmZmCVyaZmYJXJpmZglcmmZmCVyaZmYJXJpmZglc\nmmZmCVyaZmYJXJpmZglcmmZmCVyaZmYJXJpmZglcmmZmCVyaZmYJXJpmZglcmmZmCVyaZmYJXJpm\nZglcmmZmCVyaZmYJXJpmZglcmmZmCVyaTUTSckn3Sdoh6eCy81jrqzenJB0r6YeSnpL012VmbDUu\nzeayDjgVeKDsINY26s2pR4ELgE8XnqjFzSw7gI2JiA0AklR2FmsP9eZURDwCPCLp9FKCtTBvaZqZ\nJXBpFkSq9Eo9g3ARUs+gVOktO5O1NqnSKfWslZb0ZbeVzrIzTQfePS9AVpCL+2D1LOgALjwalvVJ\nlYURw+vGeUoUndFaS1aQi2+C1V3ZnBoBlp0sVRZFDG8a5ymeU1PEW5qF6F4zVpiQ3a6elY2PS/li\nVkf3yrHChHxOdWXj45poTnmuJSi9NCe4JGKupK9K2iDpVkkvKjPn3pk3d2xyj+rIx8dIukDSZuAI\nYIOkK4pKaK1m/oI6c2pB9Ui9OSXp8Hz8Q8DfSXpQ0gFFJG91zbB7vg74BvC9mvGPAesj4ixJxwKX\nAosKzjZFtm6DkYN2nuQj+fiYiFgFrCo0mrWoLUPZHNplTg1Vr1VvTkXEw8BzGhqxTZW+pRkRGyLi\nQXbdRXgR0Jev80ugU9Kzi843NfqXwrLt2aSG/PjT9mzcbE/0r4BlAzVzaiAbt0Zqhi3NejYAZwG3\nSDoJOAo4Evi/UlPtgYjhdVJlIQysgdOOhhs3Qv/SOieBzHYrYniTVFkEAyuzXfKtQ9C/os5JIJtC\nimiOk2qSNgIvi4jH8vtzgM8CLwV+CrwAeG9E3F1eyr0nERE+8G7Wqhq6pZldFtG9MjtovWV3vwl3\nau+I+B1w3tj30kZgsGFhzcwmoWGluQfXke10SYSkA4EnImK7pPcC34+IxxuV18xsMhp4Imhy15FN\ncJnNC4F+SfcArwc+0LisZmaT08Dd88ldRzbBJRG3Asc2Lp+ZWboGbmmOXkdWbdfryMzMWkkDS9PX\nkZlZ+2noJUdjZ899HdkoX3Jk1tqa5jrN6cKladbaSv8zSjOzVuLSNDNL4NI0M0vg0jQzS+DSNDNL\n4NI0M0vg0jQzS+DSNDNL4NI0M0vg0jQzS+DSNDNL4NI0M0vg0jQzS+DSNDNL4NI0M0vg0jQzS+DS\nNDNL4NJsIpI6Jd0q6V5JX5TUwE8LnXSm5ZLuk7RD0sFV46+WtE3SnflS2Gc/1ctU9fgrJG2XdFZR\nmSbKJekMSRskrZd0u6RXNUGmd+SZNkhaJ+klRWVqdS7N5vIvwCURcQywDXh3yXkA1gGnAg+M89jN\nEXFivqwc5/HCM0maAXwS+E6BeUbVy3VTRBwfESeQ/Zte2QSZBoE/i4jjgZXAFwrM1NJcms1lIXBd\n/vU1wJklZgEgIjZExIMw7ucalfJZR7vJdAHwFeDXxaaqnysinqi6ewDwTBNkujUifpvfvRU4oqhM\nrc6l2SQkHQL8JiJGf6B+BSwoMdJknCLpLknflPSissNIWgC8JSIup6RCr0fSWyTdA3wDOK/sPDXe\nA3yr7BCtovRjZtay7gCOiognJL0RuB44puRMnwE+WnW/aYozIq4HrpfUS7Y7fFrJkQCQ9FrgXUBv\n2Vlahbc0CyJVeqWeQbgIqWdQquw0SSPiUWBufkwO4EjgoQZn6pR61kpL+rLbSucEq+/0Wc8R8fjo\nbmdEfAuYNd5JmSIzAS8H/kPSRuCtwKWSztjbTFOQa+yBiHXA85rgtULSccAVwBkR8Zu9zTNtRISX\nBi8wpxfOeRoeD4jIbs95Gub07rwe/wm8Lf/6cmBZAzN1wjn312S6H+Z0jr8+G4FDqu4fXvX1ScCm\nsjPVPHY1cFaTvFZdVV+fCGxugkxHAfcBJzdqjrXrUnqA6bDAKYNjkzuqJvkpgzuvx9HAbcC9eYHO\namCmtXUyra3JdAGwGXia7DjrFfn4cqAfWA/8EHhl2Zlq1rlq6kpzr1+rC/PX6k7gFuCUJsj0BeDR\nPNN64Payf05aZSk9wHRY4MzHdp7co8uZj5WX6ay+Opn6nKn5czVjpumy+JhmIbZug5GasZF8vCxb\nhupkGiojTaYZM0Fz5mrGTNNE2a09HZbJHtMsOFNnyjGx6ZqpWXM1Y6bpsij7B7BGy86Wd6+BeXOz\nLcz+pRHD60rO1AndK2HegmwLpX9FxPAmZ2qNXM2YaTpwaZqZJfAxTTOzBC5NM7MELk0zswQuTTOz\nBC5NM7MELk0zswQuTTOzBC5NM7MELk0zswQuTTOzBC5NM7MELk0zswQuTTOzBC5NM7MELk0zswQu\nTTOzBC5NM7MELk0zK5Sk5ZLuk7RD0sFV4xVJX5d0l6SfSnpniTHrcmmaWdHWAacCD9SMLwd+FhEv\nBV4LXCJpZtHhdqfpAplZe4uIDQCSVPsQMCf/eg7waET8ochsk+HSNLNm8Xng65KGgAOAt5WcZ1ze\nPTezKSNVOqWetdKSvuy20pnw9NcD6yNiAXACcKmkAxoSdC94S9PMpkRWkItvgtVd0AGMAMtOliqL\n6nwee+3nh78L+GeAiBiQtBF4AfCTBsZO5i1NM5si3SvHChOy29Vd2fi4lC+jHgAWAUg6HDgGGGxU\n2j3l0jSzKTJ/wVhhjuoA5i2oHpF0gaTNwBHABklX5A+tBHok3Q3cCFwYEY81OnUq756b2RTZMpTt\nklcX5wiwdah6rYhYBayqfXZEbCE7rtnUvKVpZlOkfwUsG8iKEvJjmgPZePtQRO2xWDOzPZOdDOpe\nme2Sbx2C/hV1TgK1LJemmVkC756bmSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZ\nJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVwaZqZJXBpmpklcGmamSVw\naZqZJXBpmpklcGmamSVwaZqZJXBpmpkl+H8nmwKHqbW4/gAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_labeled_lines(outliers_list, 'bo-', [0, 1, 2, 3, 4], 'ro--', [4, 16], 'bo--', [4, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It seems that picking up an outlier is *sometimes* a good idea, but sometimes going directly to the nearest neighbor is a better idea. So what can we do? It is difficult to make the choice between an outlier and a nearest neighbor while we are constructing a tour, because we don't have the context of the whole tour yet. So here's an alternative idea: don't try to make the right choice while constructing the tour; just go ahead and make any choice, then when the tour is complete, *alter* it to correct problems caused by outliers (or other causes)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# New Vocabulary: \"Segment\"\n", + "\n", + "\n", + "We'll define a *segment* as a subsequence of a tour: a sequence of consecutive cities within a tour. A tour forms a loop, but a segment does not have a loop; it is open-ended on both ends. So, if `[A, B, C, D]` is a 4-city tour, then segments include `[A, B]`, `[B, C, D]`, and many others. Note that the segment `[A, B, C, D]` is different than the tour `[A, B, C, D]`; the tour returns from `D` to `A` but the segment does not. \n", + "\n", + "# Altering Tours by Reversing Segments\n", + "\n", + "\n", + "One way we could try to improve a tour is by *reversing* a segment. Consider this tour:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAASkAAAEACAYAAADvOoB8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHdpJREFUeJzt3XucnVV97/HPj4ZiweQEUk5jpcqlFZWIXI8QIhUoagG5\nBKhSIRBFCCDiaZAiXo4e8FIuFuG8IAcoEYRTLYgBBREE7CFc5E4IgigJilaoGkIuqAT59Y+1JpkM\n2TN7zzzPs9Z69vf9euU1zrBn75+zZ//medbz2+tr7o6ISK7WS12AiMhw1KREJGtqUiKSNTUpEcma\nmpSIZE1NSkSypiYlIllTkxKRrKlJiUjW1KREJGtqUiKSNTUpEcmampSIZE1NSkSypiYlIllTkxKR\nrKlJiUjW1KREJGtqUpkxs/PMbHnqOqQZZranmd1vZgvMbK6Z6TU5hH4gGTGzHYGJgDae7wNmZsBX\ngL9z922BnwJHpawpR2pSmYh/Qc8CPpa6FmnMJOD37v5k/Px7wMEJ68mSmlQ+PgzMc/dnAUtdjNTP\n3X8NjDOzHeKXDgE2S1hSltSkGmA2YZrZ1EVm05eEjxOmrf3f7TXAocD/SVOh1MFs/CFmU5ebTV8V\nPo4/ZB03ex9wrpndDSwD/tBslfkbl7qAtgsN6YBbYc76sBGwcmOYdavZhD3dl82PN9se2Ar4SVyn\n2NDMnnD3NyQrXMYkNKQDr4I5xOf91TDrKrPxh7ovv3rgdu7+A2D38D22N6DnfAhTOGi9zKYugpu3\nCL+oA1YCey92v3PLdX+PLXf38c1UKHUwm7ocbn71Op73Fe53jl9zO9vU3X9lZhsA1wNnuPv3Gy43\nazrdq93kiWv/okL4fPLEYb5JfzmKN/lVHZ73Vw354sfM7IfAQ8C1alCvpNO92j2zNJziDf2L+szS\nTt/h7hPqr0vq9czvwineK5733w2+lbufApzSaGmF0ZFU7T5xM5zm4RcUwsfjXoKFM1JWJXV7ZCYc\nz9rP+/HAT49JV1OZ1KRqZMZhsO+74akDYe/FMP05OHkFzLxm0KK5tNLy5TDjV/DOlTD9Jdh7Bex3\nF/xiHzONmPRCC+c1MWMqMA/Yy51HBn19E2ABcIQ7t6WqT+pjxkTgEWCmO98b9PUNge8D17vz2UTl\nFUdNqgZmbAXMB45y57vr+O/7ABcA27qzrOn6pF5mXAascOeEdfy3ycDdwCfduaLx4gqkJlUxMzYG\n7gLOdWfOMLe7CDB3PtRYcVI7Mw4Ezgbe6r56QWrobaYAtwIHu3N7k/WVSE2qQmb8MfBd4AF3Zo9w\n2/GE074T3LmhifqkXmZsSnhOD3HnjhFu+07gcuDt7vy4ifpKpSZVkbgYOhf4b4Rf0hHf3mDGO4Ar\nCKd9S+qtUOoUn/+rgSfduxspMOMYwhvKd3HnN3XWVzI1qYqY8QngIOCvOx3md/i+c4H/7s7f11ac\n1M6Mvwc+Aezozu9Guv2g7zsT2AXY253f11VfydSkKhBGDfgi4S/iL3v83g2BBwkLqVfVUZ/Uy4w/\nJ0yM/6079/f4vesBVwEvADPc9W6DodSkxqjTqEGP97FLvI+3uvNslfVJveJp3vXAPe58ZpT3odGE\nYWiYcwziqME3CDNPo2pQAO7cDVwKXKRBv+J8EJgMfG60d+DOC8D+wEwzDq+qsLbQkdQodTtq0MP9\nbQDcC5ztzuVjvT+pnxmbE56zPdxZWMH9aTRhHdSkRqGXUYMe73c74CbC4uvTVd2vVC+uJd0CfMed\nMyu8X40mDKHTvR7F07GLgKVU/O51dx4CzgP+Rad92fswsAFwTpV36s5NwKeBG8yYVOV9l0pHUj0a\n7ahBD/c/DrgTuLSK00ipnhlbA3cAu9Z1tKPRhDXUpHowllGDHh/nTcDtwNvceXKk20tz4h+R24Er\n3evbk16jCWvodK9LZuwGfBnYr84GBeDOY8Dngblm/FGdjyU9O5nQOC6o80HceRk4AtiacPrXt3Qk\n1YWRdjWo6THXA24DrnXnS008pgzPjLcQrr7t6M7PGnrMvt81QU1qBFWPGvT42FsCPwB2j0dXkki8\nonsP8GV35jb82H09mqAmNYy6Rg16rOFY4GhgqjurUtQgYMbpwHbA/inWh/p5NEFNqoPR7GpQYx03\nAvPdOT1FDf3OjP8BfAvYru71yBHqOIawJrZrP+2aoCbVQd2jBj3WshnwAPAudx5MWUu/MeNPCD/7\nz7jz9Qzq6bvRBDWpdWhq1KAXZhxBGB7dqV9+OXNgxjnAZu68N3Ut0J+jCWpSQ8RRg28yhl0N6hBP\n+64BHnfn46nr6Qdm7A58jbAp4a9T1zOg33ZNUJMaJMWoQS/M+DPgYeAgd+5KXU+bmfFqwlbAH3Xn\nutT1DNVPowlqUlGMmrqTBKMGvTDjEMKg53Zxiw+pgRkXAq9yZ2bqWjrpl9EENSnyGDXohRlXAr92\n56TUtbSRGe8CLgbe4s7zqesZjhl7A1+lxaMJfd+kchk16IUCRuvTKdgzZ20fTVCTymjUoBcKGK3H\ncMGeOWvzaEJfN6kcRw16oYDRanUT7JmrNo8m9G2TynXUoBcKGK1OL8GeuWrraEJfNqncRw16oYDR\nsRtNsGeu2jia0HdNqpRRg14oYHRsRhvsmau2jSb0VZMqbdSgWwoYHb2xBHvmrE2jCX3TpEocNeiF\nAkZ7V0WwZ87M+BDwMQofTein7YNPA6YAh7etQYECRkdpzMGeOXPnYsIfrm/GXMci9cWRVOmjBt1S\nwGj3qg72zFUbRhNa36TaMGrQCwWMjqyuYM9clT6a0OrTvThqcDXh7SOtb1CggNEu1RLsmav4RvT9\ngZlmvD91Pb1q7ZFUG0cNuqWA0c6aCPbMVamjCa1sUm0dNeiFAkZfqalgz5yVOJrQutO9eIpzEbAU\nyp4eHgsFjK5TI8GeOXPnZuBTwPVmTEpdTzdadyRlxieBAylsV4M6KGB0jRTBnjkradeEVjWpNaMG\nE+fD89vELz8BHOXufbmLpQJG0wZ75ir+Afs34Lf0OJpgZnsBZxLOxJYTXl+LaimUFjWpwaMGYIvd\nfUX4up0DPOvurb/U3Em/B4ymDvbMVRxNuA24oZfRBDP7EfAed3/CzI4Ddnb3D9RVZyvWpIaOGgxq\nUAb8CfT9L+ZFwBLg1NSFNC0Gex4DHKMGtbY4mnAAvY8mvEx4exnx439UXdtgxR9JdRo1MLNLgX2A\nR4F93b34d7ePRT8GjOYW7JmrXkcTzGwa4e02LwDLgF0GDgzqUPSRVFxr+AZhknateaB4+Pka4DHg\nfQnKy4o7PwdmA5eX/D6uHp0BLFCDGl58W9D7gavM+KsuvuV/Au9299cR3rT/z3XWV1yTMpswzWzq\nIrPpS2DWb+De9egwauDhMPHrwPRGi8zXFcBPoH3v+B8qBnseBmXtVZ7KmtGEx24xe8dTZtOXhNfZ\nhGmDb2dmfwq81d3vi1/6N2DXOmsbV+edVy38wA64FeasDxsBK4HjpsK8XWHZ/DW3s63c/cm4JrU/\n8HiqmnPijpsxC3jYjOvaGjAagz2/AszKKXk4fxMeg/e/Fq5fL76+NoZZt5pN2NN99evrOWCCmf2l\nu/8EeCfUe9W4qDUps6mL4OYtwg9wwEpg78Xud24ZbmNGmCoeDxgh8fe4Os+ZS9P2gNESgj1z1M3r\nK9zODgBOB/5AaFofcPen6qqrqCMpmDxx7R8ghM8nTxz4LJ7iTUM6cudqMw4CvgDtChiNwZ77Am9J\nXUt5Rn59Abj7tcC1TVVV2JrUM0t5xRD5yvh16dGJwMFm7JG6kKrEYM9LgA/knjycpzxfX4U1qYUz\nYNaqNT/IlYTPF85IWVWJYrLMMYT39k1IXU9FvgxcV0rycH7yfH0VtSYFYLbtXnDgzfDo8/DL52Dh\njEGLetKjtgSMlhzsmZNwcWrK5bDLZvDT5+Dmg1O/vgpsUuxGGNzcOXUtbdCGgNE2BHvmxoz/Rbj4\n8PHUtRR2ugfAjsB9I95KuuLOcmAmIcBhk9T19CpuzTMH+KoaVKXuI7zWkiu1SbUmHy0H7nyf8N7H\nEjeCOwx4I/Dp1IW0zP3AjjlsQV1ik9oJNak6nEb4pTw0dSHdisGe5xK2Gunr92ZWzZ1ngN8Bmycu\npawmZcZGwBaENw1LheJQ55HA+Wb8Wep6RhL/wl8CXNCm5OHM3E8Gp3xFNSnCnkCPuvNi6kLaqLCA\n0VYHe2ZCTWoUtGhev88SjlaPSF1IJzHY8wuE07y+28SvQVksnpfYpHRoX6O43/UM4Gwz/iJ1PUPF\nbW/nAme1OXk4E1ksnpfWpLRo3oDMA0b7KtgzpVwWz4tpUlo0b9wXgYnAsakLGRCDPT8NHOnOH1LX\n0yeSr0sV06TQonmj3HmJcLXvjLiHfFIx2PMrhK2Aiwi1bAk1qR5oPaphmQWM9n2wZyJqUj3Qlb00\nziWk7STbdyoGe84GZrrzcqo6+lTyxfOSmpQWzROITWEm8HEz3tT048ewja8Cpyh5uHnu/JLEi+dF\nNCktmqflziLgk4SkmfUbfvhPAU8T1qMkjaSnfEU0KbRonoPGA0YV7JkNNakuaNE8sdgkPgicaMb2\ndT9eDPa8DPhIPOWQdNSkurATWjRPruGAUQV75uN+YKdUi+elNCkdSeWj9oBRBXvmJR7J/pZEi+fZ\nNyktmuclnvbNAmaaVZ9cq2DPbCU75cu+SaFF8+y48yzhPXSXmbFhxXd/FvDv7lxX8f3K2KhJDUOn\nehly52rgXsKWKZUYFOz50aruUyqjJjUMDXHmq7KAUQV7Zi/Z4nkJTUpvh8lUxQGjCvbMWMrF86yb\nlBbN8xez+m5iDPs7xWDP3YBTqqpLapHklC/rJsUwi+ZmdoWZPW5mC8zsEjNL/S79fjYb+Bsz9un1\nG2Ow54WEPaKUPJy3EZuUmf1/M3vAzB40s1+Y2TVjfdDcm9Rwi+ZXuPsb3X1bYEPg6ObKksFGGzAa\n1zcuRMGepRixSbn77u6+g7tvD9wFtL5JdVw0d/cbB316D7BZIxXJOo0yYPQw4E0o2LMUXS+em9kE\nYE9g3lgfNPcmNeKiuZmNIySb3Djc7aQRXQeMKtizPD0unh8AfM/dV4z1cbNtUj0sml8A/Lu763Qh\nsW4DRhXsWbRuF88PA/61igfMskmZTZgG+/0YTvljmPp4+Hxdt7NPA3/q7v/QcInSQZcBowr2LFB4\nHR45DY7/qtnURcO8LicBOwPXV/LA7p7VPxg/DQ5/EVY4uIePh78I46etfTuOBu4ANkhds/4NfQ59\nA/AF4DPW8d82B/8V+JTUdepfL89pd6/LcFtmAXOremyLd5oNs6mL4OYtYKNBX10J7L3Y/c4t19zO\nVgFPASsIe3Bf4+5nNFqsdGTGdoT5qR3deTp+bT3gFuA77pyZsj7pTbevy3BbuxX4orvfVMVjj6vi\nTqo1eeLaPwgIn0+eOPgr7t70NrbSA3ceMlsdMPoudxwFexasu9clgLvvWeUjZ7gm9cxSXjHTtzJ+\nXQqzOmBUwZ6lS/e6zLBJLZwBs1at+YGsJHy+cEbKqqR3viZg9AvA7SjYs2DpXpfZrUnBwFWE7a+A\nt78ObnsKHpnhvmx+6rpkdMz4T2BTYP3YuKRA4XV5xI1hVOrx/4SFjbwus2xSA8z4OfB2dxanrkVG\nJwZ7fh9YBpzvzpfSViRjYcajwPvdeaipx8zwdG8tjwJvTl2EjM6gYM+Tgb1IFDAq1YiZi1sBP2ry\ncXNvUj8EtkldhIza6mBPTxswKtX4K+Bpd37b5IPm3qQeRU2qSB2CPRsPGJVKbUOCvd1KaFI63StM\np2DP2KwaCxiVyr0ZNalXeAx4U5xUlnJ0DPb0ZgNGpVrbEJZgGpX1i9+dpcBS4PWpa5HudBnsWXvA\nqNRCp3sd6JSvEN0Ge8bTvtoCRqV6qa7sQRlNSlf4ytF1sKfXGzAq1UtyZQ/KaFK6wleA0QR7eg0B\no1KbJKd6UE6T0ulexsYY7FlZwKjUKsmVPSijSekKX/5GHezp1QaMSn2SXNmDApqUrvDlrYpgT68g\nYFRqp9O9EeiUL0MVB3uOOmBU6pXyyh6U06R0hS8zVQd7+igDRqURya7sQTlNSlf48lN5sKePLmBU\n6pfsVA/KalI63ctEzcGeXQeMSmOSXdmDcpqUrvBlou5gT+8yYFQalezKHhTSpHSFLyu1B3t6dwGj\n0hyd7nVJp3yJmbE5YTp8hjuran64zwJbAEfU/DgyjNRX9qCsJqUrfAnFU+25wFnuLKz78dz5PTAD\nONuMv6j78aSjpFf2oKwmpSt8aTUe7Bk3+x8IGNVpXxpJT/WgvCal070EEgd7rg4YbfhxJUh6ZQ/K\nalK6wpeAGeMIe0QlCfYcFDB6hhlbNf34kvbKHhTUpHSFL5mTgReAC1IV4M5jwOcJb0L+o1R19Cmd\n7vVIp3wNisGes4GZ7rycuJxzAQdOSlxH34hX9rYEHk9ZR4lNSovnDRgU7HmKOz9LXU9skjNRwGiT\nBq7sVf2ugp6U1qQ0htCc1cGeietYTQGjjUu+HgXlNSmd7jWgQ7BnLhQw2pzkV/agvCb1Q3SFr1ad\ngj1zoYDRRiVfNIfCmlTcP1tX+OrVMdgzFwoYbYxO90ZJp3w16TLYMxcKGK1RLlf2oNwmpcXzinUb\n7JkLBYzWLosre1BmkxrxCp+ZnWBmPzazP5iZtqLtTtfBnrlQwGithj3VM7PPmdmPzOxRM/twnYWU\n2KS6Od2bD+wF/LT+cso3mmDPXChgtDYdr+yZ2VHAa919a3ffBvhanYWU2KRGvMLn7g+7+89A75wf\nyRiDPXOhgNHqDXdl7zjgfw984u61Lg8U16R0ha9yow72zIUCRmsx3OneVsD7zOxeM7vezP6yzkKK\na1JmE6bBSZvAUQvMpi4Kn8toVBHsmQsFjFbDbMI0s90Ww6feDNO+2eH1tQHwgrvvTDgKv7TWoty9\nmH8wfhoc/iKscHAPHw9/EcZPW/ftWQRskrruHP+Bbwr+S/DdUtdS4f+n8eCLwfdJXUuJ/7p9fRGO\nsF4/6POlddZV2JHUlMthzvqwUfx8I8LnUy7v8A2G1qVeoepgz1y4AkbHqOvX1zxgTwAzewc1739e\nWJOaPHHND3DARvHra5jZiWb2NPBa4GEzu6ipCgtRebBnLlwBo2PQ3esL+CfgYDNbQEgNOrrOqsbV\neefVe2YprNx47R/kyvj1Ndz9fOD8RksrxKBgz7/1DAb1anIa8KAZh7pzVepiytH16+t5YL+mqirs\nSGrhDJi1KvzgIHw81eGpoxIWVYy6gz1z4QoYHaWTr4NP+Nqvr1mrwusuHYsLX8UIVxumXB4OQZ99\nHs5/FnZ4EDjePbttRbJixtHA8cDbvP7cvOTM+DzhUvqB+t0Ynhn7A3Pg8I/AojPD6+uZpbBwhvuy\n+UlrK61JDRXnYu4A5rrzpdT15CoGe94L7OEN5OblIO6QcC9wtjudLq70PTN2AL4L7OfOD1LXM1Tx\nTQrAjNcBdwEnuDMvdT25idP5twDfcefM1PU0yYztCPNTO7rzdOp6cmPGZsDdwEnufCN1PetS2JrU\nunnYg/sA4GIzdkpdT4YaD/bMhStgtCMzxgPfBs7LtUFBS46kBphxEOHS866eQXhADmKw5x2En0nj\nuXk5iNmBdwKXujMndT05iD+Ta4FfAMfmvGbXqiYFYMZswpWdae4sS11PSvEX8XbgSvf+nhuKCTO3\nEy4aPJm6npTiEeX5wBuAfXO/iNKK070hvkT4q/n1+CLtZ8mDPXPhChgd7CPAHsChuTcoaOGRFKw+\ngvg2sJg+HU2IwZ63EhaMderL6gsItwHX9uuV4DWjBkx156nE5XSllU0K+ns0IQZ7/oCwIDo3dT05\nMWNLws9m93h01TdyHzXopI2newDE9ah9gdlxS5J+8ing52QU7JkL79OA0ThqcB1hD/tiGhS0+Ehq\nQBxJ+A7hvWr3pa6nbjHY81vAdp5hbl4O4sLxjcB8d05PXU/d4qjB7cD/K3FOrvVNCvpnNCEGez4A\nfMYzzs3LQTyyeAB4lzsPpq6nLiWNGnTS2tO9wdz5JuGq37dbvr1s9sGeufA+CBiNR4znAusT3o1R\nXIOCPjmSgtVP2AXA5sB73HkpbUXVisGeXwO29QJy83IQfyeuAR535+Op66maGScR9n6f6uWGbPRP\nk4K1RhMWUfBflqFisOcC4KNeUG5eDuJWLg8DB7lzV+p6qmLGe4D/S0GjBp30VZOCtUYTLnXnn1PX\nUwUzLgRe5c7M1LWUyIxDCIOe28W9qIpW6qhBJ33XpKBduybEYM+LgbeUfEifmhlXAr9256TUtYxF\nCbsa9KovmxS0YzQhBns+Asz0gnPzchCDGxYAR7hzW+p6RqP0UYNO+rZJQfmjCWZcBqxw54TUtbSB\nGfsQLq5sW9qb09swatBJXzcpKHfXhDhFfzbwVvfVm1LLGJlxEWDufCh1Lb0w43xgawrY1aBXalIF\njiaYsSnh1OSQNuXm5SCeMi0grFfekLqebpjxEeBYCh816KTvmxSUNZoQm+pVwCL38uPRc2TGO4Ar\nCKd9SxKXM6w2jRp00hcT5yOJR09/B7wd+GjickbS2mDPXJQSMBpHDS4lzHg9lbic2uhIapDcRxNi\nsOdDhCuSrc3Ny4EZGwIPAp/MMWC0jaMGnahJDTFoNOHdOTWCeJp3PXCPO59JXE5fMGMXYB7h4sSz\nqesZ0NZRg07UpNYhjiacTzjPz2I0od+CPXORW8Bom0cNOlGT6iCn0YR+DPbMRW4Bo20eNehETaqD\nXEYT+jnYMxe5BIy2fdSgE13d6yAeRp8IGHBewmDJvg32zEUOAaNx1OBUwhFU3zQo0JHUiOKuCfMJ\ngQ6N7pqgYM98pAwYNWN71uxqcE+Tj50DNakuDBpNON6daxt6TAV7ZiZFwGgcNbiLsFdYq0cNOtHp\nXhfiFb4DgEvM2LGhh1WwZ2aaDhiNowbfBs7v1wYFOpLqSVOjCQr2zFdTAaP9OGrQiZpUj+oeTVCw\nZ/6aCBjtx1GDTtSkelT3aIIZpwPbAfv381/P3JlxLHA04ai60ibSr6MGnahJjUJduyYo2LMcdQWM\nxlGDOcBubX7TcC/UpEap6tEEBXuWp+qA0X4fNehEV/dGKa5H7QecbMYBFdylgj0LU2XAaGx41wHH\nqUGtTUdSY1TFrgkK9ixXFQGjg3Y1uNKds6qsrw3UpCoQ9xsfCHTo6b1dCvYs31gCRuP65jzgP+jz\nUYNO1KQqMtrRBAV7tsNoA0bNOA94Ixo16EhNqiKjGU1QsGe79BowqlGD7mjhvCK97poQgz0vAT7g\nzvNmtrmZ3W1mT5jZv5rZuAbKlmqdCBxsxh4j3TCOGvwjTPoh2INm9qCZPWBm29ZfZlnUpCo0KNBh\nGiMHOnwZuG5Q8vA/Aee4+xuApcAHaytUahGTZY4hvLdvQqfbxVGDfwEOgiUrgNnuvr277+DuCxoq\ntxhqUhXrZjQhLrTvBmtFUu0Jq99EehlwUJ11Sj1iVt9NdNj/q8OogV6Hw9APpwaDdk24eOiuCTHY\n80LgyIHkYTObBDzn7i/Hm/0c+PMGS5ZqzQb+Jsa2rxZHDb5FeF/m4F0NPm9mD5nZOWa2fpOFlkBN\nqibu3Ec49L/W7L0HmU1dZDZ9CZywGL53i5KH28ud5cBMeOIrZn/9lNn0JWa7LYb7biTulz7o5qe6\n+9bAzsAk4B8TlJw1Lc7WyJ15ZvP2gtd8Ay412AhYCRz3XrPpc9yXzQ+389+Y2UQzWy8eTW1G2KJD\nijXhJTh8EtywaXzeN4ZTXw/TT3P/2epL6u7+bPy4yszmEo7CZBAdSdXuzH3hc7FBQfh44TiYMjR5\n5Dbg0Pi/j4RmdgCVuky5HM5ab+3n/YsGm621/Y6ZTY4fDTgQlAY0lJpU7SZPXPOLOmCj+PW1nAr8\ng5k9AWxCuPojxer6eb/SzB4mTKxPIryHUwbR6V7tnlkaDvUH/8KujF9fw90XA29rtDSpUdfP+17N\n1lUeHUnVbuEMmLUq/IJC+DhrVfi6tJee96robTENMJswLaxRTJ4Y/pIunDGwaC7tpee9GmpSIpI1\nne6JSNbUpEQka2pSIpI1NSkRyZqalIhkTU1KRLKmJiUiWVOTEpGsqUmJSNbUpEQka2pSIpI1NSkR\nyZqalIhkTU1KRLKmJiUiWVOTEpGsqUmJSNbUpEQka2pSIpI1NSkRyZqalIhkTU1KRLKmJiUiWVOT\nEpGsqUmJSNbUpEQka2pSIpI1NSkRyZqalIhkTU1KRLKmJiUiWVOTEpGsqUmJSNbUpEQka2pSIpI1\nNSkRyZqalIhkTU1KRLKmJiUiWfsv+abpfa0U1HMAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cross = [City(9, 3), City(3, 10), City(2, 16), City(3, 21), City(9, 28), \n", + " City(26, 3), City(32, 10), City(33, 16), City(32, 21), City(26, 28)]\n", + "\n", + "plot_labeled_lines(cross, range(-1,10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is clearly not an optimal tour. We should \"uncross\" the lines, which can be achieved by reversing a segment. The tour as it stands is `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`. If we reverse the segment `[5, 6, 7, 8, 9]`, we get the tour `[0, 1, 2, 3, 4, 9, 8, 7, 6, 5]`, which is the optimal tour. In the diagram below, reversing `[5, 6, 7, 8, 9]` is equivalent to deleting the red dashed lines and adding the green dotted lines. If the sum of the lengths of the green dotted lines is less than the sum of the lengths of the red dashed lines, then we know the reversal is an improvement." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_labeled_lines(cross, 'bo-', range(5), range(5, 10), \n", + " 'g:', (4, 9), (0, 5), \n", + " 'r--', (4, 5), (0, 9))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we see that reversing `[5, 6, 7, 8, 9]` works:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "tour = Tour(cross)\n", + "tour[5:10] = reversed(tour[5:10])\n", + "plot_tour(tour)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is how we can check if reversing a segment is an improvement, and if so to do it:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def reverse_segment_if_better(tour, i, j):\n", + " \"If reversing tour[i:j] would make the tour shorter, then do it.\" \n", + " # Given tour [...A-B...C-D...], consider reversing B...C to get [...A-C...B-D...]\n", + " A, B, C, D = tour[i-1], tour[i], tour[j-1], tour[j % len(tour)]\n", + " # Are old edges (AB + CD) longer than new ones (AC + BD)? If so, reverse segment.\n", + " if distance(A, B) + distance(C, D) > distance(A, C) + distance(B, D):\n", + " tour[i:j] = reversed(tour[i:j])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's write a function, `alter_tour`, which finds segments to swap. What segments should we consider? I don't know how to be clever about the choice, but I do know how to be fairly thorough: try all segments of all lengths at all starting positions. I have an intuition that trying longer ones first is better (although I'm not sure). \n", + "\n", + "I worry that even trying all segements won't be enough: after I reverse one segment, it might open up opportunities to reverse other segments. So, after trying all possible segments, I'll check the tour length. If it has been reduced, I'll go through the `alter_tour` process again." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def alter_tour(tour):\n", + " \"Try to alter tour for the better by reversing segments.\"\n", + " original_length = tour_length(tour)\n", + " for (start, end) in all_segments(len(tour)):\n", + " reverse_segment_if_better(tour, start, end)\n", + " # If we made an improvement, then try again; else stop and return tour.\n", + " if tour_length(tour) < original_length:\n", + " return alter_tour(tour)\n", + " return tour\n", + "\n", + "def all_segments(N):\n", + " \"Return (start, end) pairs of indexes that form segments of tour of length N.\"\n", + " return [(start, start + length)\n", + " for length in range(N, 2-1, -1)\n", + " for start in range(N - length + 1)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is what the list of all segments look like, for N=4:" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, 4), (0, 3), (1, 4), (0, 2), (1, 3), (2, 4)]" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_segments(4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that altering the cross tour does straighten it out:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_tour(alter_tour(Tour(cross)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Altered Nearest Neighbor Algorithm (`altered_nn_tsp`)\n", + "----\n", + "\n", + "Let's see what happens when we alter the output of `nn_tsp`:" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def altered_nn_tsp(cities):\n", + " \"Run nearest neighbor TSP algorithm, and alter the results by reversing segments.\"\n", + " return alter_tour(nn_tsp(cities))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try this new algorithm on some test cases:" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 93.2 in 0.000 secs for altered_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(altered_nn_tsp, set(cross))" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2333.4 in 0.000 secs for altered_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(altered_nn_tsp, Cities(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It fails to get the optimal result here. Let's try benchmarking:" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " nn_tsp | 5668 ± 488 ( 4674 to 6832) | 0.001 secs/map | 30 ⨉ 60-city maps\n", + " repeat_50_nn_tsp | 5118 ± 386 ( 4512 to 6069) | 0.029 secs/map | 30 ⨉ 60-city maps\n", + " altered_nn_tsp | 4820 ± 233 ( 4450 to 5346) | 0.008 secs/map | 30 ⨉ 60-city maps\n" + ] + } + ], + "source": [ + "algorithms = [nn_tsp, repeat_50_nn_tsp, altered_nn_tsp]\n", + "\n", + "benchmarks(algorithms)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is quite encouraging; `altered_nn_tsp` gives shorter tours and is faster than repeating nearest neighbors from 50 starting cities. Could we do better?\n", + "\n", + "Altered Repeated Nearest Neighbor Algorithm (`altered_repeated_nn_tsp`)\n", + "---\n", + "\n", + "We have seen that the *nearest neighbor* algorithm is improved by both the *alteration* and *repetition* strategies. So why not apply both strategies? " + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def repeated_altered_nn_tsp(cities, repetitions=20): \n", + " \"Use alteration to improve each repetition of nearest neighbors.\"\n", + " return shortest_tour(alter_tour(nn_tsp(cities, start)) \n", + " for start in sample(cities, repetitions))\n", + "\n", + "def repeat_5_altered_nn_tsp(cities): return repeated_altered_nn_tsp(cities, 5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see it in action:" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 city tour with length 5701.6 in 0.541 secs for repeated_altered_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(repeated_altered_nn_tsp, Cities(100))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That looks like a good tour. Let's gather more data:" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " nn_tsp | 5668 ± 488 ( 4674 to 6832) | 0.001 secs/map | 30 ⨉ 60-city maps\n", + " repeat_50_nn_tsp | 5118 ± 386 ( 4512 to 6069) | 0.029 secs/map | 30 ⨉ 60-city maps\n", + " altered_nn_tsp | 4820 ± 233 ( 4450 to 5346) | 0.008 secs/map | 30 ⨉ 60-city maps\n", + " repeated_altered_nn_tsp | 4640 ± 194 ( 4298 to 4991) | 0.148 secs/map | 30 ⨉ 60-city maps\n", + "----------------------------------------------------------------------------------------------------\n", + " nn_tsp | 7789 ± 458 ( 6877 to 8632) | 0.002 secs/map | 30 ⨉ 120-city maps\n", + " repeat_50_nn_tsp | 7189 ± 295 ( 6646 to 7742) | 0.106 secs/map | 30 ⨉ 120-city maps\n", + " altered_nn_tsp | 6589 ± 202 ( 6188 to 7016) | 0.036 secs/map | 30 ⨉ 120-city maps\n", + " repeated_altered_nn_tsp | 6402 ± 185 ( 6015 to 6779) | 0.701 secs/map | 30 ⨉ 120-city maps\n" + ] + } + ], + "source": [ + "algorithms = [nn_tsp, repeat_50_nn_tsp, altered_nn_tsp, repeated_altered_nn_tsp]\n", + "\n", + "benchmarks(algorithms)\n", + "print('-' * 100)\n", + "benchmarks(algorithms, Maps(30, 120))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, alteration gives the most gain, but alteration plus repetition gives a modest improvement in tour length, at the cost of 20 times more run time. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Non-Random Maps\n", + "====" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I thought it would be fun to work on some *real* maps, instead of random maps. First I found [a page](http://www.realestate3d.com/gps/latlong.htm) that lists geographical coordinates of US cities. Here is an excerpt from that page:\n", + "\n", + "
\n",
+    "[TCL]  33.23   87.62  Tuscaloosa,AL\n",
+    "[FLG]  35.13  111.67  Flagstaff,AZ\n",
+    "[PHX]  33.43  112.02  Phoenix,AZ\n",
+    "
\n", + "\n", + "I also found a [blog post](http://www.randalolson.com/2015/03/08/computing-the-optimal-road-trip-across-the-u-s/) by Randal S. Olson who chose 50 landmarks across the states and found a tour based on actual road-travel distances, not straight-line distance. His data looks like this:\n", + "\n", + "
\n",
+    "Mount Rushmore National Memorial, South Dakota 244, Keystone, SD\t43.879102\t-103.459067\n",
+    "Toltec Mounds, Scott, AR\t34.647037\t-92.065143\n",
+    "Ashfall Fossil Bed, Royal, NE\t42.425000\t-98.158611\n",
+    "
\n", + "You can't see, but fields are separated by tabs in this data.\n", + "\n", + "Now we have a problem: we have two similar but different data formats, and we want to convert both of them to `Maps` (sets of cities). Python provides a module, [`csv`](https://docs.python.org/3/library/csv.html) (for \"comma-separated values\"), to parse data like this. The function `csv.reader` takes an input that should be an iterable over lines of text, and optionally you can tell it what character to use as a delimiter (as well as several other options). For each line, it generates a\n", + "list of fields. For example, for the line `\"[TCL] 33.23 87.62 Tuscaloosa,AL\"` it would generate the list `['[TCL]', '33.23', '87.62', 'Tuscaloosa,AL']`.\n", + "\n", + "I define the function `Coordinate_map` to take an iterable of lines (a file object or a list of strings), parse it with `csv_reader`, pick out the latitude and longitude columns, and build a `City` out of each one:" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def lines(text): return text.strip().splitlines()\n", + "\n", + "def Coordinate_map(lines, delimiter=' ', lat_col=1, long_col=2, lat_scale=69, long_scale=-48):\n", + " \"\"\"Make a set of Cities from an iterable of lines of text.\n", + " Specify the column delimiter, and the zero-based column number of lat and long.\n", + " Treat long/lat as a square x/y grid, scaled by long_scale and lat_scale.\n", + " Source can be a file object, or list of lines.\"\"\"\n", + " return frozenset(City(long_scale * float(row[long_col]), \n", + " lat_scale * float(row[lat_col]))\n", + " for row in csv.reader(lines, delimiter=delimiter, skipinitialspace=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You might be wondering about the `lat_scale=69, long_scale=-48` part. The issue is that we have latitude and longitude for cities, and we want to compute the distance between cities. To do that accurately requires [complicated trigonometry](http://en.wikipedia.org/wiki/Haversine_formula). But we can get an approximation by assuming the earth is flat, and that latitude and longitude are on a rectangular grid. (This is a bad approximation if you're talking about distances of 10,000 miles, but close enough for 100 miles, as long as you're not too close to the poles.) I took the latitude of the center of the country (Wichita, KS: latitude 37.65) and plugged it into a [Length Of A Degree Of Latitude\n", + "And Longitude Calculator](http://www.csgnetwork.com/degreelenllavcalc.html) to find that, in Wichita, one degree of latitude is 69 miles, and one degree of longitude is 48 miles. (It is -48 rather than +48 because the US is west of the prime meridian.) \n", + "\n", + "Now let's create the map of USA cities, and find a tour for it:" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "USA_map = Coordinate_map(lines(\"\"\"\n", + "[TCL] 33.23 87.62 Tuscaloosa,AL\n", + "[FLG] 35.13 111.67 Flagstaff,AZ\n", + "[PHX] 33.43 112.02 Phoenix,AZ\n", + "[PGA] 36.93 111.45 Page,AZ\n", + "[TUS] 32.12 110.93 Tucson,AZ\n", + "[LIT] 35.22 92.38 Little Rock,AR\n", + "[SFO] 37.62 122.38 San Francisco,CA\n", + "[LAX] 33.93 118.40 Los Angeles,CA\n", + "[SAC] 38.52 121.50 Sacramento,CA\n", + "[SAN] 32.73 117.17 San Diego,CA\n", + "[SBP] 35.23 120.65 San Luis Obi,CA\n", + "[EKA] 41.33 124.28 Eureka,CA\n", + "[DEN] 39.75 104.87 Denver,CO\n", + "[DCA] 38.85 77.04 Washington/Natl,DC\n", + "[MIA] 25.82 80.28 Miami Intl,FL\n", + "[TPA] 27.97 82.53 Tampa Intl,FL\n", + "[JAX] 30.50 81.70 Jacksonville,FL\n", + "[TLH] 30.38 84.37 Tallahassee,FL\n", + "[ATL] 33.65 84.42 Atlanta,GA\n", + "[BOI] 43.57 116.22 Boise,ID\n", + "[CHI] 41.90 87.65 Chicago,IL\n", + "[IND] 39.73 86.27 Indianapolis,IN\n", + "[DSM] 41.53 93.65 Des Moines,IA\n", + "[SUX] 42.40 96.38 Sioux City,IA\n", + "[ICT] 37.65 97.43 Wichita,KS\n", + "[LEX] 38.05 85.00 Lexington,KY\n", + "[NEW] 30.03 90.03 New Orleans,LA\n", + "[BOS] 42.37 71.03 Boston,MA\n", + "[PWM] 43.65 70.32 Portland,ME\n", + "[BGR] 44.80 68.82 Bangor,ME\n", + "[CAR] 46.87 68.02 Caribou Mun,ME\n", + "[DET] 42.42 83.02 Detroit,MI\n", + "[STC] 45.55 94.07 St Cloud,MN\n", + "[DLH] 46.83 92.18 Duluth,MN\n", + "[STL] 38.75 90.37 St Louis,MO\n", + "[JAN] 32.32 90.08 Jackson,MS\n", + "[BIL] 45.80 108.53 Billings,MT\n", + "[BTM] 45.95 112.50 Butte,MT\n", + "[RDU] 35.87 78.78 Raleigh-Durh,NC\n", + "[INT] 36.13 80.23 Winston-Salem,NC\n", + "[OMA] 41.30 95.90 Omaha/Eppley,NE\n", + "[LAS] 36.08 115.17 Las Vegas,NV\n", + "[RNO] 39.50 119.78 Reno,NV\n", + "[AWH] 41.33 116.25 Wildhorse,NV\n", + "[EWR] 40.70 74.17 Newark Intl,NJ\n", + "[SAF] 35.62 106.08 Santa Fe,NM\n", + "[NYC] 40.77 73.98 New York,NY\n", + "[BUF] 42.93 78.73 Buffalo,NY\n", + "[ALB] 42.75 73.80 Albany,NY\n", + "[FAR] 46.90 96.80 Fargo,ND\n", + "[BIS] 46.77 100.75 Bismarck,ND\n", + "[CVG] 39.05 84.67 Cincinnati,OH\n", + "[CLE] 41.42 81.87 Cleveland,OH\n", + "[OKC] 35.40 97.60 Oklahoma Cty,OK\n", + "[PDX] 45.60 122.60 Portland,OR\n", + "[MFR] 42.37 122.87 Medford,OR\n", + "[AGC] 40.35 79.93 Pittsburgh,PA\n", + "[PVD] 41.73 71.43 Providence,RI\n", + "[CHS] 32.90 80.03 Charleston,SC\n", + "[RAP] 44.05 103.07 Rapid City,SD\n", + "[FSD] 43.58 96.73 Sioux Falls,SD\n", + "[MEM] 35.05 90.00 Memphis Intl,TN\n", + "[TYS] 35.82 83.98 Knoxville,TN\n", + "[CRP] 27.77 97.50 Corpus Chrst,TX\n", + "[DRT] 29.37 100.92 Del Rio,TX\n", + "[IAH] 29.97 95.35 Houston,TX\n", + "[SAT] 29.53 98.47 San Antonio,TX\n", + "[LGU] 41.78 111.85 Logan,UT\n", + "[SLC] 40.78 111.97 Salt Lake Ct,UT\n", + "[SGU] 37.08 113.60 Saint George,UT\n", + "[CNY] 38.77 109.75 Moab,UT\n", + "[MPV] 44.20 72.57 Montpelier,VT\n", + "[RIC] 37.50 77.33 Richmond,VA\n", + "[BLI] 48.80 122.53 Bellingham,WA\n", + "[SEA] 47.45 122.30 Seattle,WA\n", + "[ALW] 46.10 118.28 Walla Walla,WA\n", + "[GRB] 44.48 88.13 Green Bay,WI\n", + "[MKE] 42.95 87.90 Milwaukee,WI\n", + "[CYS] 41.15 104.82 Cheyenne,WY\n", + "[SHR] 44.77 106.97 Sheridan,WY\n", + "\"\"\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_lines(USA_map, 'bo')" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 13562.6 in 0.297 secs for repeated_altered_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(repeated_altered_nn_tsp, USA_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Not bad! There are no obvious errors in the tour (although I'm not at all confident it is the optimal tour). \n", + "\n", + "Now let's do the same for Randal Olson's landmarks. Note that the data is delimited by tabs, not spaces, and the longitude already has a minus sign, so we don't need another one in `long_scale`." + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "USA_landmarks_map = Coordinate_map(lines(\"\"\"\n", + "Mount Rushmore National Memorial, South Dakota 244, Keystone, SD\t43.879102\t-103.459067\n", + "Toltec Mounds, Scott, AR\t34.647037\t-92.065143\n", + "Ashfall Fossil Bed, Royal, NE\t42.425000\t-98.158611\n", + "Maryland State House, 100 State Cir, Annapolis, MD 21401\t38.978828\t-76.490974\n", + "The Mark Twain House & Museum, Farmington Avenue, Hartford, CT\t41.766759\t-72.701173\n", + "Columbia River Gorge National Scenic Area, Oregon\t45.711564\t-121.519633\n", + "Mammoth Cave National Park, Mammoth Cave Pkwy, Mammoth Cave, KY\t37.186998\t-86.100528\n", + "Bryce Canyon National Park, Hwy 63, Bryce, UT\t37.593038\t-112.187089\n", + "USS Alabama, Battleship Parkway, Mobile, AL\t30.681803\t-88.014426\n", + "Graceland, Elvis Presley Boulevard, Memphis, TN\t35.047691\t-90.026049\n", + "Wright Brothers National Memorial Visitor Center, Manteo, NC\t35.908226\t-75.675730\n", + "Vicksburg National Military Park, Clay Street, Vicksburg, MS\t32.346550\t-90.849850\n", + "Statue of Liberty, Liberty Island, NYC, NY\t40.689249\t-74.044500\n", + "Mount Vernon, Fairfax County, Virginia\t38.729314\t-77.107386\n", + "Fort Union Trading Post National Historic Site, Williston, North Dakota 1804, ND\t48.000160\t-104.041483\n", + "San Andreas Fault, San Benito County, CA\t36.576088\t-120.987632\n", + "Chickasaw National Recreation Area, 1008 W 2nd St, Sulfur, OK 73086\t34.457043\t-97.012213\n", + "Hanford Site, Benton County, WA\t46.550684\t-119.488974\n", + "Spring Grove Cemetery, Spring Grove Avenue, Cincinnati, OH\t39.174331\t-84.524997\n", + "Craters of the Moon National Monument & Preserve, Arco, ID\t43.416650\t-113.516650\n", + "The Alamo, Alamo Plaza, San Antonio, TX\t29.425967\t-98.486142\n", + "New Castle Historic District, Delaware\t38.910832\t-75.527670\n", + "Gateway Arch, Washington Avenue, St Louis, MO\t38.624647\t-90.184992\n", + "West Baden Springs Hotel, West Baden Avenue, West Baden Springs, IN\t38.566697\t-86.617524\n", + "Carlsbad Caverns National Park, Carlsbad, NM\t32.123169\t-104.587450\n", + "Pikes Peak, Colorado\t38.840871\t-105.042260\n", + "Okefenokee Swamp Park, Okefenokee Swamp Park Road, Waycross, GA\t31.056794\t-82.272327\n", + "Cape Canaveral, FL\t28.388333\t-80.603611\n", + "Glacier National Park, West Glacier, MT\t48.759613\t-113.787023\n", + "Congress Hall, Congress Place, Cape May, NJ 08204\t38.931843\t-74.924184\n", + "Olympia Entertainment, Woodward Avenue, Detroit, MI\t42.387579\t-83.084943\n", + "Fort Snelling, Tower Avenue, Saint Paul, MN\t44.892850\t-93.180627\n", + "Hoover Dam, Boulder City, CO\t36.012638\t-114.742225\n", + "White House, Pennsylvania Avenue Northwest, Washington, DC\t38.897676\t-77.036530\n", + "USS Constitution, Boston, MA\t42.372470\t-71.056575\n", + "Omni Mount Washington Resort, Mount Washington Hotel Road, Bretton Woods, NH\t44.258120\t-71.441189\n", + "Grand Canyon National Park, Arizona\t36.106965\t-112.112997\n", + "The Breakers, Ochre Point Avenue, Newport, RI\t41.469858\t-71.298265\n", + "Fort Sumter National Monument, Sullivan's Island, SC\t32.752348\t-79.874692\n", + "Cable Car Museum, 94108, 1201 Mason St, San Francisco, CA 94108\t37.794781\t-122.411715\n", + "Yellowstone National Park, WY 82190\t44.462085\t-110.642441\n", + "French Quarter, New Orleans, LA\t29.958443\t-90.064411\n", + "C. W. Parker Carousel Museum, South Esplanade Street, Leavenworth, KS\t39.317245\t-94.909536\n", + "Shelburne Farms, Harbor Road, Shelburne, VT\t44.408948\t-73.247227\n", + "Taliesin, County Road C, Spring Green, Wisconsin\t43.141031\t-90.070467\n", + "Acadia National Park, Maine\t44.338556\t-68.273335\n", + "Liberty Bell, 6th Street, Philadelphia, PA\t39.949610\t-75.150282\n", + "Terrace Hill, Grand Avenue, Des Moines, IA\t41.583218\t-93.648542\n", + "Lincoln Home National Historic Site Visitor Center, 426 South 7th Street, Springfield, IL\t39.797501\t-89.646211\n", + "Lost World Caverns, Lewisburg, WV\t37.801788\t-80.445630\n", + "\"\"\"), delimiter='\\t', long_scale=48)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_lines(USA_landmarks_map, 'bo')" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "50 city tour with length 10236.7 in 0.125 secs for repeated_altered_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(repeated_altered_nn_tsp, USA_landmarks_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can compare that to the tour that Randal Olson computed as the shortest based on road distances:\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "The two tours are similar but not the same. I think the difference is that roads through the rockies and along the coast of the Carolinas tend to be very windy, so Randal's tour avoids them, whereas my program assumes straight-line roads and thus includes them. William Cook provides an\n", + "analysis, and a [tour that is shorter](http://www.math.uwaterloo.ca/tsp/usa50/index.html) than either Randal's or mine.\n", + "\n", + "Now let's go back to the [original web page](http://www.realestate3d.com/gps/latlong.htm) to get a bigger map with over 1000 cities. A shell command fetches the file:" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "! [ -e latlong.htm ] || curl -O http://www.realestate3d.com/gps/latlong.htm" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I note that the page has some lines that I don't want, so I will filter out lines that are not in the continental US (that is, cities in Alaska or Hawaii), as well as header lines that do not start with `'['`." + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def continental_USA(line): \n", + " \"Does line denote a city in the continental United States?\"\n", + " return line.startswith('[') and ',AK' not in line and ',HI' not in line\n", + "\n", + "USA_big_map = Coordinate_map(filter(continental_USA, open('latlong.htm')))" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\niRIlSpTIS/8/TuRYhKOqNG4AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_lines(USA_big_map, 'bo')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's get a baseline tour with `nn_tsp`:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1089 city tour with length 52879.1 in 0.177 secs for nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(nn_tsp, USA_big_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now try to improve on that with `repeat_100_nn_tsp` and with `repeat_5_altered_nn_tsp` (which will take a while with over 1000 cities):" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1089 city tour with length 50802.6 in 17.126 secs for repeat_100_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(repeat_100_nn_tsp, USA_big_map)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nEAL5fxkVHTv2ITP1AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1089 city tour with length 44234.6 in 23.149 secs for repeat_5_altered_nn_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(repeat_5_altered_nn_tsp, USA_big_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Again we see that we do better by spending our run time budget on alteration rather than on repetition. This time we saved over 8,000 miles of travel in half a minute of computation!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Greedy Algorithm: `greedy_tsp`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At the start of the *Approximate Algorithms* section, we mentioned two ideas:\n", + "\n", + "1. **Nearest Neighbor Algorithm:** Make the tour go from a city to its nearest neighbor. Repeat.\n", + "2. **Greedy Algorithm:** Find the shortest distance between any two cities and include that in the tour. Repeat.\n", + "\n", + "It is time to develop the *greedy algorithm*, so-called because at every step it greedily adds to the tour the edge that is shortest (even if that is not best in terms of long-range planning). The nearest neighbor algorithm always extended the tour by adding on to the end. The greedy algorithm is different in that it doesn't have a notion of *end* of the tour; instead it keeps a *set* of partial segments. Here's a brief statement of the algorithm:\n", + "\n", + "> **Greedy Algorithm:** *Maintain a set of segments; initially each city defines its own 1-city segment. Find the shortest possible edge that connects two endpoints of two different segments, and join those segments with that edge. Repeat until we form a segment that tours all the cities.*\n", + "\n", + "On each step of the algorithm, we want to \"find the shortest possible edge that connects two endpoints.\" That seems like an expensive operation to do on each step. So we will add in some data structures to enable us to speed up the computation. Here's a more detailed sketch of the algorithm:\n", + "\n", + "1. Pre-compute a list of **edges**, sorted by shortest edge first. An edge is a pair of cities; if the list contains `(A, B)` then it does not contain `(B, A)`, and it never contains `(A, A)`.\n", + "2. Maintain a dict that maps **endpoints** to **segments**, e.g. `{A: [A, B, C, D], D: [A, B, C, D]}`. Initially, each city is the endpoint of its own 1-city-long segment, but as we join segments together, some cities are no longer endpoints and are removed from the dict.\n", + "3. Go through the edges in shortest-first order. When you find an edge `(A, B)` such that both `A` and `B` are endpoints of different segments, then join the two segments together. Maintain the endpoints dict to reflect this new segment. Stop when you create\n", + "a segment that contains all the cities.\n", + "\n", + "\n", + "Let's consider an example: assume we have seven cities, labeled A through G. Suppose CG happens to be the shortest edge. We would add the edge to the partial tour, by joining the segment that contains C with the segment that contains G. In this case, the joining is easy, because each segment is one city long; we join them to form a segment two cities long. We then look at the next shortest edge and continue the process, joining segments as we go, as shown in the table below. Some edges cannot be used. For example, FD cannot be used, because by the time it becomes the shortest edge, D is already in the interior of a segment. Next, AE cannot be used, even though both A and E are endpoints, because it would make a loop out of ACGDE. Finally, note that sometimes we may have to reverse a segment. For example, EF can merge AGCDE and BF, but first we have to reverse BF to FB. \n", + "\n", + "\n", + "\n", + "
Shortest EdgeUsage of edgeResulting Segments\n", + "
A; B; C; D; E; F; G\n", + "
CGJoin C to GA; B; CG; D; E; F\n", + "
DEJoin D to EA; B; CG; DE; F\n", + "
ACJoin A to CGB; ACG; DE; F\n", + "
GDJoin ACG to DB; ACGDE; F\n", + "
FDDiscardB; ACGDE; F\n", + "
AEDiscardB; ACGDE; F\n", + "
BFJoin B to FBF; ACGDE\n", + "
CFDiscardBF; ACGDE\n", + "
EFJoin ACGDE to FBACGDEFB\n", + "
\n", + "\n", + "Here is the code:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def greedy_tsp(cities):\n", + " \"\"\"Go through edges, shortest first. Use edge to join segments if possible.\"\"\"\n", + " endpoints = {c: [c] for c in cities} # A dict of {endpoint: segment}\n", + " for (A, B) in shortest_edges_first(cities):\n", + " if A in endpoints and B in endpoints and endpoints[A] != endpoints[B]:\n", + " new_segment = join_endpoints(endpoints, A, B)\n", + " if len(new_segment) == len(cities):\n", + " return new_segment\n", + " \n", + "# TO DO: functions: shortest_edges_first, join_endpoints" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "**Note:** The `endpoints` dict is serving two purposes. First, the keys of the dict are all the cities that are endpoints of some segments,\n", + "making it possible to ask \"`A in endpoints`\" to see if city `A` is an endpoint. Second, the values of the dict are all the segments, making it possible to ask \"`endpoints[A] != endpoints[B]`\" to make sure that the two cities are endpoints of different segments, not of the same segment.\n", + "\n", + "The `shortest_edges_first` function is easy: generate all `(A, B)` pairs of cities, and sort by the distance between the cities. (Note: I use the conditional `if id(A) < id(B)` so that I won't have both `(A, B)` and `(B, A)` in my list of edges, and I won't ever have `(A, A)`.)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def shortest_edges_first(cities):\n", + " \"Return all edges between distinct cities, sorted shortest first.\"\n", + " edges = [(A, B) for A in cities for B in cities \n", + " if id(A) < id(B)]\n", + " return sorted(edges, key=lambda edge: distance(*edge))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the `join_endpoints` function, I first make sure that A is the last element of one segment and B is the first element of the other, by reversing segments if necessary. Then I add the B segment on to the end of the A segment. Finally, I update the `endpoints` dict. This is a bit tricky! My first thought was that A and B are no longer endpoints, because they have been joined together in the interior of the segment. However, that isn't always true. If A was the endpoint of a 1-city segment, then when you join it to B, A is still an endpoint. I could have had complicated logic to handle the case when A, B, or both, or neither were 1-city segments, but I decided on a different tactic: first unconditionally delete A and B from the endpoints dict, no matter what. Then add the two endpoints of the new segment (which is `Asegment`) to the endpoints dict. " + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def join_endpoints(endpoints, A, B):\n", + " \"Join B's segment onto the end of A's and return the segment. Maintain endpoints dict.\"\n", + " Asegment, Bsegment = endpoints[A], endpoints[B]\n", + " if Asegment[-1] is not A: Asegment.reverse()\n", + " if Bsegment[0] is not B: Bsegment.reverse()\n", + " Asegment.extend(Bsegment)\n", + " del endpoints[A], endpoints[B] # A and B are no longer endpoints\n", + " endpoints[Asegment[0]] = endpoints[Asegment[-1]] = Asegment\n", + " return Asegment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try out the `greedy_tsp` algorithm on the two USA maps:" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nH76Nk+B8wxPEAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 16087.5 in 0.006 secs for greedy_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(greedy_tsp, USA_map)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1089 city tour with length 46981.5 in 1.052 secs for greedy_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(greedy_tsp, USA_big_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The greedy algorithm is worse than nearest neighbors, but it is fast (especially on the big map). Let's see if the *alteration* strategy can help:" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def altered_greedy_tsp(cities):\n", + " \"Run greedy TSP algorithm, and alter the results by reversing segments.\"\n", + " return alter_tour(greedy_tsp(cities))" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 14133.3 in 0.022 secs for altered_greedy_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(altered_greedy_tsp, USA_map)" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1089 city tour with length 43769.9 in 4.177 secs for altered_greedy_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(altered_greedy_tsp, USA_big_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's the best result yet on the big map. Let's look at some benchmarks:" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " altered_nn_tsp | 4820 ± 233 ( 4450 to 5346) | 0.008 secs/map | 30 ⨉ 60-city maps\n", + " altered_greedy_tsp | 4766 ± 207 ( 4320 to 5185) | 0.009 secs/map | 30 ⨉ 60-city maps\n", + " repeated_altered_nn_tsp | 4640 ± 194 ( 4298 to 4991) | 0.148 secs/map | 30 ⨉ 60-city maps\n", + "----------------------------------------------------------------------------------------------------\n", + " altered_nn_tsp | 6589 ± 202 ( 6188 to 7016) | 0.036 secs/map | 30 ⨉ 120-city maps\n", + " altered_greedy_tsp | 6539 ± 240 ( 5994 to 7203) | 0.037 secs/map | 30 ⨉ 120-city maps\n", + " repeated_altered_nn_tsp | 6402 ± 185 ( 6015 to 6779) | 0.701 secs/map | 30 ⨉ 120-city maps\n" + ] + } + ], + "source": [ + "algorithms = [altered_nn_tsp, altered_greedy_tsp, repeated_altered_nn_tsp]\n", + "\n", + "benchmarks(algorithms)\n", + "print('-' * 100)\n", + "benchmarks(algorithms, Maps(30, 120))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So overall, the altered greedy algorithm looks slightly better than the altered nearest neighbor algorithm and runs in about the same time. However, the repeated altered nearest neighbor algorithm does best of all (although it takes much longer).\n", + "\n", + "What about a repeated altered greedy algorithm? That might be a good idea, but there is no obvious way to do it. We can't just start from a sample of cities, because the greedy algorithm doesn't have a notion of starting city.\n", + "\n", + "Visualizing the Greedy Algorithm\n", + "---\n", + "\n", + "I would like to see how the process of joining segments unfolds. Although I dislike copy-and-paste (because it violates the *[Don't Repeat Yourself](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)* principle), I'll copy `greedy_tsp` and make a new version called `visualize_greedy_tsp` which adds one line to plot the segments several times as the algorithm is running:" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def visualize_greedy_tsp(cities, plot_sizes):\n", + " \"\"\"Go through edges, shortest first. Use edge to join segments if possible.\n", + " Plot segments at specified sizes.\"\"\"\n", + " edges = shortest_edges_first(cities) # A list of (A, B) pairs\n", + " endpoints = {c: [c] for c in cities} # A dict of {endpoint: segment}\n", + " for (A, B) in edges:\n", + " if A in endpoints and B in endpoints and endpoints[A] != endpoints[B]:\n", + " new_segment = join_endpoints(endpoints, A, B)\n", + " plot_segments(endpoints, plot_sizes, distance(A, B)) # <<<< NEW\n", + " if len(new_segment) == len(cities):\n", + " return new_segment\n", + " \n", + "def plot_segments(endpoints, plot_sizes, dist):\n", + " \"If the number of distinct segments is one of plot_sizes, then plot segments.\"\n", + " segments = set(map(tuple, endpoints.values()))\n", + " if len(segments) in plot_sizes:\n", + " for s in segments:\n", + " plot_lines(s)\n", + " plt.show()\n", + " print('{} segments, longest edge = {:.0f}'.format(\n", + " len(segments), dist))" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAADqCAYAAABTP2nAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFRtJREFUeJzt3X2wXVV5gPFnSYhVyJWhoCRBuSJ+1WjVYkMAtQKxSu0w\nwcqIxLFqWyJVqFpH1Gj9SI2tA07FD2hxxpYgSMuA1lIsNGBbopZpbTEQicEBMQnYgG1MFD9w9Y+T\n67039xz3vfecvddaez+/mT1Ho8lZ5+x99rvXu9Z6V4gxIknSL/KI1A2QJOXPYCFJqmSwkCRVMlhI\nkioZLCRJlQwWkqRKBgtJUiWDhSSpksFCklTJYCFJqmSwkCRVMlhIkiotSN2AYYUwNg7L1sHiJbBz\nB2xeG+Puu1O3S5LapOhg0QsUp90IFz8JDgL2AmuOC2HsFAOGJI1O4WmoZesmAwX0Xi9+Uu/PJUmj\nUniwWLxkMlBMOAg4YkmK1khSWxUeLHbu6KWeptoL3LcjRWskqa0KDxab18KauyYDxl56/33z2pSt\nkqS2CaVvq9ob5F5+Afz6y+Cmv3U2lCSNXvHBAiAEDgB+CCyKkR+lbo8ktU3haaieGHkY2AEsTd0W\nSWqjVgSLfe4BjkrdCElqo5akocbG4Xc3wkMPweb/dNxCkkar+GAxYBX3XfA5V3FL0oi0IA3lKm5J\nqlsLgoWruCWpbkUXEuyZWMU9NWC4ilvTWZ1YTWjzdeaYhbIz6h9cU9dIm28Uqtb6e1GMsfgDFo3D\nig2wamPvddF46jZ5DHMuV2+DPRFi7L2u3jbMOe1dExP/Xpzy767YkHO7Pco6mrjOUh4tSEPBvqi9\nOnU7NAqDJizctY55n+MmxrXqaLfK0u7x0xYMcKtd6vjBNVGduN03Cs1Gu6tgGyyUmTp+cE1UJ273\njUKz0e4q2MUPcNfJAcvm1TVIOHkuj1jSu4GP9ly2fnBTs1L3dZaSwWIAf/zplPqDK7Xd0mwYLAYI\n4fgNcMNZM9dvrLw8xk21D1jaq5GUk1bMhqpHugHLAb2a40IYG1EqxgAkaW6KDxb13QBTrgwf/TTM\nugKQpG4oejbU5A3whrPg6hf1Xk+7sffnw0o5s6GOXo0FF+cjhLHxEI7fEMLLN/ZeR3FtSeUpvGdR\n30KoGHffHcLYKb1/q+kByzp6Na4DmCt7Y9KkwoNFvTfAdCvDN6+FNcfNnIk1TK/Ggotz56psaULh\nwaKdN8B6ejX9AtA7H4JPLAiBA2JvH3NNY29MmlB4sKjjCTwPo+7V9A9AB30Qnn0RcHkIvDpGfjKq\n92uHdj6MSPNR/DoLF0INJwR+CbgKCMArYuShxE3KhgszVaVL09GLDxYaXggcCFwGWx4Pa+6Fwx7b\n9gt/tnwY0SBde5gwWAiAEJYcDad/Df5srAsXvjSs1FUemlb0OguN0vj7JwMFuA4jD67zyFm3JkAU\nPsCt0enWhV8C13nkbu/uLk2AsGehfdyPIT+uuh+1UfXUQuAI+Nhz4C3/09b9K/Znz0L71DMNuUuz\nRUbP3t4ojaqnFgKPAa6HYy6FKy6Dr3diAoTBQkA9CwFNowzLdR6jNfyK/H1Tza8FbgHWxbg7zvbv\nls5goZ8bfXkTy2UMp72LTtMYrqcWAgcAlwG7gHNjpFNTSQ0WqpFplGFM7+2ddAZ85fPw739sr2y+\ndt0/157a9DTqEUvhjbvg6Sd1sTyOwWJEzM33k08apdTzM9HbC4FlwAdj5O60LSrZn98P5++BDx08\nm55a/zTqOQfCNYsh/2tn5GKMHkMesGgcVm+DPRFi7L2u3gaLxlO3ze8ln3YM9xnidRB/O3U7Sj0g\nPhHiA/D242HFBli1sfc6+Bro/e8T10yccu2s2JD686Q47FmMhLn5ftLuCTJVK87PdsD03fxdCHwk\nxg9tAjbN7q+YRp3KYDESXlSDpNsTZKpWnJ/twNLUjShRCLwYeBZw5tz+Zj5p1By4KG8kXNCWt1ac\nH4PFPITAQuCjwB/FOVdU3rwW3vWjriy6q2LPYiSc4pi3ss9Pb6D1JWfCUb8awi2PLGVwfn+JJhmc\nC3wL+MLc/+ruQ+CuXfDim+FxrV90V8WqsyNiKeu8TZ6f5SfBg9+Ba84o4fy0pQx2k59j8lw/YRye\nfCw86qUxvvOmuf87XAQ8ECPvHWX7SmWwUKeEwNnAcTHy2tRtmY22lMFu6nOMKijtW6n9HeDXYuSe\nUbWvZI5ZqGtuBZ6XuhGz14rBeZr7HCMrvrgK+JqBYlKxYxalLrJSak/ZDWc+NYQ7vgTb783/uml2\nRk59v6umPsewJT0mPv8Jp8L220P4wnje10eDUi/0mN8Cm/IXWXk0f5R43TTZ5jrfq6nPMcxCuhKv\nj0avxdQNaPqC8OjuUep107uJrdgAa7bCOXfWdfOq+/uZ/BzVq6eHe4/53fBLvT6aOgpNQ7Ulj6tm\nlXndTKkPdQqwNsaP313PO9X7/TSxQHO4qgFlXh9NKTRYfO8BV1Zq7kpfkXvebhhbHsIdG+sZpyv9\n++mZf1Bqx+evTequzdy7mXEM7rwN3vBgV3KLk93302vrvnfhKDkn3UTb+7/H2btK+H5G89mffQ28\n5uESr48mjqLWWYTAo4Hrga/D2Ie7sAiuLYuycjE52+VZx8LChfDpk0r4HptdpzDxu9rzv3DxiXD0\nq2LkxlG9R26m/8Z2AZcCW34I934Rtry5hOujEamj1ewjf1wI8R8h/g3ER6RuT3Of20G3er7XeGSv\nZHVcMPu/k66H13vPGGceqzbW/D39BsT74N0ntrV3629sdkfWYxaTTzlLlsKRR8Pvb4FnvC5Gfpa6\nbfurb366g251iJHvhLB1B5x/XQhhQdU5S7+feJp8eozcHMK/XAK7/xluWNjOvdT9jc1K6mg1ONr3\ny5+++q4cn2jqnZ+e71NPyWMpvbaveWDQOYN4MMTnQDwD4lp4410pz0PK8Zacr0E/X4PfU+oGtOEE\n1tnWXAdlc23X8OfsrfdB3A7xBxBvg3g1xPXwB1tSpIFmfuf1rlPo/75pUmDNfq/lXstNHRmnoUrq\nGtbX1sl544f9K+z+Hmy5LY/B/NJ3nxt0znbtAE4Dtscp6c4Qvv542Pu0lNMq020k1e4ppfns6Ji3\njINFSRdofW2dHAtZuAgevCOfi7ikYN7PoHO29Y4YuXfm/7/sPTGG0++zv/thOPe61C3b33zHDvPY\n0TFzqbs2bega1tXWnL+DktKEo/puU6WBcjhmfvbPnAlxJ8S3QQyp27evjSfCK3fn+Htpw5H1OouS\nNhSqo60572XQhvUfJV1fOQqBJwBX09uJ7vUxsiddW8bGYfltcO2iHH8vbZBxGqqsrmE9bc031TOZ\n5118K9x/D3zzG6XdbEu6vnIUI98OgecDnwC+HAKrYmRbmtYsWwfLF+X6e2mDrIOF8h636QUMvg2c\nHSP/kbo9al6MPBQCrwfWAJtCuObt8OGTm99nZvESOJCcfy+lM1hkrYhB1UcCP07dCKUTIxH4ZAif\nvh9u+yzcsKD5xXs7d8A64E+A9zH5/r/3/cx+L8XKesxC+efVQ2Ar8LIY2Zq6LUor5Rjb5BjaO58E\nVwE/Ab76ffjqqTHu/rc637sr7FlkroC8uj0L7ZNujM21EvUzWGjeek9z5x4O2zaE8O27/XGmk8ee\n9GnH2Ap4sCqaaSjNSxumzrZFLucil3aoHp0OFnk8jZUp5zUgXZPTuch9jE3z19k0VPqS06XLdw1I\n9+RzLkwFtdcjUjcgnUGF8JatS9mqckzkp6dyTnsag87FQ8lWVKt9OhwsFi/N5WmsTJvX9vLREzep\nLNeAdES/c/HWXfCxE0PgT/dtRywNpZNpqBA4GB5/tKs958+pivkYdC7g4h8DFwK3h8CbYGyzY3Sa\nr84NcIfAOPA5+O8tcMHz4JNHO3NDbRYCK2HbJfDRx8L6g3K+3p10kq9OBYsQeCFwJbAeuAjGjmrb\nzA1/bHlLdX5CeP5n4Pozc5gxNYhTb/PWmTRUCKyhVzTmrBi5sfen7Zq54QyvvKU9P489Iv8xutJ3\nX2y3VgaL6U9v9++Eix6G5xwLnJCuhHIT/LHlLeX5ybuCcU8+U4A1U+uCRf+nt3f8AN6zPMa/b3Gg\nAH9suUt5fjavhbf+JlxwWL4VjEsIaN3Vwqmz/Z7e1j8aHjg/Zaua4dqHvKU7P7001x9+Bc7+Mpx+\nE6y8PL+xgM1r4dztTsfOUwuDRZefrl37kLc05yeEsfFeSZArV8Ku78KNr4tx0+q8AsVEQHvVR+H8\nb+Ub0LqrdWmoLndlXfuQtxTnp09a9jRYsyzfSQ8nHwYnXxoj61O3RNO1bupsCG9eDuEW+MABTr9T\n1+VUZHA2QuBa4LIYuTp1WzRdq3oWIRDgI++Fr1wEKw/36bq7XG8yobi07FPAXRdz1IpgMXljeOax\ncMjhcM2bYtza8plPGsT1JlOVk5YNgQOAJ0Kbp7eXq/gB7skbww1nwSVPhfccCsuv7/25usmKwpPK\nmPTQ+72+5Gp4F3D8X/n7zU8LehYuRNP+iku91KaESQ99eoJndbcnmK8WBAtvDNpfOamXJuS/IZEP\nfCUoPg1V+kK0iTnwIbx8Y+/V7vfwyki9aIIPfCVoQc9i81pYc9zMSpX53xjmOhDrDJ/ZKSH1oqns\nCZagFessSt0kfvAc+NfeDFe9DdgBfDdGfmr5ZrWV13YZWtCzKCEnO8jSI/t3v5/wTOAvgSXAL4fA\nLnjDwt5ML/O6ahd7gmVoRbAoUQiMwVFP69/93nR9jL0AEAILgMfBzmvhoEOn/yvmddUO5T7wdUcL\nBrjLEwKPA26Gs75YNRAbIz+Nke2w7c6SB/Illa0VYxYlCYEnAv8EbADeP9utXc3rSkrJYNGgEHgW\ncB3wwRj5xNz/fpkD+eoGZ+u1m8GiRtN/PD/7CVzwXDj6jTHy2dRtk0bJnm/7GSxq0v/Hc94OuOoE\nfzxqm6pS6PY6yudsqNr0K2HwF0vgDqe6KrnR37wHrcJ+xrNDOOdYOO1KqwCXzWBRm3aUMPCJsH3q\nKeE+aBX2wWOw6Bb48ELXCJXNqbO1KbtmFexf/v3qF/VeT7vR+lWlq6OE+6B6XJ96Ady+qQ0PTl1n\nsKhNG4rZlbkvhMUZq4y+19vrkXzuFFh5OZx+U+91YnB75/bSH5zUoTRU0+mUdpQwKC+VlmKXvPJS\ndfUU7hu8CrvcYp+aIsbY+gMWjcPqbbAnQoy919XbYNF46rbN7TOs2ACnb+y91t/23vtMfGdxyne3\nYkPq7yOXNs/32kpxPodt8/DvuWIDrGr883qM6BymbkAjH7LAm9709qcJdiUG2d7NN8aZx6qNzV5b\nL7gi5+/Vm7fHXI+OpKHKS6dMl2YnsTJTaU3vjTDo2nrhGSHwUnpl5rfve933n099Reqd4Szcp7nq\nSLAofXOVdMGuvJtK0/nxQdfWjVfA+8+lV2Z+CbB03+vT4chfKfvhRV3UkWBR+gBb6cGuOc33hgZf\nWzHyIPAgsHnq3whh02Ngb5/Vzp5P5asz5T5KLsJn3Z28zfXa8nyqRJ0JFqXr3WDO+wZsvRXuvaek\nYKeZSn54UTcZLAoRAocCdwOPiRFPmqRGuYK7HMcA3zRQSEqhIwPcc5fhqtwnA99M+P6SOsxg0UeK\nkhGz8GRgW6L3ltRxpqH6yrKAnj0LDc0ii5ovexZ9Zbni+xjg4wnfX4XLtMesQtiz6CufvSgmngRh\n7XPh5Df7JKj5y7LHrEIYLPrqtxfFW77b9Irv6ZsPrVsAn/8dNx/qruFTSFn2mFUI01B9zCwZ8dAe\n+NgJcMnCZluSpoCg8jOaFJJlYzR/BosB9i+gFwLnAJ8JgeNj5MfNtMInQU0YxYND6TXSlJLBYvY+\nCbwUeB/wjmbe0idBTRj+waGJIosZrk/SiBgsZilGYgi8HvhaCFfcBhf9Vv0/iH5Pguft9Emwi0bz\n4FBnyXlnW7WbtaHmKIS/ew1suhQ+sKCJiqHTC84dAKw/Co55enOpMOWghEq1vVl7N/Qpvb7y8hg3\nOcZWOHsWc3bhSrhhQVODzn3GTv4BeBNwwajfS/kqY9dCx9jazGAxZ8l/EG8BbgmBDTFyf0PvqRGb\nT24//10LHWNrM9dZzFnaBXsxcifw14ALqQo1ff3M1S/qvbZh/Uy/9UnOtmoLxyzmKIfccQgcAt/a\nCufdCgsf5ayTsrQ5t++mTu1lGmqO8sgdjx0CZwJXnuqskxIlT2XWJv9UmebLYDEP6X8Qy9bBhYe7\nsrtU5vZVHscsitTeJ9NuMLev8tizKJJPpiXLI5UpzY0D3AXKYZBdUrcYLArlrBNJTTJYSJIqOcAt\nSapksJAkVTJYSJIqGSwkSZVcZyFpVtwFr9sMFlKHzPeG7y54cuqs1BHDLOZsc6VczY5jFlJnLFs3\nGShgsgDlslnsjWI9sq4zDSUlkCb/P8wN33pkXWewkGj25p0u/z/MDX/zWlhz3MwUlpVyu8IxC3Ve\n04UZU+X/h/2c1iPrNnsW0sBcfl2bSaXJ/w9bGj39pl9KyWCh4g2fQmr65p0u/+8NX/NlsFBW5nrj\nH03+v+mbt/l/lccxC2Vjtjn1EHg0cETveOV6+NQLhsn/p9hMyvy/SmPPQhkZNHZw6M0hcA+wmF6Q\nOBC4r3ccecywKaQU25yaDlJpDBbKyKCxgx/sAd7DzwMEu2MkAoSwaQPs7TOzaG4pJG/e0i/mCm5l\nZGLsYKq9wO3/FSNfipE7Y+T/JgJFz+a1vZTR3in/f/P/0qg5ZqFszHfswPy/VD+DhbLijV/Kk8FC\nklTJMQtJUiWDhSSpksFCklTJdRaSZnC/be3PYCFpGvfbVj/OhlIr+WQ8f+63rX7sWah1fDIelvtt\nayYHuNVCgwoSLluXslXlGFR2xf22u8xgoRbyyXg41tvSTKah1ELpdqJrgxQl25U/B7jVOik2M5La\nzmChVrIgoTRaBgtJUiUHuCVJlQwWkqRKBgtJUiWDhSSpksFCklTJYCFJqmSwkCRVstyHpKFZEr79\nDBaShmJJ+G4wDSVpSJaE7wKDhaQhWRK+CwwWkobkZkldYLCQNCQ3S+oCq85KGpol4dvPYCFJqmQa\nSpJUyWAhSapksJAkVTJYSJIqGSwkSZUMFpKkSgYLSVIlg4UkqZLBQpJUyWAhSapksJAkVTJYSJIq\nGSwkSZUMFpKkSgYLSVIlg4UkqZLBQpJUyWAhSapksJAkVTJYSJIqGSwkSZUMFpKkSgYLSVIlg4Uk\nqZLBQpJUyWAhSapksJAkVTJYSJIqGSwkSZUMFpKkSgYLSVIlg4UkqZLBQpJUyWAhSapksJAkVTJY\nSJIq/T+l9LsUcEiXJQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "50 segments, longest edge = 119\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25 segments, longest edge = 190\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 segments, longest edge = 255\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAADqCAYAAABTP2nAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xm8V3P+wPHXW7K0XMtPqUgpyyAGE0nZyz4TsqXIT4Mr\nQ5aZscUsIsxg7IxlhiLLJIYJE1nL0pAhlbZfpBLZriJK798fn3N97/L99r33fs85n3PO9/18PM7j\nUt1z3t/v93zP+5zP8v6IqmKMMcasyVq+AzDGGJN8liyMMcYUZcnCGGNMUZYsjDHGFGXJwhhjTFGW\nLIwxxhRlycIYY0xRliyMMcYUZcnCGGNMUZYsjDHGFGXJwhhjTFGWLIwxxhS1tu8ASiVS0Rm6jYD2\nHWDxIpg2XLVqvu+4jDEmS1KdLFyi6Pcs3N4VWgLLgco9RCr6WMIwxpjwpLwZqtuIXKIA9/P2ru7P\njTHGhCXlyaJ9h1yiqNYSaNfBRzTGGJNVKU8Wixe5pqealgMfL/IRjTHGZFXKk8W04VA5N5cwluP+\nf9pwn1EZY0zWSNqXVXWd3D2uhd0Ph+cfsdFQxhgTvtQnCwARmgHfAq1V+c53PMYYkzUpb4ZyVPkB\nWARs5jsWY4zJokwki8AHQCffQRhjTBZlpBmqojOcPBFWrIBpb1m/hTHGhCv1yaLALO658LjN4jbG\nmJBkoBnKZnEbY0zUMpAsbBa3McZELdWFBJ3qWdw1E4bN4ja1WXViE4csn2fWZ2ESJ+wvXFznSJYv\nFKa4zF+LVDX1G7TuDOd/DCdPhZ6joXVn3zHZVspnOWgOLFNQdT8HzWnMZwoqoC1BNwXtCoc9mduf\n1thvz9FJitu2dG/u2hPteeZzy0AzFKhWzRfha2CAKjN9x2NKUWjAwrrjRHgKaFVna53nz1oCK4Cv\ngWXQrW30/VqF4p47AhgU3nFMcmW7/zQTyUIEATYHFviOxZSq0Bdu/Y1wz/VLgGXB9nWN/665LVc3\nqx8AkZdGw/KB9fu1loTYr9VpyyxfKExDZLv/NBPJAvgf4FvVevXKTeoU+sK9+YoqVzRtn9OGQ+Ue\ntduSL14Bd20pwmaqLCwlYhG6QpefZvlCYRpi2nD41V5w8xa1+yyyUQU7A0NnAehIBE8VIhWdRfYc\nLdJ/ovtZ0TnsY5i68pWdH7a4lC+c61x8vA/0vR+Oet79fGQH2G488JYI/Zu6bxG2AV6APiPrxz18\nJdz8g0hmbsrMGrjzbPBdcOG83HmWkc5tMjAaCkCEXwCnq3JYePvM+MiGBMuNKmrXAVZ/D9ftBl0O\nVOXN8I9FD+B+4EVgmCrLGvG72wMTgEtVuad23B8vgrZXw2N/wt2UHafKF2HHb5JFhEeBsarc7zuW\nsGUlWZwJ7KhKZXj73HM0TMjTzt33ftXJkXdY2jDMHBGOBG4GeqkyP4L9twb+AuwNDFTljQb8zk7A\n08BvVRm9hn+3NvBn4BDgcFVmhxO1SZrgs/4U2E6Vj33HE7asPB6X1AwVdJB3AHYAtnc/9/q5rw7L\nAk81e4hUlPRUk9YEpMo4EToCT4mwZ9h36Kp8DQwR4WjgCRFuBK6q2Ulekwi7AuNxTyIPFdn3KuAc\nEWYAr4gwQJWJYcZvEqM7sCCLiQIykCyCirPHwYpvRaZtt6YLYJAUNuPHhFDr53fAe8H2FszuBMv7\n+umwLDQMs90bIrwJVDVyWwYVHaNIQHFR5UYROgOPiXCgRrDIlSr/EOE14D7gIBFOVOWDmv9GhN2B\nJ4BKVcY1Yt93iDALeFCEy1S5I9TgTRL0xTVLZlKqm6HW1K8AVauonRCq//tbXEKYXuPndFWWNnTf\nUV9cRfpPhLH71f+bwW/BvZcCFQW21gX+vBX8bjX8dm1fzWphEGEt4GFgJa65aHWExzkf+A08PQL+\nuLt7Gvvhe7iuO3Q5WZUnm7jvrXHJ5t/AecGTh8kAEV4CrlTlad+xRCHlTxaF7sC3nAV8Tu5J4T/A\nvbik8FlD9uwm+lX0cZOqOneBrrtC6+PjuQsvNHx09gxVxjd2b+7iN/15aLl37b9J1zwAVVaLcCLw\nLHAlcGFUxwH+JHLbdJg1DiY0z90wDFsED09zD2xN2vdsEfYAHgL+JcJxqnwZXvTGBxFaAbsCL/uO\nJSopTxaFJnDNfE2VvfP9RmMEiWEQgAh/AiqBX5a63+LyzQto+nhtd5FduCAL8wBU+VaEfsAkET5Q\n5bbojjZqQC5RgPt5QweYXtKsbFW+FOEw4DrgVRF+rsqcEAI2/uwDTMnyXK+UJ4tCd+AffRjBwUYA\n74uwsypvR7D/H9V+qqkehllqZ3ShiWm3ri1Cs0KduUmkylIRDsV1GH+kyhPRHCm68g1B89PZIlTi\nEt/xqjxf6n6NN5nurwDSXUgw7uJtoGeATgQV36+96e9Xz9Fw5ET3s8/2oM+BPgja3Hd8Tfg8eoB+\nCrpbNPuPpzAc6P6gS0BP9/2e2tbkz/C9qM7DpGyp7uCGuhO4wrgDX9OxWBt4G7hElcejOEbcRFgP\n12kswDGqrPAcUqMETVK3Ab1VmRfuvuMb5FCj4/sZ4Hy1ju9UcOdIj2uhxy/ghYfhnUvSMLqwKVKf\nLOImwkG4CWI7qPK973jCIEJzYBTM6AiVC2CTtmmahxFMyjwLN2mvQQMYGr7vWG9GNsQl7tXA8Wod\n34lWblUeLFk0gQjjgWdVuc53LGER6dAFjpoKV1ek8cQPBiD0BPqk7emopuDp9XqgD1jHd5L5rvIQ\nt6wUEozb+cBFImziO5DwdP5jLlFAbhjyz67xGVUjXAAsBO4L5kmkkiqrVDkLuAF4RWTMACtmmVTZ\nXr+irpSPhvJDlRkiPAT8HviV53BCUujE732UCK/j5jY8C7yaxDt3dXMwBuMmu10D/NpzSCVR5XaR\nB6tgyiiY0CyNs+6zb3lVFoajN1Rq78AS4PfAcUHl0QyoHoZc03Jcpx0XAAqMBD4V4RkRfiPCLkm6\niw+S2BHA4SKc5Tue0t14KFzerP7TXrcRPqNKs7CWHRChHdy8C5z3ae2y9NlZv6Ie38Ox0ryBngc6\n3ncc4byWhg1DBt0QtB/oTaAzgqGrD4OeBtol/357joajJsa1PjrolqCLQPv5fl9Lex1HTaw9bLd6\nO3Ki79jSuIU11B60AnQq6GX1h6Nnd8117wGkeQNdB3Q26EG+Ywnn9TT+xAfdHHQw6CjQxaDzQP8K\neiwM3iXOeTB14uoeJLIevt/Xpr+GeOZ5lMsWxvsJul4w1+qWtM63avL75zuAtG+gRwQTctb2HYvv\nDVRAdwAdBvpPuPR7nxc70MODBNbV93vTtPjjnXSa9a3UJzXQZqCPBFsz368n7i0x7c0p9jjwCXCq\n70B8C86p91S5QZVfwPRJPkeLqKsM+wfcOhipG7lWeznY4Suh39i0DGVOpqVL8vfLFe6QrtnHAUOn\nw8wOwCBNUXmcsNhoqBKpoiKcC/MmiAzZFzZuk6YJbdFatND3aBFVbhehE7z/jMips6DNpmn6fKqL\nWYrQDVf+er7fiNLsmiXwO9z9Q/ECnfkn3Q1tDuPaQ/LPndD5frTJwuaaC878ypoL8r0vp37s+32B\n/9kSfvW17zhKew06HvTnvuNI6wbaGbQK5ivs/0hD+uWsz6j2Zk8Woeg2Iv+EtrkllbJOO1c99/2F\ncMpMWLk66nIZhW1zOVzVKuWfz0Lc0r+maa4DXodOG6o+d0zDfqW8Jt0VY8kiFHZS5ePWqt62DTzU\nQ70WxsvE57MQtySwaSQR+gI/BZ6ExtTbKrQEQjYn3RVjHdyhKDShrTxPqhrOBG7zmyggI5+PJYsm\nEGEd4EbgXGB/4KmG//a04XDJd2Uz6a4Ie7IIRbgr22WBCBsDRwHb+I4l7Z+P62g9eAB0+qnIpHXT\n0jlfV66Cb/sOMQ4yOAuYD0wF2gNTGv6rVRvC3KVw4AuwaeRVh5POqs6GxH0RzngTFs2FubPK+aQC\nEOHXwE6qnOQ7Fqh5oeqxP3z+EYw7Ng2fT1bKYMe7Nkj1Z71FZ9i6O6x/CFy8FbCfKic0fD/cBHym\nyu/DjC+1fPewZ2kDfRt0Z99x+N6CyUtzkzh7GvR00L/5jqPh8aZ7RA5oS9DdYODkeFYdLDSRcdpT\noCc2Iu71QJeCdvL9HiZls2aocDXDLVxT7g4GPgfe8B1IHlMgTUUG09E5L8K6wLZAt2DbIfjZHngf\n2raP53V0G5F7eqk+xu1d4eqO8MfBjdjRkcBUVT4IN770Sm2y8NT+WcxaWLIA17F9iyoJbOPcpgoG\nbCsy/UVYuCAh580axDsip9j3KlicaStyyaB66wz8HzAt2O4Lfs5VZZXIa6NheZ6FgpZ/Fe4rKJRc\nv1uhyifFfjv3+nsdCgvfE3myc7LPjxj5frQJ91HT7yQr0Jmg2/l+fzy/B1uBfgK6vu9Y6seWzPMm\nKTHnP9YvF8Gka0DvD5pZvwGdA/o46BWgA0B3BF238fuuXApzPwMdFFZRvsLNdud/nKT3Oo2b9wDC\nPSH8tuOCzgLd1vf74/k9uBb0at9x5I8tmedN8birqwFXzoIz3o/q4lX4/Tn9vaCycHfQlqW/jtzs\nadCdg0KcD4JuFM57VfeCf766mdt6D+gmWTs/4tpS2gyV2HbctaD8CoxVE6EFMBjo7juW/BJ73qxR\njfpQfYDhqrfOj+ZIhd6fT5aocm+pe69+HXX/XITuwFXAf0U4WZWJpRxDpKKPm53frgMs+xJu3wc6\ndcUVhnpPhIuAv6vWbTJO5/kRl5Qmiy8+S+jMynLv4D4BmKyJLXaX9hm5w6qgoofI9InR9NP5eX9U\n+RYYJsJ4YJQIY4BLVPmuafvLJSURTgO+VeVL4FwRRgF3ACeLcIYq7+V+M+3nR8R8P9o0/jFTK+D9\nd+CMz5PWtgj6QRRD7XysNteE1y641cMO9B3Lmt/HdLZJxxF7/mOcvjTO9wd0E9BHQf8LumMI+xsH\nOqjOnzUDPRO3ONZI0Bbute88Dgb/kMbzI5bPxncAjfzgW4C+BHpLEpczBF0A2jHcfabjAgfaK+iz\nWct3LMXfz56j4fSZcNa8pL2PheOOpz299veq76Mw9xPQPjGfSwL6v8HF/JymnlO4lSy/BG1T4O/b\ng46BOR/CkEXu/ZyvMFyh/zew+7i0nB+xfC6+A2jkB/8U6H1JvSDh1n3uEO4+09HpBvoA6DDfcTQi\n3s1BP6MRKxz6fMLztR436L6gH8OlvT2spd4VdDLoBNDNmvD7+4G+XvzfHf1cGr5jvrdE91nkxjx3\n2Aw27wKnzoAdTtF6HVP+uVjP3hDmPCzy4fzw2pOT3+kmQjvgEGCo71gaSpWPRGYtggvHi8jaxfoA\nCpSr2EOkIqayG976E14QeekOqHoOJqwT52tXZa4IewMXAW+JcKYq/2jELg6lQYUDV0vSv2OJ4Dtb\nFc72+ZpfTpybxMfCKJuKkvxkkbvTPnMeDJ2VxM9mzbFXflboMwNtBboL6HGgw12Tlc/1xP01Rybh\nHATtATob9O+gFQ38nWk0oORMEl5fGjbvAWThA4wy1qT2WSQ1rtI/s/M/DpoTvwF9B3Ss6wQ9bYaP\nZqD673nP0XD8JBi+Ag7vFs9x/TSB1Y9DW4HeAToPtHeRf9sx6PNo1rD3Nb3nclxbgpuhkt/8krNF\np6hizY0b3+RlqPoCZryTjBIVhWrwpGX1uULn19JFQD9godZo7hR5tyMs/4nf9cRrDQl9EOiDK6kR\nsWQMKVVlGXC6CL8AHhHhbuAPqqzM888PAf6tWnzeU/25GeVdiryQBC9+lI4Fa0TYB7baNapYc/02\n67SGzxcn5yROUzLPp9D5NWu6Kgu0Xr/YtOGupHbNhXAuWg6zLo0+1ryuw81NaBb9ofK99kt/gLPH\nR3/s+lT5J7BLsE0WYdvqvxOp6Cyy52j49RUwsJP7/jRkn1XzVScPUn10f/czCd+xhPH9aJPWR0Pc\nWO3LQBfDIydFEWuS34M0NROG9d7WHlba+wGY8Qbo5R7PwUmg/eN7v2oOVX9ggDv39TeEVNepCa9f\nQM/AlRI/A1r3huOrkvh9ycLmPYA1nwzJm0vh4tJ2oM+CPl89VDaKWJN8QU5yIovr/AJtCzof9Dg/\n8evRoK/4e/90C9ApoA+BtvIYx0/g/XfhsJVJ/b5kYUtwn0XtNtqkEOEAYBRwJ/BHDdpEo4k1uU09\nuXbe9lNgyQcwe2ZymsgaptTPTJVPRDgCmCDCHFXeDC24hnkM+LMIu6vGv3aIKh+KsBdwK/CqCEeq\nMsdDHDNFhrwL+3RL6vclCxKdLJIkqON/GTAEOFGV56I/ajI6FgtxCYMPgdM9XCgTQZW3RagExgUX\n7Y9jPPYqEW4EzgUGxHXcOjGsEGEIUAlMFhl3AfzpgPjXmWnbDpqT5O9L6vl+tEnDBtoB9MWg6ald\nfMfN19Rz9rew9Va+35Ma78000FiGcCZ5A/0dbrbxGtd1iOC4G+BmoodaZqZpsfztKDh3pY+mSdeM\nOF1dOfKaxz++Kk1No0nexL3RphARDgb+BtwCjNQGDMUL9/jVo6HadYAli+DOdrD9O6qcF2cchYgw\nCzhclVm+Y/FJhLWAh4GvgVNU41slUITrge9VuSCuY+aPY8/RMCHPanh971edHGlzcm6G/cVd3cew\nEnj9a3j9UNWqV6I8drmwZqgCgmany4ETgeNVedFHHHXb1UXYCHhThMnauNIHUVkH+N53EL6pslqE\nwcAkYBjwlxgPfyMwRYTL1c1F8MRfH5vNlYieJYs8ROgIjMHdJe6iyqeeQ/qRKl+IcAzwlAjv+Lyj\nD+phtYU5o8Oth5VOqiwXoR/wmgjTVfl3TMf9P5FpU+DPE0W+XuZvTfpCfWwbbSjCWhpxTbckDojJ\nFN/tYEnbQA8HXQJ6AQmtbhvEeRrou6At/Bw//UNnI/xs9grOoW3i+yxO+cj3Z5H/nBg8H2a+CTqe\nAqXCbUvHVtZ9Frn+gPYd4JOP4fpl0P0g4ARVJvmOb01EEOBeQIGTVeNrI3fH99c+nQYinAqcD+yh\nbpW2CI+VnM+idh+bawqCqoXACNxKiieo8nKcMZlwlG0zVP6S0xd9Azf0Uh31tufwilJFgyGbrwOn\nAn+N47gitAcOhp4H2pj2wlS5U4SdgDEiHK6RDoxIznycNTQFXSDCi7iaTjfhBoskbqkBU1iCa0NF\nLV8hvJEtYO6vfUbVGKp8A/QHRojwsyiOIUIzEXqKcLkIbwLTgUNgyZw01O7y7DzcAICroj1MoTpX\nKzx2dtenynigO3Aw8LQIbT2HZBqhjJNF+82ScjdWCnUd3ENxd2wbhbFPETYRYaAI9wNLgNtxT6Hn\nAm1VORb+eUL94nKVc12zgwFQVw31WOBIEU6K7kj5Cv2dvxRu7i3CFSK0iO7YjaPKR8B+wBRgqgj7\neQ7JNFBZ9lmI0ArOmQ5XdExCO28YgrH2WwH9Gvt4H8wR2BW3stihwHbARGA88FTwBc/ze/Xbp8t5\nNFQhIuwAPA/8QpXXojlG3r6ClcC1QA/gLKiYluuj8zViqmbMHIjrd7sdGBFtU50pVdklCxE6A/+E\nt6fDdbvBbV1qLBU5Fx6PaZnMcInQHHgBeFKVkQ349xsBfXHJ4RDgc1xyGA+8osp30UVbfkT4Oe6i\nuLsqC2M+dl+Ycwfc2BZGtkzS+S5CB+B+YDUwECrWS1JCMzlllSzc2hM8CFwJ3AwVnbJ0ZyzCZjBv\nKvzmv0Czml+2YPTUjuSeHnYGXib39DDPX+TlQYQLYdYA+OV0aLNpnBdDkb0egKcHJPFJOliT4zKY\nVwlXroIbOiQpoZmA77G7cW2glcHY9z6+Y4nuNbbuDEMW1h7n/svFMHUM6Eegc0FvBD0YdH3f8Zbb\n5j6fX33tp3ZSMpZGLRLjBCsxntwtk0Nna8+fWLIYbvoBdvkZ0Es9lFCOT7cRubsycD//0g5+tTX8\nbX9gtmq88zFMTd1GwFWt/CxFm+wKxoFmWRh0klWZSxaF509c1kP1iQwnCig83v6rKi3zQn/J4HM+\nxLThcP5BcO0mtZt4kjR6LRUJrWxlcOhsofkTn13oM6p4pGPd8vLl7/Nxbf5nvganvwpHPQ99709e\nX8C04XD2QhuOnUwZTBbJmc0av3zj7e3Llhx+Ph+Ris6uJMiDfWHpJ/DsKaqTByUrUVQntBNuggvn\nJTehla/MNUOV86OslWlOttzns+Aq2OtoeO7BqD+fPM2y/aCym0hFQi/CB/wPHHCXNmD4t4lX5obO\nipzbA2QSXN7Mht+ZJAqGMX8PtFSNdi2QJBUZbAgRHgNGqTLWdyymtkw9Wbgv4fW/h9duhL5t7e66\nfNUeEZesyV2qqAhfABvhyqlEKHXNstuCDcZIokwki9yFYcfusGEbGHeW6qyMj3wyheQfEVe5R8Ka\nXj4HNibyZJGeZtlgdcotIcvD29Mr9R3cuQvDhIFwx7Zw2cbQ42n356Y85RsRd3tX9+eJ8TmEU/hx\nzdIx6MF9Xw/+B1yisOed9v1Nngw8WRS6MMQx0ckkUyqaXqqfLCJVe9BD973h2y/g8X4JesLK9yQ4\nMIFPgmUvA8kiFRcGE6tUNL3EkiwgtyCRCHsBN6neOT+O4zac3fClQeqbodI+Ea16DLxI/4nupz1+\nly4VTS9fEFOyqGEy0F6ELjEftwi74UuDDDxZTBsOlXvU6cxM2oUhr8Z2xCZ5hE+S5JpeVtwNnXeG\nSU8l8L2K7cmimio/iPA4cCRunYuESMWToPFdyTCMzVXz7Dka+j8PFy+De470HVPD4u45On+VzWOe\nB/0ZaAfQtXOvcdAcHxVL07qBHgM61nccBWI7C/RmD8c9GPQV36+/dkxPDoVzvrNzO9lbBp4sai8S\nL8KpwBnAOJ8xNcxmm+d//N5iR+BOoAOwsQhL4Yx13Ugva9dthNZAle8gCohpNFQ9E4ExIrRT5WMP\nx69FhAo47GL4bCD0PcLmRiVXJpJFHfcCF4vQS5VJvoMpRIQNoNNP8j9+T35a9cfktzawKSx+DFrW\nabawdt0iWgNf+w6igNiboQBU+V6Ep4B+wB1xHz+PEcDTqif9A076h+9gTGEZ6OCuTV35hCuAP/iO\npRARNgVegIHPFOuIVWWVKgthzvtp7sj3pIJkP1nEniwCjwJHeTr2j0ToDhwLXOA7FlNc5pJF4F6g\nSzBUMFGCkSivAI/BLifD431cdc1iVTZTMcInaZL8ZOFjNFS1p4GewTrsXgRLqd4OXKDKZ77iMA2X\nxWYoVFkpwgjg98ABnsP5kQg74da8HqnKLe5Pc/0ta5Ib4bP+E9C8BUx91dp1i6oA5vsOogBvTxaq\nLBPheeAwYHRY+23kaL2hwDLgvrCOb6KVyWQRGAVcIsLeqrzkI4DaX57VK+HaXaHLr1R5qCn7cwmD\nV4H/qPLXcKPNpCR3cH8JbCDCWqqs9nD8cbimqFCSRWOGgYvQAbgM2FvVlvlNi8wmi+Dp4nJc38V+\ncR8//5dn2CJ4+PUSr19tgU/DiLEMVJDQZihVVomwDBfjlx5CeAK4QYQWqnxT+u7WPAu79o3T5l1g\n4IOqu88o/bgmLlnts6g2GthchH3jP3S+L88NHUIoZtcW+KTEfZSLJD9ZgNdO7orW8OtvYMhr4VQO\nKDQLe4edRYZ2zxX7HLsfXNkJbj7UqhWkS6aThSqrwD1dBAvOxCiyEgaxJouUlyNJ7JNFwEsnd+6p\n9w/t4O4d3UW837OlfbaFyu60qoBNJtW/cbqtS8KqAJsiMp0sAg8A7Ym9KSqymlVtiClZ1C7/Pna/\ncC4qsbIni7yiKOFeaLTe3XvDe5Ot9lP6ZT5Z+Hu6mDYczl8a5lBXEdYD1iO2C2Aq1oWop/ppCIZ3\ngj5XJji5eUoW4T/1uk7sx/vAiK9g0Ou1h4EvXmhzhNIvsx3cdYyBOb+HCyeI6FrxFOGr+gBmfwkn\nTgXWDqmEQRvg0/hGkKSvGmiegQX9oXLnKNdGKKHAo6dkEU3hvmC03mzgbFXeyP1Neot9mpwySRYV\nm8PxLeHeA2JcZnNf2Pp7ePSgMC7u7oK0762w/QYiL42OZ47F8qr0VQMt9DRU8UxQcfXrYFtW5L+/\nacjn1tQlXN3vHd8bmh8oMnXPeOfMRHrxrnvCUHsBJqv9lFZlkiy6jYDrN425CN9Q4NbwEkW8K4mJ\nsAXcsiuc9ylc1yY9d4SFnoZ+APgM14+xCdAq+O/Wdf67+v/XDYa2ViePAsnluAPhL3mS04cjgQH5\nIsx9ntdXf55d4lwZLnfx3vA5+O47mPZWiBfvesmi+phYwctUK5NkEW9zSjDpqA8wJJw9xruSWBD/\nc9D1ehgzDt5N0R1hoSaWd6aocnVD9xIUcGxF0aSybuv859Y+x4pwCLAIWBj8DP770GN8rwwXNBkt\nwZXbeDnEXedNFib9yiRZFLqALImqOeU04EHVsDqi40t2IrQBngX+psr1QV96iu4Iw2liCQZGfEmR\nCXMib/0Ulneuf249Owb+eDauzPxmwc8OwHaw+fYJ6QvaCpgT8j4tWWRUmSSLfBeQi1fAHRuFN4PV\nEaE5LlkcFNY+41pJTISNgQnAWFWuDHPfcYm/fbxwclLlc1wn9rSavyEyeQPXlOivL8iVyKclhL6m\nhSWLjBK3UlX25UasVF9Avv8j/Gc4sAPQT5WPwjkOR+NGg+wdxv7cPvN2os4tXKG2KcdgA1yieAn4\njdXsabj659aak1Mcn2fxmNkV9/T405D3ezXwhSpXhblf41+ZPFnk72ATYTDwW+B1EY5S5fUQDnUm\ncGsI+/lR7m6580yYNQUWfBDm3bIIrYB/AVOwRNFoje28TcjooK2A2RHs154sMqpskkU+wUXxahFm\nAE+KMEyVB5q6PxG2B36CW1wmZFVVwHeEXKlThPWBx4H3gbMsUcQjAaODouivAJcsNotgv8azzM/g\nbghV/olb9+IKEa4QafL7cgZwV7BaX9i2BuaEnCjWBcbi2q1P81Qq2/gRZbKwJ4sMsmQRUOUdYHdg\nb2CsSN/tG1NAL2jKGQiRrTMRarNB0BH/IPAtMFjVTUQwZWNrLFmYRijrZqi6VPlUhD7w3/tgh6lw\nxTqNmJV247f9AAALN0lEQVQ7CHhBlQURhbc1ISWLYEnL+4B1gCODYaKmvNiThWkUe7KoQ5Xv4IyV\nuUQBxQroBQUKhxJyx3YdodwJBk1sd+HqTPWPqMnMJJQrsrjPg3BpW+h1VQRFFi1ZZJQli7waPQmu\nF7AuMDHCoEpuhgqS2s1AV9xw4RVhBGbSITdkd/xxcPla8O8oSs5bssgoSxZ5NXotijNxdaBC7yCu\nUW57V9j/3KZ+sYNEcS2wK3C4ar0XaDIvlpLzy7BkkUnWZ5FXvlm5532Sr2SECO2AQ3AjoUKVZ/LW\n0VC5SxMLzo3ALQC1f3hlSEycGlsKXYQWwE7Azm7b6+cxlBmxJ4uMsmSRR/1JUyuWwc294I518vzz\nIcAjqmuuIdQ04RQQFGE4cASwrypfhB+niVqxUugitMUlhV34MTnQCZgBvO22Wa/B8gMjLjNiySKj\nLFkUUHfSlAhDgQdE2LO6UzioTFoJ/DyaKEovICjC+cBJuMl8n4YZnYlToRuHNq8EgxbW58ekwFPA\nSGBmzQEMIs89AZV5yoyEWnLekkVGWbJouNtwzU1/AC4K/uxwYIEqb0dzyNIKCAYJ7kxgH9XQC8aZ\nWBW6cfjqc9zNyofFJmzGU2ak8yZwcmuRdyfGsyKliYsliwZSRUUYArwtMuYduOkw6HUILJop8kTn\naL4Q+fpOzlnckDtBEU4BLsQliqjmfpgYuLk/W+2U/8ZhxjuqfNDQfUVZZiRoKnsGfiPQcr+YVqQ0\ncVFV2xqxwSOD4dyVsExB1f0cNAdad47meK07Q8/RcOREOHoizJ4Hus6af0dPAF0Iuo3v98u2Uj57\n3Q10Augs+NeZ7jyL57xrWrw9R+fi0xpx9hztOzbbSt/syaLRrusLE9aOa5WzPH0n/wLOwg2DrUeE\no4DrgD6qzAo7HhM9EbbFjV7bE9fs+TfVQ1eKHP+vZK9jvXnHhCzqZCJgyaLR4l2iNY/zgEkijFZl\nSc2/EOFQXN/Kwaq1F9wxyZJvGCxUrQJ+hxu59idcza4fF+ZKQKXagkToAl1/GsciXcYPm5TXaI2e\nsBcqVd4H7sXdef7ItWvzd+AXqkyNIxbTNLlhsBMGwtj93M9BU2Heu8BSYBtVrtEQV3CMkgh7A5Pg\n4Gvd6Krq70cko62MJ2WzUl5YErLK2YYwbxac8x9ovh6sXgnXdocuR6jychwxmKZzM/In5FlW9YhH\nVSf09xVXUwSDPq4EBqkyobGrBpr0sGaoRkrGKmcVG8IAhTGH5BLWsEXw8AJscnYKFGrKbL2Rj2ia\nIqhcfA1u2O7ewRNvopvKTGksWTSB/y9EtxFwXdvanew3dIDpkXSym7CVNn/GNxEqgDHAesAeqnzu\nOSQTA+uzSCXvneymJNOGp7VtX4QtgcnAh7iBFJYoyoQ9WaRSuu9My12uKbPNK/DVZzDj3TS07Yuw\nF/AwcAVwi6qt115OrIM7hZLQyW5KJ8I4YJQqj/qOpRgRTsb1UQxS5d+ewzEe2JNFCiWjk92EYBUJ\n/w4GHdkjgSNxHdkzPYdkPEn0iWoK89/JbkKQ6GQhQmvgAaAVriP7M88hGY+sg9sYfxKbLETojOvI\nXgQcaInCWLIwxp9VQDPfQdQlQi/gVeBOoFKVlZ5DMgmQyLsaY8pE4p4sRBiMq0t1kipP+47HJEei\nTlRjykxikkXQkX0l0B+3BsoMzyGZhEnEiWpMmUpEshChFXA/sAHQo1D/RL5KuTYCr3x4P1GNKWM/\nEPN3sP4Ff9/b4MpbgTeAY7TGmt31f6/e3B5bBa+MWAe3Mf7E+mSRvzT6ihfg5ceB0wolCqfbiFyi\ngNyiX91GFP4dkyX2ZGGMPzE3Q+W74F++NpzcC/Ya4ErfsxHk+7nv9laPrLxZsjDGA3eXf/xh0LyF\nyNQd4mn/L1SAsvPOuFLjXwJfAJ8Cs2r8/xfw1qWwvJ/VIytfliyMId7O21xz0PXV7f9d4mn/L1SA\nctJTqmuuBiAy+Rw4pwf8pV3temTJr5RrwmGFBE3ZW1NhRqj6AHdT1Tz4WWhb09/X+bsThsGdvetf\ntPverzo5shIupRagFPnPX+H23eDzL6weWfmxJwtjCnbedp0HCK5voXpbWef/625r+vvg79pt46P9\nv/QClN13grvOUeXFKOM0yWTJwqRe6U1Ihdry330BOCDsdRtEXhsNy/OswR19+39TC1CKsD6wIzAl\n7JhMOliyMInS2At/OOP/W6yfvy1/8aJoFviZNhwq96jfHJTo9v/uwHRVvvEdiPHDkoVJjIZe+EVo\nAbRz26Ej8zchzW3QeuQidII/bANnLYCbOsZx8U7peiR7ApN8B2H8sWRhEqRQ38HGL4jwAdAelySa\nAx+7bfOtmtr+L8JawD3Q5Rr4x0MwM7aLdwrXI+kFjPYdhPHHkoVJkEJ9B98sAy7jxwRBVXXzkMjk\nUtr/hwItgD+rVv1Aui7esRFBcE8WQ33HYvyxch8mQarnAdS0HHjvbVVeVOV9Vb6q3Y8wbbhrMlpe\n498Xb0ISYWvgd8BgVX4I7zVk0tbAclU+8h2I8cfmWZjEaOo8gFyneLddoNUGcFfvNf97mgEvA2NU\nuSncV5E9IvwvbrW8Ab5jMf5YsjCJkrvwN77vQISWwAKgmyoFm6FE+C1wMNBHldVhxJ1lItwJ/FeV\nm33HYvyxZGEyRYS/AvNUuarA33cDngd2U2V+nLGllQjTgUGqvOU7FuOPJQuTKSL0AEYB29adIyFC\nc+B14BZV7vYRX9qIsDHwAbCRKqt8x2P8sQ5ukzVv4Mpq9M7zd5cAi4F7Yo0o3XoCb1iiMJYsTKYE\nTxP3AKfU/HMRfgacAZwazazszNoTmOw7COOfNUOZzBFhU+B9oKMqX4uwHvAmMEKVMX6jS4fcQIPe\nh8H/vQXPDEn4DHMTMUsWJpNEGAc8qcrdIlwDbAkca08VxZVaytxkkyULk0kijw2BySNhyQLouB0s\n6q16j43maQCRPUe79bnjXW/DJJuV+zCZ4+6Mj7gIbmsDLdsEd8YPR78SXVYUKrti622XM+vgNhnU\nbQTclqcgYbcRPqNKj0JlV2y97XJmycJkkN0ZlyZfva0LlyV8vQ0TMWuGMhlUfWcc/0p0WVB/vY2l\nS+DuneGm/bE5KmXLOrhN5thonvCJsD3wIrCXKjN9x2PiZ8nCZFIpBQlNfiKchlvTYg9VVviOx8TL\nkoUxpkGCRZAeARaqMsx3PCZeliyMMQ0mwkbAVOAsVZ7wHY+JjyULY0yjiNALGAv8TJWFvuMx8bCh\ns8aYRlFlEnALMCpYddCUAUsWxpimuBJ3/bjQdyAmHtYMZYxpEhE2x1XzPVLVyphnnT1ZGGOaRJWP\ngNOA+0XY0Hc8Jlr2ZGGMKYkINwGbAsdZCfjssmRhjCmJW1xq9lS4/CtY/o0rt2KTILPGakMZY0pU\n0Q76t4DbflKjvMoeVhI+W6zPwhhTom4j4OYtrCR8tlmyMMaUyErClwNLFsaYEtliSeXAkoUxpkT5\nFkuqnGuLJWWLjYYyxpTMSsJnnyULY4wxRVkzlDHGmKIsWRhjjCnKkoUxxpiiLFkYY4wpypKFMcaY\noixZGGOMKcqShTHGmKIsWRhjjCnKkoUxxpiiLFkYY4wpypKFMcaYoixZGGOMKcqShTHGmKIsWRhj\njCnKkoUxxpiiLFkYY4wpypKFMcaYoixZGGOMKcqShTHGmKIsWRhjjCnKkoUxxpiiLFkYY4wpypKF\nMcaYoixZGGOMKcqShTHGmKIsWRhjjCnKkoUxxpiiLFkYY4wpypKFMcaYoixZGGOMKcqShTHGmKIs\nWRhjjCnKkoUxxpiiLFkYY4wpypKFMcaYoixZGGOMKer/AaS89+bbEXGrAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5 segments, longest edge = 335\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 segments, longest edge = 597\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 segments, longest edge = 1021\n" + ] + } + ], + "source": [ + "visualize_greedy_tsp(USA_map, (50, 25, 10, 5, 2, 1));" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Divide and Conquer Strategy\n", + "\n", + "The next general strategy to consider is *divide and conquer*. Suppose we have an algorithm, like `alltours_tsp`, that is inefficient for large *n* (the `alltours_tsp` algorithm is O(*n!*) for *n* cities). So we can't apply `alltours_tsp` directly to a large set of cities. But we can divide the problem into smaller pieces, and then combine those pieces:\n", + "\n", + "1. Split the set of cities in half.\n", + "2. Find a tour for each half.\n", + "3. Join those two tours into one.\n", + "\n", + "The trick is that when *n* is small, then step 2 can be done directly. But when *n* is large, step 2 is done with a recursive call, breaking the half into two smaller halves.\n", + "\n", + "Let's work out by hand an example with a small map of just six cities. Here are the cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cities = Cities(6)\n", + "\n", + "plot_labeled_lines(cities)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Step 1 is to divide this set in half. I'll divide it into a left half (blue circles) and a right half (black squares):" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_labeled_lines(list(cities), 'bo', [3, 4, 0], 'ks', [1, 2, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Step 2 is to find a tour for each half:" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQ4AAAEACAYAAABCu5jVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGBpJREFUeJzt3Xm4HFWdxvHvCwRIYkhkEwQFAREUiCCIbIOiqMwgCoo7\noiMiuIyKigxuuAHujDAMi4oLgwokIIqCgAJhC2sCERRkUQYhIBIIWQhJfvPHqQuXpDu363ZVV1f1\n+3kens6t2131e8jNe0+dc+ocRQRmZnmsVHUBZlY/Dg4zy83BYWa5OTjMLDcHh5nl5uAws9wcHGaW\nm4PDzHJzcJhZbg4OM8vNwWFmuTk4zCw3B4eZ5ebgMLPcHBxmlpuDw8xyc3CYWW4ODjPLzcFhZrk5\nOMwsNweHmeXm4DCz3BwcZpabg8PMcnNwmFluDg4zy83BYWa5OTjMLDcHh5nl5uAws9wcHGaWm4PD\nzHJzcJhZbg4OM8vNwWFmuTk4zCw3B4eZ5ebgMLPcHBxmlpuDow9J+p6kuVXXYdaOg6PPSHoZMAmI\nqmsxa0cR/vnsF5JWAi4G3gHcERFrVFySWUtucfSXjwDnRsRsQFUXY9bOKlUXYImk9YH9gd2rrsVs\nJG5x9Ii0xq7SzndJ+/0zva6x6zJv2RbYFPiLpLuBcZJu732lZiNzH0cPpJB44+/hpDEwHpgHHPIk\n/HKPiMeuaP0ZzY2ICb2t1KwzDo4ekHa+Cy56QQqNIfOAPe+OuGqT1p/RY+4ctX7lW5WeWG/SM0MD\n0tfrTWr3CYeG9TMHR088MCe1MIablx03qx8HR0+s+wn4PE+Hx1Afx6z3VFiU2ai5j6MHJE6Fi1eH\nL+wCk9eHhQthyhvadYya9TsHR8kktgIuAV4UwRyJPYCvRrBzxaWZjZqDo2QSvwEuiOB72dfjgIeA\ndSOW6/gwqwX3cZRIYk/ghcBJQ8cimA/MAHaqqi6zbjk4SiKxMvBN4IgIFi3z7cvw1HKrMQdHed5N\nGj6Z2uJ7Dg6rNfdxlCDrx/gz8NYIrm7x/QnA/cA6ESzodX1m3XKLoxwfB65uFRoAEcwF/gjs2NOq\nzArix+oLJrEucBgjh8LQ7cqlZddkVjS3OIr3ReCnEdw5wvvcz2G15T6OAklsAUwDtojg4RHeOxG4\nD1grgid6UZ9ZUdziKNaxwNdHCg2ACB4ldaDuUHpVZgVzcBREYndgMnBCjo9dBvxLORWZlcfBUQCJ\nlYBvAUdGsDDHR93PYbXk4CjG20j7oPwi5+euAHaSGFN8SWblcXB0SWJ14BjgUxEszfPZrC/kHmC7\nEkozK42Do3sfAWZEcPkoP+/bFasdB0cXJNYCPpP9N1oODqsdz+PogsR3gVUj+HAX51gXuJ00n2NJ\nYcWZlchTzkdJYjPgAODF3Zwnggcl/g68FLihiNrMyuZbldE7BvhOBA8WcC7frlitODhGQWIn0kNs\nxxV0SgeH1Yr7OHKSEHAlcHIEPy7onOuTHrNfO++QrlkV3OLIbz9gLHB6USeM4H7gH8DWRZ3TrEwO\njhwkVgW+TprsVfQIiJ9bsdpwcORzCHB7BJeUcG73c1htuI+jQxKTSI/BvzqCWSWc//nA9cBzIvBf\nivU1tzg6dyRwXhmhARDB30irom9ZxvnNiuQJYB2Q2Bh4P7BVyZcaul25teTrmHXFLY7OfA04Phv9\nKJP7OawW3McxAontgV+SNo1+vORrbUKaI/Jc93NYP3OLYwWyyV7fAo4qOzQydwOLSfvNmvUtB8eK\n7Q2sDZzWi4tlrQzfrljfc3C0IbEK8A3g0xEs7uGlHRzW9xwc7R1E2vfkgh5f9zJg9+w2yawvuXO0\nBYk1SJO99opgRo+vLeDvwC4R3NXLa5t1yi2O1g4Hftfr0AD3c1g9ODiWIbEhcCjwuQrL8ANv1tcc\nHMv7CmmtjXsrrOFy3OKwPuYp58NITAb2AjavuJRbgQkSz6s4wMxacovjmb4JfDmCx6osIuvncKvD\n+paDIyPxOmAj4NSqa8m4g9T6loMDkFiZNLX88AierLqejIPD+paDI3kv8AhwXsV1DHcLsHa2kLFZ\nXxn44JAYD3yZtI5o38yGy1Y7n4ZbHdaHBj44gE8Cl0dwbdWFtODbFetLAz3lXGI9YBawQwR3V13P\nsiReBvw0orttJs2KNujBcTIwN4JPVV1LK1mn7cPA5gVtNWlWiIG9VZF4MbAvaVnAvpTt3XIlnn5u\nfWZgg4O01sbRETxSdSEj8HMr1ncGMjgk9iBtQ3Bi1bV0wB2k1ncGro9DYiXSxkfHRHBW1fWMRGIM\nqZ9j4wj+WXU9ZjCYLY53AU8AZ1ddSCeymazXALtVXYvZkIEKDomxpM7Qvprs1QHfrlhfGajgAD4G\nXBfBlVUXkpODw/rKwPRxSKwD3AbsFMEdVdeTh8RqpH6ODSJ4tOp6zAapxfEF4Iy6hQZABE8A1wK7\nVl2LGQzICmASmwNvp947wQ/drpxfdSFmg9LiOBb4ZgT/qLqQLrifw/pG4/s4JHYDTidtGr2w6npG\nKxsReghYP4K5Vddjg63RLY5hm0YfWefQAIhgAXAjsHPVtZg1OjiAt5L6cX5WdSEF8XMr1hcaGxzZ\nEOYxpMleS6uupyDu57C+0Ng+DonDgFdF8IaqaylKtszhbGDdCOZXXY8Nrka2OCTWBI4g7QHbGBHM\nIy1i/Iqqa7HB1sjgAD4LTIngtqoLKYFvV6xyjQsOiU2AA4GjKi6lLA6OUZJ0mqS7JN0k6UZJ21Rd\nU101cebo0cBxEcyuupCSXAlsL7F63YeYK/LJiDin6iLqrlEtDokdSc9zfKfqWsqS7Wt7G/Dyqmup\nqUb9zFelMf8Th032+vwAjDj4dmX0jpY0Q9K3JY2pupi6akxwAG8CJgI/AZD0/ewHZIakMyWNq7a8\nQjk4hpF0iqRrpHGzpUmPpFddI+mUZd56RES8CNgBWAv4TO+rbYZGzOPI1uX8I/CRCH6XjulZEfF4\n9udvA7Mj4hsVllkYiUnAvcBaESyqup6qSboG2LHFt6ZHRMuha0m7k/o79im1uIZqSovjg8DdQ6EB\nMCw0BIyFWi0VuEIRzAH+AmxfdS39YewLOjkuab3sVaQW6qyyK2uq2geHxETgc8Cnl/+efgjcD7wI\nOL7HpZXNz608ZdVVOzz+v5JmAjNJtypfLbeu5qrlrYq0xq6w1U9gvUkwUXDQFRG7tJxanv12OR64\nPiJ+1NNCSySxL3BwBHtVXUvVpHGzYcG6y39ntYcjFq7d+4qar3YtjhQab/w9XPQCmPpsOGESnPL6\ndHx5kZLxF8B+va20dNOAnaVGzsXJaUGbDcOfmCipaX/vfaF2wZFaGieNgfHZ1+OBE1dJx58madPs\nVcA+wJ96W2e5stXM7gW2rbqWPnAzMB3GPggTHiP1Z00HfgV8V9LRklautMKGqeFvq/UmPR0aQ8Zn\nx5MsLH4saQIg0j3tob2rsWeGhmWvq7qQKkXEwcO/lnQDaej1UknrAGcC50t6Z0R4N7wC1LDF8cAc\nmLfMsXnAgqcmfUWya0RMjohtIuKAoVGWhvF8jtamAG8BiIiHgD1Jw/XXSZpcZWFNUcPgmPUeOOTJ\np8NjHvCJJXD8OIkvSbTpYW+ky4FdJdwMf6azgf0krQQQEYsj4pOk0beLJb2z0uoaoAGjKg/MSWHy\n2F3AycBGwPsiuKHiMntC4k/AOyK4qepa+omkW4BDIuLKZY5PBqYCvwQOj4jFVdRXd7UMjnay51Xe\nBXwb+D7w5Wwzo8aSOBm4LYLjqq6ln0j6IjAxIg5r8b01gTOA1YC3RcSDva6v7mp4q9JeBBHB6cBk\n4MXADRI7VFxW2dzP0drZwJuzjvJnyDpI/w24itTv0fSfkcI1KjiGRPAAad7GV4FfSxwrsXrFZZXl\nMmA3qZl/l124FVhAm2n5EbEkIj4LfJw04vK+XhZXd439YctaHz8HtgE2BW6S2KnisgoXwX3AHOAl\nVdfST7KJf2eTja6s4H3nkFpsn5F0oqRB6lwftcYGx5AIZkewP2nT6akS38p2RWsSP7fS2hTgLa1u\nV4aLiNtIT9duAPxB0nN7UVydNT44hkRwFqn1sQEwU2rUzu/u52htRvY64tyNiHgU2Be4gNTvsUuZ\nhdXdwAQHQAQPRfAO0gIuZ0ocl+1VUneXA7tno0qWyW5XnpoM1sH7l0bEV4APAOdI+tBIrZVBNVDB\nMSSCc4CtgbVJrY9a/7aO4B5gIWn5AHums+ngdmW4iPgNaY/eQ4EfSGpqx/qoDWRwAETwcATvBg4D\nzpA4QeJZVdfVBd+utHYdMI40PN+xiPgLsBPpQahpkp5fQm21NbDBMSSC84CtgGcBN0vsUXFJo+Xg\naGHY7cqbR/HZx4G3k5ZlmC7pVQWXV1uNmjnaLYl/JU1b/zVweARzKy6pYxKbkcJjw4jmLJNYBEm7\nAidGxKg3YJL0GuB04OvAcTHg/3AGvsUxXAS/IbU+xgC3SOxZcUl53Jm9blppFf3pKmBtSZuP9gQR\ncTFpz94DSEsQNmnV/NwcHMuI4NEIDiItgPx9iVOzdU37WtbK8O1KCxGxFDiHUdyuLHOee4BdgCeB\nqyVt0n119eTgaCOCC0kjL0tJrY86rO3p4GjvbLoMDoCIWAC8l/QQ5dWSXt/tOevIfRwdkHg16Qfl\nUuCwCB6ptqLWJLYALoxgo6pr6TeSVgH+DuwYEW3WKM19zt1IHacnAMcMUr+HWxwdiOAS0qzT+aTW\nx94Vl9TOn4HVJDauupB+k627cS4FLlodEdNIu8LtA0zJlqocCA6ODkUwN4IPA+8G/kviJxJrVl3X\ncFk/x+X4dqWdjmeRdioi7iP9/36INGQ7EJPwHBw5RXApqfXxCKn18aZqK1qOH3hr7/fA5pI2LPKk\nEfFERHwQ+A5psljjt5V0H0cXJHYDfkianfgf2ZYFlZLYGjgngs2qrqUfSfoRcGNEfK+k8+9I6og9\nDTgqG9FpHLc4uhDBNNKTl/eTWh+FNoNH6Y/AJIkNqi6kTxUyutJOREwnLR70SuBXkiat+BP15ODo\nUgTzI/gk6YfxaxJnSrTYjrBn9Swl7fLmfo7WLgK2GdqAugwRMRt4NWlj8OskbVXWtari4ChIBFcB\nLwXuIT3z8rYKH3P3fI42IuIJ4DdQbt9URDwZER8DvkRaHOitZV6v19zHUQKJHUn3uLcBH4pgdo+v\nvy3wswi26OV16yLbT/ZDEfGaHl1vO9KIzlnAkaPZkkHS6aRboEXAtcAHI2JJoYXm4BZHCSKYDmxH\nmldxs8S7etz6uBl4jkRpzfGauwDYQVJPdrKPiBtJ/+i3BS4Y5XVPj4gtsgf1xgEHFVljXg6OkkSw\nMIIjScvwHwGcK7F+j669BLgCD8u2FBHzgd8Bb+zhNR8GXg9cT+r32C7n5y8Y9uW1QKFDynk5OEoW\nwfWk3zYzSauNvadHrQ/3c6xYqaMrrWRbMhwBHA5cKOmAvOfIps4fQGo1VcZ9HD2U9T2cBtwHHJxt\nbVDWtXYATougcT36Rcimh98HPD8i5lRw/a1IT+wuBObD2I1h1VVh0SJYcDdwc0Qc3OJzpwCPt9qh\nrpfc4uihbH/Xl5OamjdJ/HuJrY+bgOdJ9OQ+vm4iYi5pJukbKrr+LNJzLhsCL4cF68Kjk9IrO5Jm\nJz+DpC8Aa1cdGuDg6LkIFkXwJWBP4CPAbyUKX88ygsWkBWzcz9Fe4c+u5JFaOmMXtf7u2BcM/0rS\nQcDrgHeUX9nIHBwViWAm6TfLNNIetweX0Prwcysr9ivgldU+1bpqm53jljv+P8C6wDWSbpT0uZIL\nWyH3cfQBia1IfR9zgA9k2x0Ucd6dgf+OYNsiztdEks4HfhoRP6/m+uNmZ7cnyxj7YMT85/S+os64\nxdEHIphFWor/EuB6iUML2kT6emAziWcXcK6mGtUK6MVZ0GZRoXbH+4ODo09EsDiCY4HdgAOBSyS6\nWtMygkXAdGjUdpdF+yXw2goXH76Z9HQ1MHEOjH2Q9Hd2c0X1dMTB0WciuI20IO75wLUSH+2y9eH5\nHCuQTcy6ljQ5q4rrH0zqJJ8RMefZEfOfExGvaDUU208cHH0ogiURfIu0DeHbgEslXjjK0zk4RnY2\nFY6ukB6OnDHiu/qIg6OPRXA76R/9VOBqiU9IrJzzNNcCW0qsUXiBzXEusFeFe8Q6OKxYWevjONJm\nQPsC06TON5eOYCGpk3SXkkqsvWz9jJlQ2QZcDg4rRwR/Ia0qdQZwpcSnc7Q+fLsyskomg0laibR/\nz8xeX7sbDo4aiWBpBCeQpq3vRQqQTnZhd3CMbCqwt6Q2E7JKsynwjyqel+mGg6OGIrgLeA3wI+By\nif+UWGUFH7kG2FpifC/qq6Nsm4M/A3v0+NIvpWatDXBw1FbW+jiJ9Mj+HqTO05ZPwkYwn3QPvfOK\nzilpY0nXSLpd0s+yR7gHSc8ftaeG/Rvg4Ki9bHr6a4FTgD9IfE5iTIu3dvLcyteBb0fE5qTp7+8v\nstYamAq8qceB6eCwakQQEZwKvIw0S3S6xORl3tbJDm97kDoJAX5MGsUZGNlu9PfQ2wcDHRxWrQj+\nRuo0PR64SOIoiaHOvquA7STGtvqspLWAR4ZtIPR/wHPLrrkP9Wx0RdI6wHjgr724XpEcHA2TtT5O\nIy2Muz1wncR2MOF1sM/qsP9caee50oR+2DyqH00B9pWUd6LdaEwGZtRxl/tB6/waGBHcJ/EG4AD4\nw+9hv4lwIukX3LxnwSFnSRP2j5h7dnp/PCxpkqSVslbHhlDe0ob9KiLukPQgqSN5WsmXq+WICrjF\n0WhZ6+Mn8IVVng4NsteTgK1PW+YjfwD2z/58IOnJ0UHUq9GVWvZvgINjQKyzGstN4RgPrLfssxlH\nAIdJuh1YE/hBL6rrQ1OAN2ezOstU2+DwrcpAeGBhuj0ZHh7zsuNPi4i7ScsZDrSIuFXSXNJiwtPL\nuEb2QN0mwK1lnL9sbnEMhFveB4eQwoLs9ZDsuLVR9ujKS4A7sr1sa8drjg6INIqy9Wnp9uSBhXDL\n+4Y6Rm15kiaT9j3ZtIxRD0nvB/4lIg4s+ty94FuVAZGFhIOiczcDS0nD2jeWcP7ajqiAb1XMWspa\nGWWOrtS2YxQcHGYrMgV4i6RC97vJRmsm4xaHWSNdD6xO6sgs0sbAnGyh5FpycJi1kd2ulDG6Uuvb\nFHBwmI2kjH4OB4dZw10DrCmp4wWiO1DrERVwcJitUPbA31SKbXW4xWE2AArbsEnSmsAkoK/3hh2J\ng8NsZFcAG0jqai/fzGRg5rAFk2rJwWE2gohYQpp+XsTtSu1vU8DBYdapKTg4nuLgMOvMpcBmkp7X\n5XlqP6ICDg6zjkTEk8B5wH6jPYek1YDNgT8WVVdVHBxmnet2dGVL4M6IWFBQPZVxcJh17hLgJZLW\nH+XnG9G/AQ4Os45lq3Wdz+g3qnJwmA2obh56a0xweOlAsxwkjQXuB14YEQ/l+JyAR/J+rl+5xWGW\nQ9axeSHwppwf3QiY14TQAAeH2WiM5lH7yTTkNgUcHGaj8VtgJ0nPzvGZxvRvgIPDLLeIeJw0NLtP\njo85OMws9+hKo4LDoypmoyBpInAvsGFEPDbCeydl751Y98fph7jFYTYKEfEocDmwdwdv3wa4pSmh\nAQ4Os250OrrSqNsUcHCYdeM84DWSxo/wPgeHmSUR8U/SKuh7jfBWB4eZPcMKR1ckrQpsAczqWUU9\n4OAw6865wOuzZ1ha2QL4a0TM72FNpXNwmHUhIh4EbgJe2+YtjZpqPsTBYda9FY2uNK5/AxwcZkU4\nB9g7689YloPDzJYXEX8HbgVePfx4tgaHg8PM2mq1kPGGwKKImF1BPaVycJgVYyrwRkljhh1rxB4q\nrTg4zAoQEX8D7gR2H3a4kSMq4OAwK9Ky20S27N+Q9GFJd0haku1eXzsODrPiTAH2lbRy9nW7jtEr\nSB2pf+1VYUVzcJgVJCLuJK2AvoukNYD1gDtavG9mdmujHpdYmFWqLsCsYYZGV5YCsyJiScX1lMLB\nYVasKcDFpJZGI0dUwEsHmhVG0m3ABsCE7NASYD5wX0Rs2eL9dwHbZ4/n14r7OMyKMzw0AFbOvt6g\nzftFTfs5HBxmhdHqnRyX9FFJ95ICZaakU8qvrVi+VTEriLTKk7CkRb/hyosjFo9Z/nh9ucVhVpil\nbX4LtzteXw4Os8LEwnzH68vBYVac+4C5oCdh5cXplbnZ8UZxH4eZ5eYWh5nl5uAws9wcHGaWm4PD\nzHJzcJhZbg4OM8vNwWFmuTk4zCw3B4eZ5ebgMLPcHBxmlpuDw8xyc3CYWW4ODjPLzcFhZrk5OMws\nNweHmeXm4DCz3BwcZpabg8PMcnNwmFluDg4zy+3/AX29RYzXZU88AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_labeled_lines(list(cities), 'bo-', [0, 3, 4, 0], 'ks-', [1, 2, 5, 1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Step 3 is to combine the two halves. We do that by choosing an edge from each half to delete (the edges marked by red dashes) and replacing those two edges by two edges that connect the halves (the blue dash-dot edges). Note that there are two choices of ways to connect the new dash-dot lines. Pick the one that yields the shortest tour." + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# One way to connect the two segments, giving the tour [1, 3, 4, 0, 2, 5]\n", + "plot_labeled_lines(list(cities), 'bo-', [0, 3, 4], 'ks-', [1, 2, 5],\n", + " 'b-.', [0, 1], [4, 5],\n", + " 'r--', [0, 4], [1, 5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we have a feel for what we have to do. Let's define the divide and conquer algorithm, which we will call `dq_tsp`. Like all `tsp` algorithms it gets a set of cities as input and returns a tour. If the size of the set of cities is 3 or less, then just listing the cities in any order produces an optimal tour. If there are more than 3 cities, then split the cities in half (using `split_cities`), find a tour for each half (using `dq_tsp` recursively), and join the two tours together (using `join_tours`): " + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def dq_tsp(cities):\n", + " \"\"\"Find a tour by divide and conquer: if number of cities is 3 or less,\n", + " any tour is optimal. Otherwise, split the cities in half, solve each\n", + " half recursively, then join those two tours together.\"\"\"\n", + " if len(cities) <= 3:\n", + " return Tour(cities)\n", + " else:\n", + " Cs1, Cs2 = split_cities(cities)\n", + " return join_tours(dq_tsp(Cs1), dq_tsp(Cs2))\n", + " \n", + "# TO DO: functions: split_cities, join_tours" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's verify that `dq_tsp` works for three cities:" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 city tour with length 1203.4 in 0.000 secs for dq_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(dq_tsp, Cities(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we have more than 3 cities, how do we split them? My approach is to imagine drawing an axis-aligned rectangle that is just big enough to contain all the cities. If the rectangle is wider than it is tall, then order all the cities by *x* coordinate and split that ordered list in half. If the rectangle is taller than it is wide, order and split the cities by *y* coordinate. " + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def split_cities(cities):\n", + " \"Split cities vertically if map is wider; horizontally if map is taller.\"\n", + " width, height = extent([c.x for c in cities]), extent([c.y for c in cities])\n", + " key = 'x' if (width > height) else 'y'\n", + " cities = sorted(cities, key=lambda c: getattr(c, key))\n", + " mid = len(cities) // 2\n", + " return frozenset(cities[:mid]), frozenset(cities[mid:])\n", + "\n", + "def extent(numbers): return max(numbers) - min(numbers)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's show that split_cities is working:" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQ4AAAEACAYAAABCu5jVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFKpJREFUeJzt3X+YlWWdx/H3VydRQfyNQGYYqYOCUoaJmpZpXmZmpqux\narpd6tpm5qp5lZLrJmXijzaNRNtrS5HU1VRCXcUfsWpCoq3JCIgh9MMBCX/BjIAg3/3jfsYZmGGY\n+8w55z7Pcz6v6/I6eJpzzsf0fOZ+7ud+7sfcHRGRGJulDiAi+aPiEJFoKg4RiabiEJFoKg4Riabi\nEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFo\nKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4R\niabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4RiabiEJFoKg4Riabi\nEJFoDakD1Auz/kNg+DgYNBgWN0PTWPfli1LnEimFiqMKQmkc9yhMHAp9gVbgnAPN+h+h8pA80qFK\nVQwf114aEB4nDg3Pi+SPiqMqBg1uL402fYGBg1OkEektFUdVLG4OhycdtQItb6VII9JbKo6qGHU9\nXLauvTxagQuXwY2jzdg/ZTKRUpi7p85QeGb8HGathW9tEw5PljRD01hY/jHgZuBr7kxNnVOkp1Qc\nFWbGcOAxYC93Oh2amHEAcB/wQ3d+Wu18IqVQcVSYGQ8CD7lzfTc/szuEnwMucue9auUTKYXmOCrI\njCOBPYCJ3f2cOwuBg4CRwN1mbF2FeCIlU3FUiBmbA1cD33Hn3U39vDtvAkcBK4DpZuxS4YgiJVNx\nVM6phNMn9/T0BVnBnA48AMw0Y+8KZRPpFc1xVEB2qPEScJI7M0p8j68SRixj3Hm8nPlEeksjjso4\nH5hRamkAuHMr8BXgDjNOL1sykTLQiKPMzBgAzAE+6c6CMrzfMMKhyyTgcnf0L0ySU3GUmRkTgHfd\n+dcyvucuwFRgHnCWO6vL9d4ipVBxlJEZjcCTQKM7r5f5vbcGbgN2AI7PzsKIJKE5jvL6EXBVuUsD\nwJ13gH8A/gDMMOMj5f4MkZ7SRj5lYsZhwH6ECc2KyFaUXmDGAuApM4535/eV+jyRjdGIowzM2Ay4\n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\ncYhItP8Hf62p30lzGqcAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Cs1, Cs2 = split_cities(cities)\n", + "plot_tour(dq_tsp(Cs1))\n", + "plot_tour(dq_tsp(Cs2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now for the tricky part: joining two tours together. First we consider all ways of deleting one edge from each of the two tours. If we delete a edge from a tour we get a segment. We are representing segments as lists of cities, the same surface representation as tours. But there is a difference in their interpretation. The tour `[0, 2, 5]` is a triangle of three edges, but the segment `[0, 2, 5]` consists of only two edges, from `0` to `2` and from `2` to `5`. The segments that result from deleting an edge from the tour `[0, 2, 5]` are:\n", + "\n", + "
\n",
+    "[0, 2, 5],    [2, 5, 0],    [5, 0, 2]\n",
+    "
\n", + "\n", + "You may recognize these as the *rotations* of the segment `[0, 2, 5]`. So any candidate combined tour consists of taking a rotation of the first tour, and appending to it a rotation of the second tour, with one caveat: when we go to append the two segments, there are two ways of doing it: either keep the second segment as is, or reverse the second segment.\n", + "\n", + "**Note:** In Python, `sequence[::-1]` means to reverse the sequence." + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def join_tours(tour1, tour2):\n", + " \"Consider all ways of joining the two tours together, and pick the shortest.\"\n", + " segments1, segments2 = rotations(tour1), rotations(tour2)\n", + " tours = [s1 + s2\n", + " for s1 in segments1\n", + " for s in segments2\n", + " for s2 in (s, s[::-1])]\n", + " return shortest_tour(tours)\n", + "\n", + "def rotations(sequence):\n", + " \"All possible rotations of a sequence.\"\n", + " # A rotation is some suffix of the sequence followed by the rest of the sequence.\n", + " return [sequence[i:] + sequence[:i] for i in range(len(sequence))]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see if it works, first on the 6 city example:" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQ4AAAEACAYAAABCu5jVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFqxJREFUeJzt3Xu0lVW9xvHvL/GKohkpYBrpUUFRFK8Yihrk8JaSJhJq\n5lEj5aCpmZedR0tTCTmJomB1UAQvqRh5KRGNIwoY2vGyBS8RlAmEeCwuKl74nT/m3LEFNux377XW\nXOt9n88YDYcKez0jts+ec77zndPcHRGRLD6TOoCI1B4Vh4hkpuIQkcxUHCKSmYpDRDJTcYhIZioO\nEclMxSEimak4RCQzFYeIZKbiEJHMVBwikpmKQ0QyU3GISGYqDhHJTMUhIpmpOEQkMxWHiGSm4hCR\nzFQcIpKZikNEMlNxiEhmKg4RyUzFISKZqThEJDMVh4hkpuIQkcxUHCKSmYpDRDJTcYhIZioOEclM\nxSEimak4RCQzFYeIZKbiEJHMVBwikpmKQ0QyU3GISGYqDhHJTMUhIpmpOEQkMxWHiGSm4hCRzFQc\nIpJZm9QBisKsXWfodjV07AQL5kN9nfuSealzibSEiqMCQmkcNxlG7QRtgeXAoAPN2vVReUgt0lSl\nIrpdvao0IPx11E7hn4vUHhVHRXTstKo0GrQFOnRKkUaktVQcFbFgfpieNLYcWPaPFGlEWkvFURH7\njYArVq4qj+XAhYvh1p5m7JMymUhLmLunzpB7ZvwcZn4M520RpicL50N9HSzZG7gNOMOdh1LnFGku\nFUeZmdENeALY1Z01piZm7A/8GviJOzdXOp9IS6g4ysyMR4HfuTNiHb/mSxB+HXCRO59UKp9IS2iN\no4zM6AvsDIxa169zZy5wELAXcL8Zm1UgnkiLqTjKxIwNgJ8Cl7jz4fp+vTvvAkcAS4EpZmxb5ogi\nLabiKJ9TCI9PJjT3N8SC+RbwCDDDjN3KlE2kVbTGUQZxqvEacJI701v4NU4jjFgGuPNkKfOJtJZG\nHOVxPjC9paUB4M5YoD9wtxnfKlkykRLQiKPEzNgGmAUc4M6cEny9roSpy53Ale7oD0ySU3GUmBkj\ngQ/d+V4Jv+a2wG8I05+z3FlRqq8t0hIqjhIyowswFejizjsl/tqbAeOArYF+8SmMSBJa4yit64Dr\nS10aAO68B3wD+CMw3YwdS/0ZIs2lg3xKxIzeQHfg5HJ9RtxReoEZc4CnzejnzrPl+jyRpmjEUQJm\nfAYYBlzmzgfl/jx3RgJnAw+bcUK5P09kdSqO0ugPOHBvpT7QnYcJO01vNONCM6xSny2ixdFWMmMT\n4FXgNHeeSvD5OxAe1z4FnOfOx5XOIMWjEUfrDQZeSFEaAO78FehFeJnu12ZsniKHFItGHK1gxucI\no41e7ryWOMuGwC3APsAx7sxPmUfyTSOO1qkDfpW6NADc+YiwYHof4XHtHokjSY5pxNFCZvwbMAPY\nzZ1FqfM0ZsbJwAjgFHcmpc4j+aMRR8tdCwyvttIAcOce4OvAWDPOSp1H8kcjjhYwoyfh0WuXuKOz\nKpmxM+FIwvuBy91ZmTiS5ISKI6O4X+IZYLQ7d6TOsz5mtAcmAm8Cp1dig5rkn6Yq2X0d2JTwwlnV\nc2cx8JX4t5NjkYi0ioojAzM2Aq4Hvl9LJ5HHUcY3CW/uTo9TGJEWU3FkMwh43Z3JqYNk5c5Kdy4F\nhgJTzeiVOpPULq1xNJMZWxEO0vmKO/Wp87SGGUcQThQbEp/AiGSi4mgmM4YCn3XPx+NNM/YEHiLc\n+XKdjiSULFQczWBGZ+B5oJs7CxLHKRkzOgEPEw4H+m7cfSqyXlrjaJ5rgJvyVBoA8X2WQ4AOwCNm\nbJk4ktQIFcd6mLEvcCjhoJ7ccWcZcDzwBuFUsR0SR5IaoOJYh7jZaxjhWoJlqfOUSzzDYzAwBphm\nRo/EkaTKqTjW7RigPeE/qFxzx90ZDgwBHjPjmNSZpHppcbQJZrQBXgYudOfR1HkqyYwDgAeBa+L5\npiKfohFH084E3gJ+mzpIpcWT03sBg80YbsYGqTNJddGIYy3MaEfY7HWkOy+kzpOKGZ8FJgDvEs72\nqNo3gaWyNOJYu4uBSUUuDYB4W9wRwDLg9/EqShGNOFZnxheAF4G93HkzdZ5qEJ8u/SdwGnC0O7MT\nR5LEVByrMWMMsMCdy1JnqTZmfIvwktzJ7vw+dR5JR8XRiBndgceAXdxZkjpPNTLjcOAe4CJ3xqbO\nI2moOBoxYxIwUY8g182M3QiXQN0O/EgvyBWPFkej+Kr5F4HbUmepdu7MAnoCRwO3xwOOpEBUHEDc\npzAMuFhviDaPOwsJ7/C0A34XH91KQag4gtMJexV+kzhHTYn7Ok4kPIWaZsaXEkeSCin8GocZbYHX\ngX7u/CF1nlplxmDgMuB4/f+YfxpxwIXAU/pmbx13bga+QzjXo1/qPFJehR5xmNEBqAf2c2du6jx5\nYMY+hHtcbgB+picu+VT04hgNLHXnotRZ8iQeBvQoMAU4P573ITlS2OKIexGmALvGdzKkhOIxhPcD\nHwAD8nwQUhEVeY1jKHCtSqM83PkncBTwd+CpeDCy5EQhiyNum+4K3JI6S57FPTFnEUYe083YI3Ek\nKZHCTVXM+AzwHGG0cV/qPEVhxgDgRsK5HpNS55HWKeKIYyCwgvBTUCrEnbuBE4CxZpyZOo+0TqFG\nHGZsSjjZa4A7z6TOU0Rm7EJ4Qe4+oM6dlYkjSQsUbcRxHjBTpZGOO68DBwG9gbvM2CRxJGmBwow4\nzPg8MBvo6c4bqfMUXSyMO4DtCNvUFyeOJBkUacRxBXCXSqM6uIf9HcDThBfkdk4cSTIoxIgjzquf\nAbrqJ1v1MeMs4MfACZpG1oaiFMcEYIY7Q1NnkbWLByndCfyHO/emziPrlvviMONgYBxha/kHqfNI\n08zYE3iYsDHver0gV71yXRzxWP8ZwAh3xqfOI+tnxnaE8ngOOEcnslWnvC+OngS0Ae5OHUSax523\ngEOATsDD8VY9qTK5LQ4zNgauJRzjr01GNcSdpcBxwBzgaTO2TxxJVpPb4gDOBV7RxUG1KZ7hcS5h\nr8d0M3okjiSN5HKNw4ytgVeB3rqusPaZcQIwCjjdnUdS55H8FscNQFt3BqXOIqVhxoHABOBqdx2H\nkFruisOMHYGZwO7x7g/Jifhn+yjhqcvFWrtKJ4/FcQ9Q787VqbNI6cVp6ATgHeDUeLeLVFiuFkfN\nOADoBQxPnUXKw53/A44A3gOeNGObxJEKKTfFETd7DQN+qJ9C+ebOCuA04DFghhldEkcqnDapA5TQ\n8cCWwNjUQaT84nb0/zRjLvA/ZuOHwMhjoWMnWDAf6uvcl8xLHDO3clEcZmwIXA8MdueT1Hmkcty5\n3eyeD+H58fD4BtAWWA4MOtCsXR+VR3nkZaryHWCuDsEtqhFHwY9jaUD466idoJsWyMuk5kcc8eKf\nOuCrqbNIKh07rSqNBm2BDrrLpUxqsjjM2nUOP006doL228A5U9y7v5Q6l6SyYH6YnjQuj+XAB7o9\nrkxqbh9HKI3jJoehaMN89tx5MOEwzWeLae3fExcsgh+0gR3PcmdC4oi5U4PFcdA4eHzgmj9d+o53\nn3ZKqlyS1qpRaIdOsHA+1NfBkvbAA8B4wmN6LZyXSA1OVTSflTXF0ebqPzjmmbEv8CvgETO+GTeQ\nSSvV4FOVhvlsY8uBj95PkUaqmztvA32BV4CZZnRPHCkXarA46utg0JxV5dEwn73xADOuMmOjlOmk\n+rjzsTsXEp6+TY732Eor1NwaBzQ5n/0QGA18Efi2O8+nTSnVKB6I/CDwa+AH8cAgyagmi6Mp8X2V\ngcANwC+AH8X3GkT+Jb5hexewEdA/TmckgxqcqjTNHXdnHNAd2A143oz9EseSKhMXSI8GpgPP6Xsk\nu1yNOBqLo4/+wI3AGOBK3asiqzOjH2GK+wN3xqTOUytyWxwNzNgWuBnoBpzhzvTEkaTKmNGVsO7x\nJHC+Ox8mjlT1cjVVWRt3/u7ONwiXTk8wY5gZm6bOJdUjHmh9ALAd8HszOiaOVPVyXxwN3LkP2JPw\nzfGiGb0SR5Iq4s4/gX7A7wj7PQ5KHKmq5X6qsjZxXjuSsKPwcvc1dpRJgZlxFHFdDBilO2zXVJgR\nR2PuPAjsAbQnjD56J44kVcSdR4EvA+cAvzRjk8SRqk4hiwPAnXfcOQW4ALjLjJvN2Dx1LqkO7vwJ\n6El4EWqqGTskjlRVClscDdz5DeGJy+bAS2YcnjiSVAl3lgEnA/cCz5pxWOJIVaOQaxxNiXPb0ay6\n8Gdp4khSJczoA4wjnG37s6KvexR+xNFYnNt2AzYEXjajb+JIUiXcmQwcCJwKjDdjs8SRklJxrMad\nf7pzJuEA5F+Y8fN4rqkUnDvzCIumHwHT45WUhaTiaII7jxGevKwkjD6OTBxJqoA77wOnE16inG7G\nEWkTpaE1jmYw4yuEb5QpwAXuvJs2kVQDMw4G7iG80nBdkdY9NOJoBneeIOw6fY8w+jgmcSSpAu5M\nBfYHjgMeMGOLxJEqRsXRTO4sdedcwrmWN5oxNp7rIAXmzltAb+BtwiPbXRNHqggVR0buTCGMPt4l\njD6OT5tIUnNnhTvfAYYTNot9LXWmctMaRyvEOe5/AzOBIe4sThxJEjPjAOB+Vp0BszJxpLLQiKMV\n4hy3O7CAMPo4MXEkScydZ4F9gUOBh8zYKm2i8tCIo0Tia9hjgBeBwe4sShxJEjJjQ2AYcBTQz536\nxJFKSiOOEnFnGrAXMI/wzkv/eHyhFJA7H7lzHnAV4XCgk1JnKiWNOMogznPHALOBc9z5e+JIkpAZ\nPQhXUTac/1LzVzJoxFEGcZ7bA3iNMPoYqNFHcbnzR8K6Rw/gt2a0Txyp1TTiKLN4d+kY4M/AIHcW\nJI4kiZixAXAN4fT9E2Kh1CSNOMrMnecIP21eJJw2dppGH8XkzifuXAJcDDxmxqmpM7WURhwVZMbe\nhNHHW8DZcdehFJAZ3QhXMvwWdhkB7a+Ejp3Cper1de5L5qVNuG4qjgqLl2JfCpwLXAKMKdLLUbJK\n2OMx6wEY3RN+smk4pXA54VL1iX2quTxUHImY0Z0w+lhEGH38NXEkScDsy+Ng0sBQGg2WA33Hu087\nJVWu9dEaRyLuvEi4BGgq4Y7bs7X2UUQdOn26NCD8fYdOKdI0l4ojobhJ6BrgMOAsYJIZndOmkspa\nMJ81rvVZDiycnyJNc6k4qkDcjtwTeIJwe/p3zfRnUwz1dWFNo6E8GtY46utSplofrXFUmXgB8hjg\nfeDf3flz4khSZmYHd4HDX4ZXnob5b+mpirRI3Cj0PcJTl6uAkXl9PVvAjP2B0e7snTpLc2k4XIXi\nRqFhwEGEXYZTzNg5cSwpn72AF1KHyELFUcXceZ1wLN0Ewona34ujEckXFYeUVhx9/IxwGVA/wtF0\nhTjXskBUHFIe8RLkQ4G7gGfM+L5GH7UvPj3bg/AuU81QcdQQd1a6czPhSP4jCQWyW+JY0jo7AYvd\n+UfqIFmoOGpQfETbB7gdeMqMS81okzaVtNBe1NhoA1QcNSuOPkYRXtk/nLB42i1xLMmu5tY3QMVR\n8+JFyF8FbiOcbVkXD8qV2qDikDTccXd+DuwD9CLcKNY9cSxpHhWHpBVfzT8SuAl43Iwr4/kfUoXM\n+DzhVdi/pM6Slbac55QZ2wGjge33Zoc/bc+bOy5l8y7Oxm2MFR9vwbJXF8HM6e5np85aVGb0AX7o\nTu/UWbLSSnxOufOWGccCp27JVr+cyJttYBnhf7QB9jouaUKhRqcpoKlKrsW1j7HGvE/W9u+XsnmX\nSmeST1FxSPVyNlrrDlNnY40401JxSPUyVjRxc9gnmNGusmkEwIxNgB2BWamztISKowC2YNmra/vn\nbdhqCfC6GYO196PidgfecGdF6iAtoaFqASyCmccR1jQaP1VZxryZwC3AUGCIGZcAD+q6hoqoya3m\nDfQ4VgAw46vATwmPXb7vzrTEkXLNjJuAue4MT52lJTRVEQDcmUS4FPk24F4z7tepY2VVswujoOKQ\nRuKhQXcAuwDPE16cuynucJQSiWdwdKeGpyoqDlmDO++7cy3QFXBgthmXmbFZ4mh50Rn4hzvvpA7S\nUioOaZI7b7szhHDnSw/gNTNO18ljrVbT0xRQcUgzuPOGOycCJxFunPujGUckjlXLavqJCqg4JAN3\nphNe278KuMmMSXp9v0U04pBiie+/TCBsYJoIPGbGHWZsnzhaLVFxSDHFC7NHEp7A/A14wYxrzdgy\ncbSqZsbWwFbA3NRZWkPFIa3izhJ3Lic8XtyWsIV9iA4QalJ34MVav9JTxSEl4c7f3DkD6Es4hewV\nM040wxJHqzY1vzAKKg4pMXdecudI4LvA5cA0M76cOFY1qfn1DVBxSJm4M5lwePItwF1mTNDVlYCK\nQ2Td4t0vdwJdgBnA02aMNGObxNGSMGNjwmLyK6mztJaKQ8oubmEfStjC/hFhC3tdAbewdwXmuPN+\n6iCtpeKQinFnsTvnE+6+3ZPwBOaMAm1hz8U0BVQckoA7c9w5CTgB+DZhD8iRBXgCk4snKqDikITc\neRY4BKgD/otwiVSPtKnKSiMOkVKIW9gnAnsADwCPmHGnGTskjlZScTRV02dwNKbikKoQt7DfSnjq\nMBf4XzOuN2OrxNFKZQfgPXcWpQ5SCioOqSruLHXnCsII5HOEBdTzc7CFPTfTFFBxSJVyZ747ZwKH\nE7axzzajfw0voKo4RCrFnXp3jiYcIHQxMMOMgxPHaoncPFEBFYfUCHeeBPYDRgB3mjHRjFq6+1Yj\nDpEU4hb28YQt7FOBqWbcasa2iaOtU1zg/TwwJ3WWUlFxSM1x5wN3hhEK5H1glhlXmNE2cbSm7Am8\n5M4nqYOUiopDapY777hzAWEK05XwBOZMs6q72jRX0xRQcUgOuPNndwYA/YBTCVvYj66iJzC5WhgF\nFYfkiDt/AA4FLgWGAU+YsU/SUIFGHCLVLG5hf4iwgexe4CEzxpvROUUeMzYkrMW8nOLzy0XFIbnk\nzsfujCZsYX8DeN6Mn5rx2QpH6QL8xZ33Kvy5ZaXikFxzZ5k7VwLdgC0J11heEE/jqoTcTVNAxSEF\n4c4Cd84mrIEcBrxqxoB4c3w5qThEap07s9w5lnCA0IXAs2b0LuNH5u6JCoC5e+oMIknE0UZ/4CeE\nxctL3JlVwq9vwGJgd3cWlurrVgONOKSw4hb2uwkLmFOAKWaMNqNDiT7iC8BHeSsNUHGI4M4Kd4YD\nuwJLCbfQXWnG5q380t3J4foGqDhE/sWdd925CNgX2Jmwhf3sVmxhz+XCKKg4RNbgzlx3BgJfAwYA\nL5lxbAu2sOe2OLQ4KrIOsSyOAoYCbwMXufNcM3/vn4Bj3ZldxohJaMQhsg5xC/sjhPWKccBEM+42\n40vr+n1mtAM6Aq9XIGbFqThEmiFuYf8FYQv7bOA5M24wY+smfsseQH2ezuBoTMUhkoE7y935EbA7\nsBlhC/tFZmyy2i/N7foGaI1DpFXM6ApcR5jKXA7tp8EuP4b9D4N3/wYP9ndfMi9tytJTcYiUgBmH\nwGs3wq1d4ZqNoS2wHBg0Byb2yVt5qDhESsTsoHHw+EA+dfTpcqDvePdpp6TKVQ5a4xApmY6dWOO8\n5LZAh04p0pSTikOkZBbMDyOMxpYDC+enSFNOKg6RkqmvC2saDeXRsMZRX5cyVTlojUOkhMzadYZu\nV4fpycL5UF+Xt4VRUHGISAtoqiIimak4RCQzFYeIZKbiEJHMVBwikpmKQ0QyU3GISGYqDhHJTMUh\nIpmpOEQkMxWHiGSm4hCRzFQcIpKZikNEMlNxiEhmKg4RyUzFISKZqThEJDMVh4hkpuIQkcxUHCKS\nmYpDRDL7f32INzgSOu2iAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6 city tour with length 1431.7 in 0.000 secs for dq_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(dq_tsp, Cities(6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That is indeed the optimal tour, achieved by deleting the two dashed red lines and adding the dotted blue lines.\n", + "\n", + "Now for the USA map:" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nBDopa1IAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 14883.2 in 0.142 secs for dq_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(dq_tsp, USA_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Not quite as good as `altered_greedy_tsp`. Let's alter it!" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def altered_dq_tsp(cities): return alter_tour(dq_tsp(cities))" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 14209.6 in 0.109 secs for altered_dq_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(altered_dq_tsp, USA_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's just remind ourselves how the algorithms behave on the standard test cases:" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " nn_tsp | 5668 ± 488 ( 4674 to 6832) | 0.001 secs/map | 30 ⨉ 60-city maps\n", + " greedy_tsp | 5392 ± 306 ( 4554 to 5967) | 0.002 secs/map | 30 ⨉ 60-city maps\n", + " dq_tsp | 5268 ± 236 ( 4743 to 5752) | 0.042 secs/map | 30 ⨉ 60-city maps\n", + " altered_dq_tsp | 4953 ± 221 ( 4575 to 5399) | 0.049 secs/map | 30 ⨉ 60-city maps\n", + " altered_nn_tsp | 4820 ± 233 ( 4450 to 5346) | 0.008 secs/map | 30 ⨉ 60-city maps\n", + " altered_greedy_tsp | 4766 ± 207 ( 4320 to 5185) | 0.009 secs/map | 30 ⨉ 60-city maps\n", + " repeated_altered_nn_tsp | 4640 ± 194 ( 4298 to 4991) | 0.148 secs/map | 30 ⨉ 60-city maps\n" + ] + } + ], + "source": [ + "algorithms = [nn_tsp, greedy_tsp, dq_tsp, altered_dq_tsp, altered_nn_tsp, altered_greedy_tsp, \n", + " repeated_altered_nn_tsp]\n", + "\n", + "benchmarks(algorithms)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Of the non-altered algorithms (the first three lines), divide and conquer (`dq_tsp`) does best. But interestingly, divide and conquer is helped less by `alter_tour` than is the greedy algorithm or nearest neighbor algorithm. Perhaps it is because divide and conquer constructs its tour by putting together pieces that are already good, so `alter_tour` is less able to improve it. ALso, `dq_tsp` has a standard deviation that is much smaller than the other two—this suggests that `dq_tsp` is not producing really bad tours that can be easily improved by `alter_tour`. In any event, `altered_dq_tsp` is the worst of the `altered` algorithms, both in average tour length and in run time. \n", + "\n", + "`repeated_altered_nn_tsp` remains the best in tour length, although the worst in run time." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Shoulders of Giants: Minimum Spanning Tree Algorithm: `mst_tsp`\n", + "\n", + "\n", + "\n", + "\n", + "
Joseph Kruskal (Wikipedia)
\n", + "\n", + "\n", + "I hope you now believe that you could have come up with some ideas for solving the TSP. But even if you can't come up with something all on your own, you can always [Google it](http://bit.ly/XNGt2y), in which case you'll no doubt find a giant of a mathematician, [Joseph Kruskal](http://en.wikipedia.org/wiki/Joseph_Kruskal), who, in 1956, \n", + "published [a paper](http://www.cmat.edu.uy/~marclan/TAG/Sellanes/Kruskal.pdf) that led to an algorithm that\n", + "most people would not have thought of on their own\n", + " (I know I wouldn't have):\n", + "> **Minimum Spanning Tree Traversal Algorithm:** *Construct a Minimum Spanning Tree, then do a pre-order traversal. That will give you a tour that is guaranteed to be no more than twice as long as the minimal tour.* \n", + "\n", + "What does all this jargon mean? It is part of *graph theory*, the study of vertexes and edges. Here is a glossary of terms:\n", + "\n", + "* A **graph** is a collection of vertexes and edges.\n", + "* A **vertex** is a point (such as a city).\n", + "* An **edge** is a link between two vertexes. Edges have lengths.\n", + "\n", + "* A **directed graph** is a graph where the edges have a direction. We say that the edge goes from the **parent** vertex to the **child** vertex.\n", + "\n", + "* A **tree** is a directed graph in which there is one distinguished vertex called the **root** that has no parent; every other vertex has exactly one parent. \n", + "\n", + "* A **spanning tree** (of a set of vertexes) is a tree that contains all the vertexes. \n", + "\n", + "* A **minimum spanning tree** is a spanning tree with the smallest possible sum of edge lengths.\n", + "\n", + "* A **traversal** of a tree is a way of visiting all the vertexes in some order.\n", + "\n", + "* A **pre-order traversal** means that you visit the root first, then do a pre-order traversal of each of the children.\n", + "\n", + "* A **guarantee** means that, no matter what set of cities is selected, the tour found by the minimum spanning tree traversal algorithm will never be more than twice as long as the shortest possible tour. None of the other algorithms has any guarantee at all (except for `alltours_tsp`, which is guaranteed to find the optimal algorithm, if it has enough time to complete).\n", + "\n", + "We will implement a vertex as a Point, and a directed graph as a dict of `{parent: [child, ...]}` pairs. \n", + "\n", + "Visualizing Graphs and Trees\n", + "---\n", + "\n", + "I think we will need visualization right away, so before doing anything else I will define `plot_graph`. I will make it plot in red so that we can easily tell a tour (blue) from a graph (red)." + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def plot_graph(graph):\n", + " \"Given a graph of the form {parent: [child...]}, plot the vertexes and edges.\"\n", + " vertexes = {v for parent in graph for v in graph[parent]} | set(graph)\n", + " edges = {(parent, child) for parent in graph for child in graph[parent]}\n", + " for edge in edges:\n", + " plot_lines(edge, 'ro-')\n", + " total_length = sum(distance(p, c) for (p, c) in edges)\n", + " print('{} node Graph of total length: {:.1f}'.format(len(vertexes), total_length))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try it out:" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 node Graph of total length: 10.9\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Ps = [Point(0, 0.1), \n", + " Point(-2, -1), Point(0, -1), Point(2, -1), \n", + " Point(-2.9, -1.9), Point(-1, -1.9), Point(1, -1.9), Point(2.9, -1.9)]\n", + "\n", + "Ptree = {Ps[0]: Ps[1:4], Ps[1]: Ps[4:6], Ps[3]: Ps[6:8]}\n", + "\n", + "plot_graph(Ptree)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now our plan is:\n", + "\n", + "1. Implement an algorithm to create a minimum spanning tree.\n", + "2. Implement a tree traversal; that will give us our `mst_tsp` algorithm.\n", + "3. Understand the guarantee, \n", + "\n", + "Creating a Minimum Spanning Tree (`mst`)\n", + "---\n", + "\n", + "Now let's see how to create a minimum spanning tree (or MST). Kruskal has a very nice algorithm to find MSTs, but with what we have done so far, it will be a bit easier to implement another Giant's algorithm:\n", + "\n", + "> **[Prim's algorithm for creating a MST](http://en.wikipedia.org/wiki/Prim%27s_algorithm):** *List all the edges and sort them, shortest first. Initialize a tree to be a single root city (we'll arbitrarily shoose the first city). Now repeat the following until the tree contains all the cities: find the shortest edge that links a city (A) that is in the tree to a city (B) that is not yet in the tree, and add B to the list of A's children in the tree.*\n", + "\n", + "Here's the code. One tricky bit: In the first line inside the `while` loop, we define `(A, B)` to be an edge in which one of `A` or `B` is in the tree, using the exclusive-or operator, `^`. Then in the next line, we make sure that `A` is the one that is in the tree and B is not, by swapping if necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def mst(vertexes):\n", + " \"\"\"Given a set of vertexes, build a minimum spanning tree: a dict of the form {parent: [child...]}, \n", + " where parent and children are vertexes, and the root of the tree is first(vertexes).\"\"\"\n", + " tree = {first(vertexes): []} # the first city is the root of the tree.\n", + " edges = shortest_edges_first(vertexes)\n", + " while len(tree) < len(vertexes):\n", + " (A, B) = shortest_usable_edge(edges, tree)\n", + " tree[A].append(B)\n", + " tree[B] = []\n", + " return tree\n", + "\n", + "def shortest_usable_edge(edges, tree):\n", + " \"Find the ehortest edge (A, B) where A is in tree and B is not.\"\n", + " (A, B) = first((A, B) for (A, B) in edges if (A in tree) ^ (B in tree)) # ^ is \"xor\" \n", + " return (A, B) if (A in tree) else (B, A)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what a minimum spanning tree looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 node Graph of total length: 11518.4\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_graph(mst(USA_map))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This algorithm clearly produced a spanning tree. It looks pretty good, but how can we be sure the algorithm will *always* produce a minimum spanning tree? \n", + "\n", + "1. The output is a **tree** because (1) every city is connected by a path from the root, and (2) every city only gets one parent (we only add a B that is not in tree), so there can be no loops. \n", + "2. The output is a **spanning tree** because it contains all the cities.\n", + "3. The output is a **minimum spanning tree** because each city was added with the shortest possible edge. Suppose this algorithm produces the tree T. For another putative spanning tree to be shorter, it would have to contain at least one city C whose edge from its parent was shorter than the edge in T. But that is not possible, because the algorithm always chooses the shortest possible edge from C's parent to C.\n", + "\n", + "\n", + "\n", + "**Note:** There are refinements to Prim's algorithm to make it more efficient. I won't bother with them because they complicate the code, and because `mst` is already fast enough for our purposes.\n", + "\n", + "Turning a Minimum Spanning Tree into a Tour (`mst_tsp`)\n", + "---\n", + "\n", + "Given a minimum spanning tree, we can generate a tour by doing a pre-order traversal, which means the tour starts at the root, then visits all the cities in the pre-order traversal of the first child of the root, followed by the pre-order traversals of any other children." + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def mst_tsp(cities):\n", + " \"Create a minimum spanning tree and walk it in pre-order, omitting duplicates.\"\n", + " return preorder_traversal(mst(cities), first(cities))\n", + "\n", + "def preorder_traversal(tree, root):\n", + " \"Traverse tree in pre-order, starting at root of tree.\"\n", + " result = [root]\n", + " for child in tree.get(root, ()):\n", + " result.extend(preorder_traversal(tree, child))\n", + " return result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To better understand pre-order traversal, let's go back to the `Ptree` example, and this time label the vertexes:" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 node Graph of total length: 10.9\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "P = [Point(0, 0.1), \n", + " Point(-2, -1), Point(0, -1), Point(2, -1), \n", + " Point(-2.9, -1.9), Point(-1, -1.9), Point(1, -1.9), Point(2.9, -1.9)]\n", + "\n", + "Ptree = {P[0]: P[1:4], P[1]: P[4:6], P[3]: P[6:8]}\n", + "\n", + "plot_graph(Ptree)\n", + "plot_labeled_lines(P)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A pre-order traversal starting at 0 would go to the first child, 1, then to its children, 4 and 5, then since there are no children of 4 and 5, it would continue with the other children of 0, hitting 2, then 3, and finally the children of 3, namely 6 and 7. So the following should be true:" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "preorder_traversal(Ptree, P[0]) == [P[0], P[1], P[4], P[5], P[2], P[3], P[6], P[7]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And this is what the pre-order traversal looks like as a tour:" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_tour([P[0], P[1], P[4], P[5], P[2], P[3], P[6], P[7]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can think of this as starting at the root (at the top) and going around the outside of the tree counterclockwise, as if you were walking with your left hand always touching an edge, but skipping cities you have already been to.\n", + "\n", + "We see that the result is a tour, but not an optimal one. \n", + "\n", + "Let's see what `mst_tsp` can do on the USA map:" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nMAzDSMr/BwzNZAmFc5HQAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 17924.5 in 0.004 secs for mst_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(mst_tsp, USA_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Not so great. Can the alteration strategy help?" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def altered_mst_tsp(cities): return alter_tour(mst_tsp(cities))" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\ny0KtgVW7AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "80 city tour with length 14105.0 in 0.022 secs for altered_mst_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(altered_mst_tsp, USA_map)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Better. Let's go to the benchmarks:" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " mst_tsp | 5953 ± 361 ( 5334 to 7030) | 0.002 secs/map | 30 ⨉ 60-city maps\n", + " nn_tsp | 5668 ± 488 ( 4674 to 6832) | 0.001 secs/map | 30 ⨉ 60-city maps\n", + " greedy_tsp | 5392 ± 306 ( 4554 to 5967) | 0.002 secs/map | 30 ⨉ 60-city maps\n", + " dq_tsp | 5268 ± 236 ( 4743 to 5752) | 0.042 secs/map | 30 ⨉ 60-city maps\n" + ] + } + ], + "source": [ + "benchmarks([mst_tsp, nn_tsp, greedy_tsp, dq_tsp])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Not very encouraging: `mst_tsp` is the second slowest and has the longest tours. I'm sure I could make it faster (at the cost of making the code a bit more complicated), but there is no point if the tours are going to be longer. \n", + "\n", + "What happens when we add the alteration strategy?" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " altered_dq_tsp | 4953 ± 221 ( 4575 to 5399) | 0.049 secs/map | 30 ⨉ 60-city maps\n", + " altered_nn_tsp | 4820 ± 233 ( 4450 to 5346) | 0.008 secs/map | 30 ⨉ 60-city maps\n", + " altered_mst_tsp | 4823 ± 227 ( 4354 to 5250) | 0.009 secs/map | 30 ⨉ 60-city maps\n", + " altered_greedy_tsp | 4766 ± 207 ( 4320 to 5185) | 0.009 secs/map | 30 ⨉ 60-city maps\n", + " repeated_altered_nn_tsp | 4640 ± 194 ( 4298 to 4991) | 0.148 secs/map | 30 ⨉ 60-city maps\n" + ] + } + ], + "source": [ + "benchmarks([altered_dq_tsp, altered_nn_tsp, altered_mst_tsp, altered_greedy_tsp, repeated_altered_nn_tsp])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now `altered_mst_tsp` is in the middle of the pack, both in tour length and in run time.\n", + "\n", + "So why would we want to use the rather complicated minimum spanning tree algorithm, when the greedy algorithm is simpler to implement, runs faster, and produces shorter tours?\n", + "\n", + "Guaranteed Tour Length!\n", + "---\n", + "\n", + "The great thing about the minimum spanning tree algorithm is that it comes with a *guarantee*, which none of the other algorithms offer. You are guaranteed that the tour length it comes up with will be no worse than twice as long as the optimal tour. (And, with a bit more complication, you can modify it to give a guarantee of 1.5 times longer.) The guarantee works like this:\n", + "\n", + "1. The minimum spanning tree, by definition, connects all the cities with the shortest possible total edge length.\n", + "2. So if you could follow each edge in the spanning tree just once, and that formed a legal tour, then that would be guaranteed to be\n", + "a minimal tour. \n", + "3. But you can't do that in general; in general there will be places where you skip to the next city without following the spanning tree. Any such skip, however, is a straight line, and thus will be less than you would take if you went to the next city by following along the spanning tree.\n", + "4. If you did follow along the spanning tree, you would follow some edges twice, and some edges once. Hence the total length of the tour would be at most twice the spanning tree, and thus at most twice the minimal tour.\n", + "\n", + "A guarantee is great from a theoretical point of view, but in practice the greedy or nearest neighbor algorithms do just better than the minimum spanning tree, on the maps that we actually see. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Shoulders of Giants: Held-Karp Algorithm: `hk_tsp`\n", + "\n", + "\n", + "\n", + "
Held, Shareshian, Karp (Computer History Museum)
\n", + "\n", + "\n", + "\n", + "
xkcd 399
\n", + "\n", + "Another algorithm that shows up with a literature search is the [Held-Karp Dynamic Programming Algorithm](http://en.wikipedia.org/wiki/Held%E2%80%93Karp_algorithm), named after giants [Michael Held](http://www.computerhistory.org/collections/catalog/102650390) and [Richard Karp](http://en.wikipedia.org/wiki/Richard_M._Karp). It is an algorithm for finding optimal tours, not approximate ones, so it is not appropriate for large *n*. But even in its simplest form, without any programming tricks, it can go quite a bit further than `alltours_tsp`. That is because `alltours_tsp` is O(*n*!), while the Held-Karp algorithm is only O(*n*2 2*n*). How did Held and Karp achieve this speedup? They noticed that `alltours_tsp` wastes a lot of time with permutations that can't possibly be optimal tours. Consider the following 10-city problem, with a 6-city segment shown:" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_labeled_lines(cross, 'r-', [0, 4, 1, 3, 2, 9])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `alltours_tsp` would consider 4! = 24 different tours that start with those 6 cities. But that seems wasteful: there is no way that this segment could be part of an optimal tour, so why waste time on *any* continuation of it? The proof that this segment can never be part of an optimal tour comes down to two things. First, we demonstrate another tour that also starts in city 0 and ends in city 9, and along the way goes through cities 1 through 4, and is shorter:" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_labeled_lines(cross, [0, 1, 2, 3, 4, 9])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Second, we need this key property:\n", + "\n", + ">*Given a start city A, an end city C, and a set of middle cities Bs, then out of all the possible segments that start in A, end in C, and go through all and only the cities in Bs, only the shortest of those segments could ever be part of an optimal tour. \n", + "\n", + "Of course, we don't know that the optimal tour goes through exactly those Bs cities before hitting C. But if it does, then we need only consider the permutation of Bs that leads to the shortest segment. So we can throw out the red zig-zag segment above, and keep the nice smooth blue segment.\n", + "\n", + "So far we have only been talking about segments. We know that the TSP is defined for tours, not segments. So even if we find the shortest possible segment, it might not be the shortest possible tour. But here's something we do know: a tour has to end somewhere. So just find the shortest segment from the start city, `A`, to every possible end city, `C`. That will give you *n*-2 segments. Out of those, don't choose the shortest *segment*, but rather choose the shortest *tour*.\n", + "\n", + "That gives us our algorithm:" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def hk_tsp(cities):\n", + " \"\"\"The H eld-Karpshortest tour of this set of cities.\n", + " For each end city C, find the shortest segment from A (the start) to C.\n", + " Out of all these shortest segments, pick the one that is the shortest tour.\"\"\"\n", + " A = first(cities)\n", + " return shortest_tour(shortest_segment(A, cities - {A, C}, C)\n", + " for C in cities if C is not A)\n", + "\n", + "# TO DO: function: shortest_segment(A, Bs, C)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now for `shortest_segment(A, Bs, C)`. It is defined to produce the shortest segment that starts in city `A`, ends in `C`, and visits some permutation of `Bs` cities in the middle. If there are no `Bs` cities, then of course the shortest segment is to go directly from `A` to `C`. If there are `Bs` cities, then one of them has to be the last `B` city visited (just before visiting `C`). So for each `B`, find the shortest segment that first goes from `A`, through all the other `Bs` cities, then to `B`, and finally to `C`. Out of all these candidate segments, return the one with the minimum segment length.\n", + "\n", + "**Note:** the decorator `@functools.lru_cache` makes this a **dynamic programming** algorithm, which is a fancy name meaning that we cache the results of sub-computations because we will re-use them multiple times." + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "@functools.lru_cache(None)\n", + "def shortest_segment(A, Bs, C):\n", + " \"The shortest segment starting at A, going through all Bs, and ending at C.\"\n", + " if not Bs:\n", + " return [A, C]\n", + " else:\n", + " segments = [shortest_segment(A, Bs - {B}, B) + [C] \n", + " for B in Bs]\n", + " return min(segments, key=segment_length)\n", + " \n", + "def segment_length(segment):\n", + " \"The total of distances between each pair of consecutive cities in the segment.\"\n", + " # Same as tour_length, but without distance(tour[0], tour[-1])\n", + " return sum(distance(segment[i], segment[i-1]) \n", + " for i in range(1, len(segment)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's all there is to it. Let's compare `alltours_tsp` with `hk_tsp` on 10 city tours:" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2291.8 in 1.650 secs for alltours_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(alltours_tsp, Cities(10))" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 city tour with length 2291.8 in 0.037 secs for hk_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(hk_tsp, Cities(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that `hk_tsp` returns the optimal tour, and it is a lot faster. We can take `hk_tsp` into uncharted territory well beyond the reach of `alltours_tsp`:" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "14 city tour with length 2886.6 in 1.464 secs for hk_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(hk_tsp, Cities(14))" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16 city tour with length 2868.6 in 9.018 secs for hk_tsp\n" + ] + } + ], + "source": [ + "plot_tsp(hk_tsp, Cities(16))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Not bad! In 11 seconds, we did what `alltours_tsp` would have taken an estimated 200 days to complete! Let's repeat the table of expected times, comparing the All Tours algorithm with the Held-Karp algorithm:\n", + "\n", + "\n", + "
n `alltours_tsp(Cities(n))``hk_tsp(Cities(n))`\n", + "
expected time ≈ O(n!)expected time ≈ O(n2 2n)\n", + "
10 10! tours = 2 secs 0.1 secs \n", + "
112 secs × 11! / 10! ≈ 22 secs 0.2 secs\n", + "
122 secs × 12! / 10! ≈ 4 mins 0.4 secs\n", + "
142 secs × 14! / 10! ≈ 13 hours 3 secs\n", + "
162 secs × 16! / 10! ≈ 200 days 162 216 tours = 11 secs\n", + "
182 secs × 18! / 10! ≈ 112 years\n", + "11 secs × (18/16)2 2(18-16) ≈ 1 min\n", + "
252 secs × 25! / 10! ≈ 270 billion years\n", + " 11 secs × (25/16)2 2(25-16) ≈ 4 hours\n", + "
502 secs × 50! / 10! ≈ 5 × 1050 years11 secs × (50/16)2 2(50-16) ≈ 58,000 years\n", + "
\n", + "\n", + "So if we had some patience, we could find the optimal tour for a 25 city map, but we still can't handle the 50-city landmarks map.\n", + "(There are refinements to Held-Karp that can handle 50-city maps, and could do it even with 1960s-era computing power.)\n", + "\n", + "We're starting to run out of tricks, but we have one more general strategy to consider." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Ensembles of Other Algorithms: `ensemble_tsp`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When we have several optimization algorithms and we're not sure which is best, we can always try them all and take the best result. We will define `ensemble_tsp`, to combine the algorithms we have previously developed. First, if the set of input cities is small enough, it solves the problem optimally with `hk_tsp`. If the set is too large, it tries a selection of algorithms, and chooses the best resulting tour. The result is guaranteed to be as good or better than any of the component algorithms; but the run time is guaranteed to be longer than any of the component algorithms." + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ensemble = [altered_dq_tsp, altered_greedy_tsp, altered_mst_tsp, repeated_altered_nn_tsp]\n", + "\n", + "def ensemble_tsp(cities, threshold=16, algorithms=ensemble): \n", + " \"Apply all algorithms to cities and take the shortest resulting tour.\"\n", + " if len(cities) <= threshold:\n", + " return hk_tsp(cities)\n", + " else:\n", + " return shortest_tour(tsp(cities) for tsp in algorithms)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's go to the benchmarks:" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " altered_dq_tsp | 4953 ± 221 ( 4575 to 5399) | 0.049 secs/map | 30 ⨉ 60-city maps\n", + " altered_greedy_tsp | 4766 ± 207 ( 4320 to 5185) | 0.009 secs/map | 30 ⨉ 60-city maps\n", + " altered_mst_tsp | 4823 ± 227 ( 4354 to 5250) | 0.009 secs/map | 30 ⨉ 60-city maps\n", + " repeated_altered_nn_tsp | 4640 ± 194 ( 4298 to 4991) | 0.148 secs/map | 30 ⨉ 60-city maps\n", + " ensemble_tsp | 4630 ± 187 ( 4298 to 4991) | 0.213 secs/map | 30 ⨉ 60-city maps\n" + ] + } + ], + "source": [ + "benchmarks(ensemble + [ensemble_tsp])" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " altered_dq_tsp | 6771 ± 220 ( 6273 to 7248) | 0.347 secs/map | 30 ⨉ 120-city maps\n", + " altered_greedy_tsp | 6539 ± 240 ( 5994 to 7203) | 0.037 secs/map | 30 ⨉ 120-city maps\n", + " altered_mst_tsp | 6616 ± 213 ( 6268 to 7010) | 0.050 secs/map | 30 ⨉ 120-city maps\n", + " repeated_altered_nn_tsp | 6402 ± 185 ( 6015 to 6779) | 0.701 secs/map | 30 ⨉ 120-city maps\n", + " ensemble_tsp | 6390 ± 184 ( 6015 to 6779) | 1.100 secs/map | 30 ⨉ 120-city maps\n" + ] + } + ], + "source": [ + "benchmarks(ensemble + [ensemble_tsp], Maps(30, 120))" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " altered_dq_tsp | 9750 ± 288 ( 9187 to 10167) | 3.052 secs/map | 10 ⨉ 250-city maps\n", + " altered_greedy_tsp | 9229 ± 261 ( 8723 to 9606) | 0.215 secs/map | 10 ⨉ 250-city maps\n", + " altered_mst_tsp | 9484 ± 142 ( 9190 to 9668) | 0.221 secs/map | 10 ⨉ 250-city maps\n", + " repeated_altered_nn_tsp | 9187 ± 194 ( 8785 to 9390) | 3.524 secs/map | 10 ⨉ 250-city maps\n", + " ensemble_tsp | 9153 ± 216 ( 8723 to 9390) | 6.959 secs/map | 10 ⨉ 250-city maps\n" + ] + } + ], + "source": [ + "benchmarks(ensemble + [ensemble_tsp], Maps(10, 250))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So the `ensemble_tsp` returns tours that are shortest, but the run time is slowest, as expected. It improves on `repeated_altered_nn_tsp` by less than 1%." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Further Explorations\n", + "\n", + "\n", + "That's all I'm going to write for now. But there are still plenty of open questions for you to explore:\n", + "\n", + "* **Branch and Cut**: this is a technique to cut off a search early, when a partial solution is obviously not optimal. We saw how Held-Karp cuts off some permutations of cities when another permutation is better. A refinement on that is to keep track of, say, the best total length of the segment going through all the Bs cities. Then, any time you have a partial segment through some of the Bs cities that exceeds the best total, we can stop right there, before even finishing all the Bs. With this technique, you can find optimal tours for around 50 cities.\n", + "* **Linear programming**: Lookup the topic \"linear programming\" and see how it applies to TSP.\n", + "* **Heuristic Algorithms**: There are many approaches for using heurisitic estimates to find good (but not optimal) tours. For example, *ant colony optimization algorithms* make random choices of which edge to follow, and then the edges that occur in the best tours get reinforced with some virtual pheromones, and other ants tend to follow those pheromones. *Simulated annealing* takes its inspiration from metallurgy.\n", + "* The **[Lin-Kernighan heuristic](http://akira.ruc.dk/~keld/research/LKH/LKH-1.3/DOC/LKH_REPORT.pdf)** is one of the best.\n", + "* The **[Christofides algorithm](https://en.wikipedia.org/wiki/Christofides_algorithm)** gives a guarantee of 3/2 the optimal tour length (improving on the minimum-spanning-tree guarantee).\n", + "* `altered` as a function: we defined a lot of one-line functions that just called another algorithm, and then calls `alter_tour` on the result. Can you write a function, `altered(func)`, which takes a TSP algorithm as argument, and returns a TSP algorithm that does the original algorithm and then calls `alter_tour`?\n", + "* Why does `mst` produce an optimal result, while `greedy_tsp` does not, even though the two algorithms have similar structure in the way they iterate over `shortest_edges_first`?\n", + "* The code in this notebook was designed for clarity, not efficiency. Can you make the code faster?\n", + "* [William Cook](http://www.math.uwaterloo.ca/tsp/) maintains a great page on the TSP.\n", + "* William Cook also has a [draft chapter](http://www.math.uwaterloo.ca/~bico/papers/comp_chapter1.pdf) on Discrete Optimization featuring TSP. Like my notebook here, Cook goes through a variety of algorithms for TSP, describing each one in prose and in concise, elegant code. The difference is that his code is in C and has an imperative style, while mine is in Python and is largely functional. His code is much more efficient, but if it is 100 times faster, that might only mean two more cities, so the algorithms are more important than the efficiency of the implemenation details. (Also, Cook chooses a different set of algorithms to explore.) I find his explanation very beautiful and concise, and I think it is very interesting that\n", + "there can be two quite different approaches, which (in my opinion) both turn out very well. \n", + "* If you are heavily into math, there's a [taxonomy](http://cstheory.stackexchange.com/questions/9241/approximation-algorithms-for-metric-tsp) of solutions.\n", + "* What else are you interested in?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/WWW.ipynb b/pytudes/ipynb/WWW.ipynb new file mode 100644 index 0000000..b222814 --- /dev/null +++ b/pytudes/ipynb/WWW.ipynb @@ -0,0 +1,871 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# WWW: Will the Warriors Win?\n", + "\n", + "## 18 April 2016\n", + "\n", + "The Golden State Warriors have had a historic basketball season, winning more games than any other team ever has. But will they top that off by winning the championship? There are 15 other teams in contention, including one, the Spurs, that has had a historic season as the best second-best team ever. The web site fivethirtyeight, using a complicated scoring system, [gives](http://projects.fivethirtyeight.com/2016-nba-picks/) the Warriors a 44% chance of winning, with the Spurs at 28%. Basketball-reference [has](http://www.basketball-reference.com/friv/playoff_prob.cgi) the Warriors at 41% and Spurs at 32.5%, while a [betting site](http://www.oddsshark.com/nba/nba-futures) had the Warriors at 54% and Spurs at 18%. But what's a good way to make a prediction? There are several choices:\n", + "\n", + "- Subjective impression of a team's strength? Or a statistical model?\n", + "- Predictions based on:\n", + " - Holistic impression of entire postseason (e.g. \"I think the Warriors have a 50% chance of winning it all\")\n", + " - Series by series (e.g. \"I think the Warriors have a 95% chance of beating the Rockets in the first round, then ...\")\n", + " - Game by game (e.g. \"I think the Warriors have a 83% chance of beating the Rockets in Game 1, then ...\")\n", + " - Possession by possession (e.g. simulate games basket by basket, based on past stats)\n", + " \n", + "Here are the top four teams with their Won-Loss percentage and [SRS](http://www.basketball-reference.com/blog/?p=39) (Simple rating system: average margin of victory, adjusted for strength of opponents):\n", + "\n", + " TEAM PCT SRS\n", + " Warriors .890 10.38\n", + " Spurs .817 10.28\n", + " Thunder .671 7.09\n", + " Cavaliers .695 5.45\n", + "\n", + "I decided to go with a subjective impression of one team beating another in a single game. For example, I might think that the Warriors have a 58% chance of beating the Cavaliers in any one game, and from that compute the odds of winning a series:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def win_series(p, W=0, L=0):\n", + " \"Probability of winning best-of-7 series, given a probability p of winning a game.\"\n", + " return (1 if W == 4 else\n", + " 0 if L == 4 else\n", + " p * win_series(p, W + 1, L) +\n", + " (1 - p) * win_series(p, W, L + 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6705883933696" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "win_series(0.58)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In other words, if you have a 58% chance of winning a game, you have a 67% chance of winning the series.\n", + "\n", + "Note that I ignore the fact that games aren't strictly independent; I ignore home court advantage; and I ignore the chance of catastrophic injuries. Why? Because all these factors would change the final winning estimate by only a few percentage points, and I already have more uncertainty than that.\n", + "\n", + "Note that `win_series` takes optional arguments to say how many games in the sries have been won and lost so far. Here's a table showing your chance of winning a series, given the current tally of games won and lost on the left, and your expected percentage of winning a game at the top:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def percents(items, fmt='{:4.0%}'): return ' '.join(fmt.format(item) for item in items)\n", + "\n", + "def series_table(pcts=[p/100 for p in range(20, 81, 5)]):\n", + " print('W-L | Singe Game Win Percentage')\n", + " print(' | ' + percents(pcts))\n", + " for W in range(4):\n", + " print('----+' + '-' * 5 * len(pcts))\n", + " for L in reversed(range(4)):\n", + " results = [win_series(p, W, L) for p in pcts]\n", + " print('{}-{} | {}'.format(W, L, percents(results)))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "W-L | Singe Game Win Percentage\n", + " | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n", + "----+-----------------------------------------------------------------\n", + "0-3 | 0% 0% 1% 2% 3% 4% 6% 9% 13% 18% 24% 32% 41%\n", + "0-2 | 1% 2% 3% 5% 9% 13% 19% 26% 34% 43% 53% 63% 74%\n", + "0-1 | 2% 4% 7% 12% 18% 26% 34% 44% 54% 65% 74% 83% 90%\n", + "0-0 | 3% 7% 13% 20% 29% 39% 50% 61% 71% 80% 87% 93% 97%\n", + "----+-----------------------------------------------------------------\n", + "1-3 | 1% 2% 3% 4% 6% 9% 12% 17% 22% 27% 34% 42% 51%\n", + "1-2 | 3% 5% 8% 13% 18% 24% 31% 39% 48% 56% 65% 74% 82%\n", + "1-1 | 6% 10% 16% 24% 32% 41% 50% 59% 68% 76% 84% 90% 94%\n", + "1-0 | 10% 17% 26% 35% 46% 56% 66% 74% 82% 88% 93% 96% 98%\n", + "----+-----------------------------------------------------------------\n", + "2-3 | 4% 6% 9% 12% 16% 20% 25% 30% 36% 42% 49% 56% 64%\n", + "2-2 | 10% 16% 22% 28% 35% 43% 50% 57% 65% 72% 78% 84% 90%\n", + "2-1 | 18% 26% 35% 44% 52% 61% 69% 76% 82% 87% 92% 95% 97%\n", + "2-0 | 26% 37% 47% 57% 66% 74% 81% 87% 91% 95% 97% 98% 99%\n", + "----+-----------------------------------------------------------------\n", + "3-3 | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n", + "3-2 | 36% 44% 51% 58% 64% 70% 75% 80% 84% 88% 91% 94% 96%\n", + "3-1 | 49% 58% 66% 73% 78% 83% 88% 91% 94% 96% 97% 98% 99%\n", + "3-0 | 59% 68% 76% 82% 87% 91% 94% 96% 97% 98% 99% 100% 100%\n" + ] + } + ], + "source": [ + "series_table()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And here's a function to tabulate the chances of winning each series on the way to a title:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def playoffs(name, rounds):\n", + " \"Print probability for team winning each series.\"\n", + " overall = (1, 1, 1) # (lo, med, hi) probabilities of winning it all\n", + " for (opponent, probs) in rounds:\n", + " this_round = [win_series(p) for p in probs]\n", + " overall = [overall[i] * this_round[i] for i in range(len(probs))]\n", + " print('{} vs {:8} win this round: {}; win through here: {}'.format(\n", + " name, opponent, percents(this_round), percents(overall)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I enter my subjective probability estimates (low, medium, and high), and likely opponents for each round, for the three top contenders:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: 93% 98% 99%; win through here: 93% 98% 99%\n", + "Warriors vs Clippers win this round: 83% 91% 97%; win through here: 77% 89% 95%\n", + "Warriors vs Spurs win this round: 39% 67% 87%; win through here: 30% 60% 83%\n", + "Warriors vs Cavs win this round: 71% 83% 93%; win through here: 22% 50% 78%\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.75, 0.83, 0.85)),\n", + " ('Clippers', (0.67, 0.73, 0.80)),\n", + " ('Spurs', (0.45, 0.58, 0.70)),\n", + " ('Cavs', (0.60, 0.67, 0.75))])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Spurs vs Memphis win this round: 93% 98% 99%; win through here: 93% 98% 99%\n", + "Spurs vs Thunder win this round: 39% 75% 87%; win through here: 36% 73% 86%\n", + "Spurs vs Warriors win this round: 13% 33% 61%; win through here: 5% 24% 53%\n", + "Spurs vs Cavs win this round: 71% 83% 93%; win through here: 3% 20% 49%\n" + ] + } + ], + "source": [ + "playoffs('Spurs',\n", + " [('Memphis', (0.75, 0.83, 0.85)),\n", + " ('Thunder', (0.45, 0.62, 0.70)),\n", + " ('Warriors', (0.30, 0.42, 0.55)),\n", + " ('Cavs', (0.60, 0.67, 0.75))])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cavs vs Pistons win this round: 93% 98% 99%; win through here: 93% 98% 99%\n", + "Cavs vs Hawks win this round: 39% 71% 93%; win through here: 36% 70% 92%\n", + "Cavs vs Raptors win this round: 29% 61% 80%; win through here: 11% 42% 73%\n", + "Cavs vs GSW/SAS win this round: 7% 17% 29%; win through here: 1% 7% 21%\n" + ] + } + ], + "source": [ + "playoffs('Cavs',\n", + " [('Pistons', (0.75, 0.83, 0.85)),\n", + " ('Hawks', (0.45, 0.60, 0.75)),\n", + " ('Raptors', (0.40, 0.55, 0.65)),\n", + " ('GSW/SAS', (0.25, 0.33, 0.40))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I have the Warriors at 50% (for the medium estimate of winning it all) and the Spurs at 20%, so I'm more of a Warriors fan than fivethirtyeight and basketball-reference, but I have very wide margins between my low and high estimate: 22% to 78% for the Warriors; 3% to 49% for the Spurs; 1% to 21% for the Cavs. Interestingly, while fivethirtyeight does not think this year's Warriors are better than the 1995 Bulls, they [do think](http://fivethirtyeight.com/features/the-warriors-still-arent-the-best-team-ever/) the Spurs, Thunder, and Cavs are the best ever second-, third-, and fourth-best teams in a season.\n", + "\n", + "\n", + "\n", + "What's better--a holistic guess at the outcome, or a reductionist model like this one? I can't say that one is better than the other in every case, but it can be instructive to examine the cases where the reductionist model differs from your holistic impressions. For example, look at the low end of my prediction for the Spurs. I feel like it is crazy to say the Spurs only have a 3% chance of winning the title, but I don't feel that any of the individual game win probabilities (75%, 45%, 30%, and 60%, respectively) are crazy. So now I know that at least one of my intutions is wrong. But I'm not sure how to reconcile the mismatch..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# WWWWC: Will Warriors Win Without Curry?\n", + "\n", + "## 27 April 2016\n", + "\n", + "The Playoff picture has changed! \n", + "\n", + "We have some results for first-round series, and there have been key injuries to players including Steph Curry, Avery Bradley, Chris Paul, and Blake Griffin. To update, first I make a small alteration to allow the current state of a series in terms of wins/loses to be specified as part of the input to `playoffs`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def playoffs(name, rounds):\n", + " \"Print probability for team winning each series.\"\n", + " overall = (1, 1, 1) # (lo, med, hi) probabilities of winning it all\n", + " for (opponent, probs, *args) in rounds:\n", + " this_round = [win_series(p, *args) for p in probs]\n", + " overall = [overall[i] * this_round[i] for i in range(len(probs))]\n", + " print('{} vs {:8} win this round: ({}) win through here: ({})'.format(\n", + " name, opponent, percents(this_round), percents(overall)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We don't know for sure how long Curry will be out, but here are my updated odds for the Warriors, with the middle probability value representing the assumption that Curry misses the second round, and comes back in time for the Western Conference Finals at a mildly reduced capacity; the low and high probability values represent more and less severe injuries:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: ( 88% 97% 99%) win through here: ( 88% 97% 99%)\n", + "Warriors vs Blazers win this round: ( 39% 61% 83%) win through here: ( 34% 59% 83%)\n", + "Warriors vs Spurs win this round: ( 13% 61% 83%) win through here: ( 4% 36% 69%)\n", + "Warriors vs Cavs win this round: ( 29% 71% 87%) win through here: ( 1% 26% 60%)\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.50, 0.70, 0.80), 3, 1),\n", + " ('Blazers', (0.45, 0.55, 0.67)),\n", + " ('Spurs', (0.30, 0.55, 0.67)),\n", + " ('Cavs', (0.40, 0.60, 0.70))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Spurs and Cavs are rolling; let's update their odds:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Spurs vs Memphis win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Spurs vs Thunder win this round: ( 39% 75% 87%) win through here: ( 39% 75% 87%)\n", + "Spurs vs Warriors win this round: ( 17% 39% 87%) win through here: ( 7% 29% 76%)\n", + "Spurs vs Cavs win this round: ( 71% 83% 93%) win through here: ( 5% 24% 71%)\n" + ] + } + ], + "source": [ + "playoffs('Spurs',\n", + " [('Memphis', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Thunder', (0.45, 0.62, 0.70)),\n", + " ('Warriors', (0.33, 0.45, 0.70)),\n", + " ('Cavs', (0.60, 0.67, 0.75))])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Hawks win this round: ( 39% 71% 93%) win through here: ( 39% 71% 93%)\n", + "Cavs vs Raptors win this round: ( 29% 61% 80%) win through here: ( 11% 43% 74%)\n", + "Cavs vs GSW/SAS win this round: ( 13% 29% 71%) win through here: ( 1% 13% 53%)\n" + ] + } + ], + "source": [ + "playoffs('Cavs',\n", + " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Hawks', (0.45, 0.60, 0.75)),\n", + " ('Raptors', (0.40, 0.55, 0.65)),\n", + " ('GSW/SAS', (0.30, 0.40, 0.60))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So my updated odds are that the Warriors and Spurs are roughly equally likely to win (26% and 24%); the Cavs are still less likely (13%), and there is more uncertainty.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# WWWWCB: Will Warriors Win With Curry Back?\n", + "\n", + "## 10 May 2016\n", + "\n", + "Curry has returned from his injury, and after a slow shooting start, had the highest-scoring overtime period in the history of the NBA. Meanwhile, the Thunder lead the Spurs, 3-2, and the Cavaliers have been dominant in the East, hitting a historic number of 3-point shots. Here is my revised outlook: " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Blazers win this round: ( 91% 96% 98%) win through here: ( 91% 96% 98%)\n", + "Warriors vs Spurs win this round: ( 39% 71% 83%) win through here: ( 36% 68% 82%)\n", + "Warriors vs Cavs win this round: ( 29% 61% 83%) win through here: ( 10% 42% 68%)\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n", + " ('Blazers', (0.55, 0.67, 0.75), 3, 1),\n", + " ('Spurs', (0.45, 0.60, 0.67)),\n", + " ('Cavs', (0.40, 0.55, 0.67))])" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Spurs vs Memphis win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Spurs vs Thunder win this round: ( 16% 36% 49%) win through here: ( 16% 36% 49%)\n", + "Spurs vs Warriors win this round: ( 17% 29% 61%) win through here: ( 3% 10% 30%)\n", + "Spurs vs Cavs win this round: ( 29% 50% 87%) win through here: ( 1% 5% 26%)\n" + ] + } + ], + "source": [ + "playoffs('Spurs',\n", + " [('Memphis', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Thunder', (0.40, 0.60, 0.70), 2, 3),\n", + " ('Warriors', (0.33, 0.40, 0.55)),\n", + " ('Cavs', (0.40, 0.50, 0.70))])" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Thunder vs Dallas win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Thunder vs Spurs win this round: ( 51% 64% 84%) win through here: ( 51% 64% 84%)\n", + "Thunder vs Warriors win this round: ( 17% 29% 61%) win through here: ( 9% 19% 51%)\n", + "Thunder vs Cavs win this round: ( 20% 39% 71%) win through here: ( 2% 7% 36%)\n" + ] + } + ], + "source": [ + "playoffs('Thunder',\n", + " [('Dallas', (0.75, 0.83, 0.85), 4, 1),\n", + " ('Spurs', (0.30, 0.40, 0.60), 3, 2),\n", + " ('Warriors', (0.33, 0.40, 0.55)),\n", + " ('Cavs', (0.35, 0.45, 0.60))])" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Raptors win this round: ( 50% 80% 93%) win through here: ( 50% 80% 93%)\n", + "Cavs vs GS/SA/OK win this round: ( 17% 39% 61%) win through here: ( 8% 31% 57%)\n" + ] + } + ], + "source": [ + "playoffs('Cavs',\n", + " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n", + " ('Raptors', (0.50, 0.65, 0.75)),\n", + " ('GS/SA/OK', (0.33, 0.45, 0.55))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So overall, from the start of the playoffs up to May 10th, I have:\n", + "\n", + "- **Warriors:** Dropped from 50% to 26% with Curry's injury, and rebounded to 42%. \n", + "- **Spurs:** Dropped from 20% to 5% after falling behind Thunder.\n", + "- **Thunder:** Increased to 7%.\n", + "- **Cavs:** Increased to 31%.\n", + "\n", + "# Time to Panic?\n", + "\n", + "## 17 May 2016\n", + "\n", + "The Thunder finished off the Spurs and beat the Warriors in game 1. Are the Thunder, like the Cavs, peaking at just the right time, after an inconsistent regular season? Is it time for Warriors fans to panic?\n", + "\n", + "Sure, the Warriors were down a game twice in last year's playoffs and came back to win both times. Sure, the Warriors are still 3-1 against the Thunder this year, and only lost two games all season to elite teams (Spurs, Thunder, Cavs, Clippers, Raptors). But the Thunder are playing at a top level. Here's my update, showing that the loss cost the Warriors 5%:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Thunder win this round: ( 26% 61% 74%) win through here: ( 26% 61% 74%)\n", + "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 7% 37% 60%)\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n", + " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n", + " ('Thunder', (0.45, 0.63, 0.70), 0, 1),\n", + " ('Cavs', (0.40, 0.55, 0.65))])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Not Yet?\n", + "\n", + "## 18 May 2016\n", + "\n", + "The Warriors won game two of the series, so now they're back up to 45%, with the Cavs at 35%. At this time, [fivethirtyeight](http://projects.fivethirtyeight.com/2016-nba-picks/) has the Warriors at 45%, Cavs at 28% and Thunder at 24%" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Thunder win this round: ( 41% 73% 84%) win through here: ( 41% 73% 84%)\n", + "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 12% 45% 67%)\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n", + " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n", + " ('Thunder', (0.45, 0.63, 0.70), 1, 1),\n", + " ('Cavs', (0.40, 0.55, 0.65))])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Raptors win this round: ( 66% 88% 96%) win through here: ( 66% 88% 96%)\n", + "Cavs vs GSW win this round: ( 20% 39% 71%) win through here: ( 13% 35% 68%)\n" + ] + } + ], + "source": [ + "playoffs('Cavs',\n", + " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n", + " ('Raptors', (0.50, 0.65, 0.75), 1, 0),\n", + " ('GSW', (0.35, 0.45, 0.60))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Yet!\n", + "\n", + "## 24 May 2016\n", + "\n", + "The Thunder won two in a row (first time the Warriors had lost two in a row all year), putting the Warriors down 3-1. And the Cavs are looking mortal, losing two to the Raptors. So now it looks to me like the Thunder are favorites to win it all:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Thunder win this round: ( 2% 17% 27%) win through here: ( 2% 17% 27%)\n", + "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 0% 10% 22%)\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n", + " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n", + " ('Thunder', (0.25, 0.55, 0.65), 1, 3),\n", + " ('Cavs', (0.40, 0.55, 0.65))])" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Raptors win this round: ( 50% 57% 78%) win through here: ( 50% 57% 78%)\n", + "Cavs vs Thunder win this round: ( 20% 39% 71%) win through here: ( 10% 23% 56%)\n" + ] + } + ], + "source": [ + "playoffs('Cavs',\n", + " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n", + " ('Raptors', (0.50, 0.55, 0.70), 2, 2),\n", + " ('Thunder', (0.35, 0.45, 0.60))])" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Thunder vs Dallas win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Thunder vs Spurs win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Thunder vs Warriors win this round: ( 73% 83% 98%) win through here: ( 73% 83% 98%)\n", + "Thunder vs Cavs win this round: ( 29% 61% 80%) win through here: ( 21% 51% 79%)\n" + ] + } + ], + "source": [ + "playoffs('Thunder',\n", + " [('Dallas', (0.75, 0.83, 0.85), 4, 1),\n", + " ('Spurs', (0.30, 0.40, 0.60), 4, 2),\n", + " ('Warriors', (0.35, 0.45, 0.75), 3, 1),\n", + " ('Cavs', (0.40, 0.55, 0.65))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# But Not Done Yet\n", + "\n", + "## 26 May 2016\n", + "\n", + "The Warriors won game 5, bringing them up from a 10% to an 18% chance of winning it all:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Warriors vs Thunder win this round: ( 12% 30% 42%) win through here: ( 12% 30% 42%)\n", + "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 4% 18% 34%)\n" + ] + } + ], + "source": [ + "playoffs('Warriors',\n", + " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n", + " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n", + " ('Thunder', (0.35, 0.55, 0.65), 2, 3),\n", + " ('Cavs', (0.40, 0.55, 0.65))])" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Cavs vs Raptors win this round: ( 75% 80% 91%) win through here: ( 75% 80% 91%)\n", + "Cavs vs Thunder win this round: ( 20% 39% 71%) win through here: ( 15% 31% 65%)\n" + ] + } + ], + "source": [ + "playoffs('Cavs',\n", + " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n", + " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n", + " ('Raptors', (0.50, 0.55, 0.70), 3, 2),\n", + " ('Thunder', (0.35, 0.45, 0.60))])" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Thunder vs Dallas win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Thunder vs Spurs win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n", + "Thunder vs Warriors win this round: ( 58% 70% 94%) win through here: ( 58% 70% 94%)\n", + "Thunder vs Cavs win this round: ( 29% 61% 80%) win through here: ( 17% 42% 75%)\n" + ] + } + ], + "source": [ + "playoffs('Thunder',\n", + " [('Dallas', (0.75, 0.83, 0.85), 4, 1),\n", + " ('Spurs', (0.30, 0.40, 0.60), 4, 2),\n", + " ('Warriors', (0.35, 0.45, 0.75), 3, 2),\n", + " ('Cavs', (0.40, 0.55, 0.65))])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# The Finals\n", + "\n", + "## 1 June 2016\n", + "\n", + "The Warriors completed their comeback against the Thunder, putting them in a great position to win this year (and they are already established as [favorites for next year](http://www.foxsports.com/nba/story/golden-state-warriors-title-favorites-cleveland-cavaliers-odds-2016-17-053016)). Rather than update the odds after each game 0f the finals, I'll just repeat the table (with the note that I think the Warriors are somewhere in the 60% range for each game):\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "W-L | Singe Game Win Percentage\n", + " | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n", + "----+-----------------------------------------------------------------\n", + "0-3 | 0% 0% 1% 2% 3% 4% 6% 9% 13% 18% 24% 32% 41%\n", + "0-2 | 1% 2% 3% 5% 9% 13% 19% 26% 34% 43% 53% 63% 74%\n", + "0-1 | 2% 4% 7% 12% 18% 26% 34% 44% 54% 65% 74% 83% 90%\n", + "0-0 | 3% 7% 13% 20% 29% 39% 50% 61% 71% 80% 87% 93% 97%\n", + "----+-----------------------------------------------------------------\n", + "1-3 | 1% 2% 3% 4% 6% 9% 12% 17% 22% 27% 34% 42% 51%\n", + "1-2 | 3% 5% 8% 13% 18% 24% 31% 39% 48% 56% 65% 74% 82%\n", + "1-1 | 6% 10% 16% 24% 32% 41% 50% 59% 68% 76% 84% 90% 94%\n", + "1-0 | 10% 17% 26% 35% 46% 56% 66% 74% 82% 88% 93% 96% 98%\n", + "----+-----------------------------------------------------------------\n", + "2-3 | 4% 6% 9% 12% 16% 20% 25% 30% 36% 42% 49% 56% 64%\n", + "2-2 | 10% 16% 22% 28% 35% 43% 50% 57% 65% 72% 78% 84% 90%\n", + "2-1 | 18% 26% 35% 44% 52% 61% 69% 76% 82% 87% 92% 95% 97%\n", + "2-0 | 26% 37% 47% 57% 66% 74% 81% 87% 91% 95% 97% 98% 99%\n", + "----+-----------------------------------------------------------------\n", + "3-3 | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n", + "3-2 | 36% 44% 51% 58% 64% 70% 75% 80% 84% 88% 91% 94% 96%\n", + "3-1 | 49% 58% 66% 73% 78% 83% 88% 91% 94% 96% 97% 98% 99%\n", + "3-0 | 59% 68% 76% 82% 87% 91% 94% 96% 97% 98% 99% 100% 100%\n" + ] + } + ], + "source": [ + "series_table()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/dist-climb-time.csv b/pytudes/ipynb/dist-climb-time.csv new file mode 100644 index 0000000..c6f9ff8 --- /dev/null +++ b/pytudes/ipynb/dist-climb-time.csv @@ -0,0 +1 @@ +5092,20.9,1360 13902.6,50,3183 4239.4,34,1011 14146.5,71,3407 1728,0,341 9595.8,58.6,1866 49571.4,377,8491 35040.3,113,6300 30775,60,5671 10246.2,41,1976 27850.7,67,5010 38901.6,69,7097 109988,1868.4,22392 32369.6,85,5723 40331.7,81,7573 40767.3,209,7162 1325.3,1,246 18910.7,43,3471 44109.3,86,7399 72041.9,194,11428 3683.3,8,672 62921,950,12532 38522.8,81,6817 33413.1,80,5413 32539.5,63,5828 38397.7,186,6436 21211.6,54,3526 48657.5,124,8447 40202.8,71,6669 42429,151,7301 11228.3,28,1915 24194.9,69,4318 12900.4,24,2016 15412.6,120,2305 19762.3,51,3504 1508.1,0,249 65299.3,158,10478 67507.3,876,13065 16946.2,77,2962 33243.3,112,5498 68070.4,680,13021 40093.5,196,6935 21359.9,54,3585 16272.9,58,2737 25929.6,66,4315 35441.9,127,6007 48548.5,183,8293 49959.7,417,8345 69561.3,1388,15231 0.2,0,1 8300,24,1390 8237,15,1434 26401.3,69,4627 8168,14,1380 52829.7,522,10629 90544,420,14305 23826.4,47,4256 21086.4,94,3688 39275.8,96,6794 38191.9,176,6345 22013.5,54,3740 42223.2,347,7006 65702,192,10873 33739.4,123,5642 21822.6,56,3837 48156.2,141,8536 17929.1,36,3193 64814.1,828,13178 66246.4,662,11974 83721.1,530,13959 0,0,11 65020.5,490,10428 83146.7,537,13594 17641.1,59,3075 42280.8,117,7278 49080.6,212,8387 96739.2,441,16418 112767,774,19010 41312.9,79,6969 32162.6,66,5377 33011.5,88,5915 15596.3,34,2551 50336.6,180,8616 32474.4,170,5403 28057,168,4916 23086.7,45,3707 43936.7,163,7637 72673.5,437,12868 72616,571,11927 49429.1,142,7957 80494.5,487,13948 26072.9,23.9,2108 32420.7,199,5635 19073.9,35,3322 49665,330,8026 34703.7,622,8248 9267.8,370,3502 8305.9,16,1279 32831.9,329,6889 56756.1,814,10380 33488.7,167,5813 36365.8,78,6147 33074.1,79,5575 64424.1,575,11041 64547.7,650,11491 2859.7,4,696 61900.6,321,10442 21655.9,43,3932 19244.1,38,3475 1354,5,369 59636.6,446,9253 52398.9,721,11092 22230.9,48,3773 33055.3,73,5556 54726.3,354,8969 7160.3,14,1326 58262.9,878,11317 29205,59,5105 33279.9,80,5748 38607.9,79,6432 73392.1,420,11051 26514.8,173,5638 48349.1,158,8337 34877.5,121,5978 80676.8,563,12721 22651.4,55,3744 27670.4,191,4888 17636.8,71,2876 51046.6,388,8626 30042.8,110,4658 54232.7,663,9899 24780,50,4293 65700.3,508,10326 34360.6,111,5877 27519.4,58,4746 84482.6,385,13108 7046.2,124,1453 29369.4,311,5233 31900.4,233,4671 47932.3,157,8155 32291.4,97,4985 62318.2,671,11662 17393.4,28,3106 12934.2,23,2189 19439.3,43,3300 32342.4,80,5424 33504.2,116,5455 64917.8,518,9693 9168.5,0,2427 5490.9,0,1274 1815,0,450 1566.9,0,325 81511.6,417,12496 40274.7,77,6450 48466.7,100,8391 32327.9,67,5379 34313.4,118,5611 4852.9,5,809 4003.1,10,699 64600.5,337,9666 4972.8,7,964 54646.6,419,8717 15142.8,107,2586 50941.5,726,8806 17622.9,20,3059 14987.3,38,2656 45143.8,84,7847 37883.4,82,6561 41869.6,197,6885 2909.7,5,696 128861,1840.7,27038 33671.9,76,5691 32367.1,97,5064 30664.4,111.5,6983 70708.5,408,10402 34208.1,153,6044 50046.8,168,8164 27035.1,75,4557 21870.6,78,3536 57424.6,227,9424 17102,218,3305 50667.6,459,8446 43844.1,146,7467 35509.1,132,5633 29458.2,204,5039 25335.3,53,4294 39604.9,230,6757 78509.9,1005.9,14584 25583,221,4460 43220,331,7004 38660.5,158,6438 35590.3,91,6511 24214.5,62,4284 40242.2,275,6176 24288.2,51,4087 8119.4,12,1667 54157.6,851,11248 33391.6,103,5615 1731.4,4,625 14488.5,5,4622 12931.9,19,4623 19671.6,3,6864 21323,26,7314 24358.2,60,4076 34266.7,112,5832 52480.8,108,9135 57017.8,411,8421 4547.7,9,872 76487.7,650,12624 32234.7,105,5277 42221.6,217,7086 26164.2,100,4212 7646.2,15,1097 25250.3,60,4374 23113.3,120,4018 8740.4,8,1561 34901.9,60,6499 88119.1,1611.3,16212 6387.2,51,1161 119660,2014.6,24254 25061.3,62,4305 18813.5,59,3251 18255.7,41,3217 40512,129,6758 66298.8,465,9778 23189.3,57,3702 18581,44,3180 42637,201,6947 9042.8,18,1479 8365.1,23,1326 7424.3,13,1345 15483.5,41,2575 25959,110,4217 36353.3,297.8,5620 55027.4,853,10215 26839.5,162,4649 8236.9,14,1300 16276.6,31,2776 8763,15,1385 27597.3,60,4165 7951.3,14,1129 22357.5,72,3690 14552.3,16,2389 18398.2,58,3168 8243.6,16,1342 77980.6,324,12650 24063.2,203,4107 10192.1,17,1744 3946.9,8,609 21610.1,69,3593 8824.6,11,1369 27286.8,156,4466 8190.7,13,1224 1683.8,6,345 8905.6,80,1490 17897.8,53,2879 8337.6,14,1375 32768.6,81,4876 93721.9,1232,13823 32419,99,4967 26123.5,156,4342 8645,8,1383 32184.2,117,5195 8241.7,13,1294 28078.8,212,4607 16656,54,2805 22401.7,30,3375 28791.7,76,5348 33602.8,112,5325 72761,607,12200 2901.5,6,575 38062.6,257,6482 42240.4,152,6736 42483.2,171,6573 42279.7,174,6931 81722,360,11793 40401.8,173,6283 40410.1,190,5725 32810.6,54,5203 8554.7,19,1340 45050.9,114,7240 32335.2,69,5306 10338.3,16,1622 44697.8,162,6733 40308,118,6565 101134,974,15698 6199.1,41,1156 32917.6,91,5153 42628,182,6499 56628.6,326,9673 32068.1,116,5053 8210.9,14,1433 47801.2,394,8282 40547.7,281,7043 42453.6,153,7017 16806.5,34,2509 17838.9,33,2851 38779.4,179,6400 34223.2,98,5279 59031.7,406,7940 42557.2,63,7034 30057.6,125,4886 42068.8,286,6776 22912.5,48,3591 10109.2,10,1668 45221.4,168,7615 67573.2,516,10551 58289.2,139,9663 29634.4,150,4974 18914.5,38,3085 8982.4,18,1466 8261.7,14,1208 22347.2,37,3613 18427.2,45,2900 8550.7,21,1398 8427.9,16,1248 26035.6,52,4211 63842,1639,20457 35496.6,349,6691 9699.5,15,1599 23208.6,29,4220 9677.1,32,1875 8085.8,14,1571 12882.8,39,2199 8621.9,15,1393 42704.4,285,6608 124281,1278,20170 21222.5,32,3376 20482.4,44,3395 18925.1,43,3151 97127,1387,18641 96758.6,1446,17860 21613.5,42,3895 29219.8,315,5005 10717.5,24,1770 8017.2,12,1113 25359.6,63,4063 22345,43,3691 47179.4,247,7418 38245.6,310,5473 21046.1,42,3469 26056.6,169,4637 17538,37,2902 10364.1,22,1747 8178.6,13,1215 12828.8,38,2247 8210.2,11,1264 69504.8,967,13017 19405.9,45,3347 77144.9,743,13193 16012.5,37,2737 17694.5,33,2874 25674.4,751.9,6642 5441.8,30,1001 0.4,0,6 32364.4,98,5355 16440.4,28,2686 24870.4,42,3976 18074.4,51,3094 8319.1,13,1421 50529.4,365,7801 15959.1,33,2746 19148.7,59.6,3131 19148.7,39,3131 52884.3,782,10674 17810.5,39,3069 20238.7,49,3483 16675.1,33,2679 43341,257,6214 53943.9,611,10035 16466.5,32,2611 16886.7,28,2817 21177.4,41,3628 31437.3,107,5027 17930.2,38,2917 16666.3,35,2830 34369.3,246,5370 11639.4,22,1848 8321,14,1177 21173.2,48,3262 10205.6,29,1896 8078.4,15,1102 40073.2,380,6449 59353.1,410,9097 18238.6,55,2976 1783.9,3,368 7967.9,15,1352 22521,57,3638 33117.8,226,5512 60122.6,899,13150 19575.2,40,3069 45942.5,393,7655 22129.5,46,3555 29771.8,209,4428 48716.7,595,8988 32901.9,278,5487 27113.1,188,4830 25207.2,57,4896 1.2,0,5 51867.1,454.6,8696 51867.1,401,8696 19397.8,40,3305 26616.8,190,5017 17583.5,39,3044 35412.9,253,5809 0,0,0 41739.8,277,7137 86689.3,791,14441 28797.4,69,4875 13491.4,36,2345 8983.6,12,1438 15788.4,43,2837 49185.4,437,8180 40950,524,7960 22664.3,52,3826 39810.2,383,6479 55805.8,377,8105 38857.6,298,5798 18136.4,36,3217 16924.7,41,2832 59549.1,1494.1,13248 40743.9,342,6236 26944.1,190,4844 60679.4,955,12569 57512.7,984.5,11681 3968.2,12,757 48545.8,457,8454 105785,1639.9,19780 43648.1,253,7488 21826.9,46,3631 62768.5,687,11371 10003,19,1695 19135.6,70,3179 74903.5,780,13501 18288.4,61,3161 10056.1,21,1943 19320.2,42,3152 40095.1,273.2,6417 40489.6,164,6705 18887.6,33,3209 22153,44,3809 26289,160,4654 10439.3,22,1676 52290,473.2,8435 95116.8,1075.5,18117 4211.9,7,819 63595.4,1373.2,12526 26730.2,60,4202 18138.3,43,3080 33673.2,142,5585 9556.9,13,1442 26015.2,59,4444 69268.3,708,10802 26965,181,4333 9901.1,16,1807 8370.6,12,1446 117439,2330,22075 18813.9,34,3231 24635.8,103,3887 8331.6,12,1387 33829.6,274,5242 21092.3,37,3488 23212.2,37,3793 25881,74,4101 8484.5,245,2124 13053.9,61,2063 72762.6,350,10766 17908.2,37,2970 28249.2,74,4512 13069.3,34,2218 8023.7,15,1343 10963.6,209,2187 27215.3,311.1,5391 39150.4,284,5470 13224.6,39,2340 8202.4,14,1303 24781.5,65,4025 29945,136,4814 8296.9,16,1443 33837.4,120,4989 45892,491,9084 41496.6,351,6571 61480.8,1018.6,11163 27394.8,97,4733 49517.5,316,7783 22863.9,55,4218 63064.4,1082.9,12715 65031.4,360,10978 11975.5,60,1493 5395.3,411.6,1769 2231.1,6,291 40135.4,246,6787 32339.6,147,5977 40008.3,308,6496 106241,1870.6,19131 17503.8,36,2799 5341.5,373,1824 17721.7,174,3132 45630.4,130,7831 51339.3,744.9,8669 35741.5,298,5255 23826.9,82,4185 29882.2,117,4592 52156.4,503,8993 35708.6,179,6387 75831.3,353,12903 47491,237,8038 3067,2,671 45833.8,229,7334 81653.8,404,13314 49342.1,411,8139 33022.6,112,5472 29181.3,93,4359 106755,626,17775 102383,572,17109 39991.1,236,6167 38631.7,189,5666 81950.5,571,13673 81964.8,398.2,13703 26001.1,82,4001 16768.3,56,3371 70200.3,1468.8,14547 18242.7,95,3142 62259.4,191,10545 45339,316,7227 27988.3,115,4864 29434.5,254,5508 71359.3,408,12585 8777.3,17,1769 39723,136,7745 41831.6,153,7356 9101,22,1835 16265.1,41,3003 68065,1000.9,11378 92701.5,390,15200 13401.2,10.1,2361 7942.3,0,1030 35826.2,282,5088 62040.1,221,10270 46466.4,503,7605 51524.9,198,8022 9526.9,19,1260 67075.7,331,9998 5708,8,838 26258.8,196,5262 31559,132,5072 25082,123,4330 9486.8,18,2168 87965.4,837.4,14387 12045.9,155,1941 48776.4,239,7798 15984.5,61,2711 48046.6,782.9,9324 12400.5,122,2656 42646.8,180,7307 50127.1,485,8366 51864.5,246,8685 37395.6,84,6853 29568.9,125,5029 58806.6,152,10035 42196.8,350,6538 52036,849.8,9017 42780.9,20.8,6936 59949.3,57.7,9786 51540.1,421.9,7944 10349.3,10.6,1768 43984.3,22.9,7394 38781.7,294.4,6650 42307.6,371.9,6870 22844.2,20.7,4150 58435.5,36.2,10664 54020.4,446.7,8597 6186.4,43.3,1596 98614.4,2015,18878 20111.2,10.7,3363 51123,368.7,7309 6712.3,0,1887 39805.6,315.5,5544 57155.3,35.7,9347 27255.6,10.3,4531 51923.4,651.2,10537 12235.8,11.6,2063 8687,0,1196 42550.2,21.5,6915 43805.4,329.6,6466 45026.8,21.2,7611 10776.8,13.5,1682 8539.9,0,1150 8495.5,10.5,1465 47009.9,35.1,7070 40031.4,107,6131 26784.9,160,4350 18970,102.8,2936 53976.3,632.4,9923 17097.9,101.2,2663 16524.5,109.2,2525 64358.8,540,9951 41876.1,383.2,5896 18402.7,82.6,2759 36687.9,244,5305 39686,91,7143 40726.4,338.8,6313 17813.5,152.8,2829 60963.6,471.8,9041 64671.6,899.8,12314 50185.6,243.8,8559 67757.7,943.8,12297 19529,47.8,3121 39919.5,369.6,6359 54343.7,187.6,9601 18071.1,52.8,3072 23378.9,80,4131 60903.6,501,9579 25798.5,76,4399 16702.1,40.8,2937 69203.4,1005.6,12396 22751.5,77.6,3815 17853.5,42,2723 59078.8,653.2,10530 28036.3,101,4678 33731.3,301,6681 47229,225.2,8587 19234.8,47.4,3075 42383.9,332.6,6530 81089.4,313.2,13091 22058.4,90,3521 12469.1,49,1942 9867.9,38,1431 10015.7,22,1386 50661.3,246.6,7414 98809.4,672.8,16786 10499.2,26.4,1619 83093.1,892.8,14317 12227.9,114,1888 10939.1,32,1517 161049,461.3,29295 \ No newline at end of file diff --git a/pytudes/ipynb/enable1.txt b/pytudes/ipynb/enable1.txt new file mode 100644 index 0000000..d5f7da5 --- /dev/null +++ b/pytudes/ipynb/enable1.txt @@ -0,0 +1,172820 @@ +aa +aah +aahed +aahing +aahs +aal +aalii +aaliis +aals +aardvark +aardvarks +aardwolf +aardwolves +aargh +aarrgh +aarrghh +aas +aasvogel +aasvogels +ab +aba +abaca +abacas +abaci +aback +abacterial +abacus +abacuses +abaft +abaka +abakas +abalone +abalones +abamp +abampere +abamperes +abamps +abandon +abandoned +abandoner +abandoners +abandoning +abandonment +abandonments +abandons +abapical +abas +abase +abased +abasedly +abasement +abasements +abaser +abasers +abases +abash +abashed +abashes +abashing +abashment +abashments +abasia +abasias +abasing +abatable +abate +abated +abatement +abatements +abater +abaters +abates +abating +abatis +abatises +abator +abators +abattis +abattises +abattoir +abattoirs +abaxial +abaxile +abba +abbacies +abbacy +abbas +abbatial +abbe +abbes +abbess +abbesses +abbey +abbeys +abbot +abbotcies +abbotcy +abbots +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +abbreviator +abbreviators +abdicable +abdicate +abdicated +abdicates +abdicating +abdication +abdications +abdicator +abdicators +abdomen +abdomens +abdomina +abdominal +abdominally +abduce +abduced +abducens +abducent +abducentes +abduces +abducing +abduct +abducted +abducting +abduction +abductions +abductor +abductores +abductors +abducts +abeam +abecedarian +abecedarians +abed +abele +abeles +abelia +abelian +abelias +abelmosk +abelmosks +aberrance +aberrances +aberrancies +aberrancy +aberrant +aberrantly +aberrants +aberrated +aberration +aberrational +aberrations +abet +abetment +abetments +abets +abettal +abettals +abetted +abetter +abetters +abetting +abettor +abettors +abeyance +abeyances +abeyancies +abeyancy +abeyant +abfarad +abfarads +abhenries +abhenry +abhenrys +abhor +abhorred +abhorrence +abhorrences +abhorrent +abhorrently +abhorrer +abhorrers +abhorring +abhors +abidance +abidances +abide +abided +abider +abiders +abides +abiding +abidingly +abigail +abigails +abilities +ability +abiogeneses +abiogenesis +abiogenic +abiogenically +abiogenist +abiogenists +abiological +abioses +abiosis +abiotic +abiotically +abject +abjection +abjections +abjectly +abjectness +abjectnesses +abjuration +abjurations +abjure +abjured +abjurer +abjurers +abjures +abjuring +ablate +ablated +ablates +ablating +ablation +ablations +ablative +ablatively +ablatives +ablaut +ablauts +ablaze +able +ablegate +ablegates +abler +ables +ablest +ablings +ablins +abloom +abluent +abluents +ablush +abluted +ablution +ablutionary +ablutions +ably +abmho +abmhos +abnegate +abnegated +abnegates +abnegating +abnegation +abnegations +abnegator +abnegators +abnormal +abnormalities +abnormality +abnormally +abnormals +abo +aboard +abode +aboded +abodes +aboding +abohm +abohms +aboideau +aboideaus +aboideaux +aboil +aboiteau +aboiteaus +aboiteaux +abolish +abolishable +abolished +abolisher +abolishers +abolishes +abolishing +abolishment +abolishments +abolition +abolitionary +abolitionism +abolitionisms +abolitionist +abolitionists +abolitions +abolla +abollae +aboma +abomas +abomasa +abomasal +abomasi +abomasum +abomasus +abominable +abominably +abominate +abominated +abominates +abominating +abomination +abominations +abominator +abominators +aboon +aboral +aborally +aboriginal +aboriginally +aboriginals +aborigine +aborigines +aborning +abort +aborted +aborter +aborters +abortifacient +abortifacients +aborting +abortion +abortionist +abortionists +abortions +abortive +abortively +abortiveness +abortivenesses +aborts +abos +abought +aboulia +aboulias +aboulic +abound +abounded +abounding +abounds +about +above +aboveboard +aboveground +aboves +abracadabra +abracadabras +abrachia +abrachias +abradable +abradant +abradants +abrade +abraded +abrader +abraders +abrades +abrading +abrasion +abrasions +abrasive +abrasively +abrasiveness +abrasivenesses +abrasives +abreact +abreacted +abreacting +abreaction +abreactions +abreacts +abreast +abri +abridge +abridged +abridgement +abridgements +abridger +abridgers +abridges +abridging +abridgment +abridgments +abris +abroach +abroad +abrogate +abrogated +abrogates +abrogating +abrogation +abrogations +abrosia +abrosias +abrupt +abrupter +abruptest +abruption +abruptions +abruptly +abruptness +abruptnesses +abs +abscess +abscessed +abscesses +abscessing +abscise +abscised +abscises +abscisin +abscising +abscisins +abscissa +abscissae +abscissas +abscission +abscissions +abscond +absconded +absconder +absconders +absconding +absconds +abseil +abseiled +abseiling +abseils +absence +absences +absent +absented +absentee +absenteeism +absenteeisms +absentees +absenter +absenters +absenting +absently +absentminded +absentmindedly +absentmindedness +absentmindednesses +absents +absinth +absinthe +absinthes +absinths +absolute +absolutely +absoluteness +absolutenesses +absoluter +absolutes +absolutest +absolution +absolutions +absolutism +absolutisms +absolutist +absolutistic +absolutists +absolutive +absolutize +absolutized +absolutizes +absolutizing +absolve +absolved +absolver +absolvers +absolves +absolving +absonant +absorb +absorbabilities +absorbability +absorbable +absorbance +absorbances +absorbancies +absorbancy +absorbant +absorbants +absorbed +absorbencies +absorbency +absorbent +absorbents +absorber +absorbers +absorbing +absorbingly +absorbs +absorptance +absorptances +absorption +absorptions +absorptive +absorptivities +absorptivity +absquatulate +absquatulated +absquatulates +absquatulating +abstain +abstained +abstainer +abstainers +abstaining +abstains +abstemious +abstemiously +abstemiousness +abstemiousnesses +abstention +abstentions +abstentious +absterge +absterged +absterges +absterging +abstinence +abstinences +abstinent +abstinently +abstract +abstractable +abstracted +abstractedly +abstractedness +abstractednesses +abstracter +abstracters +abstractest +abstracting +abstraction +abstractional +abstractionism +abstractionisms +abstractionist +abstractionists +abstractions +abstractive +abstractly +abstractness +abstractnesses +abstractor +abstractors +abstracts +abstrict +abstricted +abstricting +abstricts +abstruse +abstrusely +abstruseness +abstrusenesses +abstruser +abstrusest +abstrusities +abstrusity +absurd +absurder +absurdest +absurdism +absurdisms +absurdist +absurdists +absurdities +absurdity +absurdly +absurdness +absurdnesses +absurds +abubble +abuilding +abulia +abulias +abulic +abundance +abundances +abundant +abundantly +abusable +abuse +abused +abuser +abusers +abuses +abusing +abusive +abusively +abusiveness +abusivenesses +abut +abutilon +abutilons +abutment +abutments +abuts +abuttal +abuttals +abutted +abutter +abutters +abutting +abuzz +abvolt +abvolts +abwatt +abwatts +aby +abye +abyes +abying +abys +abysm +abysmal +abysmally +abysms +abyss +abyssal +abysses +acacia +acacias +academe +academes +academia +academias +academic +academical +academically +academician +academicians +academicism +academicisms +academics +academies +academism +academisms +academy +acajou +acajous +acaleph +acalephae +acalephe +acalephes +acalephs +acanthi +acanthocephalan +acanthocephalans +acanthus +acanthuses +acapnia +acapnias +acari +acariases +acariasis +acaricidal +acaricide +acaricides +acarid +acaridan +acaridans +acarids +acarine +acarines +acaroid +acarpous +acarus +acatalectic +acatalectics +acaudal +acaudate +acaulescent +acauline +acaulose +acaulous +accede +acceded +acceder +acceders +accedes +acceding +accelerando +accelerandos +accelerant +accelerants +accelerate +accelerated +accelerates +accelerating +acceleratingly +acceleration +accelerations +accelerative +accelerator +accelerators +accelerometer +accelerometers +accent +accented +accenting +accentless +accentor +accentors +accents +accentual +accentually +accentuate +accentuated +accentuates +accentuating +accentuation +accentuations +accept +acceptabilities +acceptability +acceptable +acceptableness +acceptablenesses +acceptably +acceptance +acceptances +acceptant +acceptation +acceptations +accepted +acceptedly +acceptee +acceptees +accepter +accepters +accepting +acceptingly +acceptingness +acceptingnesses +acceptive +acceptor +acceptors +accepts +access +accessaries +accessary +accessed +accesses +accessibilities +accessibility +accessible +accessibleness +accessiblenesses +accessibly +accessing +accession +accessional +accessioned +accessioning +accessions +accessorial +accessories +accessorise +accessorised +accessorises +accessorising +accessorize +accessorized +accessorizes +accessorizing +accessory +acciaccatura +acciaccaturas +accidence +accidences +accident +accidental +accidentally +accidentalness +accidentalnesses +accidentals +accidently +accidents +accidia +accidias +accidie +accidies +accipiter +accipiters +accipitrine +accipitrines +acclaim +acclaimed +acclaimer +acclaimers +acclaiming +acclaims +acclamation +acclamations +acclimate +acclimated +acclimates +acclimating +acclimation +acclimations +acclimatise +acclimatised +acclimatises +acclimatising +acclimatization +acclimatizations +acclimatize +acclimatized +acclimatizer +acclimatizers +acclimatizes +acclimatizing +acclivities +acclivity +accolade +accolades +accommodate +accommodated +accommodates +accommodating +accommodatingly +accommodation +accommodational +accommodationist +accommodationists +accommodations +accommodative +accommodativeness +accommodativenesses +accommodator +accommodators +accompanied +accompanies +accompaniment +accompaniments +accompanist +accompanists +accompany +accompanying +accomplice +accomplices +accomplish +accomplishable +accomplished +accomplisher +accomplishers +accomplishes +accomplishing +accomplishment +accomplishments +accord +accordance +accordances +accordant +accordantly +accorded +accorder +accorders +according +accordingly +accordion +accordionist +accordionists +accordions +accords +accost +accosted +accosting +accosts +accouchement +accouchements +accoucheur +accoucheurs +account +accountabilities +accountability +accountable +accountableness +accountablenesses +accountably +accountancies +accountancy +accountant +accountants +accountantship +accountantships +accounted +accounting +accountings +accounts +accouter +accoutered +accoutering +accouterment +accouterments +accouters +accoutre +accoutred +accoutrement +accoutrements +accoutres +accoutring +accredit +accreditable +accreditation +accreditations +accredited +accrediting +accredits +accrete +accreted +accretes +accreting +accretion +accretionary +accretions +accretive +accruable +accrual +accruals +accrue +accrued +accruement +accruements +accrues +accruing +acculturate +acculturated +acculturates +acculturating +acculturation +acculturational +acculturations +acculturative +accumulate +accumulated +accumulates +accumulating +accumulation +accumulations +accumulative +accumulatively +accumulativeness +accumulativenesses +accumulator +accumulators +accuracies +accuracy +accurate +accurately +accurateness +accuratenesses +accursed +accursedly +accursedness +accursednesses +accurst +accusal +accusals +accusant +accusants +accusation +accusations +accusative +accusatives +accusatory +accuse +accused +accuser +accusers +accuses +accusing +accusingly +accustom +accustomation +accustomations +accustomed +accustomedness +accustomednesses +accustoming +accustoms +ace +aced +acedia +acedias +aceldama +aceldamas +acellular +acentric +acephalous +acequia +acequias +acerate +acerated +acerb +acerbate +acerbated +acerbates +acerbating +acerber +acerbest +acerbic +acerbically +acerbities +acerbity +acerola +acerolas +acerose +acerous +acervate +acervuli +acervulus +aces +acescent +acescents +aceta +acetabula +acetabular +acetabulum +acetabulums +acetal +acetaldehyde +acetaldehydes +acetals +acetamid +acetamide +acetamides +acetamids +acetaminophen +acetaminophens +acetanilid +acetanilide +acetanilides +acetanilids +acetate +acetated +acetates +acetazolamide +acetazolamides +acetic +acetification +acetifications +acetified +acetifies +acetify +acetifying +acetin +acetins +acetone +acetones +acetonic +acetonitrile +acetonitriles +acetophenetidin +acetophenetidins +acetose +acetous +acetoxyl +acetoxyls +acetum +acetyl +acetylate +acetylated +acetylates +acetylating +acetylation +acetylations +acetylative +acetylcholine +acetylcholines +acetylcholinesterase +acetylcholinesterases +acetylene +acetylenes +acetylenic +acetylic +acetyls +acetylsalicylate +acetylsalicylates +achalasia +achalasias +ache +ached +achene +achenes +achenial +aches +achier +achiest +achievable +achieve +achieved +achievement +achievements +achiever +achievers +achieves +achieving +achillea +achilleas +achiness +achinesses +aching +achingly +achiote +achiotes +achlorhydria +achlorhydrias +achlorhydric +acholia +acholias +achondrite +achondrites +achondritic +achondroplasia +achondroplasias +achondroplastic +achoo +achromat +achromatic +achromatically +achromatism +achromatisms +achromatize +achromatized +achromatizes +achromatizing +achromats +achromic +achy +acicula +aciculae +acicular +aciculas +aciculum +aciculums +acid +acidemia +acidemias +acidhead +acidheads +acidic +acidification +acidifications +acidified +acidifier +acidifiers +acidifies +acidify +acidifying +acidimeter +acidimeters +acidimetric +acidimetries +acidimetry +acidities +acidity +acidly +acidness +acidnesses +acidophil +acidophile +acidophiles +acidophilic +acidophils +acidoses +acidosis +acidotic +acids +acidulate +acidulated +acidulates +acidulating +acidulation +acidulations +acidulent +acidulous +aciduria +acidurias +acidy +acierate +acierated +acierates +acierating +aciform +acinar +acing +acini +acinic +acinose +acinous +acinus +ackee +ackees +acknowledge +acknowledged +acknowledgedly +acknowledgement +acknowledgements +acknowledges +acknowledging +acknowledgment +acknowledgments +aclinic +acmatic +acme +acmes +acmic +acne +acned +acnes +acnode +acnodes +acock +acoelomate +acoelomates +acold +acolyte +acolytes +aconite +aconites +aconitic +aconitum +aconitums +acorn +acorns +acoustic +acoustical +acoustically +acoustician +acousticians +acoustics +acquaint +acquaintance +acquaintances +acquaintanceship +acquaintanceships +acquainted +acquainting +acquaints +acquest +acquests +acquiesce +acquiesced +acquiescence +acquiescences +acquiescent +acquiescently +acquiesces +acquiescing +acquirable +acquire +acquired +acquirement +acquirements +acquirer +acquirers +acquires +acquiring +acquisition +acquisitional +acquisitions +acquisitive +acquisitively +acquisitiveness +acquisitivenesses +acquisitor +acquisitors +acquit +acquits +acquittal +acquittals +acquittance +acquittances +acquitted +acquitter +acquitters +acquitting +acrasia +acrasias +acrasin +acrasins +acre +acreage +acreages +acred +acres +acrid +acrider +acridest +acridine +acridines +acridities +acridity +acridly +acridness +acridnesses +acriflavine +acriflavines +acrimonies +acrimonious +acrimoniously +acrimoniousness +acrimoniousnesses +acrimony +acritarch +acritarchs +acrobat +acrobatic +acrobatically +acrobatics +acrobats +acrocentric +acrocentrics +acrodont +acrodonts +acrogen +acrogens +acrolect +acrolects +acrolein +acroleins +acrolith +acroliths +acromegalic +acromegalics +acromegalies +acromegaly +acromia +acromial +acromion +acromions +acronic +acronym +acronymic +acronymically +acronyms +acropetal +acropetally +acrophobe +acrophobes +acrophobia +acrophobias +acropolis +acropolises +acrosomal +acrosome +acrosomes +across +acrostic +acrostical +acrostically +acrostics +acrotic +acrotism +acrotisms +acrylamide +acrylamides +acrylate +acrylates +acrylic +acrylics +acrylonitrile +acrylonitriles +act +acta +actabilities +actability +actable +acted +actin +actinal +acting +actings +actinia +actiniae +actinian +actinians +actinias +actinic +actinically +actinide +actinides +actinism +actinisms +actinium +actiniums +actinoid +actinoids +actinolite +actinolites +actinometer +actinometers +actinometric +actinometries +actinometry +actinomorphic +actinomorphies +actinomorphy +actinomyces +actinomycete +actinomycetes +actinomycetous +actinomycin +actinomycins +actinomycoses +actinomycosis +actinomycotic +actinon +actinons +actins +action +actionable +actionably +actionless +actions +activate +activated +activates +activating +activation +activations +activator +activators +active +actively +activeness +activenesses +actives +activism +activisms +activist +activistic +activists +activities +activity +activize +activized +activizes +activizing +actomyosin +actomyosins +actor +actorish +actors +actress +actresses +actressy +acts +actual +actualities +actuality +actualization +actualizations +actualize +actualized +actualizes +actualizing +actually +actuarial +actuarially +actuaries +actuary +actuate +actuated +actuates +actuating +actuation +actuations +actuator +actuators +acuate +acuities +acuity +aculeate +aculei +aculeus +acumen +acumens +acuminate +acupressure +acupressures +acupuncture +acupunctures +acupuncturist +acupuncturists +acutance +acutances +acute +acutely +acuteness +acutenesses +acuter +acutes +acutest +acyclic +acyclovir +acyclovirs +acyl +acylate +acylated +acylates +acylating +acylation +acylations +acyloin +acyloins +acyls +ad +adage +adages +adagial +adagio +adagios +adamance +adamances +adamancies +adamancy +adamant +adamantine +adamantly +adamants +adamsite +adamsites +adapt +adaptabilities +adaptability +adaptable +adaptation +adaptational +adaptationally +adaptations +adapted +adaptedness +adaptednesses +adapter +adapters +adapting +adaption +adaptions +adaptive +adaptively +adaptiveness +adaptivenesses +adaptivities +adaptivity +adaptor +adaptors +adapts +adaxial +add +addable +addax +addaxes +added +addedly +addend +addenda +addends +addendum +adder +adders +addible +addict +addicted +addicting +addiction +addictions +addictive +addicts +adding +addition +additional +additionally +additions +additive +additively +additives +additivities +additivity +additory +addle +addled +addlepated +addles +addling +address +addressabilities +addressability +addressable +addressed +addressee +addressees +addresser +addressers +addresses +addressing +addrest +adds +adduce +adduced +adducent +adducer +adducers +adduces +adducing +adduct +adducted +adducting +adduction +adductions +adductive +adductor +adductors +adducts +adeem +adeemed +adeeming +adeems +adenine +adenines +adenitis +adenitises +adenocarcinoma +adenocarcinomas +adenocarcinomata +adenocarcinomatous +adenohypophyseal +adenohypophyses +adenohypophysial +adenohypophysis +adenoid +adenoidal +adenoids +adenoma +adenomas +adenomata +adenomatous +adenoses +adenosine +adenosines +adenosis +adenoviral +adenovirus +adenoviruses +adenyl +adenyls +adept +adepter +adeptest +adeptly +adeptness +adeptnesses +adepts +adequacies +adequacy +adequate +adequately +adequateness +adequatenesses +adhere +adhered +adherence +adherences +adherend +adherends +adherent +adherently +adherents +adherer +adherers +adheres +adhering +adhesion +adhesional +adhesions +adhesive +adhesively +adhesiveness +adhesivenesses +adhesives +adhibit +adhibited +adhibiting +adhibits +adiabatic +adiabatically +adieu +adieus +adieux +adios +adipic +adipocyte +adipocytes +adipose +adiposes +adiposis +adiposities +adiposity +adipous +adit +adits +adjacencies +adjacency +adjacent +adjacently +adjectival +adjectivally +adjective +adjectively +adjectives +adjoin +adjoined +adjoining +adjoins +adjoint +adjoints +adjourn +adjourned +adjourning +adjournment +adjournments +adjourns +adjudge +adjudged +adjudges +adjudging +adjudicate +adjudicated +adjudicates +adjudicating +adjudication +adjudications +adjudicative +adjudicator +adjudicators +adjudicatory +adjunct +adjunction +adjunctions +adjunctive +adjunctly +adjuncts +adjuration +adjurations +adjuratory +adjure +adjured +adjurer +adjurers +adjures +adjuring +adjuror +adjurors +adjust +adjustabilities +adjustability +adjustable +adjusted +adjuster +adjusters +adjusting +adjustive +adjustment +adjustmental +adjustments +adjustor +adjustors +adjusts +adjutancies +adjutancy +adjutant +adjutants +adjuvant +adjuvants +adman +admass +admeasure +admeasured +admeasurement +admeasurements +admeasures +admeasuring +admen +administer +administered +administering +administers +administrable +administrant +administrants +administrate +administrated +administrates +administrating +administration +administrations +administrative +administratively +administrator +administrators +administratrices +administratrix +admirabilities +admirability +admirable +admirableness +admirablenesses +admirably +admiral +admirals +admiralties +admiralty +admiration +admirations +admire +admired +admirer +admirers +admires +admiring +admiringly +admissibilities +admissibility +admissible +admission +admissions +admissive +admit +admits +admittance +admittances +admitted +admittedly +admitter +admitters +admitting +admix +admixed +admixes +admixing +admixt +admixture +admixtures +admonish +admonished +admonisher +admonishers +admonishes +admonishing +admonishingly +admonishment +admonishments +admonition +admonitions +admonitorily +admonitory +adnate +adnation +adnations +adnexa +adnexal +adnoun +adnouns +ado +adobe +adobelike +adobes +adobo +adobos +adolescence +adolescences +adolescent +adolescently +adolescents +adonis +adonises +adopt +adoptabilities +adoptability +adoptable +adopted +adoptee +adoptees +adopter +adopters +adoptianism +adoptianisms +adopting +adoption +adoptionism +adoptionisms +adoptionist +adoptionists +adoptions +adoptive +adoptively +adopts +adorabilities +adorability +adorable +adorableness +adorablenesses +adorably +adoration +adorations +adore +adored +adorer +adorers +adores +adoring +adoringly +adorn +adorned +adorner +adorners +adorning +adornment +adornments +adorns +ados +adown +adoze +adrenal +adrenalectomies +adrenalectomized +adrenalectomy +adrenaline +adrenalines +adrenals +adrenergic +adrenergically +adrenochrome +adrenochromes +adrenocortical +adrenocorticosteroid +adrenocorticosteroids +adrenocorticotrophic +adrenocorticotrophin +adrenocorticotrophins +adrenocorticotropic +adrenocorticotropin +adrenocorticotropins +adrift +adroit +adroiter +adroitest +adroitly +adroitness +adroitnesses +ads +adscititious +adscript +adscripts +adsorb +adsorbable +adsorbate +adsorbates +adsorbed +adsorbent +adsorbents +adsorber +adsorbers +adsorbing +adsorbs +adsorption +adsorptions +adsorptive +adularia +adularias +adulate +adulated +adulates +adulating +adulation +adulations +adulator +adulators +adulatory +adult +adulterant +adulterants +adulterate +adulterated +adulterates +adulterating +adulteration +adulterations +adulterator +adulterators +adulterer +adulterers +adulteress +adulteresses +adulteries +adulterine +adulterous +adulterously +adultery +adulthood +adulthoods +adultlike +adultly +adultness +adultnesses +adults +adumbral +adumbrate +adumbrated +adumbrates +adumbrating +adumbration +adumbrations +adumbrative +adumbratively +adunc +aduncate +aduncous +adust +advance +advanced +advancement +advancements +advancer +advancers +advances +advancing +advantage +advantaged +advantageous +advantageously +advantageousness +advantageousnesses +advantages +advantaging +advect +advected +advecting +advection +advections +advective +advects +advent +adventitia +adventitial +adventitias +adventitious +adventitiously +adventive +adventives +advents +adventure +adventured +adventurer +adventurers +adventures +adventuresome +adventuresomeness +adventuresomenesses +adventuress +adventuresses +adventuring +adventurism +adventurisms +adventurist +adventuristic +adventurists +adventurous +adventurously +adventurousness +adventurousnesses +adverb +adverbial +adverbially +adverbials +adverbs +adversarial +adversaries +adversariness +adversarinesses +adversary +adversative +adversatively +adversatives +adverse +adversely +adverseness +adversenesses +adversities +adversity +advert +adverted +advertence +advertences +advertencies +advertency +advertent +advertently +adverting +advertise +advertised +advertisement +advertisements +advertiser +advertisers +advertises +advertising +advertisings +advertize +advertized +advertizement +advertizements +advertizes +advertizing +advertorial +advertorials +adverts +advice +advices +advisabilities +advisability +advisable +advisableness +advisablenesses +advisably +advise +advised +advisedly +advisee +advisees +advisement +advisements +adviser +advisers +advises +advising +advisor +advisories +advisors +advisory +advocacies +advocacy +advocate +advocated +advocates +advocating +advocation +advocations +advocative +advocator +advocators +advowson +advowsons +adynamia +adynamias +adynamic +adyta +adytum +adz +adze +adzes +adzuki +adzukis +ae +aecia +aecial +aecidia +aecidial +aecidium +aeciospore +aeciospores +aecium +aedes +aedile +aediles +aedine +aegis +aegises +aeneous +aeneus +aeolian +aeon +aeonian +aeonic +aeons +aepyornis +aepyornises +aequorin +aequorins +aerate +aerated +aerates +aerating +aeration +aerations +aerator +aerators +aerenchyma +aerenchymas +aerenchymata +aerial +aerialist +aerialists +aerially +aerials +aerie +aeried +aerier +aeries +aeriest +aerified +aerifies +aeriform +aerify +aerifying +aerily +aero +aerobatic +aerobatics +aerobe +aerobes +aerobia +aerobic +aerobically +aerobics +aerobiological +aerobiologies +aerobiology +aerobioses +aerobiosis +aerobium +aerobrake +aerobraked +aerobrakes +aerobraking +aerodrome +aerodromes +aeroduct +aeroducts +aerodynamic +aerodynamical +aerodynamically +aerodynamicist +aerodynamicists +aerodynamics +aerodyne +aerodynes +aeroelastic +aeroelasticities +aeroelasticity +aeroembolism +aeroembolisms +aerofoil +aerofoils +aerogel +aerogels +aerogram +aerogramme +aerogrammes +aerograms +aerolite +aerolites +aerolith +aeroliths +aerologies +aerology +aeromagnetic +aeromechanics +aeromedical +aeromedicine +aeromedicines +aerometer +aerometers +aeronaut +aeronautic +aeronautical +aeronautically +aeronautics +aeronauts +aeronomer +aeronomers +aeronomic +aeronomical +aeronomies +aeronomist +aeronomists +aeronomy +aeroplane +aeroplanes +aerosat +aerosats +aerosol +aerosolization +aerosolizations +aerosolize +aerosolized +aerosolizes +aerosolizing +aerosols +aerospace +aerospaces +aerostat +aerostatics +aerostats +aerothermodynamic +aerothermodynamics +aerugo +aerugos +aery +aesthete +aesthetes +aesthetic +aesthetical +aesthetically +aesthetician +aestheticians +aestheticism +aestheticisms +aestheticize +aestheticized +aestheticizes +aestheticizing +aesthetics +aestival +aestivate +aestivated +aestivates +aestivating +aestivation +aestivations +aether +aetheric +aethers +aetiologies +aetiology +afar +afars +afeard +afeared +afebrile +aff +affabilities +affability +affable +affably +affair +affaire +affaires +affairs +affect +affectabilities +affectability +affectable +affectation +affectations +affected +affectedly +affectedness +affectednesses +affecter +affecters +affecting +affectingly +affection +affectional +affectionally +affectionate +affectionately +affectioned +affectionless +affections +affective +affectively +affectivities +affectivity +affectless +affectlessness +affectlessnesses +affects +affenpinscher +affenpinschers +afferent +afferently +afferents +affiance +affianced +affiances +affiancing +affiant +affiants +affiche +affiches +afficionado +afficionados +affidavit +affidavits +affiliate +affiliated +affiliates +affiliating +affiliation +affiliations +affinal +affine +affined +affinely +affines +affinities +affinity +affirm +affirmable +affirmance +affirmances +affirmation +affirmations +affirmative +affirmatively +affirmatives +affirmed +affirmer +affirmers +affirming +affirms +affix +affixable +affixal +affixation +affixations +affixed +affixer +affixers +affixes +affixial +affixing +affixment +affixments +afflatus +afflatuses +afflict +afflicted +afflicting +affliction +afflictions +afflictive +afflictively +afflicts +affluence +affluences +affluencies +affluency +affluent +affluently +affluents +afflux +affluxes +afford +affordabilities +affordability +affordable +affordably +afforded +affording +affords +afforest +afforestation +afforestations +afforested +afforesting +afforests +affray +affrayed +affrayer +affrayers +affraying +affrays +affricate +affricates +affricative +affricatives +affright +affrighted +affrighting +affrights +affront +affronted +affronting +affronts +affusion +affusions +afghan +afghani +afghanis +afghans +aficionada +aficionadas +aficionado +aficionados +afield +afire +aflame +aflatoxin +aflatoxins +afloat +aflutter +afoot +afore +aforementioned +aforesaid +aforethought +afoul +afraid +afreet +afreets +afresh +afrit +afrits +aft +after +afterbirth +afterbirths +afterburner +afterburners +aftercare +aftercares +afterclap +afterclaps +afterdeck +afterdecks +aftereffect +aftereffects +afterglow +afterglows +afterimage +afterimages +afterlife +afterlives +aftermarket +aftermarkets +aftermath +aftermaths +aftermost +afternoon +afternoons +afterpiece +afterpieces +afters +aftershave +aftershaves +aftershock +aftershocks +aftertaste +aftertastes +aftertax +afterthought +afterthoughts +aftertime +aftertimes +afterward +afterwards +afterword +afterwords +afterworld +afterworlds +aftmost +aftosa +aftosas +ag +aga +again +against +agalloch +agallochs +agalwood +agalwoods +agama +agamas +agamete +agametes +agamic +agammaglobulinemia +agammaglobulinemias +agammaglobulinemic +agamospermies +agamospermy +agamous +agapae +agapai +agapanthus +agapanthuses +agape +agapeic +agar +agaric +agarics +agarose +agaroses +agars +agas +agate +agates +agatize +agatized +agatizes +agatizing +agatoid +agave +agaves +agaze +age +aged +agedly +agedness +agednesses +agee +ageing +ageings +ageism +ageisms +ageist +ageists +ageless +agelessly +agelessness +agelessnesses +agelong +agencies +agency +agenda +agendaless +agendas +agendum +agendums +agene +agenes +ageneses +agenesia +agenesias +agenesis +agenetic +agenize +agenized +agenizes +agenizing +agent +agential +agenting +agentings +agentive +agentives +agentries +agentry +agents +ager +ageratum +ageratums +agers +ages +aggadic +agger +aggers +aggie +aggies +aggiornamento +aggiornamentos +agglomerate +agglomerated +agglomerates +agglomerating +agglomeration +agglomerations +agglomerative +agglutinabilities +agglutinability +agglutinable +agglutinate +agglutinated +agglutinates +agglutinating +agglutination +agglutinations +agglutinative +agglutinin +agglutinins +agglutinogen +agglutinogenic +agglutinogens +aggradation +aggradations +aggrade +aggraded +aggrades +aggrading +aggrandise +aggrandised +aggrandises +aggrandising +aggrandize +aggrandized +aggrandizement +aggrandizements +aggrandizer +aggrandizers +aggrandizes +aggrandizing +aggravate +aggravated +aggravates +aggravating +aggravation +aggravations +aggregate +aggregated +aggregately +aggregateness +aggregatenesses +aggregates +aggregating +aggregation +aggregational +aggregations +aggregative +aggregatively +aggress +aggressed +aggresses +aggressing +aggression +aggressions +aggressive +aggressively +aggressiveness +aggressivenesses +aggressivities +aggressivity +aggressor +aggressors +aggrieve +aggrieved +aggrievedly +aggrievement +aggrievements +aggrieves +aggrieving +aggro +aggros +agha +aghas +aghast +agile +agilely +agilities +agility +agin +aging +agings +aginner +aginners +agio +agios +agiotage +agiotages +agism +agisms +agist +agisted +agisting +agists +agitable +agitate +agitated +agitatedly +agitates +agitating +agitation +agitational +agitations +agitative +agitato +agitator +agitators +agitprop +agitprops +aglare +agleam +aglee +aglet +aglets +agley +aglimmer +aglitter +aglow +agly +aglycon +aglycone +aglycones +aglycons +agma +agmas +agminate +agnail +agnails +agnate +agnates +agnatic +agnation +agnations +agnize +agnized +agnizes +agnizing +agnomen +agnomens +agnomina +agnosia +agnosias +agnostic +agnosticism +agnosticisms +agnostics +ago +agog +agon +agonal +agone +agones +agonic +agonies +agonise +agonised +agonises +agonising +agonist +agonistic +agonistically +agonists +agonize +agonized +agonizes +agonizing +agonizingly +agons +agony +agora +agorae +agoraphobe +agoraphobes +agoraphobia +agoraphobias +agoraphobic +agoraphobics +agoras +agorot +agoroth +agouti +agouties +agoutis +agouty +agrafe +agrafes +agraffe +agraffes +agranulocyte +agranulocytes +agranulocytoses +agranulocytosis +agrapha +agraphia +agraphias +agraphic +agrarian +agrarianism +agrarianisms +agrarians +agravic +agree +agreeabilities +agreeability +agreeable +agreeableness +agreeablenesses +agreeably +agreed +agreeing +agreement +agreements +agrees +agrestal +agrestic +agria +agrias +agribusiness +agribusinesses +agribusinessman +agribusinessmen +agrichemical +agrichemicals +agricultural +agriculturalist +agriculturalists +agriculturally +agriculture +agricultures +agriculturist +agriculturists +agrimonies +agrimony +agrochemical +agrochemicals +agroforester +agroforesters +agroforestries +agroforestry +agrologies +agrology +agronomic +agronomically +agronomies +agronomist +agronomists +agronomy +aground +agrypnia +agrypnias +ague +aguelike +agues +agueweed +agueweeds +aguish +aguishly +ah +aha +ahchoo +ahead +ahem +ahimsa +ahimsas +ahistoric +ahistorical +ahold +aholds +ahorse +ahoy +ahull +ai +aiblins +aid +aide +aided +aider +aiders +aides +aidful +aiding +aidless +aidman +aidmen +aids +aiglet +aiglets +aigret +aigrets +aigrette +aigrettes +aiguille +aiguilles +aiguillette +aiguillettes +aikido +aikidos +ail +ailanthus +ailanthuses +ailed +aileron +ailerons +ailing +ailment +ailments +ails +ailurophile +ailurophiles +ailurophobe +ailurophobes +ailurophobia +ailurophobias +aim +aimed +aimer +aimers +aimful +aimfully +aiming +aimless +aimlessly +aimlessness +aimlessnesses +aims +ain +ains +ainsell +ainsells +aioli +aiolis +air +airboat +airboats +airborne +airbound +airbrush +airbrushed +airbrushes +airbrushing +airburst +airbursts +airbus +airbuses +airbusses +aircheck +airchecks +aircoach +aircoaches +aircraft +aircrew +aircrews +airdate +airdates +airdrome +airdromes +airdrop +airdropped +airdropping +airdrops +aired +airer +airers +airest +airfare +airfares +airfield +airfields +airflow +airflows +airfoil +airfoils +airframe +airframes +airfreight +airfreighted +airfreighting +airfreights +airglow +airglows +airhead +airheaded +airheads +airhole +airholes +airier +airiest +airily +airiness +airinesses +airing +airings +airless +airlessness +airlessnesses +airlift +airlifted +airlifting +airlifts +airlike +airline +airliner +airliners +airlines +airmail +airmailed +airmailing +airmails +airman +airmanship +airmanships +airmen +airmobile +airn +airns +airpark +airparks +airplane +airplanes +airplay +airplays +airport +airports +airpost +airposts +airpower +airpowers +airproof +airproofed +airproofing +airproofs +airs +airscape +airscapes +airscrew +airscrews +airshed +airsheds +airship +airships +airsick +airsickness +airsicknesses +airspace +airspaces +airspeed +airspeeds +airstream +airstreams +airstrip +airstrips +airt +airted +airth +airthed +airthing +airths +airtight +airtightness +airtightnesses +airtime +airtimes +airting +airts +airward +airwave +airwaves +airway +airways +airwise +airwoman +airwomen +airworthier +airworthiest +airworthiness +airworthinesses +airworthy +airy +ais +aisle +aisled +aisles +aisleway +aisleways +ait +aitch +aitchbone +aitchbones +aitches +aits +aiver +aivers +ajar +ajee +ajiva +ajivas +ajowan +ajowans +ajuga +ajugas +akee +akees +akela +akelas +akene +akenes +akimbo +akin +akvavit +akvavits +al +ala +alabaster +alabasters +alabastrine +alack +alacrities +alacritous +alacrity +alae +alameda +alamedas +alamo +alamode +alamodes +alamos +alan +aland +alands +alane +alang +alanin +alanine +alanines +alanins +alans +alant +alants +alanyl +alanyls +alar +alarm +alarmed +alarming +alarmingly +alarmism +alarmisms +alarmist +alarmists +alarms +alarum +alarumed +alaruming +alarums +alary +alas +alaska +alaskas +alastor +alastors +alate +alated +alates +alation +alations +alb +alba +albacore +albacores +albas +albata +albatas +albatross +albatrosses +albedo +albedoes +albedos +albeit +albicore +albicores +albinal +albinic +albinism +albinisms +albinistic +albino +albinos +albinotic +albite +albites +albitic +albizia +albizias +albizzia +albizzias +albs +album +albumen +albumens +albumin +albuminous +albumins +albuminuria +albuminurias +albuminuric +albumose +albumoses +albums +alburnum +alburnums +alcade +alcades +alcahest +alcahests +alcaic +alcaics +alcaide +alcaides +alcalde +alcaldes +alcayde +alcaydes +alcazar +alcazars +alchemic +alchemical +alchemically +alchemies +alchemist +alchemistic +alchemistical +alchemists +alchemize +alchemized +alchemizes +alchemizing +alchemy +alchymies +alchymy +alcid +alcidine +alcids +alcohol +alcoholic +alcoholically +alcoholics +alcoholism +alcoholisms +alcohols +alcove +alcoved +alcoves +alcyonarian +alcyonarians +aldehyde +aldehydes +aldehydic +alder +alderflies +alderfly +alderman +aldermanic +aldermen +alders +alderwoman +alderwomen +aldol +aldolase +aldolases +aldolization +aldolizations +aldols +aldose +aldoses +aldosterone +aldosterones +aldosteronism +aldosteronisms +aldrin +aldrins +ale +aleatoric +aleatory +alec +alecs +alee +alef +alefs +alegar +alegars +alehouse +alehouses +alembic +alembics +alencon +alencons +aleph +alephs +alert +alerted +alerter +alertest +alerting +alertly +alertness +alertnesses +alerts +ales +aleuron +aleurone +aleurones +aleurons +alevin +alevins +alewife +alewives +alexander +alexanders +alexandrine +alexandrines +alexandrite +alexandrites +alexia +alexias +alexin +alexine +alexines +alexins +alfa +alfaki +alfakis +alfalfa +alfalfas +alfaqui +alfaquin +alfaquins +alfaquis +alfas +alfilaria +alfilarias +alforja +alforjas +alfresco +alga +algae +algaecide +algaecides +algal +algaroba +algarobas +algarroba +algarrobas +algas +algebra +algebraic +algebraically +algebraist +algebraists +algebras +algerine +algerines +algicidal +algicide +algicides +algid +algidities +algidity +algin +alginate +alginates +algins +algoid +algolagnia +algolagniac +algolagniacs +algolagnias +algological +algologies +algologist +algologists +algology +algor +algorism +algorisms +algorithm +algorithmic +algorithmically +algorithms +algors +algum +algums +alias +aliases +alibi +alibied +alibies +alibiing +alibis +alible +alicyclic +alidad +alidade +alidades +alidads +alien +alienabilities +alienability +alienable +alienage +alienages +alienate +alienated +alienates +alienating +alienation +alienations +alienator +alienators +aliened +alienee +alienees +aliener +alieners +aliening +alienism +alienisms +alienist +alienists +alienly +alienness +aliennesses +alienor +alienors +aliens +alif +aliform +alifs +alight +alighted +alighting +alightment +alightments +alights +align +aligned +aligner +aligners +aligning +alignment +alignments +aligns +alike +alikeness +alikenesses +aliment +alimentary +alimentation +alimentations +alimented +alimenting +aliments +alimonies +alimony +aline +alined +alinement +alinements +aliner +aliners +alines +alining +aliped +alipeds +aliphatic +aliquant +aliquot +aliquots +alist +alit +aliteracies +aliteracy +aliterate +aliterates +aliunde +alive +aliveness +alivenesses +aliya +aliyah +aliyahs +aliyas +aliyos +aliyot +alizarin +alizarins +alkahest +alkahestic +alkahests +alkali +alkalic +alkalies +alkalified +alkalifies +alkalify +alkalifying +alkalimeter +alkalimeters +alkalimetries +alkalimetry +alkalin +alkaline +alkalinities +alkalinity +alkalinization +alkalinizations +alkalinize +alkalinized +alkalinizes +alkalinizing +alkalis +alkalise +alkalised +alkalises +alkalising +alkalize +alkalized +alkalizes +alkalizing +alkaloid +alkaloidal +alkaloids +alkaloses +alkalosis +alkalotic +alkane +alkanes +alkanet +alkanets +alkene +alkenes +alkies +alkine +alkines +alkoxide +alkoxides +alkoxy +alky +alkyd +alkyds +alkyl +alkylate +alkylated +alkylates +alkylating +alkylation +alkylations +alkylic +alkyls +alkyne +alkynes +all +allanite +allanites +allantoic +allantoides +allantoin +allantoins +allantois +allargando +allay +allayed +allayer +allayers +allaying +allays +allee +allees +allegation +allegations +allege +alleged +allegedly +alleger +allegers +alleges +allegiance +allegiances +allegiant +alleging +allegorical +allegorically +allegoricalness +allegoricalnesses +allegories +allegorise +allegorised +allegorises +allegorising +allegorist +allegorists +allegorization +allegorizations +allegorize +allegorized +allegorizer +allegorizers +allegorizes +allegorizing +allegory +allegretto +allegrettos +allegro +allegros +allele +alleles +allelic +allelism +allelisms +allelomorph +allelomorphic +allelomorphism +allelomorphisms +allelomorphs +allelopathic +allelopathies +allelopathy +alleluia +alleluias +allemande +allemandes +allergen +allergenic +allergenicities +allergenicity +allergens +allergic +allergies +allergin +allergins +allergist +allergists +allergy +allethrin +allethrins +alleviate +alleviated +alleviates +alleviating +alleviation +alleviations +alleviator +alleviators +alley +alleys +alleyway +alleyways +allheal +allheals +alliable +alliaceous +alliance +alliances +allicin +allicins +allied +allies +alligator +alligators +alliterate +alliterated +alliterates +alliterating +alliteration +alliterations +alliterative +alliteratively +allium +alliums +alloantibodies +alloantibody +alloantigen +alloantigens +allobar +allobars +allocable +allocatable +allocate +allocated +allocates +allocating +allocation +allocations +allocator +allocators +allocution +allocutions +allod +allodia +allodial +allodium +allods +allogamies +allogamous +allogamy +allogeneic +allogenic +allograft +allografted +allografting +allografts +allograph +allographic +allographs +allometric +allometries +allometry +allomorph +allomorphic +allomorphism +allomorphisms +allomorphs +allonge +allonges +allonym +allonyms +allopath +allopaths +allopatric +allopatrically +allopatries +allopatry +allophane +allophanes +allophone +allophones +allophonic +allopolyploid +allopolyploidies +allopolyploids +allopolyploidy +allopurinol +allopurinols +allosaurus +allosauruses +allosteric +allosterically +allosteries +allostery +allot +allotetraploid +allotetraploidies +allotetraploids +allotetraploidy +allotment +allotments +allotrope +allotropes +allotropic +allotropies +allotropy +allots +allotted +allottee +allottees +allotter +allotters +allotting +allotype +allotypes +allotypic +allotypically +allotypies +allotypy +allover +allovers +allow +allowable +allowably +allowance +allowanced +allowances +allowancing +allowed +allowedly +allowing +allows +alloxan +alloxans +alloy +alloyed +alloying +alloys +alls +allseed +allseeds +allspice +allspices +allude +alluded +alludes +alluding +allure +allured +allurement +allurements +allurer +allurers +allures +alluring +alluringly +allusion +allusions +allusive +allusively +allusiveness +allusivenesses +alluvia +alluvial +alluvials +alluvion +alluvions +alluvium +alluviums +ally +allying +allyl +allylic +allyls +alma +almagest +almagests +almah +almahs +almanac +almanacs +almandine +almandines +almandite +almandites +almas +alme +almeh +almehs +almemar +almemars +almes +almightiness +almightinesses +almighty +almner +almners +almond +almonds +almoner +almoners +almonries +almonry +almost +alms +almsgiver +almsgivers +almsgiving +almsgivings +almshouse +almshouses +almsman +almsmen +almuce +almuces +almud +almude +almudes +almuds +almug +almugs +alnico +alnicoes +alodia +alodial +alodium +aloe +aloes +aloetic +aloft +alogical +alogically +aloha +alohas +aloin +aloins +alone +aloneness +alonenesses +along +alongshore +alongside +aloof +aloofly +aloofness +aloofnesses +alopecia +alopecias +alopecic +aloud +alow +alp +alpaca +alpacas +alpenglow +alpenglows +alpenhorn +alpenhorns +alpenstock +alpenstocks +alpha +alphabet +alphabeted +alphabetic +alphabetical +alphabetically +alphabeting +alphabetization +alphabetizations +alphabetize +alphabetized +alphabetizer +alphabetizers +alphabetizes +alphabetizing +alphabets +alphameric +alphanumeric +alphanumerical +alphanumerically +alphanumerics +alphas +alphorn +alphorns +alphosis +alphosises +alphyl +alphyls +alpine +alpinely +alpines +alpinism +alpinisms +alpinist +alpinists +alps +already +alright +als +alsike +alsikes +also +alt +altar +altarpiece +altarpieces +altars +altazimuth +altazimuths +alter +alterabilities +alterability +alterable +alterably +alterant +alterants +alteration +alterations +altercate +altercated +altercates +altercating +altercation +altercations +altered +alterer +alterers +altering +alternate +alternated +alternately +alternates +alternating +alternation +alternations +alternative +alternatively +alternativeness +alternativenesses +alternatives +alternator +alternators +alters +althaea +althaeas +althea +altheas +altho +althorn +althorns +although +altimeter +altimeters +altimetries +altimetry +altiplano +altiplanos +altitude +altitudes +altitudinal +altitudinous +alto +altocumuli +altocumulus +altogether +altogethers +altoist +altoists +altos +altostrati +altostratus +altricial +altruism +altruisms +altruist +altruistic +altruistically +altruists +alts +aludel +aludels +alula +alulae +alular +alum +alumin +alumina +aluminas +aluminate +aluminates +alumine +alumines +aluminic +aluminium +aluminiums +aluminize +aluminized +aluminizes +aluminizing +aluminosilicate +aluminosilicates +aluminous +alumins +aluminum +aluminums +alumna +alumnae +alumni +alumnus +alumroot +alumroots +alums +alunite +alunites +alveolar +alveolarly +alveolars +alveolate +alveoli +alveolus +alvine +alway +always +alyssum +alyssums +am +ama +amadavat +amadavats +amadou +amadous +amah +amahs +amain +amalgam +amalgamate +amalgamated +amalgamates +amalgamating +amalgamation +amalgamations +amalgamator +amalgamators +amalgams +amandine +amanita +amanitas +amanitin +amanitins +amantadine +amantadines +amanuenses +amanuensis +amaranth +amaranthine +amaranths +amarelle +amarelles +amaretti +amaretto +amarettos +amarna +amaryllis +amaryllises +amas +amass +amassed +amasser +amassers +amasses +amassing +amassment +amassments +amateur +amateurish +amateurishly +amateurishness +amateurishnesses +amateurism +amateurisms +amateurs +amative +amatively +amativeness +amativenesses +amatol +amatols +amatory +amauroses +amaurosis +amaurotic +amaze +amazed +amazedly +amazement +amazements +amazes +amazing +amazingly +amazon +amazonite +amazonites +amazons +amazonstone +amazonstones +ambage +ambages +ambari +ambaries +ambaris +ambary +ambassador +ambassadorial +ambassadors +ambassadorship +ambassadorships +ambassadress +ambassadresses +ambeer +ambeers +amber +ambergris +ambergrises +amberies +amberina +amberinas +amberjack +amberjacks +amberoid +amberoids +ambers +ambery +ambiance +ambiances +ambidexterities +ambidexterity +ambidextrous +ambidextrously +ambience +ambiences +ambient +ambients +ambiguities +ambiguity +ambiguous +ambiguously +ambiguousness +ambiguousnesses +ambisexual +ambisexualities +ambisexuality +ambisexuals +ambit +ambition +ambitioned +ambitioning +ambitionless +ambitions +ambitious +ambitiously +ambitiousness +ambitiousnesses +ambits +ambivalence +ambivalences +ambivalent +ambivalently +ambiversion +ambiversions +ambivert +ambiverts +amble +ambled +ambler +amblers +ambles +ambling +amblygonite +amblygonites +amblyopia +amblyopias +amblyopic +ambo +amboina +amboinas +ambones +ambos +amboyna +amboynas +ambries +ambroid +ambroids +ambrosia +ambrosial +ambrosially +ambrosias +ambrotype +ambrotypes +ambry +ambsace +ambsaces +ambulacra +ambulacral +ambulacrum +ambulance +ambulances +ambulant +ambulate +ambulated +ambulates +ambulating +ambulation +ambulations +ambulatories +ambulatorily +ambulatory +ambuscade +ambuscaded +ambuscader +ambuscaders +ambuscades +ambuscading +ambush +ambushed +ambusher +ambushers +ambushes +ambushing +ambushment +ambushments +ameba +amebae +ameban +amebas +amebean +amebiases +amebiasis +amebic +amebocyte +amebocytes +ameboid +ameer +ameerate +ameerates +ameers +amelcorn +amelcorns +ameliorate +ameliorated +ameliorates +ameliorating +amelioration +ameliorations +ameliorative +ameliorator +ameliorators +amelioratory +ameloblast +ameloblasts +amen +amenabilities +amenability +amenable +amenably +amend +amendable +amendatory +amended +amender +amenders +amending +amendment +amendments +amends +amenities +amenity +amenorrhea +amenorrheas +amenorrheic +amens +ament +amentia +amentias +amentiferous +aments +amerce +amerced +amercement +amercements +amercer +amercers +amerces +amerciable +amercing +americium +americiums +amesace +amesaces +amethyst +amethystine +amethysts +ametropia +ametropias +ametropic +ami +amia +amiabilities +amiability +amiable +amiableness +amiablenesses +amiably +amiantus +amiantuses +amias +amicabilities +amicability +amicable +amicableness +amicablenesses +amicably +amice +amices +amici +amicus +amid +amidase +amidases +amide +amides +amidic +amidin +amidine +amidines +amidins +amido +amidogen +amidogens +amidol +amidols +amidone +amidones +amids +amidship +amidships +amidst +amie +amies +amiga +amigas +amigo +amigos +amin +amine +amines +aminic +aminities +aminity +amino +aminoaciduria +aminoacidurias +aminopeptidase +aminopeptidases +aminophylline +aminophyllines +aminopterin +aminopterins +aminopyrine +aminopyrines +aminotransferase +aminotransferases +amins +amir +amirate +amirates +amirs +amis +amiss +amities +amitoses +amitosis +amitotic +amitotically +amitriptyline +amitriptylines +amitrole +amitroles +amity +ammeter +ammeters +ammine +ammines +ammino +ammo +ammocete +ammocetes +ammonal +ammonals +ammonia +ammoniac +ammoniacal +ammoniacs +ammonias +ammoniate +ammoniated +ammoniates +ammoniating +ammoniation +ammoniations +ammonic +ammonification +ammonifications +ammonified +ammonifies +ammonify +ammonifying +ammonite +ammonites +ammonitic +ammonium +ammoniums +ammono +ammonoid +ammonoids +ammos +ammunition +ammunitions +amnesia +amnesiac +amnesiacs +amnesias +amnesic +amnesics +amnestic +amnestied +amnesties +amnesty +amnestying +amnia +amnic +amniocenteses +amniocentesis +amnion +amnionic +amnions +amniote +amniotes +amniotic +amobarbital +amobarbitals +amoeba +amoebae +amoeban +amoebas +amoebean +amoebiases +amoebiasis +amoebic +amoebocyte +amoebocytes +amoeboid +amok +amoks +amole +amoles +among +amongst +amontillado +amontillados +amoral +amoralism +amoralisms +amoralities +amorality +amorally +amoretti +amoretto +amorettos +amorini +amorino +amorist +amoristic +amorists +amoroso +amorous +amorously +amorousness +amorousnesses +amorphous +amorphously +amorphousness +amorphousnesses +amort +amortise +amortised +amortises +amortising +amortizable +amortization +amortizations +amortize +amortized +amortizes +amortizing +amosite +amosites +amotion +amotions +amount +amounted +amounting +amounts +amour +amours +amoxicillin +amoxicillins +amoxycillin +amoxycillins +amp +amperage +amperages +ampere +amperes +amperometric +ampersand +ampersands +amphetamine +amphetamines +amphibia +amphibian +amphibians +amphibious +amphibiously +amphibiousness +amphibiousnesses +amphibole +amphiboles +amphibolies +amphibolite +amphibolites +amphibologies +amphibology +amphiboly +amphibrach +amphibrachic +amphibrachs +amphictyonic +amphictyonies +amphictyony +amphidiploid +amphidiploidies +amphidiploids +amphidiploidy +amphimacer +amphimacers +amphimixes +amphimixis +amphioxi +amphioxus +amphioxuses +amphipathic +amphiphile +amphiphiles +amphiphilic +amphiploid +amphiploidies +amphiploids +amphiploidy +amphipod +amphipods +amphiprostyle +amphiprostyles +amphisbaena +amphisbaenas +amphisbaenic +amphitheater +amphitheaters +amphitheatric +amphitheatrical +amphitheatrically +amphora +amphorae +amphoral +amphoras +amphoteric +ampicillin +ampicillins +ample +ampleness +amplenesses +ampler +amplest +amplexus +amplexuses +amplidyne +amplidynes +amplification +amplifications +amplified +amplifier +amplifiers +amplifies +amplify +amplifying +amplitude +amplitudes +amply +ampoule +ampoules +amps +ampul +ampule +ampules +ampulla +ampullae +ampullar +ampullary +ampuls +amputate +amputated +amputates +amputating +amputation +amputations +amputee +amputees +amreeta +amreetas +amrita +amritas +amtrac +amtrack +amtracks +amtracs +amu +amuck +amucks +amulet +amulets +amus +amusable +amuse +amused +amusedly +amusement +amusements +amuser +amusers +amuses +amusia +amusias +amusing +amusingly +amusingness +amusingnesses +amusive +amygdala +amygdalae +amygdale +amygdales +amygdalin +amygdalins +amygdaloid +amygdaloidal +amygdaloids +amygdule +amygdules +amyl +amylase +amylases +amylene +amylenes +amylic +amylogen +amylogens +amyloid +amyloidoses +amyloidosis +amyloidosises +amyloids +amylolytic +amylopectin +amylopectins +amyloplast +amyloplasts +amylopsin +amylopsins +amylose +amyloses +amyls +amylum +amylums +amyotonia +amyotonias +an +ana +anabaena +anabaenas +anabaptism +anabaptisms +anabas +anabases +anabasis +anabatic +anableps +anablepses +anabolic +anabolism +anabolisms +anachronic +anachronism +anachronisms +anachronistic +anachronistically +anachronous +anachronously +anaclitic +anacolutha +anacoluthic +anacoluthically +anacoluthon +anacoluthons +anaconda +anacondas +anacreontic +anacreontics +anacruses +anacrusis +anadem +anadems +anadiploses +anadiplosis +anadromous +anaemia +anaemias +anaemic +anaerobe +anaerobes +anaerobic +anaerobically +anaerobioses +anaerobiosis +anaesthesia +anaesthesias +anaesthetic +anaesthetics +anageneses +anagenesis +anaglyph +anaglyphic +anaglyphs +anagnorises +anagnorisis +anagoge +anagoges +anagogic +anagogical +anagogically +anagogies +anagogy +anagram +anagrammatic +anagrammatical +anagrammatically +anagrammatization +anagrammatizations +anagrammatize +anagrammatized +anagrammatizes +anagrammatizing +anagrammed +anagramming +anagrams +anal +analcime +analcimes +analcite +analcites +analecta +analects +analemma +analemmas +analemmata +analemmatic +analeptic +analeptics +analgesia +analgesias +analgesic +analgesics +analgetic +analgetics +analgia +analgias +analities +anality +anally +analog +analogic +analogical +analogically +analogies +analogist +analogists +analogize +analogized +analogizes +analogizing +analogous +analogously +analogousness +analogousnesses +analogs +analogue +analogues +analogy +analphabet +analphabetic +analphabetics +analphabetism +analphabetisms +analphabets +analysand +analysands +analyse +analysed +analyser +analysers +analyses +analysing +analysis +analyst +analysts +analytic +analytical +analytically +analyticities +analyticity +analytics +analyzabilities +analyzability +analyzable +analyzation +analyzations +analyze +analyzed +analyzer +analyzers +analyzes +analyzing +anamneses +anamnesis +anamnestic +anamorphic +ananke +anankes +anapaest +anapaests +anapest +anapestic +anapestics +anapests +anaphase +anaphases +anaphasic +anaphor +anaphora +anaphoras +anaphoric +anaphorically +anaphors +anaphrodisiac +anaphrodisiacs +anaphylactic +anaphylactically +anaphylactoid +anaphylaxes +anaphylaxis +anaplasia +anaplasias +anaplasmoses +anaplasmosis +anaplastic +anarch +anarchic +anarchical +anarchically +anarchies +anarchism +anarchisms +anarchist +anarchistic +anarchists +anarchs +anarchy +anas +anasarca +anasarcas +anasarcous +anastigmat +anastigmatic +anastigmats +anastomose +anastomosed +anastomoses +anastomosing +anastomosis +anastomotic +anastrophe +anastrophes +anatase +anatases +anathema +anathemas +anathemata +anathematize +anathematized +anathematizes +anathematizing +anatomic +anatomical +anatomically +anatomies +anatomise +anatomised +anatomises +anatomising +anatomist +anatomists +anatomize +anatomized +anatomizes +anatomizing +anatomy +anatoxin +anatoxins +anatropous +anatto +anattos +ancestor +ancestored +ancestoring +ancestors +ancestral +ancestrally +ancestress +ancestresses +ancestries +ancestry +anchor +anchorage +anchorages +anchored +anchoress +anchoresses +anchoret +anchorets +anchoring +anchorite +anchorites +anchoritic +anchoritically +anchorless +anchorman +anchormen +anchorpeople +anchorperson +anchorpersons +anchors +anchorwoman +anchorwomen +anchoveta +anchovetas +anchovetta +anchovettas +anchovies +anchovy +anchusa +anchusas +anchusin +anchusins +ancient +ancienter +ancientest +anciently +ancientness +ancientnesses +ancientries +ancientry +ancients +ancilla +ancillae +ancillaries +ancillary +ancillas +ancon +anconal +ancone +anconeal +ancones +anconoid +ancress +ancresses +ancylostomiases +ancylostomiasis +and +andalusite +andalusites +andante +andantes +andantino +andantinos +andesite +andesites +andesitic +andesyte +andesytes +andiron +andirons +andouille +andouilles +andouillette +andouillettes +andradite +andradites +androcentric +androecia +androecium +androgen +androgeneses +androgenesis +androgenetic +androgenic +androgens +androgyne +androgynes +androgynies +androgynous +androgyny +android +androids +andromeda +andromedas +androsterone +androsterones +ands +ane +anear +aneared +anearing +anears +anecdota +anecdotage +anecdotages +anecdotal +anecdotalism +anecdotalisms +anecdotalist +anecdotalists +anecdotally +anecdote +anecdotes +anecdotic +anecdotical +anecdotically +anecdotist +anecdotists +anechoic +anelastic +anelasticities +anelasticity +anele +aneled +aneles +aneling +anemia +anemias +anemic +anemically +anemograph +anemographs +anemometer +anemometers +anemometries +anemometry +anemone +anemones +anemophilous +anemoses +anemosis +anencephalic +anencephalies +anencephaly +anenst +anent +anergia +anergias +anergic +anergies +anergy +aneroid +aneroids +anes +anesthesia +anesthesias +anesthesiologies +anesthesiologist +anesthesiologists +anesthesiology +anesthetic +anesthetically +anesthetics +anesthetist +anesthetists +anesthetize +anesthetized +anesthetizes +anesthetizing +anestri +anestrous +anestrus +anestruses +anethol +anethole +anetholes +anethols +aneuploid +aneuploidies +aneuploids +aneuploidy +aneurin +aneurins +aneurism +aneurisms +aneurysm +aneurysmal +aneurysms +anew +anfractuosities +anfractuosity +anfractuous +anga +angakok +angakoks +angaria +angarias +angaries +angary +angas +angel +angeled +angelfish +angelfishes +angelic +angelica +angelical +angelically +angelicas +angeling +angelologies +angelologist +angelologists +angelology +angels +angelus +angeluses +anger +angered +angering +angerless +angerly +angers +angina +anginal +anginas +anginose +anginous +angiocardiographic +angiocardiographies +angiocardiography +angiogeneses +angiogenesis +angiogenic +angiogram +angiograms +angiographic +angiographies +angiography +angioma +angiomas +angiomata +angiomatous +angioplasties +angioplasty +angiosperm +angiospermous +angiosperms +angiotensin +angiotensins +angle +angled +anglepod +anglepods +angler +anglerfish +anglerfishes +anglers +angles +anglesite +anglesites +angleworm +angleworms +anglice +anglicise +anglicised +anglicises +anglicising +anglicism +anglicisms +anglicization +anglicizations +anglicize +anglicized +anglicizes +anglicizing +angling +anglings +anglophone +angora +angoras +angrier +angriest +angrily +angriness +angrinesses +angry +angst +angstrom +angstroms +angsts +anguine +anguish +anguished +anguishes +anguishing +angular +angularities +angularity +angularly +angulate +angulated +angulates +angulating +angulation +angulations +angulose +angulous +anhedonia +anhedonias +anhedonic +anhinga +anhingas +anhydride +anhydrides +anhydrite +anhydrites +anhydrous +ani +anil +anile +anilin +anilinctus +anilinctuses +aniline +anilines +anilingus +anilinguses +anilins +anilities +anility +anils +anima +animadversion +animadversions +animadvert +animadverted +animadverting +animadverts +animal +animalcula +animalcule +animalcules +animalculum +animalic +animalier +animaliers +animalism +animalisms +animalistic +animalities +animality +animalization +animalizations +animalize +animalized +animalizes +animalizing +animallike +animally +animals +animas +animate +animated +animatedly +animately +animateness +animatenesses +animater +animaters +animates +animating +animation +animations +animato +animator +animators +anime +animes +animi +animis +animism +animisms +animist +animistic +animists +animosities +animosity +animus +animuses +anion +anionic +anions +anis +anise +aniseed +aniseeds +aniseikonia +aniseikonias +aniseikonic +anises +anisette +anisettes +anisic +anisogamies +anisogamous +anisogamy +anisole +anisoles +anisometropia +anisometropias +anisometropic +anisotropic +anisotropically +anisotropies +anisotropism +anisotropisms +anisotropy +ankerite +ankerites +ankh +ankhs +ankle +anklebone +anklebones +ankled +ankles +anklet +anklets +ankling +ankus +ankuses +ankush +ankushes +ankylosaur +ankylosaurs +ankylosaurus +ankylosauruses +ankylose +ankylosed +ankyloses +ankylosing +ankylosis +ankylostomiases +ankylostomiasis +ankylotic +anlace +anlaces +anlage +anlagen +anlages +anlas +anlases +anna +annal +annalist +annalistic +annalists +annals +annas +annates +annatto +annattos +anneal +annealed +annealer +annealers +annealing +anneals +annelid +annelidan +annelidans +annelids +annex +annexation +annexational +annexationist +annexationists +annexations +annexe +annexed +annexes +annexing +annihilate +annihilated +annihilates +annihilating +annihilation +annihilations +annihilator +annihilators +annihilatory +anniversaries +anniversary +annotate +annotated +annotates +annotating +annotation +annotations +annotative +annotator +annotators +announce +announced +announcement +announcements +announcer +announcers +announces +announcing +annoy +annoyance +annoyances +annoyed +annoyer +annoyers +annoying +annoyingly +annoys +annual +annualize +annualized +annualizes +annualizing +annually +annuals +annuitant +annuitants +annuities +annuity +annul +annular +annulate +annulation +annulations +annulet +annulets +annuli +annulled +annulling +annulment +annulments +annulose +annuls +annulus +annuluses +annunciate +annunciated +annunciates +annunciating +annunciation +annunciations +annunciator +annunciators +annunciatory +anoa +anoas +anodal +anodally +anode +anodes +anodic +anodically +anodization +anodizations +anodize +anodized +anodizes +anodizing +anodyne +anodynes +anodynic +anoint +anointed +anointer +anointers +anointing +anointment +anointments +anoints +anole +anoles +anolyte +anolytes +anomalies +anomalous +anomalously +anomalousness +anomalousnesses +anomaly +anomic +anomie +anomies +anomy +anon +anonym +anonymities +anonymity +anonymous +anonymously +anonymousness +anonymousnesses +anonyms +anoopsia +anoopsias +anopheles +anopheline +anophelines +anopia +anopias +anopsia +anopsias +anorak +anoraks +anorectic +anorectics +anoretic +anoretics +anorexia +anorexias +anorexic +anorexics +anorexies +anorexigenic +anorexy +anorthic +anorthite +anorthites +anorthitic +anorthosite +anorthosites +anorthositic +anosmia +anosmias +anosmic +another +anovular +anovulatory +anoxemia +anoxemias +anoxemic +anoxia +anoxias +anoxic +ansa +ansae +ansate +ansated +anserine +anserines +anserous +answer +answerable +answered +answerer +answerers +answering +answers +ant +anta +antacid +antacids +antae +antagonism +antagonisms +antagonist +antagonistic +antagonistically +antagonists +antagonize +antagonized +antagonizes +antagonizing +antalgic +antalgics +antarctic +antas +antbear +antbears +ante +anteater +anteaters +antebellum +antecede +anteceded +antecedence +antecedences +antecedent +antecedently +antecedents +antecedes +anteceding +antecessor +antecessors +antechamber +antechambers +antechapel +antechapels +antechoir +antechoirs +anted +antedate +antedated +antedates +antedating +antediluvian +antediluvians +anteed +antefix +antefixa +antefixae +antefixes +anteing +antelope +antelopes +antemortem +antenatal +antenatally +antenna +antennae +antennal +antennas +antennular +antennule +antennules +antenuptial +antepast +antepasts +antependia +antependium +antependiums +antepenult +antepenultima +antepenultimas +antepenultimate +antepenultimates +antepenults +anterior +anteriorly +anteroom +anterooms +antes +antetype +antetypes +antevert +anteverted +anteverting +anteverts +anthelia +anthelices +anthelion +anthelions +anthelix +anthelixes +anthelmintic +anthelmintics +anthem +anthemed +anthemia +antheming +anthemion +anthems +anther +antheral +antherid +antheridia +antheridial +antheridium +antherids +anthers +antheses +anthesis +anthill +anthills +anthocyan +anthocyanin +anthocyanins +anthocyans +anthodia +anthodium +anthoid +anthological +anthologies +anthologist +anthologists +anthologize +anthologized +anthologizer +anthologizers +anthologizes +anthologizing +anthology +anthophilous +anthophyllite +anthophyllites +anthozoan +anthozoans +anthracene +anthracenes +anthraces +anthracite +anthracites +anthracitic +anthracnose +anthracnoses +anthranilate +anthranilates +anthraquinone +anthraquinones +anthrax +anthropic +anthropical +anthropocentric +anthropocentrically +anthropocentricities +anthropocentricity +anthropocentrism +anthropocentrisms +anthropogenic +anthropoid +anthropoids +anthropological +anthropologically +anthropologies +anthropologist +anthropologists +anthropology +anthropometric +anthropometries +anthropometry +anthropomorph +anthropomorphic +anthropomorphically +anthropomorphism +anthropomorphisms +anthropomorphist +anthropomorphists +anthropomorphization +anthropomorphizations +anthropomorphize +anthropomorphized +anthropomorphizes +anthropomorphizing +anthropomorphs +anthropopathism +anthropopathisms +anthropophagi +anthropophagies +anthropophagous +anthropophagus +anthropophagy +anthroposophies +anthroposophy +anthurium +anthuriums +anti +antiabortion +antiabortionist +antiabortionists +antiacademic +antiacademics +antiadministration +antiaggression +antiaging +antiair +antiaircraft +antiaircrafts +antialcohol +antialcoholism +antialcoholisms +antialien +antiallergenic +antiallergenics +antianemia +antianxiety +antiapartheid +antiapartheids +antiaphrodisiac +antiaphrodisiacs +antiar +antiarin +antiarins +antiaristocratic +antiarrhythmic +antiarrhythmics +antiars +antiarthritic +antiarthritics +antiarthritis +antiassimilation +antiassimilations +antiasthma +antiatom +antiatoms +antiauthoritarian +antiauthoritarianism +antiauthoritarianisms +antiauthority +antiauxin +antiauxins +antibacklash +antibacterial +antibacterials +antibaryon +antibaryons +antibias +antibillboard +antibioses +antibiosis +antibiotic +antibiotically +antibiotics +antiblack +antiblackism +antiblackisms +antibodies +antibody +antiboss +antibourgeois +antiboycott +antiboycotts +antibug +antibureaucratic +antiburglar +antiburglary +antibusiness +antibusing +antic +anticaking +antically +anticancer +anticapitalism +anticapitalisms +anticapitalist +anticapitalists +anticar +anticarcinogen +anticarcinogenic +anticarcinogens +anticaries +anticatalyst +anticatalysts +anticathode +anticathodes +anticellulite +anticensorship +anticholesterol +anticholinergic +anticholinergics +anticholinesterase +anticholinesterases +antichurch +anticigarette +anticipant +anticipants +anticipatable +anticipate +anticipated +anticipates +anticipating +anticipation +anticipations +anticipator +anticipators +anticipatory +anticity +antick +anticked +anticking +anticks +anticlassical +anticlerical +anticlericalism +anticlericalisms +anticlericalist +anticlericalists +anticlericals +anticlimactic +anticlimactical +anticlimactically +anticlimax +anticlimaxes +anticlinal +anticline +anticlines +anticling +anticlockwise +anticlotting +anticly +anticoagulant +anticoagulants +anticodon +anticodons +anticold +anticollision +anticolonial +anticolonialism +anticolonialisms +anticolonialist +anticolonialists +anticolonials +anticommercial +anticommercialism +anticommercialisms +anticommunism +anticommunisms +anticommunist +anticommunists +anticompetitive +anticonglomerate +anticonservation +anticonservationist +anticonservationists +anticonservations +anticonsumer +anticonsumers +anticonventional +anticonvulsant +anticonvulsants +anticonvulsive +anticonvulsives +anticorporate +anticorrosion +anticorrosive +anticorrosives +anticorruption +anticorruptions +anticounterfeiting +anticrack +anticreative +anticrime +anticruelty +antics +anticult +anticultural +anticyclone +anticyclones +anticyclonic +antidandruff +antidefamation +antidemocratic +antidepressant +antidepressants +antidepression +antidepressions +antiderivative +antiderivatives +antidesegregation +antidesertification +antidesiccant +antidesiccants +antidevelopment +antidiabetic +antidiarrheal +antidilution +antidiscrimination +antidogmatic +antidora +antidotal +antidotally +antidote +antidoted +antidotes +antidoting +antidraft +antidromic +antidromically +antidrug +antidumping +antieconomic +antieducational +antiegalitarian +antielectron +antielectrons +antielite +antielites +antielitism +antielitisms +antielitist +antielitists +antiemetic +antiemetics +antientropic +antiepilepsy +antiepileptic +antiepileptics +antierotic +antiestablishment +antiestrogen +antiestrogens +antievolution +antievolutionary +antievolutionism +antievolutionisms +antievolutionist +antievolutionists +antifamily +antifascism +antifascisms +antifascist +antifascists +antifashion +antifashionable +antifashions +antifat +antifatigue +antifederalist +antifederalists +antifemale +antifeminine +antifeminism +antifeminisms +antifeminist +antifeminists +antiferromagnet +antiferromagnetic +antiferromagnetically +antiferromagnetism +antiferromagnetisms +antiferromagnets +antifertility +antifilibuster +antifilibusters +antiflu +antifluoridationist +antifluoridationists +antifoam +antifoaming +antifogging +antiforeclosure +antiforeign +antiforeigner +antiformalist +antiformalists +antifouling +antifraud +antifreeze +antifreezes +antifriction +antifrictions +antifungal +antifungals +antifur +antigambling +antigay +antigen +antigene +antigenes +antigenic +antigenically +antigenicities +antigenicity +antigens +antiglare +antiglobulin +antiglobulins +antigovernment +antigravities +antigravity +antigrowth +antiguerrilla +antiguerrillas +antigun +antihero +antiheroes +antiheroic +antiheroine +antiheroines +antiherpes +antihierarchical +antihijack +antihistamine +antihistamines +antihistaminic +antihistaminics +antihistorical +antihomosexual +antihuman +antihumanism +antihumanisms +antihumanistic +antihumanitarian +antihumanitarians +antihunter +antihunting +antihuntings +antihypertensive +antihypertensives +antihysteric +antihysterics +antijam +antijamming +antikickback +antiking +antikings +antiknock +antiknocks +antilabor +antileak +antileft +antileprosy +antilepton +antileptons +antileukemic +antiliberal +antiliberalism +antiliberalisms +antiliberals +antilibertarian +antilibertarians +antilife +antiliterate +antiliterates +antilitter +antilittering +antilock +antilog +antilogarithm +antilogarithmic +antilogarithms +antilogical +antilogies +antilogs +antilogy +antilynching +antimacassar +antimacassars +antimacho +antimagnetic +antimalaria +antimalarial +antimalarials +antimale +antiman +antimanagement +antimanagements +antimarijuana +antimarket +antimask +antimasks +antimaterialism +antimaterialisms +antimaterialist +antimaterialists +antimatter +antimatters +antimechanist +antimechanists +antimere +antimeres +antimerger +antimetabolic +antimetabolics +antimetabolite +antimetabolites +antimetaphysical +antimicrobial +antimicrobials +antimilitarism +antimilitarisms +antimilitarist +antimilitarists +antimilitary +antimiscegenation +antimissile +antimissiles +antimitotic +antimitotics +antimodern +antimodernist +antimodernists +antimoderns +antimonarchical +antimonarchist +antimonarchists +antimonial +antimonials +antimonide +antimonides +antimonies +antimonopolist +antimonopolists +antimonopoly +antimony +antimosquito +antimusical +antimycin +antimycins +antinarrative +antinational +antinationalist +antinationalists +antinatural +antinature +antinatures +antinausea +antineoplastic +antinepotism +antinepotisms +antineutrino +antineutrinos +antineutron +antineutrons +anting +antings +antinodal +antinode +antinodes +antinoise +antinomian +antinomianism +antinomianisms +antinomians +antinomic +antinomies +antinomy +antinovel +antinovelist +antinovelists +antinovels +antinuclear +antinucleon +antinucleons +antinuke +antiobesities +antiobesity +antiobscenities +antiobscenity +antiorganization +antiorganizations +antioxidant +antioxidants +antiozonant +antiozonants +antipapal +antiparallel +antiparasitic +antiparasitics +antiparticle +antiparticles +antiparty +antipasti +antipasto +antipastos +antipathetic +antipathetically +antipathies +antipathy +antiperiodic +antipersonnel +antiperspirant +antiperspirants +antipesticide +antiphlogistic +antiphon +antiphonal +antiphonally +antiphonals +antiphonaries +antiphonary +antiphonies +antiphons +antiphony +antiphrases +antiphrasis +antipill +antipiracies +antipiracy +antiplague +antiplagues +antiplaque +antipleasure +antipleasures +antipoaching +antipodal +antipodals +antipode +antipodean +antipodeans +antipodes +antipoetic +antipole +antipoles +antipolice +antipolitical +antipolitics +antipollution +antipollutions +antipope +antipopes +antipopular +antiporn +antipornographic +antipornography +antipot +antipoverty +antipredator +antipredators +antipress +antiprofiteering +antiprogressive +antiprostitution +antiproton +antiprotons +antipruritic +antipruritics +antipsychotic +antipsychotics +antipyic +antipyics +antipyreses +antipyresis +antipyretic +antipyretics +antipyrine +antipyrines +antiquarian +antiquarianism +antiquarianisms +antiquarians +antiquaries +antiquark +antiquarks +antiquary +antiquate +antiquated +antiquates +antiquating +antiquation +antiquations +antique +antiqued +antiquer +antiquers +antiques +antiquing +antiquities +antiquity +antirabies +antirachitic +antiracism +antiracisms +antiracist +antiracists +antiracketeering +antiradar +antiradical +antiradicalism +antiradicalisms +antirape +antirational +antirationalism +antirationalisms +antirationalist +antirationalists +antirationalities +antirationality +antirealism +antirealisms +antirealist +antirealists +antirecession +antirecessionary +antirecessions +antired +antireductionism +antireductionisms +antireductionist +antireductionists +antireflection +antireflective +antireform +antiregulatory +antirejection +antireligion +antireligious +antirevolutionaries +antirevolutionary +antirheumatic +antirheumatics +antiriot +antiritualism +antiritualisms +antirock +antiroll +antiromantic +antiromanticism +antiromanticisms +antiromantics +antiroyalist +antiroyalists +antirrhinum +antirrhinums +antirust +antirusts +antis +antisag +antisatellite +antischizophrenia +antischizophrenic +antiscience +antisciences +antiscientific +antiscorbutic +antiscorbutics +antisecrecy +antisegregation +antiseizure +antisense +antisentimental +antiseparatist +antiseparatists +antisepses +antisepsis +antiseptic +antiseptically +antiseptics +antisera +antiserum +antiserums +antisex +antisexist +antisexists +antisexual +antisexualities +antisexuality +antishark +antiship +antishock +antishoplifting +antiskid +antislaveries +antislavery +antisleep +antislip +antismog +antismoke +antismoker +antismokers +antismoking +antismuggling +antismut +antisnob +antisocial +antisocialist +antisocialists +antisocially +antisolar +antispasmodic +antispasmodics +antispeculation +antispeculative +antispending +antistat +antistate +antistatic +antistick +antistories +antistory +antistress +antistrike +antistrophe +antistrophes +antistrophic +antistrophically +antistudent +antisubmarine +antisubsidy +antisubversion +antisubversions +antisubversive +antisubversives +antisuicide +antisymmetric +antisyphilitic +antisyphilitics +antitakeover +antitank +antitarnish +antitax +antitechnological +antitechnologies +antitechnology +antiterrorism +antiterrorisms +antiterrorist +antiterrorists +antitheft +antitheoretical +antitheses +antithesis +antithetic +antithetical +antithetically +antithrombin +antithrombins +antithyroid +antitobacco +antitotalitarian +antitoxic +antitoxin +antitoxins +antitrades +antitraditional +antitrust +antitruster +antitrusters +antitubercular +antituberculosis +antituberculous +antitumor +antitumoral +antitussive +antitussives +antitype +antitypes +antityphoid +antiulcer +antiunemployment +antiunion +antiuniversities +antiuniversity +antiurban +antivenin +antivenins +antiviolence +antiviral +antivirus +antivitamin +antivitamins +antivivisection +antivivisectionist +antivivisectionists +antiwar +antiwear +antiweed +antiwelfare +antiwhaling +antiwhite +antiwoman +antiwrinkle +antler +antlered +antlers +antlike +antlion +antlions +antonomasia +antonomasias +antonym +antonymic +antonymies +antonymous +antonyms +antonymy +antra +antral +antre +antres +antrorse +antrum +antrums +ants +antsier +antsiest +antsy +anural +anuran +anurans +anureses +anuresis +anuretic +anuria +anurias +anuric +anurous +anus +anuses +anvil +anviled +anviling +anvilled +anvilling +anvils +anviltop +anviltops +anxieties +anxiety +anxiolytic +anxiolytics +anxious +anxiously +anxiousness +anxiousnesses +any +anybodies +anybody +anyhow +anymore +anyone +anyplace +anything +anythings +anytime +anyway +anyways +anywhere +anywheres +anywise +aorist +aoristic +aoristically +aorists +aorta +aortae +aortal +aortas +aortic +aortographic +aortographies +aortography +aoudad +aoudads +apace +apache +apaches +apagoge +apagoges +apagogic +apanage +apanages +aparejo +aparejos +apart +apartheid +apartheids +apartment +apartmental +apartments +apartness +apartnesses +apatetic +apathetic +apathetically +apathies +apathy +apatite +apatites +apatosaurus +apatosauruses +ape +apeak +aped +apeek +apelike +aper +apercu +apercus +aperient +aperients +aperies +aperiodic +aperiodically +aperiodicities +aperiodicity +aperitif +aperitifs +apers +aperture +apertures +apery +apes +apetalies +apetalous +apetaly +apex +apexes +aphaereses +aphaeresis +aphaeretic +aphagia +aphagias +aphanite +aphanites +aphanitic +aphasia +aphasiac +aphasiacs +aphasias +aphasic +aphasics +aphelia +aphelian +aphelion +aphelions +aphereses +apheresis +apheses +aphesis +aphetic +aphetically +aphid +aphides +aphidian +aphidians +aphids +aphis +apholate +apholates +aphonia +aphonias +aphonic +aphonics +aphorise +aphorised +aphorises +aphorising +aphorism +aphorisms +aphorist +aphoristic +aphoristically +aphorists +aphorize +aphorized +aphorizes +aphorizing +aphotic +aphrodisiac +aphrodisiacal +aphrodisiacs +aphtha +aphthae +aphthous +aphyllies +aphylly +apian +apiarian +apiarians +apiaries +apiarist +apiarists +apiary +apical +apically +apicals +apices +apiculate +apiculi +apicultural +apiculture +apicultures +apiculturist +apiculturists +apiculus +apiece +apimania +apimanias +aping +apiologies +apiology +apish +apishly +apishness +apishnesses +aplanatic +aplasia +aplasias +aplastic +aplenty +aplite +aplites +aplitic +aplomb +aplombs +apnea +apneal +apneas +apneic +apnoea +apnoeal +apnoeas +apnoeic +apoapsides +apoapsis +apocalypse +apocalypses +apocalyptic +apocalyptical +apocalyptically +apocalypticism +apocalypticisms +apocalyptism +apocalyptisms +apocalyptist +apocalyptists +apocarp +apocarpies +apocarps +apocarpy +apochromatic +apocope +apocopes +apocopic +apocrine +apocrypha +apocryphal +apocryphally +apocryphalness +apocryphalnesses +apod +apodal +apodeictic +apodictic +apodictically +apodoses +apodosis +apodous +apods +apoenzyme +apoenzymes +apogamic +apogamies +apogamous +apogamy +apogeal +apogean +apogee +apogees +apogeic +apolipoprotein +apolipoproteins +apolitical +apolitically +apollo +apollos +apolog +apologal +apologetic +apologetically +apologetics +apologia +apologiae +apologias +apologies +apologise +apologised +apologises +apologising +apologist +apologists +apologize +apologized +apologizer +apologizers +apologizes +apologizing +apologs +apologue +apologues +apology +apolune +apolunes +apomict +apomictic +apomictically +apomicts +apomixes +apomixis +apomorphine +apomorphines +aponeuroses +aponeurosis +aponeurotic +apophonies +apophony +apophthegm +apophthegms +apophyge +apophyges +apophyllite +apophyllites +apophyseal +apophyses +apophysis +apoplectic +apoplectically +apoplexies +apoplexy +aport +aposematic +aposematically +aposiopeses +aposiopesis +aposiopetic +apospories +aposporous +apospory +apostacies +apostacy +apostasies +apostasy +apostate +apostates +apostatise +apostatised +apostatises +apostatising +apostatize +apostatized +apostatizes +apostatizing +apostil +apostils +apostle +apostles +apostleship +apostleships +apostolate +apostolates +apostolic +apostolicities +apostolicity +apostrophe +apostrophes +apostrophic +apostrophise +apostrophised +apostrophises +apostrophising +apostrophize +apostrophized +apostrophizes +apostrophizing +apothecaries +apothecary +apothece +apotheces +apothecia +apothecial +apothecium +apothegm +apothegmatic +apothegms +apothem +apothems +apotheoses +apotheosis +apotheosize +apotheosized +apotheosizes +apotheosizing +apotropaic +apotropaically +appal +appall +appalled +appalling +appallingly +appalls +appals +appanage +appanages +apparat +apparatchik +apparatchiki +apparatchiks +apparats +apparatus +apparatuses +apparel +appareled +appareling +apparelled +apparelling +apparels +apparent +apparently +apparentness +apparentnesses +apparition +apparitional +apparitions +apparitor +apparitors +appeal +appealabilities +appealability +appealable +appealed +appealer +appealers +appealing +appealingly +appeals +appear +appearance +appearances +appeared +appearing +appears +appeasable +appease +appeased +appeasement +appeasements +appeaser +appeasers +appeases +appeasing +appel +appellant +appellants +appellate +appellation +appellations +appellative +appellatively +appellatives +appellee +appellees +appellor +appellors +appels +append +appendage +appendages +appendant +appendants +appendectomies +appendectomy +appended +appendicectomies +appendicectomy +appendices +appendicites +appendicitides +appendicitis +appendicitises +appendicular +appending +appendix +appendixes +appends +apperceive +apperceived +apperceives +apperceiving +apperception +apperceptions +apperceptive +appertain +appertained +appertaining +appertains +appestat +appestats +appetence +appetences +appetencies +appetency +appetent +appetiser +appetisers +appetising +appetite +appetites +appetitive +appetizer +appetizers +appetizing +appetizingly +applaud +applaudable +applaudably +applauded +applauder +applauders +applauding +applauds +applause +applauses +apple +applecart +applecarts +applejack +applejacks +apples +applesauce +applesauces +appliance +appliances +applicabilities +applicability +applicable +applicant +applicants +application +applications +applicative +applicatively +applicator +applicators +applicatory +applied +applier +appliers +applies +applique +appliqued +appliqueing +appliques +apply +applying +appoggiatura +appoggiaturas +appoint +appointed +appointee +appointees +appointing +appointive +appointment +appointments +appoints +apportion +apportionable +apportioned +apportioning +apportionment +apportionments +apportions +appose +apposed +apposer +apposers +apposes +apposing +apposite +appositely +appositeness +appositenesses +apposition +appositional +appositions +appositive +appositively +appositives +appraisal +appraisals +appraise +appraised +appraisee +appraisees +appraisement +appraisements +appraiser +appraisers +appraises +appraising +appraisingly +appraisive +appreciable +appreciably +appreciate +appreciated +appreciates +appreciating +appreciation +appreciations +appreciative +appreciatively +appreciativeness +appreciativenesses +appreciator +appreciators +appreciatory +apprehend +apprehended +apprehending +apprehends +apprehensible +apprehensibly +apprehension +apprehensions +apprehensive +apprehensively +apprehensiveness +apprehensivenesses +apprentice +apprenticed +apprentices +apprenticeship +apprenticeships +apprenticing +appressed +appressoria +appressorium +apprise +apprised +appriser +apprisers +apprises +apprising +apprize +apprized +apprizer +apprizers +apprizes +apprizing +approach +approachabilities +approachability +approachable +approached +approaches +approaching +approbate +approbated +approbates +approbating +approbation +approbations +approbatory +appropriable +appropriate +appropriated +appropriately +appropriateness +appropriatenesses +appropriates +appropriating +appropriation +appropriations +appropriative +appropriator +appropriators +approvable +approvably +approval +approvals +approve +approved +approver +approvers +approves +approving +approvingly +approximate +approximated +approximately +approximates +approximating +approximation +approximations +approximative +appulse +appulses +appurtenance +appurtenances +appurtenant +appurtenants +apractic +apraxia +apraxias +apraxic +apres +apricot +apricots +apriorities +apriority +apron +aproned +aproning +aprons +apropos +aprotic +apse +apses +apsidal +apsides +apsis +apt +apter +apteral +apteria +apterium +apterous +apteryx +apteryxes +aptest +aptitude +aptitudes +aptitudinal +aptitudinally +aptly +aptness +aptnesses +apyrase +apyrases +apyretic +aqua +aquacade +aquacades +aquacultural +aquaculture +aquacultures +aquaculturist +aquaculturists +aquae +aquamarine +aquamarines +aquanaut +aquanauts +aquaplane +aquaplaned +aquaplaner +aquaplaners +aquaplanes +aquaplaning +aquarelle +aquarelles +aquarellist +aquarellists +aquaria +aquarial +aquarian +aquarians +aquarist +aquarists +aquarium +aquariums +aquas +aquatic +aquatically +aquatics +aquatint +aquatinted +aquatinter +aquatinters +aquatinting +aquatintist +aquatintists +aquatints +aquatone +aquatones +aquavit +aquavits +aqueduct +aqueducts +aqueous +aquiculture +aquicultures +aquifer +aquiferous +aquifers +aquilegia +aquilegias +aquiline +aquilinities +aquilinity +aquiver +ar +arabesk +arabesks +arabesque +arabesques +arabic +arabica +arabicas +arabicization +arabicizations +arabicize +arabicized +arabicizes +arabicizing +arabilities +arability +arabinose +arabinoses +arabinoside +arabinosides +arabize +arabized +arabizes +arabizing +arable +arables +araceous +arachnid +arachnids +arachnoid +arachnoids +aragonite +aragonites +aragonitic +arak +araks +aramid +aramids +araneid +araneids +arapaima +arapaimas +araroba +ararobas +araucaria +araucarian +araucarias +arb +arbalest +arbalests +arbalist +arbalists +arbelest +arbelests +arbiter +arbiters +arbitrable +arbitrage +arbitraged +arbitrager +arbitragers +arbitrages +arbitrageur +arbitrageurs +arbitraging +arbitral +arbitrament +arbitraments +arbitrarily +arbitrariness +arbitrarinesses +arbitrary +arbitrate +arbitrated +arbitrates +arbitrating +arbitration +arbitrational +arbitrations +arbitrative +arbitrator +arbitrators +arbor +arboreal +arboreally +arbored +arboreous +arbores +arborescence +arborescences +arborescent +arboreta +arboretum +arboretums +arboricultural +arboriculture +arboricultures +arborist +arborists +arborization +arborizations +arborize +arborized +arborizes +arborizing +arborous +arbors +arborvitae +arborvitaes +arbour +arboured +arbours +arbovirus +arboviruses +arbs +arbuscle +arbuscles +arbute +arbutean +arbutes +arbutus +arbutuses +arc +arcade +arcaded +arcades +arcadia +arcadian +arcadians +arcadias +arcading +arcadings +arcana +arcane +arcanum +arcanums +arcature +arcatures +arccosine +arccosines +arced +arch +archaebacteria +archaebacterium +archaeoastronomies +archaeoastronomy +archaeological +archaeologically +archaeologies +archaeologist +archaeologists +archaeology +archaeopteryx +archaeopteryxes +archaic +archaically +archaise +archaised +archaises +archaising +archaism +archaisms +archaist +archaistic +archaists +archaize +archaized +archaizes +archaizing +archangel +archangelic +archangels +archbishop +archbishopric +archbishoprics +archbishops +archconservative +archconservatives +archdeacon +archdeaconries +archdeaconry +archdeacons +archdiocesan +archdiocese +archdioceses +archducal +archduchess +archduchesses +archduchies +archduchy +archduke +archdukedom +archdukedoms +archdukes +arched +archegonia +archegonial +archegoniate +archegoniates +archegonium +archenemies +archenemy +archenteron +archenterons +archeological +archeologically +archeologies +archeologist +archeologists +archeology +archer +archerfish +archerfishes +archeries +archers +archery +arches +archesporia +archesporial +archesporium +archetypal +archetypally +archetype +archetypes +archetypical +archfiend +archfiends +archidiaconal +archiepiscopal +archiepiscopally +archiepiscopate +archiepiscopates +archil +archils +archimandrite +archimandrites +archine +archines +arching +archings +archipelagic +archipelago +archipelagoes +archipelagos +architect +architectonic +architectonically +architectonics +architects +architectural +architecturally +architecture +architectures +architrave +architraves +archival +archive +archived +archives +archiving +archivist +archivists +archivolt +archivolts +archly +archness +archnesses +archon +archons +archosaur +archosaurian +archosaurs +archpriest +archpriests +archway +archways +arciform +arcing +arcked +arcking +arco +arcs +arcsine +arcsines +arctangent +arctangents +arctic +arctically +arctics +arcuate +arcuated +arcuately +arcus +arcuses +ardeb +ardebs +ardencies +ardency +ardent +ardently +ardor +ardors +ardour +ardours +arduous +arduously +arduousness +arduousnesses +are +area +areae +areal +areally +areas +areaway +areaways +areca +arecas +arecoline +arecolines +areic +arena +arenaceous +arenas +arenicolous +arenite +arenites +arenose +arenous +areocentric +areola +areolae +areolar +areolas +areolate +areole +areoles +areologies +areology +ares +arete +aretes +arethusa +arethusas +arf +arfs +argal +argala +argalas +argali +argalis +argals +argent +argental +argentic +argentiferous +argentine +argentines +argentite +argentites +argents +argentum +argentums +argil +argillaceous +argillite +argillites +argils +arginase +arginases +arginine +arginines +argle +argled +argles +argling +argol +argols +argon +argonaut +argonauts +argons +argosies +argosy +argot +argotic +argots +arguable +arguably +argue +argued +arguer +arguers +argues +argufied +argufier +argufiers +argufies +argufy +argufying +arguing +argument +argumenta +argumentation +argumentations +argumentative +argumentatively +argumentive +arguments +argumentum +argus +arguses +argyle +argyles +argyll +argylls +arhat +arhats +arhatship +arhatships +aria +arias +ariboflavinoses +ariboflavinosis +ariboflavinosises +arid +arider +aridest +aridities +aridity +aridly +aridness +aridnesses +ariel +ariels +arietta +ariettas +ariette +ariettes +aright +aril +ariled +arillate +arillode +arillodes +arilloid +arils +ariose +ariosi +arioso +ariosos +arise +arisen +arises +arising +arista +aristae +aristas +aristate +aristo +aristocracies +aristocracy +aristocrat +aristocratic +aristocratically +aristocrats +aristos +arithmetic +arithmetical +arithmetically +arithmetician +arithmeticians +arithmetics +ark +arkose +arkoses +arkosic +arks +arles +arm +armada +armadas +armadillo +armadillos +armagnac +armagnacs +armament +armamentaria +armamentarium +armaments +armature +armatured +armatures +armaturing +armband +armbands +armchair +armchairs +armed +armer +armers +armet +armets +armful +armfuls +armhole +armholes +armies +armiger +armigeral +armigero +armigeros +armigerous +armigers +armilla +armillae +armillas +arming +armings +armistice +armistices +armless +armlet +armlets +armlike +armload +armloads +armlock +armlocks +armoire +armoires +armonica +armonicas +armor +armored +armorer +armorers +armorial +armorially +armorials +armories +armoring +armorless +armors +armory +armour +armoured +armourer +armourers +armouries +armouring +armours +armoury +armpit +armpits +armrest +armrests +arms +armsful +armure +armures +army +armyworm +armyworms +arnatto +arnattos +arnica +arnicas +arnotto +arnottos +aroid +aroids +aroint +arointed +arointing +aroints +aroma +aromas +aromatherapies +aromatherapist +aromatherapists +aromatherapy +aromatic +aromatically +aromaticities +aromaticity +aromatics +aromatization +aromatizations +aromatize +aromatized +aromatizes +aromatizing +arose +around +arousal +arousals +arouse +aroused +arouser +arousers +arouses +arousing +aroynt +aroynted +aroynting +aroynts +arpeggiate +arpeggiated +arpeggiates +arpeggiating +arpeggio +arpeggios +arpen +arpens +arpent +arpents +arquebus +arquebuses +arrack +arracks +arraign +arraigned +arraigning +arraignment +arraignments +arraigns +arrange +arranged +arrangement +arrangements +arranger +arrangers +arranges +arranging +arrant +arrantly +arras +arrased +array +arrayal +arrayals +arrayed +arrayer +arrayers +arraying +arrays +arrear +arrearage +arrearages +arrears +arrest +arrestant +arrestants +arrested +arrestee +arrestees +arrester +arresters +arresting +arrestingly +arrestment +arrestments +arrestor +arrestors +arrests +arrhizal +arrhythmia +arrhythmias +arrhythmic +arris +arrises +arrival +arrivals +arrive +arrived +arriver +arrivers +arrives +arriving +arriviste +arrivistes +arroba +arrobas +arrogance +arrogances +arrogant +arrogantly +arrogate +arrogated +arrogates +arrogating +arrogation +arrogations +arrondissement +arrondissements +arrow +arrowed +arrowhead +arrowheads +arrowing +arrowroot +arrowroots +arrows +arrowwood +arrowwoods +arrowworm +arrowworms +arrowy +arroyo +arroyos +ars +arse +arsenal +arsenals +arsenate +arsenates +arsenic +arsenical +arsenicals +arsenics +arsenide +arsenides +arsenious +arsenite +arsenites +arseno +arsenopyrite +arsenopyrites +arsenous +arses +arshin +arshins +arsine +arsines +arsino +arsis +arson +arsonist +arsonists +arsonous +arsons +arsphenamine +arsphenamines +art +artal +artefact +artefacts +artel +artels +artemisia +artemisias +arterial +arterially +arterials +arteries +arteriogram +arteriograms +arteriographic +arteriographies +arteriography +arteriolar +arteriole +arterioles +arterioscleroses +arteriosclerosis +arteriosclerotic +arteriosclerotics +arteriovenous +arteritides +arteritis +artery +artful +artfully +artfulness +artfulnesses +arthralgia +arthralgias +arthralgic +arthritic +arthritically +arthritics +arthritides +arthritis +arthrodeses +arthrodesis +arthropathies +arthropathy +arthropod +arthropodan +arthropods +arthroscope +arthroscopes +arthroscopic +arthroscopies +arthroscopy +arthroses +arthrosis +arthrospore +arthrospores +artichoke +artichokes +article +articled +articles +articling +articulable +articulacies +articulacy +articular +articulate +articulated +articulately +articulateness +articulatenesses +articulates +articulating +articulation +articulations +articulative +articulator +articulators +articulatory +artier +artiest +artifact +artifacts +artifactual +artifice +artificer +artificers +artifices +artificial +artificialities +artificiality +artificially +artificialness +artificialnesses +artilleries +artillerist +artillerists +artillery +artilleryman +artillerymen +artily +artiness +artinesses +artiodactyl +artiodactyls +artisan +artisanal +artisans +artisanship +artisanships +artist +artiste +artistes +artistic +artistically +artistries +artistry +artists +artless +artlessly +artlessness +artlessnesses +arts +artsier +artsiest +artsy +artwork +artworks +arty +arugola +arugolas +arugula +arugulas +arum +arums +aruspex +aruspices +arval +arvo +arvos +aryl +aryls +arytenoid +arytenoids +arythmia +arythmias +arythmic +as +asafetida +asafetidas +asafoetida +asafoetidas +asana +asanas +asarum +asarums +asbestic +asbestos +asbestoses +asbestosis +asbestus +asbestuses +ascariases +ascariasis +ascarid +ascarides +ascarids +ascaris +ascend +ascendable +ascendance +ascendances +ascendancies +ascendancy +ascendant +ascendantly +ascendants +ascended +ascendence +ascendences +ascendencies +ascendency +ascendent +ascendents +ascender +ascenders +ascendible +ascending +ascends +ascension +ascensional +ascensions +ascensive +ascent +ascents +ascertain +ascertainable +ascertained +ascertaining +ascertainment +ascertainments +ascertains +asceses +ascesis +ascetic +ascetical +ascetically +asceticism +asceticisms +ascetics +asci +ascidia +ascidian +ascidians +ascidium +ascites +ascitic +asclepiad +asclepiads +ascocarp +ascocarpic +ascocarps +ascogonia +ascogonium +ascomycete +ascomycetes +ascomycetous +ascorbate +ascorbates +ascorbic +ascospore +ascospores +ascosporic +ascot +ascots +ascribable +ascribe +ascribed +ascribes +ascribing +ascription +ascriptions +ascriptive +ascus +asdic +asdics +asea +asepses +asepsis +aseptic +aseptically +asexual +asexualities +asexuality +asexually +ash +ashamed +ashamedly +ashcan +ashcans +ashed +ashen +ashes +ashfall +ashfalls +ashier +ashiest +ashiness +ashinesses +ashing +ashlar +ashlared +ashlaring +ashlars +ashler +ashlered +ashlering +ashlers +ashless +ashman +ashmen +ashore +ashplant +ashplants +ashram +ashrams +ashtray +ashtrays +ashy +aside +asides +asinine +asininely +asininities +asininity +ask +askance +askant +asked +asker +askers +askeses +askesis +askew +askewness +askewnesses +asking +askings +askoi +askos +asks +aslant +asleep +aslope +asocial +asp +asparagine +asparagines +asparagus +asparkle +aspartame +aspartames +aspartate +aspartates +aspect +aspects +aspectual +aspen +aspens +asper +asperate +asperated +asperates +asperating +asperges +aspergilla +aspergilli +aspergilloses +aspergillosis +aspergillum +aspergillums +aspergillus +asperities +asperity +aspers +asperse +aspersed +asperser +aspersers +asperses +aspersing +aspersion +aspersions +aspersor +aspersors +asphalt +asphalted +asphaltic +asphalting +asphaltite +asphaltites +asphalts +asphaltum +asphaltums +aspheric +aspherical +asphodel +asphodels +asphyxia +asphyxias +asphyxiate +asphyxiated +asphyxiates +asphyxiating +asphyxiation +asphyxiations +asphyxies +asphyxy +aspic +aspics +aspidistra +aspidistras +aspirant +aspirants +aspirata +aspiratae +aspirate +aspirated +aspirates +aspirating +aspiration +aspirational +aspirations +aspirator +aspirators +aspire +aspired +aspirer +aspirers +aspires +aspirin +aspiring +aspirins +aspis +aspises +aspish +asps +asquint +asrama +asramas +ass +assagai +assagaied +assagaiing +assagais +assai +assail +assailable +assailant +assailants +assailed +assailer +assailers +assailing +assails +assais +assassin +assassinate +assassinated +assassinates +assassinating +assassination +assassinations +assassinator +assassinators +assassins +assault +assaulted +assaulter +assaulters +assaulting +assaultive +assaultively +assaultiveness +assaultivenesses +assaults +assay +assayed +assayer +assayers +assaying +assays +assegai +assegaied +assegaiing +assegais +assemblage +assemblages +assemblagist +assemblagists +assemble +assembled +assembler +assemblers +assembles +assemblies +assembling +assembly +assemblyman +assemblymen +assemblywoman +assemblywomen +assent +assentation +assentations +assented +assenter +assenters +assenting +assentor +assentors +assents +assert +asserted +assertedly +asserter +asserters +asserting +assertion +assertions +assertive +assertively +assertiveness +assertivenesses +assertor +assertors +asserts +asses +assess +assessable +assessed +assesses +assessing +assessment +assessments +assessor +assessors +asset +assets +asseverate +asseverated +asseverates +asseverating +asseveration +asseverations +asseverative +asshole +assholes +assiduities +assiduity +assiduous +assiduously +assiduousness +assiduousnesses +assign +assignabilities +assignability +assignable +assignat +assignation +assignations +assignats +assigned +assignee +assignees +assigner +assigners +assigning +assignment +assignments +assignor +assignors +assigns +assimilabilities +assimilability +assimilable +assimilate +assimilated +assimilates +assimilating +assimilation +assimilationism +assimilationisms +assimilationist +assimilationists +assimilations +assimilative +assimilator +assimilators +assimilatory +assist +assistance +assistances +assistant +assistants +assistantship +assistantships +assisted +assister +assisters +assisting +assistor +assistors +assists +assize +assizes +asslike +associate +associated +associates +associateship +associateships +associating +association +associational +associationism +associationisms +associationist +associationistic +associationists +associations +associative +associatively +associativities +associativity +assoil +assoiled +assoiling +assoilment +assoilments +assoils +assonance +assonances +assonant +assonantal +assonants +assort +assortative +assortatively +assorted +assorter +assorters +assorting +assortment +assortments +assorts +assuage +assuaged +assuagement +assuagements +assuages +assuaging +assuasive +assumabilities +assumability +assumable +assumably +assume +assumed +assumer +assumers +assumes +assuming +assumpsit +assumpsits +assumption +assumptions +assumptive +assurance +assurances +assure +assured +assuredly +assuredness +assurednesses +assureds +assurer +assurers +assures +assurgent +assuring +assuror +assurors +asswage +asswaged +asswages +asswaging +astarboard +astasia +astasias +astatic +astatine +astatines +aster +asteria +asterias +asteriated +asterisk +asterisked +asterisking +asteriskless +asterisks +asterism +asterisms +astern +asternal +asteroid +asteroidal +asteroids +asters +asthenia +asthenias +asthenic +asthenics +asthenies +asthenosphere +asthenospheres +asthenospheric +astheny +asthma +asthmas +asthmatic +asthmatically +asthmatics +astigmatic +astigmatics +astigmatism +astigmatisms +astigmia +astigmias +astilbe +astilbes +astir +astomous +astonied +astonies +astonish +astonished +astonishes +astonishing +astonishingly +astonishment +astonishments +astony +astonying +astound +astounded +astounding +astoundingly +astounds +astraddle +astragal +astragals +astrakhan +astrakhans +astral +astrally +astrals +astray +astrict +astricted +astricting +astricts +astride +astringe +astringed +astringencies +astringency +astringent +astringently +astringents +astringes +astringing +astrobiologies +astrobiologist +astrobiologists +astrobiology +astrocyte +astrocytes +astrocytic +astrocytoma +astrocytomas +astrocytomata +astrodome +astrodomes +astrolabe +astrolabes +astrologer +astrologers +astrological +astrologically +astrologies +astrology +astrometric +astrometries +astrometry +astronaut +astronautic +astronautical +astronautically +astronautics +astronauts +astronomer +astronomers +astronomic +astronomical +astronomically +astronomies +astronomy +astrophotograph +astrophotographer +astrophotographers +astrophotographies +astrophotographs +astrophotography +astrophysical +astrophysically +astrophysicist +astrophysicists +astrophysics +astute +astutely +astuteness +astutenesses +astylar +asunder +aswarm +aswirl +aswoon +asyla +asylum +asylums +asymmetric +asymmetrical +asymmetrically +asymmetries +asymmetry +asymptomatic +asymptomatically +asymptote +asymptotes +asymptotic +asymptotically +asynapses +asynapsis +asynchronies +asynchronism +asynchronisms +asynchronous +asynchronously +asynchrony +asyndeta +asyndetic +asyndetically +asyndeton +asyndetons +at +atabal +atabals +atactic +ataghan +ataghans +atalaya +atalayas +ataman +atamans +atamasco +atamascos +atap +ataps +ataractic +ataractics +ataraxia +ataraxias +ataraxic +ataraxics +ataraxies +ataraxy +atavic +atavism +atavisms +atavist +atavistic +atavistically +atavists +ataxia +ataxias +ataxic +ataxics +ataxies +ataxy +ate +atechnic +atelectases +atelectasis +atelic +atelier +ateliers +atemoya +atemoyas +atemporal +ates +athanasies +athanasy +atheism +atheisms +atheist +atheistic +atheistical +atheistically +atheists +atheling +athelings +athenaeum +athenaeums +atheneum +atheneums +atheoretical +atherogeneses +atherogenesis +atherogenic +atheroma +atheromas +atheromata +atheromatous +atheroscleroses +atherosclerosis +atherosclerotic +athetoid +athirst +athlete +athletes +athletic +athletically +athleticism +athleticisms +athletics +athodyd +athodyds +athrocyte +athrocytes +athwart +athwartship +athwartships +atilt +atingle +atlantes +atlas +atlases +atlatl +atlatls +atma +atman +atmans +atmas +atmometer +atmometers +atmosphere +atmosphered +atmospheres +atmospheric +atmospherically +atmospherics +atoll +atolls +atom +atomic +atomical +atomically +atomics +atomies +atomise +atomised +atomiser +atomisers +atomises +atomising +atomism +atomisms +atomist +atomistic +atomistically +atomists +atomization +atomizations +atomize +atomized +atomizer +atomizers +atomizes +atomizing +atoms +atomy +atonable +atonal +atonalism +atonalisms +atonalist +atonalists +atonalities +atonality +atonally +atone +atoned +atonement +atonements +atoner +atoners +atones +atonic +atonics +atonies +atoning +atony +atop +atopic +atopies +atopy +atrabilious +atrabiliousness +atrabiliousnesses +atrazine +atrazines +atremble +atresia +atresias +atria +atrial +atrioventricular +atrip +atrium +atriums +atrocious +atrociously +atrociousness +atrociousnesses +atrocities +atrocity +atrophia +atrophias +atrophic +atrophied +atrophies +atrophy +atrophying +atropin +atropine +atropines +atropins +atropism +atropisms +att +attaboy +attach +attachable +attache +attached +attacher +attachers +attaches +attaching +attachment +attachments +attack +attacked +attacker +attackers +attacking +attackman +attackmen +attacks +attain +attainabilities +attainability +attainable +attainder +attainders +attained +attainer +attainers +attaining +attainment +attainments +attains +attaint +attainted +attainting +attaints +attar +attars +attemper +attempered +attempering +attempers +attempt +attemptable +attempted +attempting +attempts +attend +attendance +attendances +attendant +attendants +attended +attendee +attendees +attender +attenders +attending +attends +attent +attention +attentional +attentions +attentive +attentively +attentiveness +attentivenesses +attenuate +attenuated +attenuates +attenuating +attenuation +attenuations +attenuator +attenuators +attest +attestation +attestations +attested +attester +attesters +attesting +attestor +attestors +attests +attic +atticism +atticisms +atticist +atticists +attics +attire +attired +attires +attiring +attitude +attitudes +attitudinal +attitudinally +attitudinise +attitudinised +attitudinises +attitudinising +attitudinize +attitudinized +attitudinizes +attitudinizing +attorn +attorned +attorney +attorneys +attorneyship +attorneyships +attorning +attornment +attornments +attorns +attract +attractance +attractances +attractancies +attractancy +attractant +attractants +attracted +attracting +attraction +attractions +attractive +attractively +attractiveness +attractivenesses +attractor +attractors +attracts +attributable +attribute +attributed +attributes +attributing +attribution +attributional +attributions +attributive +attributively +attributives +attrite +attrited +attrition +attritional +attritions +attune +attuned +attunement +attunements +attunes +attuning +atwain +atween +atwitter +atypic +atypical +atypicalities +atypicality +atypically +aubade +aubades +auberge +auberges +aubergine +aubergines +aubretia +aubretias +aubrieta +aubrietas +auburn +auburns +auction +auctioned +auctioneer +auctioneers +auctioning +auctions +auctorial +aucuba +aucubas +audacious +audaciously +audaciousness +audaciousnesses +audacities +audacity +audad +audads +audial +audibilities +audibility +audible +audibles +audibly +audience +audiences +audient +audients +audile +audiles +auding +audings +audio +audiocassette +audiocassettes +audiogenic +audiogram +audiograms +audiologic +audiological +audiologies +audiologist +audiologists +audiology +audiometer +audiometers +audiometric +audiometries +audiometry +audiophile +audiophiles +audios +audiotape +audiotapes +audiovisual +audiovisuals +audit +auditable +audited +auditing +audition +auditioned +auditioning +auditions +auditive +auditives +auditor +auditoria +auditories +auditorily +auditorium +auditoriums +auditors +auditory +audits +augend +augends +auger +augers +aught +aughts +augite +augites +augitic +augment +augmentation +augmentations +augmentative +augmentatives +augmented +augmenter +augmenters +augmenting +augmentor +augmentors +augments +augur +augural +augured +augurer +augurers +auguries +auguring +augurs +augury +august +auguster +augustest +augustly +augustness +augustnesses +auk +auklet +auklets +auks +auld +aulder +auldest +aulic +aunt +aunthood +aunthoods +auntie +aunties +auntlier +auntliest +auntlike +auntly +aunts +aunty +aura +aurae +aural +aurally +aurar +auras +aurate +aurated +aureate +aurei +aureola +aureolae +aureolas +aureole +aureoled +aureoles +aureoling +aures +aureus +auric +auricle +auricled +auricles +auricula +auriculae +auricular +auriculas +auriculate +auriferous +auriform +auris +aurist +aurists +aurochs +aurochses +aurora +aurorae +auroral +auroras +aurorean +aurous +aurum +aurums +auscultate +auscultated +auscultates +auscultating +auscultation +auscultations +auscultatory +ausform +ausformed +ausforming +ausforms +auslander +auslanders +auspex +auspice +auspices +auspicious +auspiciously +auspiciousness +auspiciousnesses +austenite +austenites +austenitic +austere +austerely +austereness +austerenesses +austerer +austerest +austerities +austerity +austral +australes +australopithecine +australopithecines +australs +ausubo +ausubos +autacoid +autacoids +autarchic +autarchical +autarchies +autarchy +autarkic +autarkical +autarkies +autarky +autecism +autecisms +autecological +autecologies +autecology +auteur +auteurist +auteurists +auteurs +authentic +authentically +authenticate +authenticated +authenticates +authenticating +authentication +authentications +authenticator +authenticators +authenticities +authenticity +author +authored +authoress +authoresses +authorial +authoring +authorise +authorised +authorises +authorising +authoritarian +authoritarianism +authoritarianisms +authoritarians +authoritative +authoritatively +authoritativeness +authoritativenesses +authorities +authority +authorization +authorizations +authorize +authorized +authorizer +authorizers +authorizes +authorizing +authors +authorship +authorships +autism +autisms +autistic +autistically +autistics +auto +autoantibodies +autoantibody +autobahn +autobahnen +autobahns +autobiographer +autobiographers +autobiographic +autobiographical +autobiographically +autobiographies +autobiography +autobus +autobuses +autobusses +autocade +autocades +autocatalyses +autocatalysis +autocatalytic +autocatalytically +autocephalies +autocephalous +autocephaly +autochthon +autochthones +autochthonous +autochthonously +autochthons +autoclave +autoclaved +autoclaves +autoclaving +autocoid +autocoids +autocorrelation +autocorrelations +autocracies +autocracy +autocrat +autocratic +autocratical +autocratically +autocrats +autocross +autocrosses +autodidact +autodidactic +autodidacts +autodyne +autodynes +autoecious +autoeciously +autoecism +autoecisms +autoed +autoerotic +autoeroticism +autoeroticisms +autoerotism +autoerotisms +autogamies +autogamous +autogamy +autogenic +autogenies +autogenous +autogenously +autogeny +autogiro +autogiros +autograft +autografted +autografting +autografts +autograph +autographed +autographic +autographically +autographies +autographing +autographs +autography +autogyro +autogyros +autohypnoses +autohypnosis +autohypnotic +autoimmune +autoimmunities +autoimmunity +autoimmunization +autoimmunizations +autoinfection +autoinfections +autoing +autointoxication +autointoxications +autoloading +autologous +autolysate +autolysates +autolyse +autolysed +autolyses +autolysing +autolysis +autolytic +autolyzate +autolyzates +autolyze +autolyzed +autolyzes +autolyzing +automaker +automakers +automan +automata +automatable +automate +automated +automates +automatic +automatically +automaticities +automaticity +automatics +automating +automation +automations +automatism +automatisms +automatist +automatists +automatization +automatizations +automatize +automatized +automatizes +automatizing +automaton +automatons +automen +automobile +automobiled +automobiles +automobiling +automobilist +automobilists +automobilities +automobility +automorphism +automorphisms +automotive +autonomic +autonomically +autonomies +autonomist +autonomists +autonomous +autonomously +autonomy +autopilot +autopilots +autopolyploid +autopolyploidies +autopolyploids +autopolyploidy +autopsic +autopsied +autopsies +autopsy +autopsying +autoradiogram +autoradiograms +autoradiograph +autoradiographic +autoradiographies +autoradiographs +autoradiography +autorotate +autorotated +autorotates +autorotating +autorotation +autorotations +autoroute +autoroutes +autos +autosexing +autosomal +autosomally +autosome +autosomes +autostrada +autostradas +autostrade +autosuggest +autosuggested +autosuggesting +autosuggestion +autosuggestions +autosuggests +autotelic +autotetraploid +autotetraploidies +autotetraploids +autotetraploidy +autotomies +autotomize +autotomized +autotomizes +autotomizing +autotomous +autotomy +autotransformer +autotransformers +autotransfusion +autotransfusions +autotroph +autotrophic +autotrophically +autotrophies +autotrophs +autotrophy +autotype +autotypes +autotypies +autotypy +autoworker +autoworkers +autoxidation +autoxidations +autumn +autumnal +autumnally +autumns +autunite +autunites +auxeses +auxesis +auxetic +auxetics +auxiliaries +auxiliary +auxin +auxinic +auxins +auxotroph +auxotrophic +auxotrophies +auxotrophs +auxotrophy +ava +avadavat +avadavats +avail +availabilities +availability +available +availableness +availablenesses +availably +availed +availing +avails +avalanche +avalanched +avalanches +avalanching +avant +avarice +avarices +avaricious +avariciously +avariciousness +avariciousnesses +avascular +avascularities +avascularity +avast +avatar +avatars +avaunt +ave +avellan +avellane +avenge +avenged +avenger +avengers +avenges +avenging +avens +avenses +aventail +aventails +aventurine +aventurines +avenue +avenues +aver +average +averaged +averagely +averageness +averagenesses +averages +averaging +averment +averments +averred +averring +avers +averse +aversely +averseness +aversenesses +aversion +aversions +aversive +aversively +aversiveness +aversivenesses +avert +averted +averting +averts +aves +avgas +avgases +avgasses +avgolemono +avgolemonos +avian +avianize +avianized +avianizes +avianizing +avians +aviaries +aviarist +aviarists +aviary +aviate +aviated +aviates +aviating +aviation +aviations +aviator +aviators +aviatrices +aviatrix +aviatrixes +avicular +aviculture +avicultures +aviculturist +aviculturists +avid +avidin +avidins +avidities +avidity +avidly +avidness +avidnesses +avifauna +avifaunae +avifaunal +avifaunas +avigator +avigators +avion +avionic +avionics +avions +avirulent +aviso +avisos +avitaminoses +avitaminosis +avitaminotic +avo +avocado +avocadoes +avocados +avocation +avocational +avocationally +avocations +avocet +avocets +avodire +avodires +avoid +avoidable +avoidably +avoidance +avoidances +avoided +avoider +avoiders +avoiding +avoids +avoirdupois +avoirdupoises +avos +avoset +avosets +avouch +avouched +avoucher +avouchers +avouches +avouching +avouchment +avouchments +avow +avowable +avowably +avowal +avowals +avowed +avowedly +avower +avowers +avowing +avows +avulse +avulsed +avulses +avulsing +avulsion +avulsions +avuncular +avuncularities +avuncularity +avuncularly +aw +awa +await +awaited +awaiter +awaiters +awaiting +awaits +awake +awaked +awaken +awakened +awakener +awakeners +awakening +awakens +awakes +awaking +award +awardable +awarded +awardee +awardees +awarder +awarders +awarding +awards +aware +awareness +awarenesses +awash +away +awayness +awaynesses +awe +aweary +aweather +awed +awee +aweigh +aweing +aweless +awes +awesome +awesomely +awesomeness +awesomenesses +awestricken +awestruck +awful +awfuller +awfullest +awfully +awfulness +awfulnesses +awhile +awhirl +awing +awkward +awkwarder +awkwardest +awkwardly +awkwardness +awkwardnesses +awl +awless +awls +awlwort +awlworts +awmous +awn +awned +awning +awninged +awnings +awnless +awns +awny +awoke +awoken +awol +awols +awry +ax +axal +axe +axed +axel +axels +axeman +axemen +axenic +axenically +axes +axial +axialities +axiality +axially +axil +axile +axilla +axillae +axillar +axillaries +axillars +axillary +axillas +axils +axing +axiological +axiologically +axiologies +axiology +axiom +axiomatic +axiomatically +axiomatisation +axiomatisations +axiomatization +axiomatizations +axiomatize +axiomatized +axiomatizes +axiomatizing +axioms +axion +axions +axis +axised +axises +axisymmetric +axisymmetrical +axisymmetries +axisymmetry +axite +axites +axle +axled +axles +axletree +axletrees +axlike +axman +axmen +axolotl +axolotls +axon +axonal +axone +axonemal +axoneme +axonemes +axones +axonic +axonometric +axons +axoplasm +axoplasmic +axoplasms +axseed +axseeds +ay +ayah +ayahs +ayahuasca +ayahuascas +ayatollah +ayatollahs +aye +ayes +ayin +ayins +ays +ayurveda +ayurvedas +azalea +azaleas +azan +azans +azathioprine +azathioprines +azeotrope +azeotropes +azide +azides +azido +azidothymidine +azidothymidines +azimuth +azimuthal +azimuthally +azimuths +azine +azines +azlon +azlons +azo +azoic +azole +azoles +azon +azonal +azonic +azons +azoospermia +azoospermias +azote +azoted +azotemia +azotemias +azotemic +azotes +azoth +azoths +azotic +azotise +azotised +azotises +azotising +azotize +azotized +azotizes +azotizing +azotobacter +azotobacters +azoturia +azoturias +azure +azures +azurite +azurites +azygos +azygoses +azygous +ba +baa +baaed +baaing +baal +baalim +baalism +baalisms +baals +baas +baases +baaskaap +baaskaaps +baba +babas +babassu +babassus +babbitt +babbitted +babbitting +babbitts +babble +babbled +babblement +babblements +babbler +babblers +babbles +babbling +babblings +babe +babel +babels +babes +babesia +babesias +babesioses +babesiosis +babesiosises +babiche +babiches +babied +babies +babirusa +babirusas +babka +babkas +baboo +babool +babools +baboon +baboons +baboos +babu +babul +babuls +babus +babushka +babushkas +baby +babyhood +babyhoods +babying +babyish +babysitter +babysitters +bacalao +bacalaos +bacca +baccae +baccalaureate +baccalaureates +baccara +baccaras +baccarat +baccarats +baccate +baccated +bacchanal +bacchanalia +bacchanalian +bacchanalians +bacchanals +bacchant +bacchante +bacchantes +bacchants +bacchic +bacchii +bacchius +bach +bached +bachelor +bachelordom +bachelordoms +bachelorette +bachelorettes +bachelorhood +bachelorhoods +bachelors +baches +baching +bacillar +bacillary +bacilli +bacillus +bacitracin +bacitracins +back +backache +backaches +backbeat +backbeats +backbench +backbencher +backbenchers +backbenches +backbend +backbends +backbit +backbite +backbiter +backbiters +backbites +backbiting +backbitings +backbitten +backblock +backblocks +backboard +backboards +backbone +backbones +backbreaker +backbreakers +backbreaking +backcast +backcasts +backchat +backchats +backcloth +backcloths +backcountries +backcountry +backcourt +backcourtman +backcourtmen +backcourts +backcross +backcrossed +backcrosses +backcrossing +backdate +backdated +backdates +backdating +backdoor +backdrop +backdropped +backdropping +backdrops +backdropt +backed +backer +backers +backfield +backfields +backfill +backfilled +backfilling +backfills +backfire +backfired +backfires +backfiring +backfit +backfits +backfitted +backfitting +backflow +backflows +backgammon +backgammons +background +backgrounded +backgrounder +backgrounders +backgrounding +backgrounds +backhand +backhanded +backhandedly +backhander +backhanders +backhanding +backhands +backhaul +backhauled +backhauling +backhauls +backhoe +backhoes +backhouse +backhouses +backing +backings +backland +backlands +backlash +backlashed +backlasher +backlashers +backlashes +backlashing +backless +backlight +backlighted +backlighting +backlights +backlist +backlisted +backlisting +backlists +backlit +backlog +backlogged +backlogging +backlogs +backmost +backout +backouts +backpack +backpacked +backpacker +backpackers +backpacking +backpacks +backpedal +backpedaled +backpedaling +backpedalled +backpedalling +backpedals +backrest +backrests +backroom +backrooms +backrush +backrushes +backs +backsaw +backsaws +backscatter +backscattered +backscattering +backscatterings +backscatters +backseat +backseats +backset +backsets +backside +backsides +backslap +backslapped +backslapper +backslappers +backslapping +backslaps +backslash +backslashes +backslid +backslidden +backslide +backslider +backsliders +backslides +backsliding +backspace +backspaced +backspaces +backspacing +backspin +backspins +backsplash +backsplashes +backstab +backstabbed +backstabber +backstabbers +backstabbing +backstabbings +backstabs +backstage +backstairs +backstay +backstays +backstitch +backstitched +backstitches +backstitching +backstop +backstopped +backstopping +backstops +backstreet +backstreets +backstretch +backstretches +backstroke +backstrokes +backswept +backswing +backswings +backsword +backswords +backtrack +backtracked +backtracking +backtracks +backup +backups +backward +backwardly +backwardness +backwardnesses +backwards +backwash +backwashed +backwashes +backwashing +backwater +backwaters +backwood +backwoods +backwoodsman +backwoodsmen +backwoodsy +backwrap +backwraps +backyard +backyards +bacon +bacons +bacteremia +bacteremias +bacteremic +bacteria +bacterial +bacterially +bacterias +bactericidal +bactericidally +bactericide +bactericides +bacterin +bacterins +bacteriochlorophyll +bacteriochlorophylls +bacteriocin +bacteriocins +bacteriologic +bacteriological +bacteriologically +bacteriologies +bacteriologist +bacteriologists +bacteriology +bacteriolyses +bacteriolysis +bacteriolytic +bacteriophage +bacteriophages +bacteriophagies +bacteriophagy +bacteriorhodopsin +bacteriorhodopsins +bacteriostases +bacteriostasis +bacteriostat +bacteriostatic +bacteriostats +bacterium +bacteriuria +bacteriurias +bacterization +bacterizations +bacterize +bacterized +bacterizes +bacterizing +bacteroid +bacteroids +bacula +baculine +baculum +baculums +bad +badass +badassed +badasses +badder +baddest +baddie +baddies +baddy +bade +badge +badged +badger +badgered +badgering +badgerly +badgers +badges +badging +badinage +badinaged +badinages +badinaging +badland +badlands +badly +badman +badmen +badminton +badmintons +badmouth +badmouthed +badmouthing +badmouths +badness +badnesses +bads +baff +baffed +baffies +baffing +baffle +baffled +bafflegab +bafflegabs +bafflement +bafflements +baffler +bafflers +baffles +baffling +bafflingly +baffs +baffy +bag +bagass +bagasse +bagasses +bagatelle +bagatelles +bagel +bagels +bagful +bagfuls +baggage +baggages +bagged +bagger +baggers +baggie +baggier +baggies +baggiest +baggily +bagginess +bagginesses +bagging +baggings +baggy +baghouse +baghouses +bagman +bagmen +bagnio +bagnios +bagpipe +bagpiper +bagpipers +bagpipes +bags +bagsful +baguet +baguets +baguette +baguettes +bagwig +bagwigs +bagworm +bagworms +bah +bahadur +bahadurs +baht +bahts +baidarka +baidarkas +bail +bailable +bailed +bailee +bailees +bailer +bailers +bailey +baileys +bailie +bailies +bailiff +bailiffs +bailiffship +bailiffships +bailing +bailiwick +bailiwicks +bailment +bailments +bailor +bailors +bailout +bailouts +bails +bailsman +bailsmen +bairn +bairnish +bairnlier +bairnliest +bairnly +bairns +bait +baited +baiter +baiters +baith +baiting +baits +baiza +baizas +baize +baizes +bake +baked +bakemeat +bakemeats +baker +bakeries +bakers +bakery +bakes +bakeshop +bakeshops +baking +bakings +baklava +baklavas +baklawa +baklawas +baksheesh +baksheeshes +bakshish +bakshished +bakshishes +bakshishing +bal +balaclava +balaclavas +balalaika +balalaikas +balance +balanced +balancer +balancers +balances +balancing +balas +balases +balata +balatas +balboa +balboas +balbriggan +balbriggans +balconied +balconies +balcony +bald +baldachin +baldachino +baldachinos +baldachins +balded +balder +balderdash +balderdashes +baldest +baldhead +baldheaded +baldheads +baldies +balding +baldish +baldly +baldness +baldnesses +baldpate +baldpates +baldric +baldrick +baldricks +baldrics +balds +baldy +bale +baled +baleen +baleens +balefire +balefires +baleful +balefully +balefulness +balefulnesses +baler +balers +bales +baling +balisaur +balisaurs +balk +balkanization +balkanizations +balkanize +balkanized +balkanizes +balkanizing +balked +balker +balkers +balkier +balkiest +balkily +balkiness +balkinesses +balking +balkline +balklines +balks +balky +ball +ballad +ballade +balladeer +balladeers +ballades +balladic +balladist +balladists +balladries +balladry +ballads +ballast +ballasted +ballasting +ballasts +ballcarrier +ballcarriers +balled +baller +ballerina +ballerinas +ballers +ballet +balletic +balletomane +balletomanes +balletomania +balletomanias +ballets +ballgame +ballgames +ballhandling +ballhandlings +ballhawk +ballhawks +ballies +balling +ballista +ballistae +ballistic +ballistically +ballistics +ballon +ballonet +ballonets +ballonne +ballonnes +ballons +balloon +ballooned +ballooning +balloonings +balloonist +balloonists +balloons +ballot +balloted +balloter +balloters +balloting +ballots +ballpark +ballparks +ballplayer +ballplayers +ballpoint +ballpoints +ballroom +ballrooms +balls +ballsier +ballsiest +ballsy +ballute +ballutes +bally +ballyhoo +ballyhooed +ballyhooing +ballyhoos +ballyrag +ballyragged +ballyragging +ballyrags +balm +balmacaan +balmacaans +balmier +balmiest +balmily +balminess +balminesses +balmlike +balmoral +balmorals +balms +balmy +balneal +balneologies +balneology +baloney +baloneys +bals +balsa +balsam +balsamed +balsamic +balsaming +balsams +balsas +baluster +balusters +balustrade +balustraded +balustrades +bam +bambini +bambino +bambinos +bamboo +bamboos +bamboozle +bamboozled +bamboozlement +bamboozlements +bamboozles +bamboozling +bammed +bamming +bams +ban +banal +banalities +banality +banalize +banalized +banalizes +banalizing +banally +banana +bananas +banausic +banco +bancos +band +bandage +bandaged +bandager +bandagers +bandages +bandaging +bandana +bandanas +bandanna +bandannas +bandbox +bandboxes +bandeau +bandeaus +bandeaux +banded +bander +banderilla +banderillas +banderillero +banderilleros +banderol +banderole +banderoles +banderols +banders +bandicoot +bandicoots +bandied +bandies +banding +bandit +banditries +banditry +bandits +banditti +bandleader +bandleaders +bandmaster +bandmasters +bandog +bandogs +bandoleer +bandoleers +bandolier +bandoliers +bandora +bandoras +bandore +bandores +bands +bandsman +bandsmen +bandstand +bandstands +bandwagon +bandwagons +bandwidth +bandwidths +bandy +bandying +bane +baneberries +baneberry +baned +baneful +banefully +banes +bang +banged +banger +bangers +banging +bangkok +bangkoks +bangle +bangles +bangs +bangtail +bangtails +bani +banian +banians +baning +banish +banished +banisher +banishers +banishes +banishing +banishment +banishments +banister +banistered +banisters +banjax +banjaxed +banjaxes +banjaxing +banjo +banjoes +banjoist +banjoists +banjos +bank +bankabilities +bankability +bankable +bankbook +bankbooks +bankcard +bankcards +banked +banker +bankerly +bankers +banking +bankings +banknote +banknotes +bankroll +bankrolled +bankroller +bankrollers +bankrolling +bankrolls +bankrupt +bankruptcies +bankruptcy +bankrupted +bankrupting +bankrupts +banks +banksia +banksias +bankside +banksides +banned +banner +bannered +banneret +bannerets +bannerette +bannerettes +bannering +bannerol +bannerols +banners +bannet +bannets +banning +bannister +bannisters +bannock +bannocks +banns +banquet +banqueted +banqueter +banqueters +banqueting +banquets +banquette +banquettes +bans +banshee +banshees +banshie +banshies +bantam +bantams +bantamweight +bantamweights +banteng +bantengs +banter +bantered +banterer +banterers +bantering +banteringly +banters +banties +bantling +bantlings +banty +banyan +banyans +banzai +banzais +baobab +baobabs +bap +baps +baptise +baptised +baptises +baptisia +baptisias +baptising +baptism +baptismal +baptismally +baptisms +baptist +baptisteries +baptistery +baptistries +baptistry +baptists +baptize +baptized +baptizer +baptizers +baptizes +baptizing +bar +barathea +baratheas +barb +barbal +barbarian +barbarianism +barbarianisms +barbarians +barbaric +barbarically +barbarism +barbarisms +barbarities +barbarity +barbarization +barbarizations +barbarize +barbarized +barbarizes +barbarizing +barbarous +barbarously +barbarousness +barbarousnesses +barbasco +barbascoes +barbascos +barbate +barbe +barbecue +barbecued +barbecuer +barbecuers +barbecues +barbecuing +barbed +barbel +barbell +barbells +barbels +barbeque +barbequed +barbeques +barbequing +barber +barbered +barbering +barberries +barberry +barbers +barbershop +barbershops +barbes +barbet +barbets +barbette +barbettes +barbican +barbicans +barbicel +barbicels +barbing +barbital +barbitals +barbitone +barbitones +barbiturate +barbiturates +barbless +barbs +barbule +barbules +barbut +barbuts +barbwire +barbwires +barcarole +barcaroles +barcarolle +barcarolles +barchan +barchans +bard +barde +barded +bardes +bardic +barding +bardolater +bardolaters +bardolatries +bardolatry +bards +bare +bareback +barebacked +bareboat +bareboats +bared +barefaced +barefacedly +barefacedness +barefacednesses +barefit +barefoot +barefooted +barege +bareges +barehead +bareheaded +barely +bareness +barenesses +barer +bares +baresark +baresarks +barest +barf +barfed +barfing +barflies +barfly +barfs +bargain +bargained +bargainer +bargainers +bargaining +bargains +barge +bargeboard +bargeboards +barged +bargee +bargees +bargello +bargellos +bargeman +bargemen +barges +barghest +barghests +barging +barguest +barguests +barhop +barhopped +barhopping +barhops +baric +barilla +barillas +baring +barite +barites +baritonal +baritone +baritones +barium +bariums +bark +barked +barkeep +barkeeper +barkeepers +barkeeps +barkentine +barkentines +barker +barkers +barkier +barkiest +barking +barkless +barks +barky +barleduc +barleducs +barless +barley +barleycorn +barleycorns +barleys +barlow +barlows +barm +barmaid +barmaids +barman +barmen +barmie +barmier +barmiest +barms +barmy +barn +barnacle +barnacled +barnacles +barnier +barniest +barnlike +barns +barnstorm +barnstormed +barnstormer +barnstormers +barnstorming +barnstorms +barny +barnyard +barnyards +baroceptor +baroceptors +barogram +barograms +barograph +barographic +barographs +barometer +barometers +barometric +barometrically +barometries +barometry +baron +baronage +baronages +baroness +baronesses +baronet +baronetage +baronetages +baronetcies +baronetcy +baronets +barong +barongs +baronial +baronies +baronne +baronnes +barons +barony +baroque +baroquely +baroques +baroreceptor +baroreceptors +barouche +barouches +barque +barquentine +barquentines +barques +barquette +barquettes +barrable +barrack +barracked +barracker +barrackers +barracking +barracks +barracoon +barracoons +barracouta +barracoutas +barracuda +barracudas +barrage +barraged +barrages +barraging +barramunda +barramundas +barramundi +barramundis +barranca +barrancas +barranco +barrancos +barrater +barraters +barrator +barrators +barratries +barratry +barre +barred +barrel +barrelage +barrelages +barreled +barrelful +barrelfuls +barrelhead +barrelheads +barrelhouse +barrelhouses +barreling +barrelled +barrelling +barrels +barrelsful +barren +barrener +barrenest +barrenly +barrenness +barrennesses +barrens +barres +barret +barretor +barretors +barretries +barretry +barrets +barrette +barrettes +barricade +barricaded +barricades +barricading +barricado +barricadoed +barricadoes +barricadoing +barrier +barriers +barring +barrio +barrios +barrister +barristers +barroom +barrooms +barrow +barrows +bars +barstool +barstools +bartend +bartended +bartender +bartenders +bartending +bartends +barter +bartered +barterer +barterers +bartering +barters +bartisan +bartisans +bartizan +bartizans +barware +barwares +barye +baryes +baryon +baryonic +baryons +baryta +barytas +baryte +barytes +barytic +barytone +barytones +bas +basal +basally +basalt +basaltes +basaltic +basalts +bascule +bascules +base +baseball +baseballs +baseboard +baseboards +baseborn +based +baseless +baseline +baseliner +baseliners +baselines +basely +baseman +basemen +basement +basementless +basements +baseness +basenesses +basenji +basenjis +baser +baserunning +baserunnings +bases +basest +bash +bashaw +bashaws +bashed +basher +bashers +bashes +bashful +bashfully +bashfulness +bashfulnesses +bashing +bashlyk +bashlyks +basic +basically +basicities +basicity +basics +basidia +basidial +basidiomycete +basidiomycetes +basidiomycetous +basidiospore +basidiospores +basidium +basification +basifications +basified +basifier +basifiers +basifies +basify +basifying +basil +basilar +basilary +basilic +basilica +basilicae +basilican +basilicas +basilisk +basilisks +basils +basin +basinal +basined +basinet +basinets +basinful +basinfuls +basing +basins +basion +basions +basipetal +basipetally +basis +bask +basked +basket +basketball +basketballs +basketful +basketfuls +basketlike +basketries +basketry +baskets +basketsful +basketwork +basketworks +basking +basks +basmati +basmatis +basophil +basophile +basophiles +basophilia +basophilias +basophilic +basophils +basque +basques +bass +basses +basset +basseted +basseting +bassets +bassett +bassetted +bassetting +bassetts +bassi +bassinet +bassinets +bassist +bassists +bassly +bassness +bassnesses +basso +bassoon +bassoonist +bassoonists +bassoons +bassos +basswood +basswoods +bassy +bast +bastard +bastardies +bastardise +bastardised +bastardises +bastardising +bastardization +bastardizations +bastardize +bastardized +bastardizes +bastardizing +bastardly +bastards +bastardy +baste +basted +baster +basters +bastes +bastile +bastiles +bastille +bastilles +bastinade +bastinades +bastinado +bastinadoed +bastinadoes +bastinadoing +basting +bastings +bastion +bastioned +bastions +basts +bat +batboy +batboys +batch +batched +batcher +batchers +batches +batching +bate +bateau +bateaux +bated +bates +batfish +batfishes +batfowl +batfowled +batfowling +batfowls +bath +bathe +bathed +bather +bathers +bathes +bathetic +bathetically +bathhouse +bathhouses +bathing +bathless +bathmat +bathmats +batholith +batholithic +batholiths +bathos +bathoses +bathrobe +bathrobes +bathroom +bathrooms +baths +bathtub +bathtubs +bathwater +bathwaters +bathyal +bathymetric +bathymetrical +bathymetrically +bathymetries +bathymetry +bathypelagic +bathyscaph +bathyscaphe +bathyscaphes +bathyscaphs +bathysphere +bathyspheres +bathythermograph +bathythermographs +batik +batiks +bating +batiste +batistes +batlike +batman +batmen +baton +batons +batrachian +batrachians +bats +batsman +batsmen +batt +battailous +battalia +battalias +battalion +battalions +batteau +batteaux +batted +battement +battements +batten +battened +battener +batteners +battening +battens +batter +battered +batterie +batteries +battering +batters +battery +battier +battiest +battik +battiks +battiness +battinesses +batting +battings +battle +battled +battlefield +battlefields +battlefront +battlefronts +battleground +battlegrounds +battlement +battlemented +battlements +battler +battlers +battles +battleship +battleships +battlewagon +battlewagons +battling +batts +battu +battue +battues +batty +batwing +baubee +baubees +bauble +baubles +baud +baudekin +baudekins +baudrons +baudronses +bauds +bauhinia +bauhinias +baulk +baulked +baulkier +baulkiest +baulking +baulks +baulky +bausond +bauxite +bauxites +bauxitic +bawbee +bawbees +bawcock +bawcocks +bawd +bawdier +bawdies +bawdiest +bawdily +bawdiness +bawdinesses +bawdric +bawdrics +bawdries +bawdry +bawds +bawdy +bawdyhouse +bawdyhouses +bawl +bawled +bawler +bawlers +bawling +bawls +bawsunt +bawtie +bawties +bawty +bay +bayadeer +bayadeers +bayadere +bayaderes +bayamo +bayamos +bayard +bayards +bayberries +bayberry +bayed +baying +bayman +baymen +bayonet +bayoneted +bayoneting +bayonets +bayonetted +bayonetting +bayou +bayous +bays +baywood +baywoods +bazaar +bazaars +bazar +bazars +bazoo +bazooka +bazookas +bazooms +bazoos +bdellium +bdelliums +be +beach +beachboy +beachboys +beachcomb +beachcombed +beachcomber +beachcombers +beachcombing +beachcombs +beached +beaches +beachfront +beachfronts +beachgoer +beachgoers +beachhead +beachheads +beachier +beachiest +beaching +beachside +beachwear +beachy +beacon +beaconed +beaconing +beacons +bead +beaded +beadier +beadiest +beadily +beading +beadings +beadle +beadles +beadlike +beadman +beadmen +beadroll +beadrolls +beads +beadsman +beadsmen +beadwork +beadworks +beady +beagle +beagles +beak +beaked +beaker +beakers +beakier +beakiest +beakless +beaklike +beaks +beaky +beam +beamed +beamier +beamiest +beamily +beaming +beamish +beamishly +beamless +beamlike +beams +beamy +bean +beanbag +beanbags +beanball +beanballs +beaned +beaneries +beanery +beanie +beanies +beaning +beanlike +beano +beanos +beanpole +beanpoles +beans +beanstalk +beanstalks +bear +bearabilities +bearability +bearable +bearably +bearbaiting +bearbaitings +bearberries +bearberry +bearcat +bearcats +beard +bearded +beardedness +beardednesses +bearding +beardless +beards +beardtongue +beardtongues +bearer +bearers +bearhug +bearhugs +bearing +bearings +bearish +bearishly +bearishness +bearishnesses +bearlike +bears +bearskin +bearskins +bearwood +bearwoods +beast +beastie +beasties +beastings +beastlier +beastliest +beastliness +beastlinesses +beastly +beasts +beat +beatable +beaten +beater +beaters +beatific +beatifically +beatification +beatifications +beatified +beatifies +beatify +beatifying +beating +beatings +beatitude +beatitudes +beatless +beatnik +beatniks +beats +beau +beaucoup +beauish +beaus +beaut +beauteous +beauteously +beauteousness +beauteousnesses +beautician +beauticians +beauties +beautification +beautifications +beautified +beautifier +beautifiers +beautifies +beautiful +beautifuler +beautifulest +beautifully +beautifulness +beautifulnesses +beautify +beautifying +beauts +beauty +beaux +beaver +beaverboard +beaverboards +beavered +beavering +beavers +bebeeru +bebeerus +beblood +beblooded +beblooding +bebloods +bebop +bebopper +beboppers +bebops +becalm +becalmed +becalming +becalms +became +becap +becapped +becapping +becaps +becarpet +becarpeted +becarpeting +becarpets +because +bechalk +bechalked +bechalking +bechalks +bechamel +bechamels +bechance +bechanced +bechances +bechancing +becharm +becharmed +becharming +becharms +beck +becked +becket +beckets +becking +beckon +beckoned +beckoner +beckoners +beckoning +beckons +becks +beclamor +beclamored +beclamoring +beclamors +beclasp +beclasped +beclasping +beclasps +becloak +becloaked +becloaking +becloaks +beclog +beclogged +beclogging +beclogs +beclothe +beclothed +beclothes +beclothing +becloud +beclouded +beclouding +beclouds +beclown +beclowned +beclowning +beclowns +become +becomes +becoming +becomingly +becomings +becoward +becowarded +becowarding +becowards +becrawl +becrawled +becrawling +becrawls +becrime +becrimed +becrimes +becriming +becrowd +becrowded +becrowding +becrowds +becrust +becrusted +becrusting +becrusts +becudgel +becudgeled +becudgeling +becudgelled +becudgelling +becudgels +becurse +becursed +becurses +becursing +becurst +bed +bedabble +bedabbled +bedabbles +bedabbling +bedamn +bedamned +bedamning +bedamns +bedarken +bedarkened +bedarkening +bedarkens +bedaub +bedaubed +bedaubing +bedaubs +bedazzle +bedazzled +bedazzlement +bedazzlements +bedazzles +bedazzling +bedbug +bedbugs +bedchair +bedchairs +bedchamber +bedchambers +bedclothes +bedcover +bedcovering +bedcoverings +bedcovers +beddable +bedded +bedder +bedders +bedding +beddings +bedeafen +bedeafened +bedeafening +bedeafens +bedeck +bedecked +bedecking +bedecks +bedel +bedell +bedells +bedels +bedeman +bedemen +bedesman +bedesmen +bedevil +bedeviled +bedeviling +bedevilled +bedevilling +bedevilment +bedevilments +bedevils +bedew +bedewed +bedewing +bedews +bedfast +bedfellow +bedfellows +bedframe +bedframes +bedgown +bedgowns +bediaper +bediapered +bediapering +bediapers +bedight +bedighted +bedighting +bedights +bedim +bedimmed +bedimming +bedimple +bedimpled +bedimples +bedimpling +bedims +bedirtied +bedirties +bedirty +bedirtying +bedizen +bedizened +bedizening +bedizenment +bedizenments +bedizens +bedlam +bedlamite +bedlamites +bedlamp +bedlamps +bedlams +bedless +bedlike +bedmaker +bedmakers +bedmate +bedmates +bedotted +bedouin +bedouins +bedpan +bedpans +bedplate +bedplates +bedpost +bedposts +bedquilt +bedquilts +bedraggle +bedraggled +bedraggles +bedraggling +bedrail +bedrails +bedrape +bedraped +bedrapes +bedraping +bedrench +bedrenched +bedrenches +bedrenching +bedrid +bedridden +bedrivel +bedriveled +bedriveling +bedrivelled +bedrivelling +bedrivels +bedrock +bedrocks +bedroll +bedrolls +bedroom +bedroomed +bedrooms +bedrug +bedrugged +bedrugging +bedrugs +beds +bedsheet +bedsheets +bedside +bedsides +bedsit +bedsits +bedsonia +bedsoniae +bedsonias +bedsore +bedsores +bedspread +bedspreads +bedspring +bedsprings +bedstand +bedstands +bedstead +bedsteads +bedstraw +bedstraws +bedtick +bedticks +bedtime +bedtimes +bedu +beduin +beduins +bedumb +bedumbed +bedumbing +bedumbs +bedunce +bedunced +bedunces +beduncing +bedward +bedwards +bedwarf +bedwarfed +bedwarfing +bedwarfs +bee +beebee +beebees +beebread +beebreads +beech +beechdrops +beechen +beeches +beechier +beechiest +beechnut +beechnuts +beechy +beef +beefalo +beefaloes +beefalos +beefcake +beefcakes +beefeater +beefeaters +beefed +beefier +beefiest +beefily +beefing +beefless +beefs +beefsteak +beefsteaks +beefwood +beefwoods +beefy +beehive +beehives +beekeeper +beekeepers +beekeeping +beekeepings +beelike +beeline +beelined +beelines +beelining +been +beep +beeped +beeper +beepers +beeping +beeps +beer +beerier +beeriest +beers +beery +bees +beestings +beeswax +beeswaxes +beeswing +beeswings +beet +beetle +beetled +beetler +beetlers +beetles +beetling +beetroot +beetroots +beets +beeves +beeyard +beeyards +beezer +beezers +befall +befallen +befalling +befalls +befell +befinger +befingered +befingering +befingers +befit +befits +befitted +befitting +befittingly +beflag +beflagged +beflagging +beflags +beflea +befleaed +befleaing +befleas +befleck +beflecked +beflecking +beflecks +beflower +beflowered +beflowering +beflowers +befog +befogged +befogging +befogs +befool +befooled +befooling +befools +before +beforehand +beforetime +befoul +befouled +befouler +befoulers +befouling +befouls +befret +befrets +befretted +befretting +befriend +befriended +befriending +befriends +befringe +befringed +befringes +befringing +befuddle +befuddled +befuddlement +befuddlements +befuddles +befuddling +beg +begall +begalled +begalling +begalls +began +begat +begaze +begazed +begazes +begazing +beget +begets +begetter +begetters +begetting +beggar +beggared +beggaries +beggaring +beggarliness +beggarlinesses +beggarly +beggars +beggarweed +beggarweeds +beggary +begged +begging +begin +beginner +beginners +beginning +beginnings +begins +begird +begirded +begirding +begirdle +begirdled +begirdles +begirdling +begirds +begirt +begirting +beglad +begladded +begladding +beglads +beglamor +beglamored +beglamoring +beglamors +beglamour +beglamoured +beglamouring +beglamours +begloom +begloomed +beglooming +beglooms +begone +begonia +begonias +begorah +begorra +begorrah +begot +begotten +begrim +begrime +begrimed +begrimes +begriming +begrimmed +begrimming +begrims +begroan +begroaned +begroaning +begroans +begrudge +begrudged +begrudges +begrudging +begrudgingly +begs +beguile +beguiled +beguilement +beguilements +beguiler +beguilers +beguiles +beguiling +beguilingly +beguine +beguines +begulf +begulfed +begulfing +begulfs +begum +begums +begun +behalf +behalves +behave +behaved +behaver +behavers +behaves +behaving +behavior +behavioral +behaviorally +behaviorism +behaviorisms +behaviorist +behavioristic +behaviorists +behaviors +behaviour +behaviours +behead +beheaded +beheading +beheadings +beheads +beheld +behemoth +behemoths +behest +behests +behind +behindhand +behinds +behold +beholden +beholder +beholders +beholding +beholds +behoof +behoove +behooved +behooves +behooving +behove +behoved +behoves +behoving +behowl +behowled +behowling +behowls +beige +beiges +beignet +beignets +beigy +being +beings +bejabers +bejeezus +bejesus +bejewel +bejeweled +bejeweling +bejewelled +bejewelling +bejewels +bejumble +bejumbled +bejumbles +bejumbling +bekiss +bekissed +bekisses +bekissing +beknight +beknighted +beknighting +beknights +beknot +beknots +beknotted +beknotting +bel +belabor +belabored +belaboring +belabors +belabour +belaboured +belabouring +belabours +belaced +beladied +beladies +belady +beladying +belated +belatedly +belatedness +belatednesses +belaud +belauded +belauding +belauds +belay +belayed +belaying +belays +belch +belched +belcher +belchers +belches +belching +beldam +beldame +beldames +beldams +beleaguer +beleaguered +beleaguering +beleaguerment +beleaguerments +beleaguers +beleap +beleaped +beleaping +beleaps +beleapt +belemnite +belemnites +belfried +belfries +belfry +belga +belgas +belie +belied +belief +beliefs +belier +beliers +belies +believabilities +believability +believable +believably +believe +believed +believer +believers +believes +believing +belike +beliquor +beliquored +beliquoring +beliquors +belittle +belittled +belittlement +belittlements +belittler +belittlers +belittles +belittling +belive +bell +belladonna +belladonnas +bellbird +bellbirds +bellboy +bellboys +belle +belled +belleek +belleeks +belles +belletrist +belletristic +belletrists +bellflower +bellflowers +bellhop +bellhops +bellicose +bellicosely +bellicosities +bellicosity +bellied +bellies +belligerence +belligerences +belligerencies +belligerency +belligerent +belligerently +belligerents +belling +bellman +bellmen +bellow +bellowed +bellower +bellowers +bellowing +bellows +bellpull +bellpulls +bells +bellwether +bellwethers +bellwort +bellworts +belly +bellyache +bellyached +bellyacher +bellyachers +bellyaches +bellyaching +bellyband +bellybands +bellybutton +bellybuttons +bellyful +bellyfuls +bellying +belong +belonged +belonging +belongingness +belongingnesses +belongings +belongs +beloved +beloveds +below +belowdecks +belowground +belows +bels +belt +belted +belter +belters +belting +beltings +beltless +beltline +beltlines +belts +beltway +beltways +beluga +belugas +belvedere +belvederes +belying +bema +bemadam +bemadamed +bemadaming +bemadams +bemadden +bemaddened +bemaddening +bemaddens +bemas +bemata +bemean +bemeaned +bemeaning +bemeans +bemedaled +bemedalled +bemingle +bemingled +bemingles +bemingling +bemire +bemired +bemires +bemiring +bemist +bemisted +bemisting +bemists +bemix +bemixed +bemixes +bemixing +bemixt +bemoan +bemoaned +bemoaning +bemoans +bemock +bemocked +bemocking +bemocks +bemuddle +bemuddled +bemuddles +bemuddling +bemurmur +bemurmured +bemurmuring +bemurmurs +bemuse +bemused +bemusedly +bemusement +bemusements +bemuses +bemusing +bemuzzle +bemuzzled +bemuzzles +bemuzzling +ben +bename +benamed +benames +benaming +bench +benched +bencher +benchers +benches +benching +benchland +benchlands +benchmark +benchmarks +benchwarmer +benchwarmers +bend +bendable +benday +bendayed +bendaying +bendays +bended +bendee +bendees +bender +benders +bending +bends +bendways +bendwise +bendy +bendys +bene +beneath +benedick +benedicks +benedict +benediction +benedictions +benedictory +benedicts +benefaction +benefactions +benefactor +benefactors +benefactress +benefactresses +benefic +benefice +beneficed +beneficence +beneficences +beneficent +beneficently +benefices +beneficial +beneficially +beneficialness +beneficialnesses +beneficiaries +beneficiary +beneficiate +beneficiated +beneficiates +beneficiating +beneficiation +beneficiations +beneficing +benefit +benefited +benefiter +benefiters +benefiting +benefits +benefitted +benefitting +benempt +benempted +benes +benevolence +benevolences +benevolent +benevolently +benevolentness +benevolentnesses +bengaline +bengalines +benighted +benightedly +benightedness +benightednesses +benign +benignancies +benignancy +benignant +benignantly +benignities +benignity +benignly +benison +benisons +benjamin +benjamins +benne +bennes +bennet +bennets +benni +bennies +bennis +benny +benomyl +benomyls +bens +bent +benthal +benthic +benthonic +benthos +benthoses +bentonite +bentonites +bentonitic +bents +bentwood +bentwoods +benumb +benumbed +benumbing +benumbs +benzal +benzaldehyde +benzaldehydes +benzanthracene +benzanthracenes +benzene +benzenes +benzenoid +benzidin +benzidine +benzidines +benzidins +benzimidazole +benzimidazoles +benzin +benzine +benzines +benzins +benzoapyrene +benzoapyrenes +benzoate +benzoates +benzocaine +benzocaines +benzodiazepine +benzodiazepines +benzofuran +benzofurans +benzoic +benzoin +benzoins +benzol +benzole +benzoles +benzols +benzophenone +benzophenones +benzoyl +benzoyls +benzyl +benzylic +benzyls +bepaint +bepainted +bepainting +bepaints +bepimple +bepimpled +bepimples +bepimpling +bequeath +bequeathal +bequeathals +bequeathed +bequeathing +bequeaths +bequest +bequests +berake +beraked +berakes +beraking +berascal +berascaled +berascaling +berascals +berate +berated +berates +berating +berberin +berberine +berberines +berberins +berberis +berberises +berceuse +berceuses +berdache +berdaches +bereave +bereaved +bereavement +bereavements +bereaver +bereavers +bereaves +bereaving +bereft +beret +berets +beretta +berettas +berg +bergamot +bergamots +bergere +bergeres +bergs +berhyme +berhymed +berhymes +berhyming +beribboned +beriberi +beriberis +berime +berimed +berimes +beriming +beringed +berkelium +berkeliums +berlin +berline +berlines +berlins +berm +berme +bermes +berms +bermudas +bernicle +bernicles +berobed +berouged +berretta +berrettas +berried +berries +berry +berrying +berrylike +berseem +berseems +berserk +berserker +berserkers +berserkly +berserks +berth +bertha +berthas +berthed +berthing +berths +beryl +beryline +beryllium +berylliums +beryls +bescorch +bescorched +bescorches +bescorching +bescour +bescoured +bescouring +bescours +bescreen +bescreened +bescreening +bescreens +beseech +beseeched +beseeches +beseeching +beseechingly +beseem +beseemed +beseeming +beseems +beset +besetment +besetments +besets +besetter +besetters +besetting +beshadow +beshadowed +beshadowing +beshadows +beshame +beshamed +beshames +beshaming +beshiver +beshivered +beshivering +beshivers +beshout +beshouted +beshouting +beshouts +beshrew +beshrewed +beshrewing +beshrews +beshroud +beshrouded +beshrouding +beshrouds +beside +besides +besiege +besieged +besieger +besiegers +besieges +besieging +beslaved +beslime +beslimed +beslimes +besliming +besmear +besmeared +besmearing +besmears +besmile +besmiled +besmiles +besmiling +besmirch +besmirched +besmirches +besmirching +besmoke +besmoked +besmokes +besmoking +besmooth +besmoothed +besmoothing +besmooths +besmudge +besmudged +besmudges +besmudging +besmut +besmuts +besmutted +besmutting +besnow +besnowed +besnowing +besnows +besom +besoms +besoothe +besoothed +besoothes +besoothing +besot +besots +besotted +besotting +besought +bespake +bespatter +bespattered +bespattering +bespatters +bespeak +bespeaking +bespeaks +bespectacled +bespoke +bespoken +bespouse +bespoused +bespouses +bespousing +bespread +bespreading +bespreads +besprent +besprinkle +besprinkled +besprinkles +besprinkling +best +bestead +besteaded +besteading +besteads +bested +bestial +bestialities +bestiality +bestialize +bestialized +bestializes +bestializing +bestially +bestiaries +bestiary +besting +bestir +bestirred +bestirring +bestirs +bestow +bestowal +bestowals +bestowed +bestowing +bestows +bestrew +bestrewed +bestrewing +bestrewn +bestrews +bestrid +bestridden +bestride +bestrides +bestriding +bestrode +bestrow +bestrowed +bestrowing +bestrown +bestrows +bests +bestseller +bestsellerdom +bestsellerdoms +bestsellers +bestud +bestudded +bestudding +bestuds +beswarm +beswarmed +beswarming +beswarms +bet +beta +betaine +betaines +betake +betaken +betakes +betaking +betas +betatron +betatrons +betatter +betattered +betattering +betatters +betaxed +betel +betelnut +betelnuts +betels +beth +bethank +bethanked +bethanking +bethanks +bethel +bethels +bethesda +bethesdas +bethink +bethinking +bethinks +bethorn +bethorned +bethorning +bethorns +bethought +beths +bethump +bethumped +bethumping +bethumps +betide +betided +betides +betiding +betime +betimes +betise +betises +betoken +betokened +betokening +betokens +beton +betonies +betons +betony +betook +betray +betrayal +betrayals +betrayed +betrayer +betrayers +betraying +betrays +betroth +betrothal +betrothals +betrothed +betrotheds +betrothing +betroths +bets +betta +bettas +betted +better +bettered +bettering +betterment +betterments +betters +betting +bettor +bettors +between +betweenbrain +betweenbrains +betweenness +betweennesses +betweentimes +betweenwhiles +betwixt +beuncled +bevatron +bevatrons +bevel +beveled +beveler +bevelers +beveling +bevelled +beveller +bevellers +bevelling +bevels +beverage +beverages +bevies +bevomit +bevomited +bevomiting +bevomits +bevor +bevors +bevy +bewail +bewailed +bewailer +bewailers +bewailing +bewails +beware +bewared +bewares +bewaring +bewearied +bewearies +beweary +bewearying +beweep +beweeping +beweeps +bewept +bewhiskered +bewig +bewigged +bewigging +bewigs +bewilder +bewildered +bewilderedly +bewilderedness +bewilderednesses +bewildering +bewilderingly +bewilderment +bewilderments +bewilders +bewinged +bewitch +bewitched +bewitcheries +bewitchery +bewitches +bewitching +bewitchingly +bewitchment +bewitchments +beworm +bewormed +beworming +beworms +beworried +beworries +beworry +beworrying +bewrap +bewrapped +bewrapping +bewraps +bewrapt +bewray +bewrayed +bewrayer +bewrayers +bewraying +bewrays +bey +beylic +beylics +beylik +beyliks +beyond +beyonds +beys +bezant +bezants +bezazz +bezazzes +bezel +bezels +bezil +bezils +bezique +beziques +bezoar +bezoars +bezzant +bezzants +bhakta +bhaktas +bhakti +bhaktis +bhang +bhangs +bharal +bharals +bheestie +bheesties +bheesty +bhistie +bhisties +bhoot +bhoots +bhut +bhuts +bi +biacetyl +biacetyls +biali +bialis +bialy +bialys +biannual +biannually +bias +biased +biasedly +biases +biasing +biasness +biasnesses +biassed +biasses +biassing +biathlete +biathletes +biathlon +biathlons +biaxal +biaxial +biaxially +bib +bibasic +bibb +bibbed +bibber +bibberies +bibbers +bibbery +bibbing +bibbs +bibcock +bibcocks +bibelot +bibelots +bible +bibles +bibless +biblical +biblically +biblicism +biblicisms +biblicist +biblicists +biblike +bibliographer +bibliographers +bibliographic +bibliographical +bibliographically +bibliographies +bibliography +bibliolater +bibliolaters +bibliolatries +bibliolatrous +bibliolatry +bibliologies +bibliology +bibliomania +bibliomaniac +bibliomaniacal +bibliomaniacs +bibliomanias +bibliopegic +bibliopegies +bibliopegist +bibliopegists +bibliopegy +bibliophile +bibliophiles +bibliophilic +bibliophilies +bibliophilism +bibliophilisms +bibliophily +bibliopole +bibliopoles +bibliopolist +bibliopolists +bibliotheca +bibliothecae +bibliothecal +bibliothecas +bibliotherapies +bibliotherapy +bibliotic +bibliotics +bibliotist +bibliotists +biblist +biblists +bibs +bibulous +bibulously +bibulousness +bibulousnesses +bicameral +bicameralism +bicameralisms +bicarb +bicarbonate +bicarbonates +bicarbs +bicaudal +bice +bicentenaries +bicentenary +bicentennial +bicentennials +biceps +bicepses +bices +bichromate +bichromated +bichromates +bichrome +bicipital +bicker +bickered +bickerer +bickerers +bickering +bickers +bicoastal +bicolor +bicolored +bicolors +bicolour +bicolours +bicomponent +biconcave +biconcavities +biconcavity +biconditional +biconditionals +biconvex +biconvexities +biconvexity +bicorn +bicorne +bicornes +bicron +bicrons +bicultural +biculturalism +biculturalisms +bicuspid +bicuspids +bicycle +bicycled +bicycler +bicyclers +bicycles +bicyclic +bicycling +bicyclist +bicyclists +bid +bidarka +bidarkas +bidarkee +bidarkees +biddabilities +biddability +biddable +biddably +bidden +bidder +bidders +biddies +bidding +biddings +biddy +bide +bided +bidental +bider +biders +bides +bidet +bidets +bidialectal +bidialectalism +bidialectalisms +biding +bidirectional +bidirectionally +bidonville +bidonvilles +bids +bield +bielded +bielding +bields +biennale +biennales +biennia +biennial +biennially +biennials +biennium +bienniums +bier +biers +biface +bifaces +bifacial +bifacially +biff +biffed +biffies +biffin +biffing +biffins +biffs +biffy +bifid +bifidities +bifidity +bifidly +bifilar +bifilarly +biflagellate +biflex +bifocal +bifocals +bifold +biforate +biforked +biform +biformed +bifunctional +bifurcate +bifurcated +bifurcates +bifurcating +bifurcation +bifurcations +big +bigamies +bigamist +bigamists +bigamous +bigamously +bigamy +bigarade +bigarades +bigaroon +bigaroons +bigeminal +bigeminies +bigeminy +bigeneric +bigeye +bigeyes +bigfeet +bigfoot +bigfoots +bigger +biggest +biggety +biggie +biggies +biggin +bigging +biggings +biggins +biggish +biggity +bighead +bigheaded +bigheads +bighearted +bigheartedly +bigheartedness +bigheartednesses +bighorn +bighorns +bight +bighted +bighting +bights +bigly +bigmouth +bigmouthed +bigmouths +bigness +bignesses +bignonia +bignonias +bigot +bigoted +bigotedly +bigotries +bigotry +bigots +bigs +bigwig +bigwigs +bihourly +bijection +bijections +bijective +bijou +bijous +bijouterie +bijouteries +bijoux +bijugate +bijugous +bike +biked +biker +bikers +bikes +bikeway +bikeways +bikie +bikies +biking +bikini +bikinied +bikinis +bilabial +bilabials +bilabiate +bilander +bilanders +bilateral +bilateralism +bilateralisms +bilaterally +bilayer +bilayers +bilberries +bilberry +bilbo +bilboa +bilboas +bilboes +bilbos +bildungsroman +bildungsromane +bildungsromans +bile +biles +bilge +bilged +bilges +bilgewater +bilgewaters +bilgier +bilgiest +bilging +bilgy +bilharzia +bilharzial +bilharzias +bilharziases +bilharziasis +biliary +bilinear +bilingual +bilingualism +bilingualisms +bilingually +bilinguals +bilious +biliously +biliousness +biliousnesses +bilirubin +bilirubins +biliverdin +biliverdins +bilk +bilked +bilker +bilkers +bilking +bilks +bill +billable +billabong +billabongs +billboard +billboarded +billboarding +billboards +billbug +billbugs +billed +biller +billers +billet +billeted +billeter +billeters +billeting +billets +billfish +billfishes +billfold +billfolds +billhead +billheads +billhook +billhooks +billiard +billiards +billie +billies +billing +billings +billingsgate +billingsgates +billion +billionaire +billionaires +billions +billionth +billionths +billon +billons +billow +billowed +billowier +billowiest +billowing +billows +billowy +bills +billy +billycan +billycans +billycock +billycocks +bilobate +bilobed +bilocation +bilocations +bilsted +bilsteds +biltong +biltongs +bima +bimah +bimahs +bimanous +bimanual +bimanually +bimas +bimbo +bimboes +bimbos +bimensal +bimester +bimesters +bimetal +bimetallic +bimetallics +bimetallism +bimetallisms +bimetallist +bimetallistic +bimetallists +bimetals +bimethyl +bimethyls +bimillenaries +bimillenary +bimillennial +bimillennials +bimodal +bimodalities +bimodality +bimolecular +bimolecularly +bimonthlies +bimonthly +bimorph +bimorphemic +bimorphs +bin +binal +binaries +binary +binate +binately +binational +binaural +binaurally +bind +bindable +binder +binderies +binders +bindery +bindi +binding +bindingly +bindingness +bindingnesses +bindings +bindis +bindle +bindles +binds +bindweed +bindweeds +bine +bines +binge +binged +bingeing +binger +bingers +binges +binging +bingo +bingos +binit +binits +binnacle +binnacles +binned +binning +binocle +binocles +binocs +binocular +binocularities +binocularity +binocularly +binoculars +binomial +binomially +binomials +bins +bint +bints +binucleate +binucleated +bio +bioacoustics +bioactive +bioactivities +bioactivity +bioassay +bioassayed +bioassaying +bioassays +bioavailabilities +bioavailability +bioavailable +biocenoses +biocenosis +biochemical +biochemically +biochemicals +biochemist +biochemistries +biochemistry +biochemists +biochip +biochips +biocidal +biocide +biocides +bioclean +bioclimatic +biocoenoses +biocoenosis +biocompatibilities +biocompatibility +biocompatible +biocontrol +biocontrols +bioconversion +bioconversions +biocycle +biocycles +biodegradabilities +biodegradability +biodegradable +biodegradation +biodegradations +biodegrade +biodegraded +biodegrades +biodegrading +biodeterioration +biodeteriorations +biodiversities +biodiversity +biodynamic +bioelectric +bioelectrical +bioelectricities +bioelectricity +bioenergetic +bioenergetics +bioengineer +bioengineered +bioengineering +bioengineerings +bioengineers +bioethic +bioethical +bioethicist +bioethicists +bioethics +biofeedback +biofeedbacks +biofouling +biofoulings +biogas +biogases +biogasses +biogen +biogeneses +biogenesis +biogenetic +biogenetically +biogenic +biogenies +biogenous +biogens +biogeny +biogeochemical +biogeochemicals +biogeochemistries +biogeochemistry +biogeographer +biogeographers +biogeographic +biogeographical +biogeographies +biogeography +biographee +biographees +biographer +biographers +biographic +biographical +biographically +biographies +biography +biohazard +biohazards +bioherm +bioherms +biologic +biological +biologically +biologicals +biologics +biologies +biologism +biologisms +biologist +biologistic +biologists +biology +bioluminescence +bioluminescences +bioluminescent +biolyses +biolysis +biolytic +biomass +biomasses +biomaterial +biomaterials +biomathematical +biomathematician +biomathematicians +biomathematics +biome +biomechanical +biomechanically +biomechanics +biomedical +biomedicine +biomedicines +biomes +biometeorological +biometeorologies +biometeorology +biometric +biometrical +biometrician +biometricians +biometrics +biometries +biometry +biomolecular +biomolecule +biomolecules +biomorphic +bionic +bionics +bionomic +bionomics +bionomies +bionomy +biont +biontic +bionts +biophysical +biophysicist +biophysicists +biophysics +biopic +biopics +bioplasm +bioplasms +biopolymer +biopolymers +biopsic +biopsied +biopsies +biopsy +biopsying +bioptic +bioreactor +bioreactors +biorhythm +biorhythmic +biorhythms +bios +biosafeties +biosafety +bioscience +biosciences +bioscientific +bioscientist +bioscientists +bioscope +bioscopes +bioscopies +bioscopy +biosensor +biosensors +biosocial +biosocially +biosphere +biospheres +biospheric +biostatistical +biostatistician +biostatisticians +biostatistics +biostratigraphic +biostratigraphies +biostratigraphy +biosyntheses +biosynthesis +biosynthetic +biosynthetically +biosystematic +biosystematics +biosystematist +biosystematists +biota +biotas +biotech +biotechnical +biotechnological +biotechnologies +biotechnologist +biotechnologists +biotechnology +biotechs +biotelemetric +biotelemetries +biotelemetry +biotic +biotical +biotics +biotin +biotins +biotite +biotites +biotitic +biotope +biotopes +biotoxin +biotoxins +biotransformation +biotransformations +biotron +biotrons +biotype +biotypes +biotypic +biovular +bipack +bipacks +biparental +biparentally +biparous +biparted +bipartisan +bipartisanism +bipartisanisms +bipartisanship +bipartisanships +bipartite +bipartitely +bipartition +bipartitions +biparty +biped +bipedal +bipedalism +bipedalisms +bipedalities +bipedality +bipedally +bipeds +biphasic +biphenyl +biphenyls +bipinnate +bipinnately +biplane +biplanes +bipod +bipods +bipolar +bipolarities +bipolarity +bipolarization +bipolarizations +bipolarize +bipolarized +bipolarizes +bipolarizing +bipropellant +bipropellants +bipyramid +bipyramidal +bipyramids +biquadratic +biquadratics +biracial +biracialism +biracialisms +biradial +biramose +biramous +birch +birched +birchen +birches +birching +bird +birdbath +birdbaths +birdbrain +birdbrained +birdbrains +birdcage +birdcages +birdcall +birdcalls +birded +birder +birders +birdfarm +birdfarms +birdhouse +birdhouses +birdie +birdied +birdieing +birdies +birding +birdings +birdlike +birdlime +birdlimed +birdlimes +birdliming +birdman +birdmen +birds +birdseed +birdseeds +birdseye +birdseyes +birdshot +birdshots +birdsong +birdsongs +birdwatcher +birdwatchers +birefringence +birefringences +birefringent +bireme +biremes +biretta +birettas +birk +birkie +birkies +birks +birl +birle +birled +birler +birlers +birles +birling +birlings +birls +birr +birred +birretta +birrettas +birring +birrotch +birrs +birse +birses +birth +birthdate +birthdates +birthday +birthdays +birthed +birthing +birthmark +birthmarks +birthplace +birthplaces +birthrate +birthrates +birthright +birthrights +birthroot +birthroots +births +birthstone +birthstones +birthwort +birthworts +bis +biscuit +biscuits +bise +bisect +bisected +bisecting +bisection +bisectional +bisectionally +bisections +bisector +bisectors +bisects +bises +bisexual +bisexualities +bisexuality +bisexually +bisexuals +bishop +bishoped +bishoping +bishopric +bishoprics +bishops +bisk +bisks +bismuth +bismuthic +bismuths +bisnaga +bisnagas +bison +bisons +bisontine +bisque +bisques +bistate +bister +bistered +bisters +bistort +bistorts +bistouries +bistoury +bistre +bistred +bistres +bistro +bistroic +bistros +bisulfate +bisulfates +bisulfide +bisulfides +bisulfite +bisulfites +bit +bitable +bitartrate +bitartrates +bitch +bitched +bitcheries +bitchery +bitches +bitchier +bitchiest +bitchily +bitchiness +bitchinesses +bitching +bitchy +bite +biteable +biter +biters +bites +bitewing +bitewings +biting +bitingly +bits +bitstock +bitstocks +bitsy +bitt +bitted +bitten +bitter +bitterbrush +bitterbrushes +bittered +bitterer +bitterest +bittering +bitterish +bitterly +bittern +bitterness +bitternesses +bitterns +bitterroot +bitterroots +bitters +bittersweet +bittersweetly +bittersweetness +bittersweetnesses +bittersweets +bitterweed +bitterweeds +bittier +bittiest +bitting +bittings +bittock +bittocks +bitts +bitty +bitumen +bitumens +bituminization +bituminizations +bituminize +bituminized +bituminizes +bituminizing +bituminous +biunique +biuniqueness +biuniquenesses +bivalent +bivalents +bivalve +bivalved +bivalves +bivariate +bivinyl +bivinyls +bivouac +bivouacked +bivouacking +bivouacks +bivouacs +biweeklies +biweekly +biyearly +biz +bizarre +bizarrely +bizarreness +bizarrenesses +bizarrerie +bizarreries +bizarres +bize +bizes +biznaga +biznagas +bizonal +bizone +bizones +bizzes +blab +blabbed +blabber +blabbered +blabbering +blabbermouth +blabbermouths +blabbers +blabbing +blabby +blabs +black +blackamoor +blackamoors +blackball +blackballed +blackballing +blackballs +blackberries +blackberry +blackbird +blackbirded +blackbirder +blackbirders +blackbirding +blackbirds +blackboard +blackboards +blackbodies +blackbody +blackboy +blackboys +blackcap +blackcaps +blackcock +blackcocks +blacked +blacken +blackened +blackener +blackeners +blackening +blackenings +blackens +blacker +blackest +blackface +blackfaces +blackfin +blackfins +blackfish +blackfishes +blackflies +blackfly +blackguard +blackguarded +blackguarding +blackguardism +blackguardisms +blackguardly +blackguards +blackgum +blackgums +blackhander +blackhanders +blackhead +blackheads +blackheart +blackhearts +blacking +blackings +blackish +blackjack +blackjacked +blackjacking +blackjacks +blackland +blacklands +blacklead +blackleads +blackleg +blacklegs +blacklist +blacklisted +blacklister +blacklisters +blacklisting +blacklists +blackly +blackmail +blackmailed +blackmailer +blackmailers +blackmailing +blackmails +blackness +blacknesses +blackout +blackouts +blackpoll +blackpolls +blacks +blacksmith +blacksmithing +blacksmithings +blacksmiths +blacksnake +blacksnakes +blacktail +blacktails +blackthorn +blackthorns +blacktop +blacktopped +blacktopping +blacktops +blackwater +blackwaters +blackwood +blackwoods +bladder +bladderlike +bladdernut +bladdernuts +bladders +bladderwort +bladderworts +bladdery +blade +bladed +bladelike +blades +blae +blaeberries +blaeberry +blah +blahs +blain +blains +blam +blamable +blamably +blame +blamed +blameful +blamefully +blameless +blamelessly +blamelessness +blamelessnesses +blamer +blamers +blames +blameworthiness +blameworthinesses +blameworthy +blaming +blams +blanch +blanched +blancher +blanchers +blanches +blanching +blancmange +blancmanges +bland +blander +blandest +blandish +blandished +blandisher +blandishers +blandishes +blandishing +blandishment +blandishments +blandly +blandness +blandnesses +blank +blanked +blanker +blankest +blanket +blanketed +blanketflower +blanketflowers +blanketing +blanketlike +blankets +blanking +blankly +blankness +blanknesses +blanks +blanquette +blanquettes +blare +blared +blares +blaring +blarney +blarneyed +blarneying +blarneys +blase +blaspheme +blasphemed +blasphemer +blasphemers +blasphemes +blasphemies +blaspheming +blasphemous +blasphemously +blasphemousness +blasphemousnesses +blasphemy +blast +blasted +blastema +blastemal +blastemas +blastemata +blastematic +blaster +blasters +blastie +blastier +blasties +blastiest +blasting +blastings +blastment +blastments +blastocoel +blastocoele +blastocoeles +blastocoelic +blastocoels +blastocyst +blastocysts +blastoderm +blastoderms +blastodisc +blastodiscs +blastoff +blastoffs +blastoma +blastomas +blastomata +blastomere +blastomeres +blastomycoses +blastomycosis +blastopore +blastopores +blastoporic +blastospore +blastospores +blasts +blastula +blastulae +blastulas +blastulation +blastulations +blasty +blat +blatancies +blatancy +blatant +blatantly +blate +blather +blathered +blatherer +blatherers +blathering +blathers +blatherskite +blatherskites +blats +blatted +blatter +blattered +blattering +blatters +blatting +blaubok +blauboks +blaw +blawed +blawing +blawn +blaws +blaxploitation +blaxploitations +blaze +blazed +blazer +blazers +blazes +blazing +blazingly +blazon +blazoned +blazoner +blazoners +blazoning +blazonings +blazonries +blazonry +blazons +bleach +bleachable +bleached +bleacher +bleacherite +bleacherites +bleachers +bleaches +bleaching +bleak +bleaker +bleakest +bleakish +bleakly +bleakness +bleaknesses +bleaks +blear +bleared +blearier +bleariest +blearily +bleariness +blearinesses +blearing +blears +bleary +bleat +bleated +bleater +bleaters +bleating +bleats +bleb +blebby +blebs +bled +bleed +bleeder +bleeders +bleeding +bleedings +bleeds +bleep +bleeped +bleeping +bleeps +blellum +blellums +blemish +blemished +blemishes +blemishing +blench +blenched +blencher +blenchers +blenches +blenching +blend +blende +blended +blender +blenders +blendes +blending +blends +blennies +blenny +blent +blepharoplast +blepharoplasties +blepharoplasts +blepharoplasty +blepharospasm +blepharospasms +blesbok +blesboks +blesbuck +blesbucks +bless +blessed +blesseder +blessedest +blessedly +blessedness +blessednesses +blesser +blessers +blesses +blessing +blessings +blest +blet +blether +blethered +blethering +blethers +blets +blew +blight +blighted +blighter +blighters +blighties +blighting +blights +blighty +blimey +blimp +blimpish +blimpishly +blimpishness +blimpishnesses +blimps +blimy +blin +blind +blindage +blindages +blinded +blinder +blinders +blindest +blindfish +blindfishes +blindfold +blindfolded +blindfolding +blindfolds +blinding +blindingly +blindly +blindness +blindnesses +blinds +blindside +blindsided +blindsides +blindsiding +blindworm +blindworms +blini +blinis +blink +blinkard +blinkards +blinked +blinker +blinkered +blinkering +blinkers +blinking +blinks +blintz +blintze +blintzes +blip +blipped +blipping +blips +bliss +blissed +blisses +blissful +blissfully +blissfulness +blissfulnesses +blissing +blister +blistered +blistering +blisteringly +blisters +blistery +blite +blites +blithe +blithely +blither +blithered +blithering +blithers +blithesome +blithesomely +blithest +blitz +blitzed +blitzes +blitzing +blitzkrieg +blitzkriegs +blizzard +blizzardly +blizzards +blizzardy +bloat +bloated +bloater +bloaters +bloating +bloats +blob +blobbed +blobbing +blobs +bloc +block +blockade +blockaded +blockader +blockaders +blockades +blockading +blockage +blockages +blockbuster +blockbusters +blockbusting +blockbustings +blocked +blocker +blockers +blockhead +blockheads +blockhouse +blockhouses +blockier +blockiest +blocking +blockish +blocks +blocky +blocs +bloke +blokes +blond +blonde +blonder +blondes +blondest +blondish +blonds +blood +bloodbath +bloodbaths +bloodcurdling +blooded +bloodfin +bloodfins +bloodguilt +bloodguiltiness +bloodguiltinesses +bloodguilts +bloodguilty +bloodhound +bloodhounds +bloodied +bloodier +bloodies +bloodiest +bloodily +bloodiness +bloodinesses +blooding +bloodings +bloodless +bloodlessly +bloodlessness +bloodlessnesses +bloodletting +bloodlettings +bloodline +bloodlines +bloodmobile +bloodmobiles +bloodred +bloodroot +bloodroots +bloods +bloodshed +bloodsheds +bloodshot +bloodstain +bloodstained +bloodstains +bloodstock +bloodstocks +bloodstone +bloodstones +bloodstream +bloodstreams +bloodsucker +bloodsuckers +bloodsucking +bloodthirstily +bloodthirstiness +bloodthirstinesses +bloodthirsty +bloodworm +bloodworms +bloody +bloodying +blooey +blooie +bloom +bloomed +bloomer +bloomeries +bloomers +bloomery +bloomier +bloomiest +blooming +blooms +bloomy +bloop +blooped +blooper +bloopers +blooping +bloops +blossom +blossomed +blossoming +blossoms +blossomy +blot +blotch +blotched +blotches +blotchier +blotchiest +blotchily +blotching +blotchy +blotless +blots +blotted +blotter +blotters +blottier +blottiest +blotting +blotto +blotty +blouse +bloused +blouses +blousier +blousiest +blousily +blousing +blouson +blousons +blousy +bloviate +bloviated +bloviates +bloviating +blow +blowback +blowbacks +blowball +blowballs +blowby +blowbys +blowdown +blowdowns +blowed +blower +blowers +blowfish +blowfishes +blowflies +blowfly +blowgun +blowguns +blowhard +blowhards +blowhole +blowholes +blowier +blowiest +blowing +blowjob +blowjobs +blown +blowoff +blowoffs +blowout +blowouts +blowpipe +blowpipes +blows +blowsed +blowsier +blowsiest +blowsily +blowsy +blowtorch +blowtorches +blowtube +blowtubes +blowup +blowups +blowy +blowzed +blowzier +blowziest +blowzily +blowzy +blub +blubbed +blubber +blubbered +blubbering +blubbers +blubbery +blubbing +blubs +blucher +bluchers +bludgeon +bludgeoned +bludgeoning +bludgeons +bludger +bludgers +blue +blueball +blueballs +bluebeard +bluebeards +bluebell +bluebells +blueberries +blueberry +bluebill +bluebills +bluebird +bluebirds +bluebonnet +bluebonnets +bluebook +bluebooks +bluebottle +bluebottles +bluecap +bluecaps +bluecoat +bluecoats +blued +bluefin +bluefins +bluefish +bluefishes +bluegill +bluegills +bluegrass +bluegrasses +bluegum +bluegums +bluehead +blueheads +blueing +blueings +blueish +bluejack +bluejacket +bluejackets +bluejacks +bluejay +bluejays +bluejeans +blueline +bluelines +bluely +blueness +bluenesses +bluenose +bluenoses +bluepoint +bluepoints +blueprint +blueprinted +blueprinting +blueprints +bluer +blues +blueshift +blueshifted +blueshifts +bluesier +bluesiest +bluesman +bluesmen +bluest +bluestem +bluestems +bluestocking +bluestockings +bluestone +bluestones +bluesy +bluet +bluetick +blueticks +bluetongue +bluetongues +bluets +blueweed +blueweeds +bluewood +bluewoods +bluey +blueys +bluff +bluffed +bluffer +bluffers +bluffest +bluffing +bluffly +bluffness +bluffnesses +bluffs +bluing +bluings +bluish +bluishness +bluishnesses +blume +blumed +blumes +bluming +blunder +blunderbuss +blunderbusses +blundered +blunderer +blunderers +blundering +blunderingly +blunders +blunge +blunged +blunger +blungers +blunges +blunging +blunt +blunted +blunter +bluntest +blunting +bluntly +bluntness +bluntnesses +blunts +blur +blurb +blurbed +blurbing +blurbs +blurred +blurrier +blurriest +blurrily +blurriness +blurrinesses +blurring +blurringly +blurry +blurs +blurt +blurted +blurter +blurters +blurting +blurts +blush +blushed +blusher +blushers +blushes +blushful +blushing +blushingly +bluster +blustered +blusterer +blusterers +blustering +blusteringly +blusterous +blusters +blustery +blype +blypes +bo +boa +boar +board +boarded +boarder +boarders +boarding +boardinghouse +boardinghouses +boardings +boardlike +boardman +boardmen +boardroom +boardrooms +boards +boardsailing +boardsailings +boardsailor +boardsailors +boardwalk +boardwalks +boarfish +boarfishes +boarish +boars +boart +boarts +boas +boast +boasted +boaster +boasters +boastful +boastfully +boastfulness +boastfulnesses +boasting +boasts +boat +boatable +boatbill +boatbills +boatbuilder +boatbuilders +boatbuilding +boatbuildings +boated +boatel +boatels +boater +boaters +boatful +boatfuls +boathook +boathooks +boathouse +boathouses +boating +boatings +boatlike +boatload +boatloads +boatman +boatmen +boats +boatsman +boatsmen +boatswain +boatswains +boatyard +boatyards +bob +bobbed +bobber +bobberies +bobbers +bobbery +bobbies +bobbin +bobbinet +bobbinets +bobbing +bobbins +bobble +bobbled +bobbles +bobbling +bobby +bobcat +bobcats +bobeche +bobeches +bobolink +bobolinks +bobs +bobsled +bobsledded +bobsledder +bobsledders +bobsledding +bobsleddings +bobsleds +bobstay +bobstays +bobtail +bobtailed +bobtailing +bobtails +bobwhite +bobwhites +bocaccio +bocaccios +bocce +bocces +bocci +boccia +boccias +boccie +boccies +boccis +boche +boches +bock +bocks +bod +bodacious +bodaciously +boddhisattva +boddhisattvas +bode +boded +bodega +bodegas +bodement +bodements +bodes +bodhisattva +bodhisattvas +bodhran +bodhrans +bodice +bodices +bodied +bodies +bodiless +bodily +boding +bodingly +bodings +bodkin +bodkins +bods +body +bodybuilder +bodybuilders +bodybuilding +bodybuildings +bodycheck +bodychecked +bodychecking +bodychecks +bodyguard +bodyguards +bodying +bodysuit +bodysuits +bodysurf +bodysurfed +bodysurfer +bodysurfers +bodysurfing +bodysurfs +bodywork +bodyworks +boehmite +boehmites +boff +boffin +boffins +boffo +boffola +boffolas +boffos +boffs +bog +bogan +bogans +bogbean +bogbeans +bogey +bogeyed +bogeying +bogeyman +bogeymen +bogeys +bogged +boggier +boggiest +bogging +boggish +boggle +boggled +boggler +bogglers +boggles +boggling +boggy +bogie +bogies +bogle +bogles +bogs +bogus +bogwood +bogwoods +bogy +bogyism +bogyisms +bogyman +bogymen +bohea +boheas +bohemia +bohemian +bohemianism +bohemianisms +bohemians +bohemias +bohunk +bohunks +boil +boilable +boiled +boiler +boilermaker +boilermakers +boilerplate +boilerplates +boilers +boilersuit +boilersuits +boiling +boiloff +boiloffs +boils +boing +boiserie +boiseries +boisterous +boisterously +boisterousness +boisterousnesses +boite +boites +bola +bolar +bolas +bolases +bold +bolder +boldest +boldface +boldfaced +boldfaces +boldfacing +boldly +boldness +boldnesses +bolds +bole +bolero +boleros +boles +bolete +boletes +boleti +boletus +boletuses +bolide +bolides +bolivar +bolivares +bolivars +bolivia +boliviano +bolivianos +bolivias +boll +bollard +bollards +bolled +bolling +bollix +bollixed +bollixes +bollixing +bollocks +bollox +bolloxed +bolloxes +bolloxing +bolls +bollworm +bollworms +bolo +bologna +bolognas +bolometer +bolometers +bolometric +bolometrically +boloney +boloneys +bolos +bolshevism +bolshevisms +bolshevize +bolshevized +bolshevizes +bolshevizing +bolshie +bolshies +bolshy +bolson +bolsons +bolster +bolstered +bolsterer +bolsterers +bolstering +bolsters +bolt +bolted +bolter +bolters +bolthead +boltheads +bolthole +boltholes +bolting +boltonia +boltonias +boltrope +boltropes +bolts +bolus +boluses +bomb +bombard +bombarded +bombardier +bombardiers +bombarding +bombardment +bombardments +bombardon +bombardons +bombards +bombast +bombastic +bombastically +bombasts +bombax +bombazine +bombazines +bombe +bombed +bomber +bombers +bombes +bombesin +bombesins +bombinate +bombinated +bombinates +bombinating +bombination +bombinations +bombing +bombings +bombload +bombloads +bombproof +bombs +bombshell +bombshells +bombsight +bombsights +bombycid +bombycids +bombyx +bombyxes +bonaci +bonacis +bonanza +bonanzas +bonbon +bonbons +bond +bondable +bondage +bondages +bonded +bonder +bonders +bondholder +bondholders +bonding +bondings +bondmaid +bondmaids +bondman +bondmen +bonds +bondsman +bondsmen +bondstone +bondstones +bonduc +bonducs +bondwoman +bondwomen +bone +boned +bonefish +bonefishes +bonefishing +bonefishings +bonehead +boneheaded +boneheadedness +boneheadednesses +boneheads +boneless +bonemeal +bonemeals +boner +boners +bones +boneset +bonesets +bonesetter +bonesetters +boney +boneyard +boneyards +bonfire +bonfires +bong +bonged +bonging +bongo +bongoes +bongoist +bongoists +bongos +bongs +bonhomie +bonhomies +bonhomous +bonier +boniest +boniface +bonifaces +boniness +boninesses +boning +bonita +bonitas +bonito +bonitoes +bonitos +bonk +bonked +bonkers +bonking +bonks +bonne +bonnes +bonnet +bonneted +bonneting +bonnets +bonnie +bonnier +bonniest +bonnily +bonnock +bonnocks +bonny +bonnyclabber +bonnyclabbers +bonsai +bonspell +bonspells +bonspiel +bonspiels +bontebok +bonteboks +bonus +bonuses +bony +bonze +bonzer +bonzes +boo +boob +boobed +boobie +boobies +boobing +boobish +booboisie +booboisies +booboo +booboos +boobs +booby +boodle +boodled +boodler +boodlers +boodles +boodling +booed +booger +boogerman +boogermen +boogers +boogey +boogeyed +boogeying +boogeyman +boogeymen +boogeys +boogie +boogied +boogies +boogy +boogying +boogyman +boogymen +boohoo +boohooed +boohooing +boohoos +booing +book +bookable +bookbinder +bookbinderies +bookbinders +bookbindery +bookbinding +bookbindings +bookcase +bookcases +booked +bookend +bookends +booker +bookers +bookful +bookfuls +bookie +bookies +booking +bookings +bookish +bookishly +bookishness +bookishnesses +bookkeeper +bookkeepers +bookkeeping +bookkeepings +booklet +booklets +booklice +booklore +booklores +booklouse +bookmaker +bookmakers +bookmaking +bookmakings +bookman +bookmark +bookmarker +bookmarkers +bookmarks +bookmen +bookmobile +bookmobiles +bookplate +bookplates +bookrack +bookracks +bookrest +bookrests +books +bookseller +booksellers +bookselling +booksellings +bookshelf +bookshelves +bookshop +bookshops +bookstall +bookstalls +bookstore +bookstores +bookworm +bookworms +boom +boombox +boomboxes +boomed +boomer +boomerang +boomeranged +boomeranging +boomerangs +boomers +boomier +boomiest +booming +boomkin +boomkins +boomlet +boomlets +booms +boomtown +boomtowns +boomy +boon +boondock +boondocks +boondoggle +boondoggled +boondoggler +boondogglers +boondoggles +boondoggling +boonies +boons +boor +boorish +boorishly +boorishness +boorishnesses +boors +boos +boost +boosted +booster +boosterism +boosterisms +boosters +boosting +boosts +boot +bootable +bootblack +bootblacks +booted +bootee +bootees +booteries +bootery +booth +booths +bootie +booties +booting +bootjack +bootjacks +bootlace +bootlaces +bootleg +bootlegged +bootlegger +bootleggers +bootlegging +bootlegs +bootless +bootlessly +bootlessness +bootlessnesses +bootlick +bootlicked +bootlicker +bootlickers +bootlicking +bootlicks +boots +bootstrap +bootstrapped +bootstrapping +bootstraps +booty +booze +boozed +boozer +boozers +boozes +boozier +booziest +boozily +boozing +boozy +bop +bopeep +bopeeps +bopped +bopper +boppers +bopping +bops +bora +boraces +boracic +boracite +boracites +borage +borages +boral +borals +borane +boranes +boras +borate +borated +borates +borating +borax +boraxes +borborygmi +borborygmus +bordeaux +bordel +bordello +bordellos +bordels +border +bordereau +bordereaux +bordered +borderer +borderers +bordering +borderland +borderlands +borderline +borderlines +borders +bordure +bordures +bore +boreal +borecole +borecoles +bored +boredom +boredoms +boreen +boreens +borehole +boreholes +borer +borers +bores +borescope +borescopes +boresome +boric +boride +borides +boring +boringly +boringness +boringnesses +borings +born +borne +borneol +borneols +bornite +bornites +borohydride +borohydrides +boron +boronic +borons +borosilicate +borosilicates +borough +boroughs +borrow +borrowed +borrower +borrowers +borrowing +borrowings +borrows +borsch +borsches +borscht +borschts +borsht +borshts +borstal +borstals +bort +borts +borty +bortz +bortzes +borzoi +borzois +bos +boscage +boscages +boschbok +boschboks +bosh +boshbok +boshboks +boshes +boshvark +boshvarks +bosk +boskage +boskages +bosker +bosket +boskets +boskier +boskiest +bosks +bosky +bosom +bosomed +bosoming +bosoms +bosomy +boson +bosons +bosque +bosques +bosquet +bosquets +boss +bossdom +bossdoms +bossed +bosses +bossier +bossies +bossiest +bossily +bossiness +bossinesses +bossing +bossism +bossisms +bossy +boston +bostons +bosun +bosuns +bot +bota +botanic +botanica +botanical +botanically +botanicals +botanicas +botanies +botanise +botanised +botanises +botanising +botanist +botanists +botanize +botanized +botanizes +botanizing +botany +botas +botch +botched +botcher +botcheries +botchers +botchery +botches +botchier +botchiest +botchily +botching +botchy +botel +botels +botflies +botfly +both +bother +botheration +botherations +bothered +bothering +bothers +bothersome +bothies +bothria +bothrium +bothriums +bothy +botonee +botonnee +botryoid +botryoidal +botryose +botrytis +botrytises +bots +bott +bottle +bottlebrush +bottlebrushes +bottled +bottleful +bottlefuls +bottleneck +bottlenecked +bottlenecking +bottlenecks +bottler +bottlers +bottles +bottling +bottlings +bottom +bottomed +bottomer +bottomers +bottoming +bottomland +bottomlands +bottomless +bottomlessly +bottomlessness +bottomlessnesses +bottommost +bottomries +bottomry +bottoms +botts +botulin +botulinal +botulins +botulinum +botulinums +botulinus +botulinuses +botulism +botulisms +boubou +boubous +bouchee +bouchees +boucle +boucles +boudoir +boudoirs +bouffant +bouffants +bouffe +bouffes +bougainvillaea +bougainvillaeas +bougainvillea +bougainvilleas +bough +boughed +boughpot +boughpots +boughs +bought +boughten +bougie +bougies +bouillabaisse +bouillabaisses +bouillon +bouillons +boulder +bouldered +boulders +bouldery +boule +boules +boulevard +boulevardier +boulevardiers +boulevards +bouleversement +bouleversements +boulle +boulles +bounce +bounced +bouncer +bouncers +bounces +bouncier +bounciest +bouncily +bouncing +bouncingly +bouncy +bound +boundaries +boundary +bounded +boundedness +boundednesses +bounden +bounder +bounderish +bounders +bounding +boundless +boundlessly +boundlessness +boundlessnesses +bounds +bounteous +bounteously +bounteousness +bounteousnesses +bountied +bounties +bountiful +bountifully +bountifulness +bountifulnesses +bounty +bouquet +bouquets +bourbon +bourbonism +bourbonisms +bourbons +bourdon +bourdons +bourg +bourgeois +bourgeoise +bourgeoises +bourgeoisie +bourgeoisies +bourgeoisification +bourgeoisifications +bourgeoisified +bourgeoisifies +bourgeoisify +bourgeoisifying +bourgeon +bourgeoned +bourgeoning +bourgeons +bourgs +bourguignon +bourguignonne +bourn +bourne +bournes +bourns +bourree +bourrees +bourride +bourrides +bourse +bourses +bourtree +bourtrees +bouse +boused +bouses +bousing +bousouki +bousoukia +bousoukis +boustrophedon +boustrophedonic +boustrophedons +bousy +bout +boutique +boutiques +bouton +boutonniere +boutonnieres +boutons +bouts +bouvier +bouviers +bouzouki +bouzoukia +bouzoukis +bovid +bovids +bovine +bovinely +bovines +bovinities +bovinity +bow +bowdlerise +bowdlerised +bowdlerises +bowdlerising +bowdlerization +bowdlerizations +bowdlerize +bowdlerized +bowdlerizer +bowdlerizers +bowdlerizes +bowdlerizing +bowed +bowel +boweled +boweling +bowelled +bowelless +bowelling +bowels +bower +bowerbird +bowerbirds +bowered +boweries +bowering +bowers +bowery +bowfin +bowfins +bowfront +bowhead +bowheads +bowing +bowingly +bowings +bowknot +bowknots +bowl +bowlder +bowlders +bowled +bowleg +bowlegged +bowlegs +bowler +bowlers +bowless +bowlful +bowlfuls +bowlike +bowline +bowlines +bowling +bowlings +bowllike +bowls +bowman +bowmen +bowpot +bowpots +bows +bowse +bowsed +bowses +bowshot +bowshots +bowsing +bowsprit +bowsprits +bowstring +bowstrings +bowwow +bowwowed +bowwowing +bowwows +bowyer +bowyers +box +boxberries +boxberry +boxboard +boxboards +boxcar +boxcars +boxed +boxer +boxers +boxes +boxfish +boxfishes +boxful +boxfuls +boxhaul +boxhauled +boxhauling +boxhauls +boxier +boxiest +boxiness +boxinesses +boxing +boxings +boxlike +boxthorn +boxthorns +boxwood +boxwoods +boxy +boy +boyar +boyard +boyards +boyarism +boyarisms +boyars +boychick +boychicks +boychik +boychiks +boycott +boycotted +boycotter +boycotters +boycotting +boycotts +boyfriend +boyfriends +boyhood +boyhoods +boyish +boyishly +boyishness +boyishnesses +boyla +boylas +boyo +boyos +boys +boysenberries +boysenberry +bozo +bozos +bra +brabble +brabbled +brabbler +brabblers +brabbles +brabbling +brace +braced +bracelet +bracelets +bracer +bracero +braceros +bracers +braces +brach +braches +brachet +brachets +brachia +brachial +brachials +brachiate +brachiated +brachiates +brachiating +brachiation +brachiations +brachiator +brachiators +brachiopod +brachiopods +brachium +brachs +brachycephalic +brachycephalies +brachycephaly +brachypterous +bracing +bracingly +bracings +braciola +braciolas +braciole +bracioles +bracken +brackens +bracket +bracketed +bracketing +brackets +brackish +brackishness +brackishnesses +braconid +braconids +bract +bracteal +bracteate +bracted +bracteole +bracteoles +bractlet +bractlets +bracts +brad +bradawl +bradawls +bradded +bradding +bradoon +bradoons +brads +bradycardia +bradycardias +bradykinin +bradykinins +brae +braes +brag +braggadocio +braggadocios +braggart +braggarts +bragged +bragger +braggers +braggest +braggier +braggiest +bragging +braggy +brags +brahma +brahmas +braid +braided +braider +braiders +braiding +braidings +braids +brail +brailed +brailing +braille +brailled +brailles +braillewriter +braillewriters +brailling +braillist +braillists +brails +brain +braincase +braincases +brainchild +brainchildren +brained +brainier +brainiest +brainily +braininess +braininesses +braining +brainish +brainless +brainlessly +brainlessness +brainlessnesses +brainpan +brainpans +brainpower +brainpowers +brains +brainsick +brainsickly +brainstorm +brainstormed +brainstormer +brainstormers +brainstorming +brainstormings +brainstorms +brainteaser +brainteasers +brainwash +brainwashed +brainwasher +brainwashers +brainwashes +brainwashing +brainwashings +brainy +braise +braised +braises +braising +braize +braizes +brake +brakeage +brakeages +braked +brakeless +brakeman +brakemen +brakes +brakier +brakiest +braking +braky +braless +bramble +brambled +brambles +bramblier +brambliest +brambling +brambly +bran +branch +branched +branches +branchia +branchiae +branchial +branchier +branchiest +branching +branchiopod +branchiopods +branchless +branchlet +branchlets +branchline +branchlines +branchy +brand +branded +brander +branders +brandied +brandies +branding +brandish +brandished +brandishes +brandishing +brands +brandy +brandying +brank +branks +branned +branner +branners +brannier +branniest +brannigan +brannigans +branning +branny +brans +brant +brantail +brantails +brants +bras +brash +brasher +brashes +brashest +brashier +brashiest +brashly +brashness +brashnesses +brashy +brasier +brasiers +brasil +brasilin +brasilins +brasils +brass +brassage +brassages +brassard +brassards +brassart +brassarts +brassbound +brassed +brasserie +brasseries +brasses +brassica +brassicas +brassie +brassier +brassiere +brassieres +brassies +brassiest +brassily +brassiness +brassinesses +brassing +brassish +brassy +brat +brats +brattice +bratticed +brattices +bratticing +brattier +brattiest +brattiness +brattinesses +brattish +brattle +brattled +brattles +brattling +bratty +bratwurst +bratwursts +braunite +braunites +braunschweiger +braunschweigers +brava +bravado +bravadoes +bravados +bravas +brave +braved +bravely +braver +braveries +bravers +bravery +braves +bravest +bravi +braving +bravo +bravoed +bravoes +bravoing +bravos +bravura +bravuras +bravure +braw +brawer +brawest +brawl +brawled +brawler +brawlers +brawlie +brawlier +brawliest +brawling +brawls +brawly +brawn +brawnier +brawniest +brawnily +brawniness +brawninesses +brawns +brawny +braws +braxies +braxy +bray +brayed +brayer +brayers +braying +brays +braza +brazas +braze +brazed +brazen +brazened +brazening +brazenly +brazenness +brazennesses +brazens +brazer +brazers +brazes +brazier +braziers +brazil +brazilin +brazilins +brazils +brazilwood +brazilwoods +brazing +breach +breached +breacher +breachers +breaches +breaching +bread +breadbasket +breadbaskets +breadboard +breadboarded +breadboarding +breadboards +breadbox +breadboxes +breaded +breadfruit +breadfruits +breading +breadline +breadlines +breadnut +breadnuts +breads +breadstuff +breadstuffs +breadth +breadths +breadthwise +breadwinner +breadwinners +breadwinning +breadwinnings +bready +break +breakable +breakables +breakage +breakages +breakaway +breakaways +breakdown +breakdowns +breaker +breakers +breakeven +breakevens +breakfast +breakfasted +breakfaster +breakfasters +breakfasting +breakfasts +breakfront +breakfronts +breaking +breakings +breakneck +breakout +breakouts +breaks +breaksaway +breakthrough +breakthroughs +breakup +breakups +breakwater +breakwaters +bream +breamed +breaming +breams +breast +breastbone +breastbones +breasted +breasting +breastplate +breastplates +breasts +breaststroke +breaststroker +breaststrokers +breaststrokes +breastwork +breastworks +breath +breathabilities +breathability +breathable +breathe +breathed +breather +breathers +breathes +breathier +breathiest +breathily +breathiness +breathinesses +breathing +breathings +breathless +breathlessly +breathlessness +breathlessnesses +breaths +breathtaking +breathtakingly +breathy +breccia +breccial +breccias +brecciate +brecciated +brecciates +brecciating +brecciation +brecciations +brecham +brechams +brechan +brechans +bred +brede +bredes +bree +breech +breechblock +breechblocks +breechcloth +breechcloths +breechclout +breechclouts +breeched +breeches +breeching +breechings +breechloader +breechloaders +breed +breeder +breeders +breeding +breedings +breeds +breeks +brees +breeze +breezed +breezeless +breezes +breezeway +breezeways +breezier +breeziest +breezily +breeziness +breezinesses +breezing +breezy +bregma +bregmata +bregmate +bremsstrahlung +bremsstrahlungs +bren +brens +brent +brents +brethren +breve +breves +brevet +brevetcies +brevetcy +breveted +breveting +brevets +brevetted +brevetting +breviaries +breviary +brevier +breviers +brevities +brevity +brew +brewage +brewages +brewed +brewer +breweries +brewers +brewery +brewing +brewings +brewis +brewises +brews +briar +briard +briards +briars +briary +bribable +bribe +bribed +bribee +bribees +briber +briberies +bribers +bribery +bribes +bribing +brick +brickbat +brickbats +bricked +brickfield +brickfields +brickier +brickiest +bricking +bricklayer +bricklayers +bricklaying +bricklayings +brickle +brickles +bricks +brickwork +brickworks +bricky +brickyard +brickyards +bricolage +bricolages +bricole +bricoles +bridal +bridally +bridals +bride +bridegroom +bridegrooms +brides +bridesmaid +bridesmaids +bridewell +bridewells +bridge +bridgeable +bridged +bridgehead +bridgeheads +bridgeless +bridges +bridgework +bridgeworks +bridging +bridgings +bridle +bridled +bridler +bridlers +bridles +bridling +bridoon +bridoons +brie +brief +briefcase +briefcases +briefed +briefer +briefers +briefest +briefing +briefings +briefless +briefly +briefness +briefnesses +briefs +brier +briers +briery +bries +brig +brigade +brigaded +brigades +brigadier +brigadiers +brigading +brigand +brigandage +brigandages +brigandine +brigandines +brigands +brigantine +brigantines +bright +brighten +brightened +brightener +brighteners +brightening +brightens +brighter +brightest +brightly +brightness +brightnesses +brights +brightwork +brightworks +brigs +brill +brilliance +brilliances +brilliancies +brilliancy +brilliant +brilliantine +brilliantines +brilliantly +brilliants +brills +brim +brimful +brimfull +brimless +brimmed +brimmer +brimmers +brimming +brims +brimstone +brimstones +brin +brinded +brindle +brindled +brindles +brine +brined +briner +briners +brines +bring +bringdown +bringdowns +bringer +bringers +bringing +brings +brinier +brinies +briniest +brininess +brininesses +brining +brinish +brink +brinkmanship +brinkmanships +brinks +brinksmanship +brinksmanships +brins +briny +brio +brioche +brioches +briolette +briolettes +brionies +briony +brios +briquet +briquets +briquette +briquetted +briquettes +briquetting +bris +brisance +brisances +brisant +brisk +brisked +brisker +briskest +brisket +briskets +brisking +briskly +briskness +brisknesses +brisks +brisling +brislings +brisses +bristle +bristled +bristlelike +bristles +bristletail +bristletails +bristlier +bristliest +bristling +bristly +bristol +bristols +brit +britches +brits +britska +britskas +britt +brittle +brittled +brittlely +brittleness +brittlenesses +brittler +brittles +brittlest +brittling +brittly +britts +britzka +britzkas +britzska +britzskas +bro +broach +broached +broacher +broachers +broaches +broaching +broad +broadax +broadaxe +broadaxes +broadband +broadcast +broadcasted +broadcaster +broadcasters +broadcasting +broadcasts +broadcloth +broadcloths +broaden +broadened +broadening +broadens +broader +broadest +broadish +broadleaf +broadloom +broadlooms +broadly +broadness +broadnesses +broads +broadscale +broadsheet +broadsheets +broadside +broadsided +broadsides +broadsiding +broadsword +broadswords +broadtail +broadtails +brocade +brocaded +brocades +brocading +brocatel +brocatelle +brocatelles +brocatels +broccoli +broccolis +broche +brochette +brochettes +brochure +brochures +brock +brockage +brockages +brocket +brockets +brocks +brocoli +brocolis +brogan +brogans +brogue +brogueries +broguery +brogues +broguish +broider +broidered +broideries +broidering +broiders +broidery +broil +broiled +broiler +broilers +broiling +broils +brokage +brokages +broke +broken +brokenhearted +brokenly +brokenness +brokennesses +broker +brokerage +brokerages +brokered +brokering +brokerings +brokers +broking +brokings +brollies +brolly +bromal +bromals +bromate +bromated +bromates +bromating +brome +bromegrass +bromegrasses +bromelain +bromelains +bromeliad +bromeliads +bromelin +bromelins +bromes +bromic +bromid +bromide +bromides +bromidic +bromids +bromin +brominate +brominated +brominates +brominating +bromination +brominations +bromine +bromines +bromins +bromism +bromisms +bromize +bromized +bromizes +bromizing +bromo +bromocriptine +bromocriptines +bromos +bromouracil +bromouracils +bronc +bronchi +bronchia +bronchial +bronchially +bronchiectases +bronchiectasis +bronchiolar +bronchiole +bronchioles +bronchites +bronchitic +bronchitides +bronchitis +bronchitises +bronchium +broncho +bronchodilator +bronchodilators +bronchogenic +bronchopneumonia +bronchopneumonias +bronchos +bronchoscope +bronchoscopes +bronchoscopic +bronchoscopies +bronchoscopist +bronchoscopists +bronchoscopy +bronchospasm +bronchospasms +bronchospastic +bronchus +bronco +broncobuster +broncobusters +broncos +broncs +brontosaur +brontosaurs +brontosaurus +brontosauruses +bronze +bronzed +bronzer +bronzers +bronzes +bronzier +bronziest +bronzing +bronzings +bronzy +broo +brooch +brooches +brood +brooded +brooder +brooders +broodier +broodiest +broodily +broodiness +broodinesses +brooding +broodingly +broodmare +broodmares +broods +broody +brook +brooked +brookie +brookies +brooking +brookite +brookites +brooklet +brooklets +brooks +broom +broomball +broomballer +broomballers +broomballs +broomcorn +broomcorns +broomed +broomier +broomiest +brooming +broomrape +broomrapes +brooms +broomstick +broomsticks +broomy +broos +bros +brose +broses +brosy +broth +brothel +brothels +brother +brothered +brotherhood +brotherhoods +brothering +brotherliness +brotherlinesses +brotherly +brothers +broths +brothy +brougham +broughams +brought +brouhaha +brouhahas +brow +browband +browbands +browbeat +browbeaten +browbeating +browbeats +browed +browless +brown +browned +browner +brownest +brownie +brownier +brownies +browniest +browning +brownish +brownnose +brownnosed +brownnoser +brownnosers +brownnoses +brownnosing +brownout +brownouts +browns +brownshirt +brownshirts +brownstone +brownstones +browny +browridge +browridges +brows +browse +browsed +browser +browsers +browses +browsing +brr +brrr +brucella +brucellae +brucellas +brucelloses +brucellosis +brucin +brucine +brucines +brucins +brugh +brughs +bruin +bruins +bruise +bruised +bruiser +bruisers +bruises +bruising +bruit +bruited +bruiter +bruiters +bruiting +bruits +brulot +brulots +brulyie +brulyies +brulzie +brulzies +brumal +brumbies +brumby +brume +brumes +brummagem +brummagems +brumous +brunch +brunched +brunches +brunching +brunet +brunets +brunette +brunettes +brunizem +brunizems +brunt +brunts +brush +brushabilities +brushability +brushback +brushbacks +brushed +brusher +brushers +brushes +brushfire +brushier +brushiest +brushing +brushland +brushlands +brushoff +brushoffs +brushup +brushups +brushwood +brushwoods +brushwork +brushworks +brushy +brusk +brusker +bruskest +brusque +brusquely +brusqueness +brusquenesses +brusquer +brusquerie +brusqueries +brusquest +brut +brutal +brutalise +brutalised +brutalises +brutalising +brutalities +brutality +brutalization +brutalizations +brutalize +brutalized +brutalizes +brutalizing +brutally +brute +bruted +brutely +brutes +brutified +brutifies +brutify +brutifying +bruting +brutish +brutishly +brutishness +brutishnesses +brutism +brutisms +bruxism +bruxisms +bryological +bryologies +bryologist +bryologists +bryology +bryonies +bryony +bryophyllum +bryophyllums +bryophyte +bryophytes +bryophytic +bryozoan +bryozoans +bub +bubal +bubale +bubales +bubaline +bubalis +bubalises +bubals +bubbies +bubble +bubbled +bubblegum +bubblegums +bubblehead +bubbleheaded +bubbleheads +bubbler +bubblers +bubbles +bubblier +bubblies +bubbliest +bubbling +bubbly +bubby +bubinga +bubingas +bubo +buboed +buboes +bubonic +bubs +buccal +buccally +buccaneer +buccaneered +buccaneering +buccaneerish +buccaneers +buccinator +buccinators +buck +buckaroo +buckaroos +buckayro +buckayros +buckbean +buckbeans +buckboard +buckboards +bucked +buckeen +buckeens +bucker +buckeroo +buckeroos +buckers +bucket +bucketed +bucketful +bucketfuls +bucketing +buckets +bucketsful +buckeye +buckeyes +bucking +buckish +buckle +buckled +buckler +bucklered +bucklering +bucklers +buckles +buckling +buckminsterfullerene +buckminsterfullerenes +bucko +buckoes +buckra +buckram +buckramed +buckraming +buckrams +buckras +bucks +bucksaw +bucksaws +buckshee +buckshees +buckshot +buckshots +buckskin +buckskinned +buckskins +bucktail +bucktails +buckteeth +buckthorn +buckthorns +bucktooth +bucktoothed +buckwheat +buckwheats +buckyball +buckyballs +bucolic +bucolically +bucolics +bud +budded +budder +budders +buddied +buddies +budding +buddings +buddle +buddleia +buddleias +buddles +buddy +buddying +budge +budged +budger +budgerigar +budgerigars +budgers +budges +budget +budgetary +budgeted +budgeteer +budgeteers +budgeter +budgeters +budgeting +budgets +budgie +budgies +budging +budless +budlike +buds +budworm +budworms +buff +buffable +buffalo +buffaloberries +buffaloberry +buffaloed +buffaloes +buffalofish +buffalofishes +buffaloing +buffalos +buffed +buffer +buffered +buffering +buffers +buffet +buffeted +buffeter +buffeters +buffeting +buffets +buffi +buffier +buffiest +buffing +bufflehead +buffleheads +buffo +buffoon +buffooneries +buffoonery +buffoonish +buffoons +buffos +buffs +buffy +bug +bugaboo +bugaboos +bugbane +bugbanes +bugbear +bugbears +bugeye +bugeyes +bugged +bugger +buggered +buggeries +buggering +buggers +buggery +buggier +buggies +buggiest +bugging +buggy +bughouse +bughouses +bugle +bugled +bugler +buglers +bugles +bugleweed +bugleweeds +bugling +bugloss +buglosses +bugs +bugseed +bugseeds +bugsha +bugshas +buhl +buhls +buhlwork +buhlworks +buhr +buhrs +buhrstone +buhrstones +build +buildable +builded +builder +builders +building +buildings +builds +buildup +buildups +built +buirdly +bulb +bulbar +bulbed +bulbel +bulbels +bulbil +bulbils +bulblet +bulblets +bulbous +bulbously +bulbs +bulbul +bulbuls +bulge +bulged +bulger +bulgers +bulges +bulgier +bulgiest +bulging +bulgur +bulgurs +bulgy +bulimia +bulimiac +bulimias +bulimic +bulimics +bulk +bulkage +bulkages +bulked +bulkhead +bulkheads +bulkier +bulkiest +bulkily +bulkiness +bulkinesses +bulking +bulks +bulky +bull +bulla +bullace +bullaces +bullae +bullate +bullbaiting +bullbaitings +bullbat +bullbats +bulldog +bulldogged +bulldogger +bulldoggers +bulldogging +bulldoggings +bulldogs +bulldoze +bulldozed +bulldozer +bulldozers +bulldozes +bulldozing +bulled +bullet +bulleted +bulletin +bulletined +bulleting +bulletining +bulletins +bulletproof +bullets +bullfight +bullfighter +bullfighters +bullfighting +bullfightings +bullfights +bullfinch +bullfinches +bullfrog +bullfrogs +bullhead +bullheaded +bullheadedly +bullheadedness +bullheadednesses +bullheads +bullhorn +bullhorns +bullied +bullier +bullies +bulliest +bulling +bullion +bullions +bullish +bullishly +bullishness +bullishnesses +bullmastiff +bullmastiffs +bullneck +bullnecked +bullnecks +bullnose +bullnoses +bullock +bullocks +bullocky +bullous +bullpen +bullpens +bullpout +bullpouts +bullring +bullrings +bullrush +bullrushes +bulls +bullshit +bullshits +bullshitted +bullshitting +bullshot +bullshots +bullterrier +bullterriers +bullweed +bullweeds +bullwhip +bullwhipped +bullwhipping +bullwhips +bully +bullyboy +bullyboys +bullying +bullyrag +bullyragged +bullyragging +bullyrags +bulrush +bulrushes +bulwark +bulwarked +bulwarking +bulwarks +bum +bumbershoot +bumbershoots +bumble +bumblebee +bumblebees +bumbled +bumbler +bumblers +bumbles +bumbling +bumblingly +bumblings +bumboat +bumboats +bumf +bumfs +bumkin +bumkins +bummed +bummer +bummers +bummest +bumming +bump +bumped +bumper +bumpered +bumpering +bumpers +bumph +bumphs +bumpier +bumpiest +bumpily +bumpiness +bumpinesses +bumping +bumpkin +bumpkinish +bumpkinly +bumpkins +bumps +bumptious +bumptiously +bumptiousness +bumptiousnesses +bumpy +bums +bun +bunch +bunchberries +bunchberry +bunched +bunches +bunchgrass +bunchgrasses +bunchier +bunchiest +bunchily +bunching +bunchy +bunco +buncoed +buncoing +buncombe +buncombes +buncos +bund +bundist +bundists +bundle +bundled +bundler +bundlers +bundles +bundling +bundlings +bunds +bundt +bundts +bung +bungalow +bungalows +bunged +bungee +bungees +bunghole +bungholes +bunging +bungle +bungled +bungler +bunglers +bungles +bunglesome +bungling +bunglingly +bunglings +bungs +bunion +bunions +bunk +bunked +bunker +bunkered +bunkering +bunkers +bunkhouse +bunkhouses +bunking +bunkmate +bunkmates +bunko +bunkoed +bunkoing +bunkos +bunks +bunkum +bunkums +bunn +bunnies +bunns +bunny +bunraku +bunrakus +buns +bunt +bunted +bunter +bunters +bunting +buntings +buntline +buntlines +bunts +bunya +bunyas +buoy +buoyage +buoyages +buoyance +buoyances +buoyancies +buoyancy +buoyant +buoyantly +buoyed +buoying +buoys +buppie +buppies +buqsha +buqshas +bur +bura +buran +burans +buras +burble +burbled +burbler +burblers +burbles +burblier +burbliest +burbling +burbly +burbot +burbots +burbs +burd +burden +burdened +burdener +burdeners +burdening +burdens +burdensome +burdie +burdies +burdock +burdocks +burds +bureau +bureaucracies +bureaucracy +bureaucrat +bureaucratese +bureaucrateses +bureaucratic +bureaucratically +bureaucratise +bureaucratised +bureaucratises +bureaucratising +bureaucratism +bureaucratisms +bureaucratization +bureaucratizations +bureaucratize +bureaucratized +bureaucratizes +bureaucratizing +bureaucrats +bureaus +bureaux +buret +burets +burette +burettes +burg +burgage +burgages +burgee +burgees +burgeon +burgeoned +burgeoning +burgeons +burger +burgers +burgess +burgesses +burgh +burghal +burgher +burghers +burghs +burglar +burglaries +burglarious +burglariously +burglarize +burglarized +burglarizes +burglarizing +burglarproof +burglars +burglary +burgle +burgled +burgles +burgling +burgomaster +burgomasters +burgonet +burgonets +burgoo +burgoos +burgout +burgouts +burgrave +burgraves +burgs +burgundies +burgundy +burial +burials +buried +burier +buriers +buries +burin +burins +burke +burked +burker +burkers +burkes +burking +burkite +burkites +burl +burladero +burladeros +burlap +burlaps +burled +burler +burlers +burlesk +burlesks +burlesque +burlesqued +burlesquely +burlesquer +burlesquers +burlesques +burlesquing +burley +burleys +burlier +burliest +burlily +burliness +burlinesses +burling +burls +burly +burn +burnable +burnables +burned +burner +burners +burnet +burnets +burnie +burnies +burning +burningly +burnings +burnish +burnished +burnisher +burnishers +burnishes +burnishing +burnishings +burnoose +burnoosed +burnooses +burnous +burnouses +burnout +burnouts +burns +burnsides +burnt +burp +burped +burping +burps +burr +burred +burrer +burrers +burrier +burriest +burring +burrito +burritos +burro +burros +burrow +burrowed +burrower +burrowers +burrowing +burrows +burrs +burrstone +burrstones +burry +burs +bursa +bursae +bursal +bursar +bursaries +bursars +bursary +bursas +bursate +burse +burseed +burseeds +bursera +burses +bursitis +bursitises +burst +bursted +burster +bursters +bursting +burstone +burstones +bursts +burthen +burthened +burthening +burthens +burton +burtons +burweed +burweeds +bury +burying +bus +busbar +busbars +busbies +busboy +busboys +busby +bused +buses +bush +bushbuck +bushbucks +bushed +bushel +busheled +busheler +bushelers +busheling +bushelled +bushelling +bushels +busher +bushers +bushes +bushfire +bushfires +bushgoat +bushgoats +bushido +bushidos +bushier +bushiest +bushily +bushiness +bushinesses +bushing +bushings +bushland +bushlands +bushless +bushlike +bushman +bushmaster +bushmasters +bushmen +bushpig +bushpigs +bushranger +bushrangers +bushranging +bushrangings +bushtit +bushtits +bushwa +bushwah +bushwahs +bushwas +bushwhack +bushwhacked +bushwhacker +bushwhackers +bushwhacking +bushwhacks +bushy +busied +busier +busies +busiest +busily +business +businesses +businesslike +businessman +businessmen +businesspeople +businessperson +businesspersons +businesswoman +businesswomen +busing +busings +busk +busked +busker +buskers +buskin +buskined +busking +buskins +busks +busload +busloads +busman +busmen +buss +bussed +busses +bussing +bussings +bust +bustard +bustards +busted +buster +busters +bustic +bustics +bustier +bustiers +bustiest +busting +bustle +bustled +bustles +bustline +bustlines +bustling +bustlingly +busts +busty +busulfan +busulfans +busy +busybodies +busybody +busying +busyness +busynesses +busywork +busyworks +but +butadiene +butadienes +butane +butanes +butanol +butanols +butanone +butanones +butch +butcher +butchered +butcheries +butchering +butcherly +butchers +butchery +butches +bute +butene +butenes +buteo +buteos +butle +butled +butler +butleries +butlers +butlery +butles +butling +buts +butt +buttals +butte +butted +butter +butterball +butterballs +buttercup +buttercups +buttered +butterfat +butterfats +butterfingered +butterfingers +butterfish +butterfishes +butterflied +butterflies +butterfly +butterflyer +butterflyers +butterflying +butterier +butteries +butteriest +buttering +butterless +buttermilk +buttermilks +butternut +butternuts +butters +butterscotch +butterscotches +butterweed +butterweeds +butterwort +butterworts +buttery +buttes +butties +butting +buttinski +buttinskies +buttinsky +buttock +buttocks +button +buttonball +buttonballs +buttonbush +buttonbushes +buttoned +buttoner +buttoners +buttonhole +buttonholed +buttonholer +buttonholers +buttonholes +buttonholing +buttonhook +buttonhooked +buttonhooking +buttonhooks +buttoning +buttonless +buttons +buttonwood +buttonwoods +buttony +buttress +buttressed +buttresses +buttressing +butts +buttstock +buttstocks +butty +butut +bututs +butyl +butylate +butylated +butylates +butylating +butylation +butylations +butylene +butylenes +butyls +butyral +butyraldehyde +butyraldehydes +butyrals +butyrate +butyrates +butyric +butyrin +butyrins +butyrophenone +butyrophenones +butyrous +butyryl +butyryls +buxom +buxomer +buxomest +buxomly +buxomness +buxomnesses +buy +buyable +buyback +buybacks +buyer +buyers +buying +buyout +buyouts +buys +buzuki +buzukia +buzukis +buzz +buzzard +buzzards +buzzed +buzzer +buzzers +buzzes +buzzing +buzzwig +buzzwigs +buzzword +buzzwords +bwana +bwanas +by +bye +byelaw +byelaws +byes +bygone +bygones +bylaw +bylaws +byline +bylined +byliner +byliners +bylines +bylining +byname +bynames +bypass +bypassed +bypasses +bypassing +bypast +bypath +bypaths +byplay +byplays +byproduct +byproducts +byre +byres +byrl +byrled +byrling +byrls +byrnie +byrnies +byroad +byroads +bys +byssi +byssinoses +byssinosis +byssus +byssuses +bystander +bystanders +bystreet +bystreets +bytalk +bytalks +byte +bytes +byway +byways +byword +bywords +bywork +byworks +byzant +byzantine +byzants +cab +cabal +cabala +cabalas +cabaletta +cabalettas +cabalism +cabalisms +cabalist +cabalistic +cabalists +caballed +caballero +caballeros +caballing +cabals +cabana +cabanas +cabaret +cabarets +cabbage +cabbaged +cabbages +cabbageworm +cabbageworms +cabbaging +cabbala +cabbalah +cabbalahs +cabbalas +cabbed +cabbie +cabbies +cabbing +cabby +cabdriver +cabdrivers +caber +cabernet +cabernets +cabers +cabestro +cabestros +cabezon +cabezone +cabezones +cabezons +cabildo +cabildos +cabin +cabined +cabinet +cabinetmaker +cabinetmakers +cabinetmaking +cabinetmakings +cabinetries +cabinetry +cabinets +cabinetwork +cabinetworks +cabining +cabins +cable +cabled +cablegram +cablegrams +cables +cablet +cablets +cableway +cableways +cabling +cabman +cabmen +cabob +cabobs +caboched +cabochon +cabochons +cabomba +cabombas +caboodle +caboodles +caboose +cabooses +caboshed +cabotage +cabotages +cabresta +cabrestas +cabresto +cabrestos +cabretta +cabrettas +cabrilla +cabrillas +cabriole +cabrioles +cabriolet +cabriolets +cabs +cabstand +cabstands +caca +cacao +cacaos +cacas +cacciatore +cachalot +cachalots +cache +cachectic +cached +cachepot +cachepots +caches +cachet +cacheted +cacheting +cachets +cachexia +cachexias +cachexic +cachexies +cachexy +caching +cachinnate +cachinnated +cachinnates +cachinnating +cachinnation +cachinnations +cachou +cachous +cachucha +cachuchas +cacique +caciques +caciquism +caciquisms +cackle +cackled +cackler +cacklers +cackles +cackling +cacodemon +cacodemonic +cacodemons +cacodyl +cacodyls +cacoethes +cacographical +cacographies +cacography +cacomistle +cacomistles +cacomixl +cacomixls +cacophonies +cacophonous +cacophonously +cacophony +cacti +cactoid +cactus +cactuses +cacuminal +cad +cadaster +cadasters +cadastral +cadastrally +cadastre +cadastres +cadaver +cadaveric +cadaverine +cadaverines +cadaverous +cadaverously +cadavers +caddice +caddices +caddie +caddied +caddies +caddis +caddises +caddish +caddishly +caddishness +caddishnesses +caddisworm +caddisworms +caddy +caddying +cade +cadelle +cadelles +cadence +cadenced +cadences +cadencies +cadencing +cadency +cadent +cadential +cadenza +cadenzas +cades +cadet +cadets +cadetship +cadetships +cadge +cadged +cadger +cadgers +cadges +cadging +cadgy +cadi +cadis +cadmic +cadmium +cadmiums +cadre +cadres +cads +caducean +caducei +caduceus +caducities +caducity +caducous +caeca +caecal +caecally +caecilian +caecilians +caecum +caeoma +caeomas +caesar +caesarean +caesareans +caesarian +caesarians +caesars +caesium +caesiums +caespitose +caestus +caestuses +caesura +caesurae +caesural +caesuras +caesuric +cafe +cafes +cafeteria +cafeterias +cafetorium +cafetoriums +caff +caffein +caffeinated +caffeine +caffeines +caffeins +caffs +caftan +caftans +cage +caged +cageful +cagefuls +cageling +cagelings +cager +cagers +cages +cagey +cageyness +cageynesses +cagier +cagiest +cagily +caginess +caginesses +caging +cagy +cahier +cahiers +cahoot +cahoots +cahow +cahows +caid +caids +caiman +caimans +cain +cains +caique +caiques +caird +cairds +cairn +cairned +cairngorm +cairngorms +cairns +cairny +caisson +caissons +caitiff +caitiffs +cajaput +cajaputs +cajeput +cajeputs +cajole +cajoled +cajolement +cajolements +cajoler +cajoleries +cajolers +cajolery +cajoles +cajoling +cajon +cajones +cajuput +cajuputs +cake +caked +cakes +cakewalk +cakewalked +cakewalker +cakewalkers +cakewalking +cakewalks +cakey +cakier +cakiest +caking +caky +calabash +calabashes +calaboose +calabooses +caladium +caladiums +calamander +calamanders +calamar +calamari +calamaries +calamaris +calamars +calamary +calami +calamine +calamined +calamines +calamining +calamint +calamints +calamite +calamites +calamities +calamitous +calamitously +calamity +calamondin +calamondins +calamus +calando +calash +calashes +calathi +calathos +calathus +calcanea +calcaneal +calcanei +calcaneum +calcaneus +calcar +calcareous +calcareously +calcaria +calcars +calceate +calces +calcic +calcicole +calcicoles +calcicolous +calciferol +calciferols +calciferous +calcific +calcification +calcifications +calcified +calcifies +calcifuge +calcifuges +calcifugous +calcify +calcifying +calcimine +calcimined +calcimines +calcimining +calcination +calcinations +calcine +calcined +calcines +calcining +calcinoses +calcinosis +calcite +calcites +calcitic +calcitonin +calcitonins +calcium +calciums +calcspar +calcspars +calctufa +calctufas +calctuff +calctuffs +calculable +calculate +calculated +calculatedly +calculatedness +calculatednesses +calculates +calculating +calculatingly +calculation +calculational +calculations +calculator +calculators +calculi +calculous +calculus +calculuses +caldaria +caldarium +caldera +calderas +caldron +caldrons +caleche +caleches +calefactories +calefactory +calendal +calendar +calendared +calendaring +calendars +calender +calendered +calenderer +calenderers +calendering +calenders +calendric +calendrical +calends +calendula +calendulas +calenture +calentures +calesa +calesas +calf +calflike +calfs +calfskin +calfskins +caliber +calibers +calibrate +calibrated +calibrates +calibrating +calibration +calibrations +calibrator +calibrators +calibre +calibred +calibres +calices +caliche +caliches +calicle +calicles +calico +calicoes +calicos +calif +califate +califates +californium +californiums +califs +caliginous +calipash +calipashes +calipee +calipees +caliper +calipered +calipering +calipers +caliph +caliphal +caliphate +caliphates +caliphs +calisaya +calisayas +calisthenic +calisthenics +calix +calk +calked +calker +calkers +calkin +calking +calkins +calks +call +calla +callable +callaloo +callaloos +callan +callans +callant +callants +callas +callback +callbacks +callboy +callboys +called +caller +callers +callet +callets +calligrapher +calligraphers +calligraphic +calligraphically +calligraphies +calligraphist +calligraphists +calligraphy +calling +callings +calliope +calliopes +callipee +callipees +calliper +callipered +callipering +callipers +callipygian +callipygous +callithump +callithumpian +callithumps +callose +calloses +callosities +callosity +callous +calloused +callouses +callousing +callously +callousness +callousnesses +callow +callower +callowest +callowness +callownesses +calls +callus +callused +calluses +callusing +calm +calmative +calmatives +calmed +calmer +calmest +calming +calmly +calmness +calmnesses +calmodulin +calmodulins +calms +calo +calomel +calomels +caloric +calorically +calorics +calorie +calories +calorific +calorimeter +calorimeters +calorimetric +calorimetrically +calorimetries +calorimetry +calorize +calorized +calorizes +calorizing +calory +calotte +calottes +calotype +calotypes +caloyer +caloyers +calpac +calpack +calpacks +calpacs +calque +calqued +calques +calquing +calthrop +calthrops +caltrap +caltraps +caltrop +caltrops +calumet +calumets +calumniate +calumniated +calumniates +calumniating +calumniation +calumniations +calumniator +calumniators +calumnies +calumnious +calumniously +calumny +calutron +calutrons +calvados +calvadoses +calvaria +calvarias +calvaries +calvarium +calvary +calve +calved +calves +calving +calx +calxes +calycate +calyceal +calyces +calycine +calycle +calycles +calyculi +calyculus +calypso +calypsoes +calypsonian +calypsonians +calypsos +calypter +calypters +calyptra +calyptras +calyx +calyxes +calzone +calzones +cam +camail +camailed +camails +camaraderie +camaraderies +camarilla +camarillas +camas +camases +camass +camasses +camber +cambered +cambering +cambers +cambia +cambial +cambism +cambisms +cambist +cambists +cambium +cambiums +cambogia +cambogias +cambric +cambrics +camcorder +camcorders +came +camel +camelback +camelbacks +cameleer +cameleers +camelia +camelias +camellia +camellias +camelopard +camelopards +camels +cameo +cameoed +cameoing +cameos +camera +camerae +cameral +cameraman +cameramen +cameraperson +camerapersons +cameras +camerawoman +camerawomen +camerlengo +camerlengos +cames +camion +camions +camisa +camisade +camisades +camisado +camisadoes +camisados +camisas +camise +camises +camisia +camisias +camisole +camisoles +camlet +camlets +camomile +camomiles +camorra +camorras +camorrista +camorristi +camouflage +camouflageable +camouflaged +camouflages +camouflagic +camouflaging +camp +campagna +campagne +campaign +campaigned +campaigner +campaigners +campaigning +campaigns +campanile +campaniles +campanili +campanologies +campanologist +campanologists +campanology +campanula +campanulas +campanulate +campcraft +campcrafts +camped +camper +campers +campesino +campesinos +campestral +campfire +campfires +campground +campgrounds +camphene +camphenes +camphine +camphines +camphire +camphires +camphol +camphols +camphor +camphoraceous +camphorate +camphorated +camphorates +camphorating +camphors +campi +campier +campiest +campily +campiness +campinesses +camping +campings +campion +campions +campo +campong +campongs +camporee +camporees +campos +camps +campsite +campsites +campus +campused +campuses +campusing +campy +campylobacter +campylobacters +campylotropous +cams +camshaft +camshafts +can +canaille +canailles +canakin +canakins +canal +canaled +canalicular +canaliculi +canaliculus +canaling +canalise +canalised +canalises +canalising +canalization +canalizations +canalize +canalized +canalizes +canalizing +canalled +canaller +canallers +canalling +canals +canape +canapes +canard +canards +canaries +canary +canasta +canastas +cancan +cancans +cancel +cancelable +cancelation +cancelations +canceled +canceler +cancelers +canceling +cancellable +cancellation +cancellations +cancelled +canceller +cancellers +cancelling +cancellous +cancels +cancer +cancerous +cancerously +cancers +cancha +canchas +cancroid +cancroids +candela +candelabra +candelabras +candelabrum +candelabrums +candelas +candent +candescence +candescences +candescent +candid +candida +candidacies +candidacy +candidas +candidate +candidates +candidature +candidatures +candider +candidest +candidiases +candidiasis +candidly +candidness +candidnesses +candids +candied +candies +candle +candleberries +candleberry +candled +candlefish +candlefishes +candleholder +candleholders +candlelight +candlelighted +candlelighter +candlelighters +candlelights +candlelit +candlenut +candlenuts +candlepin +candlepins +candlepower +candlepowers +candler +candlers +candles +candlesnuffer +candlesnuffers +candlestick +candlesticks +candlewick +candlewicks +candlewood +candlewoods +candling +candor +candors +candour +candours +candy +candyfloss +candyflosses +candying +candytuft +candytufts +cane +canebrake +canebrakes +caned +canella +canellas +canephor +canephors +caner +caners +canes +canescent +caneware +canewares +canfield +canfields +canful +canfuls +cangue +cangues +canicular +canid +canids +canikin +canikins +canine +canines +caning +caninities +caninity +canister +canisters +canities +canker +cankered +cankering +cankerous +cankers +cankerworm +cankerworms +canna +cannabic +cannabin +cannabinoid +cannabinoids +cannabinol +cannabinols +cannabins +cannabis +cannabises +cannas +canned +cannel +cannelloni +cannelon +cannelons +cannels +canner +canneries +canners +cannery +cannibal +cannibalise +cannibalised +cannibalises +cannibalising +cannibalism +cannibalisms +cannibalistic +cannibalization +cannibalizations +cannibalize +cannibalized +cannibalizes +cannibalizing +cannibals +cannie +cannier +canniest +cannikin +cannikins +cannily +canniness +canninesses +canning +cannings +cannister +cannisters +cannoli +cannon +cannonade +cannonaded +cannonades +cannonading +cannonball +cannonballed +cannonballing +cannonballs +cannoned +cannoneer +cannoneers +cannoning +cannonries +cannonry +cannons +cannot +cannula +cannulae +cannular +cannulas +canny +canoe +canoeable +canoed +canoeing +canoeist +canoeists +canoes +canola +canon +canoness +canonesses +canonic +canonical +canonically +canonicals +canonicities +canonicity +canonise +canonised +canonises +canonising +canonist +canonists +canonization +canonizations +canonize +canonized +canonizes +canonizing +canonries +canonry +canons +canoodle +canoodled +canoodles +canoodling +canopied +canopies +canopy +canopying +canorous +canorously +canorousness +canorousnesses +cans +cansful +canso +cansos +canst +cant +cantabile +cantala +cantalas +cantaloup +cantaloupe +cantaloupes +cantaloups +cantankerous +cantankerously +cantankerousness +cantankerousnesses +cantata +cantatas +cantatrice +cantatrices +cantatrici +cantdog +cantdogs +canted +canteen +canteens +canter +cantered +cantering +canters +canthal +cantharides +cantharidin +cantharidins +cantharis +canthaxanthin +canthaxanthins +canthi +canthus +cantic +canticle +canticles +cantilena +cantilenas +cantilever +cantilevered +cantilevering +cantilevers +cantillate +cantillated +cantillates +cantillating +cantillation +cantillations +cantina +cantinas +canting +cantle +cantles +canto +canton +cantonal +cantoned +cantoning +cantonment +cantonments +cantons +cantor +cantorial +cantors +cantos +cantraip +cantraips +cantrap +cantraps +cantrip +cantrips +cants +cantus +canty +canula +canulae +canulas +canulate +canulated +canulates +canulating +canvas +canvasback +canvasbacks +canvased +canvaser +canvasers +canvases +canvasing +canvaslike +canvass +canvassed +canvasser +canvassers +canvasses +canvassing +canyon +canyons +canzona +canzonas +canzone +canzones +canzonet +canzonets +canzoni +caoutchouc +caoutchoucs +cap +capabilities +capability +capable +capableness +capablenesses +capabler +capablest +capably +capacious +capaciously +capaciousness +capaciousnesses +capacitance +capacitances +capacitate +capacitated +capacitates +capacitating +capacitation +capacitations +capacities +capacitive +capacitively +capacitor +capacitors +capacity +caparison +caparisoned +caparisoning +caparisons +cape +caped +capelan +capelans +capelet +capelets +capelin +capelins +caper +capercaillie +capercaillies +capercailzie +capercailzies +capered +caperer +caperers +capering +capers +capes +capeskin +capeskins +capework +capeworks +capful +capfuls +caph +caphs +capias +capiases +capillaries +capillarities +capillarity +capillary +capita +capital +capitalise +capitalised +capitalises +capitalising +capitalism +capitalisms +capitalist +capitalistic +capitalistically +capitalists +capitalization +capitalizations +capitalize +capitalized +capitalizes +capitalizing +capitally +capitals +capitate +capitation +capitations +capitol +capitols +capitula +capitular +capitularies +capitulary +capitulate +capitulated +capitulates +capitulating +capitulation +capitulations +capitulum +capless +caplet +caplets +caplin +caplins +capmaker +capmakers +capo +capon +caponata +caponatas +caponier +caponiers +caponize +caponized +caponizes +caponizing +capons +caporal +caporals +capos +capote +capotes +capouch +capouches +capped +cappelletti +capper +cappers +capping +cappings +cappuccino +cappuccinos +capric +capricci +capriccio +capriccios +caprice +caprices +capricious +capriciously +capriciousness +capriciousnesses +caprification +caprifications +caprifig +caprifigs +caprine +capriole +caprioled +caprioles +caprioling +capris +caprock +caprocks +caprolactam +caprolactams +caps +capsaicin +capsaicins +capsicin +capsicins +capsicum +capsicums +capsid +capsidal +capsids +capsize +capsized +capsizes +capsizing +capsomer +capsomers +capstan +capstans +capstone +capstones +capsular +capsulated +capsule +capsuled +capsules +capsuling +capsulize +capsulized +capsulizes +capsulizing +captain +captaincies +captaincy +captained +captaining +captains +captainship +captainships +captan +captans +caption +captioned +captioning +captionless +captions +captious +captiously +captiousness +captiousnesses +captivate +captivated +captivates +captivating +captivation +captivations +captivator +captivators +captive +captives +captivities +captivity +captopril +captoprils +captor +captors +capture +captured +capturer +capturers +captures +capturing +capuche +capuched +capuches +capuchin +capuchins +caput +capybara +capybaras +car +carabao +carabaos +carabid +carabids +carabin +carabine +carabineer +carabineers +carabiner +carabinero +carabineros +carabiners +carabines +carabinier +carabiniere +carabinieri +carabiniers +carabins +caracal +caracals +caracara +caracaras +carack +caracks +caracol +caracole +caracoled +caracoles +caracoling +caracolled +caracolling +caracols +caracul +caraculs +carafe +carafes +caragana +caraganas +carageen +carageens +caramba +carambola +carambolas +caramel +caramelise +caramelised +caramelises +caramelising +caramelize +caramelized +caramelizes +caramelizing +caramels +carangid +carangids +carapace +carapaces +carapax +carapaxes +carassow +carassows +carat +carate +carates +carats +caravan +caravaned +caravaner +caravaners +caravaning +caravanned +caravanner +caravanners +caravanning +caravans +caravansaries +caravansary +caravanserai +caravanserais +caravel +caravels +caraway +caraways +carb +carbachol +carbachols +carbamate +carbamates +carbamic +carbamide +carbamides +carbamino +carbamyl +carbamyls +carbanion +carbanions +carbarn +carbarns +carbaryl +carbaryls +carbazole +carbazoles +carbide +carbides +carbine +carbines +carbinol +carbinols +carbo +carbocyclic +carbohydrase +carbohydrases +carbohydrate +carbohydrates +carbolic +carbolics +carbon +carbonaceous +carbonade +carbonades +carbonado +carbonadoed +carbonadoes +carbonadoing +carbonados +carbonara +carbonaras +carbonate +carbonated +carbonates +carbonating +carbonation +carbonations +carbonic +carboniferous +carbonization +carbonizations +carbonize +carbonized +carbonizes +carbonizing +carbonless +carbonnade +carbonnades +carbons +carbonyl +carbonylation +carbonylations +carbonylic +carbonyls +carbora +carboras +carbos +carboxyl +carboxylase +carboxylases +carboxylate +carboxylated +carboxylates +carboxylating +carboxylation +carboxylations +carboxylic +carboxyls +carboxymethylcellulose +carboxymethylcelluloses +carboxypeptidase +carboxypeptidases +carboy +carboyed +carboys +carbs +carbuncle +carbuncled +carbuncles +carbuncular +carburet +carbureted +carbureting +carburetion +carburetions +carburetor +carburetors +carburets +carburetted +carburetter +carburetters +carburetting +carburettor +carburettors +carburise +carburised +carburises +carburising +carburization +carburizations +carburize +carburized +carburizes +carburizing +carcajou +carcajous +carcanet +carcanets +carcase +carcases +carcass +carcasses +carcel +carcels +carcinogen +carcinogeneses +carcinogenesis +carcinogenic +carcinogenicities +carcinogenicity +carcinogens +carcinoid +carcinoids +carcinoma +carcinomas +carcinomata +carcinomatoses +carcinomatosis +carcinomatosises +carcinomatous +carcinosarcoma +carcinosarcomas +carcinosarcomata +card +cardamom +cardamoms +cardamon +cardamons +cardamum +cardamums +cardboard +cardboards +cardcase +cardcases +carded +carder +carders +cardholder +cardholders +cardia +cardiac +cardiacs +cardiae +cardias +cardigan +cardigans +cardinal +cardinalate +cardinalates +cardinalities +cardinality +cardinally +cardinals +cardinalship +cardinalships +carding +cardings +cardiogenic +cardiogram +cardiograms +cardiograph +cardiographic +cardiographies +cardiographs +cardiography +cardioid +cardioids +cardiological +cardiologies +cardiologist +cardiologists +cardiology +cardiomyopathies +cardiomyopathy +cardiopathies +cardiopathy +cardiopulmonary +cardiorespiratory +cardiothoracic +cardiotonic +cardiotonics +cardiovascular +carditic +carditis +carditises +cardoon +cardoons +cardplayer +cardplayers +cards +cardsharp +cardsharper +cardsharpers +cardsharps +care +cared +careen +careened +careener +careeners +careening +careens +career +careered +careerer +careerers +careering +careerism +careerisms +careerist +careerists +careers +carefree +careful +carefuller +carefullest +carefully +carefulness +carefulnesses +caregiver +caregivers +caregiving +caregivings +careless +carelessly +carelessness +carelessnesses +carer +carers +cares +caress +caressed +caresser +caressers +caresses +caressing +caressingly +caressive +caressively +caret +caretake +caretaken +caretaker +caretakers +caretakes +caretaking +caretakings +caretook +carets +careworn +carex +carfare +carfares +carful +carfuls +cargo +cargoes +cargos +carhop +carhops +caribe +caribes +caribou +caribous +caricatural +caricature +caricatured +caricatures +caricaturing +caricaturist +caricaturists +carices +caried +caries +carillon +carillonned +carillonneur +carillonneurs +carillonning +carillons +carina +carinae +carinal +carinas +carinate +carinated +caring +carioca +cariocas +cariogenic +cariole +carioles +carious +caritas +caritases +carjacker +carjackers +carjacking +carjackings +cark +carked +carking +carks +carl +carle +carles +carless +carlin +carline +carlines +carling +carlings +carlins +carlish +carload +carloads +carls +carmagnole +carmagnoles +carmaker +carmakers +carman +carmen +carminative +carminatives +carmine +carmines +carn +carnage +carnages +carnal +carnalities +carnality +carnallite +carnallites +carnally +carnassial +carnassials +carnation +carnations +carnauba +carnaubas +carnelian +carnelians +carnet +carnets +carney +carneys +carnie +carnies +carnified +carnifies +carnify +carnifying +carnitine +carnitines +carnival +carnivals +carnivora +carnivore +carnivores +carnivorous +carnivorously +carnivorousness +carnivorousnesses +carnotite +carnotites +carns +carny +caroach +caroaches +carob +carobs +caroch +caroche +caroches +carol +caroled +caroler +carolers +caroli +caroling +carolled +caroller +carollers +carolling +carols +carolus +caroluses +carom +caromed +caroming +caroms +carotene +carotenes +carotenoid +carotenoids +carotid +carotids +carotin +carotinoid +carotinoids +carotins +carousal +carousals +carouse +caroused +carousel +carousels +carouser +carousers +carouses +carousing +carp +carpaccio +carpaccios +carpal +carpale +carpalia +carpals +carped +carpel +carpellary +carpellate +carpels +carpenter +carpentered +carpentering +carpenters +carpentries +carpentry +carper +carpers +carpet +carpetbag +carpetbagger +carpetbaggeries +carpetbaggers +carpetbaggery +carpetbagging +carpetbags +carpeted +carpeting +carpetings +carpets +carpetweed +carpetweeds +carpi +carping +carpingly +carpings +carpogonia +carpogonial +carpogonium +carpool +carpooled +carpooler +carpoolers +carpooling +carpools +carpophore +carpophores +carport +carports +carpospore +carpospores +carps +carpus +carr +carrack +carracks +carrageen +carrageenan +carrageenans +carrageenin +carrageenins +carrageens +carragheen +carragheens +carrefour +carrefours +carrel +carrell +carrells +carrels +carriage +carriages +carriageway +carriageways +carried +carrier +carriers +carries +carriole +carrioles +carrion +carrions +carritch +carritches +carroch +carroches +carrom +carromed +carroming +carroms +carronade +carronades +carrot +carrotier +carrotiest +carrotin +carrotins +carrots +carrottop +carrottopped +carrottops +carroty +carrousel +carrousels +carrs +carry +carryall +carryalls +carryback +carrybacks +carryforward +carryforwards +carrying +carryon +carryons +carryout +carryouts +carryover +carryovers +cars +carse +carses +carsick +carsickness +carsicknesses +cart +cartable +cartage +cartages +carte +carted +cartel +cartelise +cartelised +cartelises +cartelising +cartelization +cartelizations +cartelize +cartelized +cartelizes +cartelizing +cartels +carter +carters +cartes +cartilage +cartilages +cartilaginous +carting +cartload +cartloads +cartographer +cartographers +cartographic +cartographical +cartographically +cartographies +cartography +carton +cartoned +cartoning +cartons +cartoon +cartooned +cartooning +cartoonings +cartoonish +cartoonishly +cartoonist +cartoonists +cartoonlike +cartoons +cartoony +cartop +cartopper +cartoppers +cartouch +cartouche +cartouches +cartridge +cartridges +carts +cartularies +cartulary +cartwheel +cartwheeled +cartwheeler +cartwheelers +cartwheeling +cartwheels +caruncle +caruncles +carvacrol +carvacrols +carve +carved +carvel +carvels +carven +carver +carvers +carves +carving +carvings +carwash +carwashes +caryatic +caryatid +caryatides +caryatids +caryopses +caryopsides +caryopsis +caryotin +caryotins +casa +casaba +casabas +casas +casava +casavas +casbah +casbahs +cascabel +cascabels +cascable +cascables +cascade +cascaded +cascades +cascading +cascara +cascaras +cascarilla +cascarillas +case +casease +caseases +caseate +caseated +caseates +caseating +caseation +caseations +casebearer +casebearers +casebook +casebooks +cased +casefied +casefies +casefy +casefying +caseic +casein +caseinate +caseinates +caseins +caseload +caseloads +casemate +casemates +casement +casements +caseose +caseoses +caseous +casern +caserne +casernes +caserns +cases +casette +casettes +casework +caseworker +caseworkers +caseworks +caseworm +caseworms +cash +cashable +cashaw +cashaws +cashbook +cashbooks +cashbox +cashboxes +cashed +cashes +cashew +cashews +cashier +cashiered +cashiering +cashiers +cashing +cashless +cashmere +cashmeres +cashoo +cashoos +casimere +casimeres +casimire +casimires +casing +casings +casini +casino +casinos +casita +casitas +cask +casked +casket +casketed +casketing +caskets +casking +casks +casky +casque +casqued +casques +cassaba +cassabas +cassata +cassatas +cassava +cassavas +casserole +casseroles +cassette +cassettes +cassia +cassias +cassimere +cassimeres +cassino +cassinos +cassis +cassises +cassiterite +cassiterites +cassock +cassocks +cassoulet +cassoulets +cassowaries +cassowary +cast +castabilities +castability +castable +castanet +castanets +castaway +castaways +caste +casteism +casteisms +castellan +castellans +castellated +caster +casters +castes +castigate +castigated +castigates +castigating +castigation +castigations +castigator +castigators +casting +castings +castle +castled +castles +castling +castoff +castoffs +castor +castoreum +castoreums +castors +castrate +castrated +castrates +castrati +castrating +castration +castrations +castrato +castrator +castrators +castratory +castratos +casts +casual +casually +casualness +casualnesses +casuals +casualties +casualty +casuarina +casuarinas +casuist +casuistic +casuistical +casuistries +casuistry +casuists +casus +cat +catabolic +catabolically +catabolism +catabolisms +catabolite +catabolites +catabolize +catabolized +catabolizes +catabolizing +catachreses +catachresis +catachrestic +catachrestical +catachrestically +cataclysm +cataclysmal +cataclysmic +cataclysmically +cataclysms +catacomb +catacombs +catadioptric +catadromous +catafalque +catafalques +catalase +catalases +catalatic +catalectic +catalectics +catalepsies +catalepsy +cataleptic +cataleptically +cataleptics +catalexes +catalexis +catalo +cataloes +catalog +cataloged +cataloger +catalogers +cataloging +catalogs +catalogue +catalogued +cataloguer +cataloguers +catalogues +cataloguing +catalos +catalpa +catalpas +catalyses +catalysis +catalyst +catalysts +catalytic +catalytically +catalyze +catalyzed +catalyzer +catalyzers +catalyzes +catalyzing +catamaran +catamarans +catamenia +catamenial +catamite +catamites +catamount +catamounts +cataphora +cataphoras +cataphoreses +cataphoresis +cataphoretic +cataphoretically +cataphoric +cataplasm +cataplasms +cataplexies +cataplexy +catapult +catapulted +catapulting +catapults +cataract +cataractous +cataracts +catarrh +catarrhal +catarrhally +catarrhine +catarrhines +catarrhs +catastrophe +catastrophes +catastrophic +catastrophically +catastrophism +catastrophisms +catastrophist +catastrophists +catatonia +catatonias +catatonic +catatonically +catatonics +catawba +catawbas +catbird +catbirds +catboat +catboats +catbrier +catbriers +catcall +catcalled +catcalling +catcalls +catch +catchable +catchall +catchalls +catcher +catchers +catches +catchflies +catchfly +catchier +catchiest +catching +catchment +catchments +catchpenny +catchphrase +catchphrases +catchpole +catchpoles +catchpoll +catchpolls +catchup +catchups +catchword +catchwords +catchy +catclaw +catclaws +cate +catecheses +catechesis +catechetical +catechin +catechins +catechism +catechismal +catechisms +catechist +catechistic +catechists +catechization +catechizations +catechize +catechized +catechizer +catechizers +catechizes +catechizing +catechol +catecholamine +catecholaminergic +catecholamines +catechols +catechu +catechumen +catechumens +catechus +categoric +categorical +categorically +categories +categorise +categorised +categorises +categorising +categorization +categorizations +categorize +categorized +categorizes +categorizing +category +catena +catenae +catenaries +catenary +catenas +catenate +catenated +catenates +catenating +catenation +catenations +catenoid +catenoids +cater +cateran +caterans +catercorner +catercornered +catered +caterer +caterers +cateress +cateresses +catering +caterpillar +caterpillars +caters +caterwaul +caterwauled +caterwauling +caterwauls +cates +catface +catfaces +catfacing +catfacings +catfall +catfalls +catfight +catfights +catfish +catfishes +catgut +catguts +catharses +catharsis +cathartic +cathartics +cathead +catheads +cathect +cathected +cathectic +cathecting +cathects +cathedra +cathedrae +cathedral +cathedrals +cathedras +cathepsin +cathepsins +catheter +catheterization +catheterizations +catheterize +catheterized +catheterizes +catheterizing +catheters +cathexes +cathexis +cathodal +cathodally +cathode +cathodes +cathodic +cathodically +catholic +catholically +catholicate +catholicates +catholicities +catholicity +catholicize +catholicized +catholicizes +catholicizing +catholicoi +catholicon +catholicons +catholicos +catholicoses +catholics +cathouse +cathouses +cation +cationic +cationically +cations +catkin +catkins +catlike +catlin +catling +catlings +catlins +catmint +catmints +catnap +catnaper +catnapers +catnapped +catnapper +catnappers +catnapping +catnaps +catnip +catnips +catoptric +cats +catspaw +catspaws +catsup +catsups +cattail +cattails +cattalo +cattaloes +cattalos +catted +catteries +cattery +cattie +cattier +catties +cattiest +cattily +cattiness +cattinesses +catting +cattish +cattle +cattleman +cattlemen +cattleya +cattleyas +catty +catwalk +catwalks +caucus +caucused +caucuses +caucusing +caucussed +caucusses +caucussing +caudad +caudal +caudally +caudate +caudated +caudates +caudex +caudexes +caudices +caudillismo +caudillismos +caudillo +caudillos +caudle +caudles +caught +caul +cauld +cauldron +cauldrons +caulds +caules +caulicle +caulicles +cauliflower +caulifloweret +cauliflowerets +cauliflowers +cauline +caulis +caulk +caulked +caulker +caulkers +caulking +caulkings +caulks +cauls +causable +causal +causalgia +causalgias +causalgic +causalities +causality +causally +causals +causation +causations +causative +causatively +causatives +cause +caused +causeless +causer +causerie +causeries +causers +causes +causeway +causewayed +causewaying +causeways +causey +causeys +causing +caustic +caustically +causticities +causticity +caustics +cauteries +cauterization +cauterizations +cauterize +cauterized +cauterizes +cauterizing +cautery +caution +cautionary +cautioned +cautioning +cautions +cautious +cautiously +cautiousness +cautiousnesses +cavalcade +cavalcades +cavalero +cavaleros +cavaletti +cavalier +cavaliered +cavaliering +cavalierism +cavalierisms +cavalierly +cavaliers +cavalla +cavallas +cavalletti +cavallies +cavally +cavalries +cavalry +cavalryman +cavalrymen +cavatina +cavatinas +cavatine +cave +caveat +caveated +caveating +caveator +caveators +caveats +caved +cavefish +cavefishes +cavelike +caveman +cavemen +caver +cavern +caverned +cavernicolous +caverning +cavernous +cavernously +caverns +cavers +caves +cavetti +cavetto +cavettos +caviar +caviare +caviares +caviars +cavicorn +cavie +cavies +cavil +caviled +caviler +cavilers +caviling +cavilled +caviller +cavillers +cavilling +cavils +caving +cavings +cavitary +cavitate +cavitated +cavitates +cavitating +cavitation +cavitations +cavitied +cavities +cavity +cavort +cavorted +cavorter +cavorters +cavorting +cavorts +cavy +caw +cawed +cawing +caws +cay +cayenne +cayenned +cayennes +cayman +caymans +cays +cayuse +cayuses +cazique +caziques +ceanothus +ceanothuses +cease +ceased +ceaseless +ceaselessly +ceaselessness +ceaselessnesses +ceases +ceasing +cebid +cebids +ceboid +ceboids +ceca +cecal +cecally +cecum +cedar +cedarbird +cedarbirds +cedarn +cedars +cedarwood +cedarwoods +cede +ceded +ceder +ceders +cedes +cedi +cedilla +cedillas +ceding +cedis +cedula +cedulas +cee +cees +ceiba +ceibas +ceil +ceiled +ceiler +ceilers +ceiling +ceilinged +ceilings +ceilometer +ceilometers +ceils +ceinture +ceintures +cel +celadon +celadons +celandine +celandines +celeb +celebrant +celebrants +celebrate +celebrated +celebratedness +celebratednesses +celebrates +celebrating +celebration +celebrations +celebrator +celebrators +celebratory +celebrities +celebrity +celebs +celeriac +celeriacs +celeries +celerities +celerity +celery +celesta +celestas +celeste +celestes +celestial +celestially +celestials +celestite +celestites +celiac +celiacs +celibacies +celibacy +celibate +celibates +cell +cella +cellae +cellar +cellarage +cellarages +cellared +cellarer +cellarers +cellaret +cellarets +cellarette +cellarettes +cellaring +cellars +cellblock +cellblocks +celled +celli +celling +cellist +cellists +cellmate +cellmates +cello +cellobiose +cellobioses +celloidin +celloidins +cellophane +cellophanes +cellos +cells +cellular +cellularities +cellularity +cellulase +cellulases +cellule +cellules +cellulite +cellulites +cellulitides +cellulitis +cellulitises +celluloid +celluloids +cellulolytic +cellulose +celluloses +cellulosic +cellulosics +celom +celomata +celoms +celosia +celosias +cels +celt +celts +cembali +cembalo +cembalos +cement +cementa +cementation +cementations +cemented +cementer +cementers +cementing +cementite +cementites +cementitious +cements +cementum +cemeteries +cemetery +cenacle +cenacles +cenobite +cenobites +cenobitic +cenospecies +cenotaph +cenotaphs +cenote +cenotes +cense +censed +censer +censers +censes +censing +censor +censored +censorial +censoring +censorious +censoriously +censoriousness +censoriousnesses +censors +censorship +censorships +censual +censurable +censure +censured +censurer +censurers +censures +censuring +census +censused +censuses +censusing +cent +cental +centals +centare +centares +centaur +centaurea +centaureas +centauries +centaurs +centaury +centavo +centavos +centenarian +centenarians +centenaries +centenary +centennial +centennially +centennials +center +centerboard +centerboards +centered +centeredness +centerednesses +centerfold +centerfolds +centering +centerless +centerline +centerlines +centerpiece +centerpieces +centers +centeses +centesimal +centesimi +centesimo +centesimos +centesis +centiare +centiares +centigrade +centigram +centigrams +centile +centiles +centiliter +centiliters +centillion +centillions +centime +centimes +centimeter +centimeters +centimo +centimorgan +centimorgans +centimos +centipede +centipedes +centner +centners +cento +centones +centos +centra +central +centraler +centralest +centralise +centralised +centralises +centralising +centralism +centralisms +centralist +centralistic +centralists +centralities +centrality +centralization +centralizations +centralize +centralized +centralizer +centralizers +centralizes +centralizing +centrally +centrals +centre +centred +centres +centric +centrically +centricities +centricity +centrifugal +centrifugally +centrifugals +centrifugation +centrifugations +centrifuge +centrifuged +centrifuges +centrifuging +centring +centrings +centriole +centrioles +centripetal +centripetally +centrism +centrisms +centrist +centrists +centroid +centroids +centromere +centromeres +centromeric +centrosome +centrosomes +centrosymmetric +centrum +centrums +cents +centum +centums +centuple +centupled +centuples +centupling +centuries +centurion +centurions +century +ceorl +ceorlish +ceorls +cep +cepe +cepes +cephalad +cephalexin +cephalexins +cephalic +cephalically +cephalin +cephalins +cephalization +cephalizations +cephalometric +cephalometries +cephalometry +cephalopod +cephalopods +cephaloridine +cephaloridines +cephalosporin +cephalosporins +cephalothin +cephalothins +cephalothoraces +cephalothorax +cephalothoraxes +cepheid +cepheids +ceps +ceramal +ceramals +ceramic +ceramicist +ceramicists +ceramics +ceramist +ceramists +cerastes +cerate +cerated +cerates +ceratin +ceratins +ceratoid +ceratopsian +ceratopsians +cercaria +cercariae +cercarial +cercarias +cerci +cercis +cercises +cercus +cere +cereal +cereals +cerebella +cerebellar +cerebellum +cerebellums +cerebra +cerebral +cerebrally +cerebrals +cerebrate +cerebrated +cerebrates +cerebrating +cerebration +cerebrations +cerebric +cerebroside +cerebrosides +cerebrospinal +cerebrovascular +cerebrum +cerebrums +cerecloth +cerecloths +cered +cerement +cerements +ceremonial +ceremonialism +ceremonialisms +ceremonialist +ceremonialists +ceremonially +ceremonials +ceremonies +ceremonious +ceremoniously +ceremoniousness +ceremoniousnesses +ceremony +ceres +cereus +cereuses +ceria +cerias +ceric +cering +ceriph +ceriphs +cerise +cerises +cerite +cerites +cerium +ceriums +cermet +cermets +cernuous +cero +ceros +cerotic +cerotype +cerotypes +cerous +certain +certainer +certainest +certainly +certainties +certainty +certes +certifiable +certifiably +certificate +certificated +certificates +certificating +certification +certifications +certificatory +certified +certifier +certifiers +certifies +certify +certifying +certiorari +certioraris +certitude +certitudes +cerulean +ceruleans +ceruloplasmin +ceruloplasmins +cerumen +cerumens +ceruminous +ceruse +ceruses +cerusite +cerusites +cerussite +cerussites +cervelas +cervelases +cervelat +cervelats +cervical +cervices +cervicites +cervicitides +cervicitis +cervicitises +cervid +cervine +cervix +cervixes +cesarean +cesareans +cesarian +cesarians +cesium +cesiums +cess +cessation +cessations +cessed +cesses +cessing +cession +cessions +cesspit +cesspits +cesspool +cesspools +cesta +cestas +cesti +cestode +cestodes +cestoi +cestoid +cestoids +cestos +cestus +cestuses +cesura +cesurae +cesuras +cetacean +cetaceans +cetaceous +cetane +cetanes +cete +cetes +cetologies +cetologist +cetologists +cetology +ceviche +ceviches +chablis +chabouk +chabouks +chabuk +chabuks +chacma +chacmas +chaconne +chaconnes +chad +chadar +chadarim +chadars +chadless +chador +chadors +chadri +chads +chaeta +chaetae +chaetal +chaetognath +chaetognaths +chafe +chafed +chafer +chafers +chafes +chaff +chaffed +chaffer +chaffered +chafferer +chafferers +chaffering +chaffers +chaffier +chaffiest +chaffinch +chaffinches +chaffing +chaffs +chaffy +chafing +chagrin +chagrined +chagrining +chagrinned +chagrinning +chagrins +chain +chaine +chained +chaines +chaining +chainman +chainmen +chains +chainsaw +chainsawed +chainsawing +chainsaws +chainwheel +chainwheels +chair +chaired +chairing +chairlift +chairlifts +chairman +chairmaned +chairmaning +chairmanned +chairmanning +chairmans +chairmanship +chairmanships +chairmen +chairperson +chairpersons +chairs +chairwoman +chairwomen +chaise +chaises +chakra +chakras +chalah +chalahs +chalaza +chalazae +chalazal +chalazas +chalazia +chalazion +chalazions +chalcedonic +chalcedonies +chalcedony +chalcid +chalcids +chalcocite +chalcocites +chalcogen +chalcogenide +chalcogenides +chalcogens +chalcopyrite +chalcopyrites +chaldron +chaldrons +chaleh +chalehs +chalet +chalets +chalice +chaliced +chalices +chalk +chalkboard +chalkboards +chalked +chalkier +chalkiest +chalking +chalks +chalky +challa +challah +challahs +challas +challenge +challenged +challenger +challengers +challenges +challenging +challengingly +challie +challies +challis +challises +challot +challoth +chally +chalone +chalones +chalot +chaloth +chalutz +chalutzim +chalybeate +chalybeates +cham +chamade +chamades +chamaephyte +chamaephytes +chamber +chambered +chambering +chamberlain +chamberlains +chambermaid +chambermaids +chambers +chambray +chambrays +chameleon +chameleonic +chameleonlike +chameleons +chamfer +chamfered +chamfering +chamfers +chamfron +chamfrons +chamise +chamises +chamiso +chamisos +chammied +chammies +chammy +chammying +chamois +chamoised +chamoises +chamoising +chamoix +chamomile +chamomiles +champ +champac +champacs +champagne +champagnes +champaign +champaigns +champak +champaks +champed +champer +champers +champerties +champertous +champerty +champignon +champignons +champing +champion +championed +championing +champions +championship +championships +champleve +champleves +champs +champy +chams +chance +chanced +chanceful +chancel +chancelleries +chancellery +chancellor +chancellories +chancellors +chancellorship +chancellorships +chancellory +chancels +chanceries +chancery +chances +chancier +chanciest +chancily +chanciness +chancinesses +chancing +chancre +chancres +chancroid +chancroidal +chancroids +chancrous +chancy +chandelier +chandeliered +chandeliers +chandelle +chandelled +chandelles +chandelling +chandler +chandleries +chandlers +chandlery +chanfron +chanfrons +chang +change +changeabilities +changeability +changeable +changeableness +changeablenesses +changeably +changed +changeful +changefully +changefulness +changefulnesses +changeless +changelessly +changelessness +changelessnesses +changeling +changelings +changeover +changeovers +changer +changers +changes +changing +changs +channel +channeled +channeler +channelers +channeling +channelization +channelizations +channelize +channelized +channelizes +channelizing +channelled +channelling +channels +chanson +chansonnier +chansonniers +chansons +chant +chantage +chantages +chanted +chanter +chanterelle +chanterelles +chanters +chanteuse +chanteuses +chantey +chanteys +chanticleer +chanticleers +chanties +chanting +chantor +chantors +chantries +chantry +chants +chanty +chao +chaos +chaoses +chaotic +chaotically +chap +chaparajos +chaparejos +chaparral +chaparrals +chapati +chapatis +chapatti +chapattis +chapbook +chapbooks +chape +chapeau +chapeaus +chapeaux +chapel +chapels +chaperon +chaperonage +chaperonages +chaperone +chaperoned +chaperones +chaperoning +chaperons +chapes +chapfallen +chapiter +chapiters +chaplain +chaplaincies +chaplaincy +chaplains +chaplet +chapleted +chaplets +chapman +chapmen +chappati +chappatis +chapped +chapping +chaps +chapt +chapter +chaptered +chaptering +chapters +chaqueta +chaquetas +char +charabanc +charabancs +characid +characids +characin +characins +character +charactered +characterful +characteries +charactering +characteristic +characteristically +characteristics +characterization +characterizations +characterize +characterized +characterizes +characterizing +characterless +characterological +characterologically +characters +charactery +charade +charades +charas +charases +charbroil +charbroiled +charbroiler +charbroilers +charbroiling +charbroils +charcoal +charcoaled +charcoaling +charcoals +charcuterie +charcuteries +chard +chardonnay +chardonnays +chards +chare +chared +chares +charge +chargeable +charged +chargehand +chargehands +charger +chargers +charges +charging +charier +chariest +charily +chariness +charinesses +charing +chariot +charioted +charioteer +charioteers +charioting +chariots +charism +charisma +charismata +charismatic +charismatics +charisms +charitable +charitableness +charitablenesses +charitably +charities +charity +charivari +charivaris +chark +charka +charkas +charked +charkha +charkhas +charking +charks +charladies +charlady +charlatan +charlatanism +charlatanisms +charlatanries +charlatanry +charlatans +charley +charleys +charlie +charlies +charlock +charlocks +charlotte +charlottes +charm +charmed +charmer +charmers +charmeuse +charmeuses +charming +charminger +charmingest +charmingly +charmless +charms +charnel +charnels +charpai +charpais +charpoy +charpoys +charqui +charquid +charquis +charr +charred +charrier +charriest +charring +charro +charros +charrs +charry +chars +chart +charted +charter +chartered +charterer +charterers +chartering +charters +charting +chartist +chartists +chartreuse +chartreuses +charts +chartularies +chartulary +charwoman +charwomen +chary +chase +chased +chaser +chasers +chases +chasing +chasings +chasm +chasmal +chasmed +chasmic +chasms +chasmy +chasse +chassed +chasseing +chassepot +chassepots +chasses +chasseur +chasseurs +chassis +chaste +chastely +chasten +chastened +chastener +chasteners +chasteness +chastenesses +chastening +chastens +chaster +chastest +chastise +chastised +chastisement +chastisements +chastiser +chastisers +chastises +chastising +chastities +chastity +chasuble +chasubles +chat +chatchka +chatchkas +chatchke +chatchkes +chateau +chateaubriand +chateaubriands +chateaus +chateaux +chatelain +chatelaine +chatelaines +chatelains +chatoyance +chatoyances +chatoyancies +chatoyancy +chatoyant +chatoyants +chats +chatted +chattel +chattels +chatter +chatterbox +chatterboxes +chattered +chatterer +chatterers +chattering +chatters +chattery +chattier +chattiest +chattily +chattiness +chattinesses +chatting +chatty +chaufer +chaufers +chauffer +chauffers +chauffeur +chauffeured +chauffeuring +chauffeurs +chaulmoogra +chaulmoogras +chaunt +chaunted +chaunter +chaunters +chaunting +chaunts +chausses +chaussure +chaussures +chautauqua +chautauquas +chauvinism +chauvinisms +chauvinist +chauvinistic +chauvinistically +chauvinists +chaw +chawbacon +chawbacons +chawed +chawer +chawers +chawing +chaws +chay +chayote +chayotes +chays +chazan +chazanim +chazans +chazzan +chazzanim +chazzans +chazzen +chazzenim +chazzens +cheap +cheapen +cheapened +cheapening +cheapens +cheaper +cheapest +cheapie +cheapies +cheapish +cheapishly +cheapjack +cheapjacks +cheaply +cheapness +cheapnesses +cheapo +cheapos +cheaps +cheapskate +cheapskates +cheat +cheated +cheater +cheaters +cheating +cheats +chebec +chebecs +chechako +chechakos +check +checkable +checkbook +checkbooks +checked +checker +checkerberries +checkerberry +checkerboard +checkerboards +checkered +checkering +checkers +checking +checkless +checklist +checklists +checkmark +checkmarked +checkmarking +checkmarks +checkmate +checkmated +checkmates +checkmating +checkoff +checkoffs +checkout +checkouts +checkpoint +checkpoints +checkrein +checkreins +checkroom +checkrooms +checkrow +checkrowed +checkrowing +checkrows +checks +checkup +checkups +cheddar +cheddars +cheddite +cheddites +cheder +cheders +chedite +chedites +cheechako +cheechakos +cheek +cheekbone +cheekbones +cheeked +cheekful +cheekfuls +cheekier +cheekiest +cheekily +cheekiness +cheekinesses +cheeking +cheeks +cheeky +cheep +cheeped +cheeper +cheepers +cheeping +cheeps +cheer +cheered +cheerer +cheerers +cheerful +cheerfuller +cheerfullest +cheerfully +cheerfulness +cheerfulnesses +cheerier +cheeriest +cheerily +cheeriness +cheerinesses +cheering +cheerio +cheerios +cheerlead +cheerleader +cheerleaders +cheerleading +cheerleads +cheerled +cheerless +cheerlessly +cheerlessness +cheerlessnesses +cheerly +cheero +cheeros +cheers +cheery +cheese +cheeseburger +cheeseburgers +cheesecake +cheesecakes +cheesecloth +cheesecloths +cheesed +cheeseparing +cheeseparings +cheeses +cheesier +cheesiest +cheesily +cheesiness +cheesinesses +cheesing +cheesy +cheetah +cheetahs +chef +chefdom +chefdoms +cheffed +cheffing +chefs +chegoe +chegoes +chela +chelae +chelas +chelatable +chelate +chelated +chelates +chelating +chelation +chelations +chelator +chelators +chelicera +chelicerae +cheliceral +cheliped +chelipeds +cheloid +cheloids +chelonian +chelonians +chemic +chemical +chemically +chemicals +chemics +chemiluminescence +chemiluminescences +chemiluminescent +chemiosmotic +chemise +chemises +chemisette +chemisettes +chemism +chemisms +chemisorb +chemisorbed +chemisorbing +chemisorbs +chemisorption +chemisorptions +chemist +chemistries +chemistry +chemists +chemo +chemoautotrophic +chemoautotrophies +chemoautotrophy +chemoprophylactic +chemoprophylaxes +chemoprophylaxis +chemoreception +chemoreceptions +chemoreceptive +chemoreceptor +chemoreceptors +chemos +chemosurgeries +chemosurgery +chemosurgical +chemosyntheses +chemosynthesis +chemosynthetic +chemotactic +chemotactically +chemotaxes +chemotaxis +chemotaxonomic +chemotaxonomies +chemotaxonomist +chemotaxonomists +chemotaxonomy +chemotherapeutic +chemotherapeutically +chemotherapeutics +chemotherapies +chemotherapist +chemotherapists +chemotherapy +chemotropism +chemotropisms +chemurgies +chemurgy +chenille +chenilles +chenopod +chenopods +cheongsam +cheongsams +cheque +chequer +chequered +chequering +chequers +cheques +cherimoya +cherimoyas +cherish +cherishable +cherished +cherisher +cherishers +cherishes +cherishing +chernozem +chernozemic +chernozems +cheroot +cheroots +cherries +cherry +cherrylike +cherrystone +cherrystones +chert +chertier +chertiest +cherts +cherty +cherub +cherubic +cherubically +cherubim +cherubims +cherublike +cherubs +chervil +chervils +chess +chessboard +chessboards +chesses +chessman +chessmen +chest +chested +chesterfield +chesterfields +chestful +chestfuls +chestier +chestiest +chestnut +chestnuts +chests +chesty +chetah +chetahs +cheth +cheths +chetrum +chetrums +chevalet +chevalets +chevalier +chevaliers +chevelure +chevelures +cheveron +cheverons +chevied +chevies +cheviot +cheviots +chevre +chevres +chevron +chevrons +chevy +chevying +chew +chewable +chewed +chewer +chewers +chewier +chewiest +chewing +chewink +chewinks +chews +chewy +chez +chi +chia +chiao +chiaroscurist +chiaroscurists +chiaroscuro +chiaroscuros +chias +chiasm +chiasma +chiasmal +chiasmas +chiasmata +chiasmatic +chiasmi +chiasmic +chiasms +chiasmus +chiastic +chiaus +chiauses +chibouk +chibouks +chibouque +chibouques +chic +chicane +chicaned +chicaner +chicaneries +chicaners +chicanery +chicanes +chicaning +chicano +chicanos +chiccories +chiccory +chicer +chicest +chichi +chichis +chick +chickadee +chickadees +chickaree +chickarees +chickee +chickees +chicken +chickened +chickenhearted +chickening +chickenpox +chickenpoxes +chickens +chickenshit +chickenshits +chickories +chickory +chickpea +chickpeas +chicks +chickweed +chickweeds +chicle +chicles +chicly +chicness +chicnesses +chico +chicories +chicory +chicos +chics +chid +chidden +chide +chided +chider +chiders +chides +chiding +chief +chiefdom +chiefdoms +chiefer +chiefest +chiefly +chiefs +chiefship +chiefships +chieftain +chieftaincies +chieftaincy +chieftains +chieftainship +chieftainships +chiel +chield +chields +chiels +chiffchaff +chiffchaffs +chiffon +chiffonade +chiffonades +chiffonier +chiffoniers +chiffons +chifforobe +chifforobes +chigetai +chigetais +chigger +chiggers +chignon +chignons +chigoe +chigoes +chihuahua +chihuahuas +chilblain +chilblains +child +childbearing +childbearings +childbed +childbeds +childbirth +childbirths +childe +childes +childhood +childhoods +childing +childish +childishly +childishness +childishnesses +childless +childlessness +childlessnesses +childlier +childliest +childlike +childlikeness +childlikenesses +childly +childproof +childproofed +childproofing +childproofs +children +chile +chiles +chili +chiliad +chiliads +chiliasm +chiliasms +chiliast +chiliastic +chiliasts +chilidog +chilidogs +chilies +chill +chilled +chiller +chillers +chillest +chilli +chillier +chillies +chilliest +chillily +chilliness +chillinesses +chilling +chillingly +chillness +chillnesses +chills +chillum +chillums +chilly +chilopod +chilopods +chimaera +chimaeras +chimaeric +chimaerism +chimaerisms +chimar +chimars +chimb +chimbley +chimbleys +chimblies +chimbly +chimbs +chime +chimed +chimer +chimera +chimeras +chimere +chimeres +chimeric +chimerical +chimerically +chimerism +chimerisms +chimers +chimes +chimichanga +chimichangas +chiming +chimla +chimlas +chimley +chimleys +chimney +chimneylike +chimneypiece +chimneypieces +chimneys +chimp +chimpanzee +chimpanzees +chimps +chin +china +chinaberries +chinaberry +chinas +chinaware +chinawares +chinbone +chinbones +chinch +chincherinchee +chincherinchees +chinches +chinchier +chinchiest +chinchilla +chinchillas +chinchy +chine +chined +chines +chining +chink +chinkapin +chinkapins +chinked +chinkier +chinkiest +chinking +chinks +chinky +chinless +chinned +chinning +chino +chinoiserie +chinoiseries +chinone +chinones +chinook +chinooks +chinos +chinquapin +chinquapins +chins +chints +chintses +chintz +chintzes +chintzier +chintziest +chintzy +chionodoxa +chionodoxas +chip +chipboard +chipboards +chipmuck +chipmucks +chipmunk +chipmunks +chipped +chipper +chippered +chippering +chippers +chippie +chippier +chippies +chippiest +chipping +chippy +chips +chiral +chiralities +chirality +chirimoya +chirimoyas +chirk +chirked +chirker +chirkest +chirking +chirks +chirm +chirmed +chirming +chirms +chiro +chirographer +chirographers +chirographic +chirographical +chirographies +chirography +chiromancer +chiromancers +chiromancies +chiromancy +chironomid +chironomids +chiropodies +chiropodist +chiropodists +chiropody +chiropractic +chiropractics +chiropractor +chiropractors +chiropteran +chiropterans +chiros +chirp +chirped +chirper +chirpers +chirpier +chirpiest +chirpily +chirping +chirps +chirpy +chirr +chirre +chirred +chirres +chirring +chirrs +chirrup +chirruped +chirruping +chirrups +chirrupy +chirurgeon +chirurgeons +chis +chisel +chiseled +chiseler +chiselers +chiseling +chiselled +chiseller +chisellers +chiselling +chisels +chit +chital +chitchat +chitchats +chitchatted +chitchatting +chitin +chitinous +chitins +chitlin +chitling +chitlings +chitlins +chiton +chitons +chitosan +chitosans +chits +chitter +chittered +chittering +chitterlings +chitters +chitties +chitty +chivalric +chivalries +chivalrous +chivalrously +chivalrousness +chivalrousnesses +chivalry +chivaree +chivareed +chivareeing +chivarees +chivari +chivaried +chivaries +chivariing +chive +chives +chivied +chivies +chivvied +chivvies +chivvy +chivvying +chivy +chivying +chlamydes +chlamydia +chlamydiae +chlamydial +chlamydospore +chlamydospores +chlamys +chlamyses +chloasma +chloasmata +chloracne +chloracnes +chloral +chloralose +chloralosed +chloraloses +chlorals +chloramine +chloramines +chloramphenicol +chloramphenicols +chlorate +chlorates +chlordan +chlordane +chlordanes +chlordans +chlordiazepoxide +chlordiazepoxides +chlorella +chlorellas +chlorenchyma +chlorenchymas +chlorenchymata +chloric +chlorid +chloride +chlorides +chlorids +chlorin +chlorinate +chlorinated +chlorinates +chlorinating +chlorination +chlorinations +chlorinator +chlorinators +chlorine +chlorines +chlorinities +chlorinity +chlorins +chlorite +chlorites +chloritic +chlorobenzene +chlorobenzenes +chlorofluorocarbon +chlorofluorocarbons +chlorofluoromethane +chlorofluoromethanes +chloroform +chloroformed +chloroforming +chloroforms +chlorohydrin +chlorohydrins +chlorophyll +chlorophyllous +chlorophylls +chloropicrin +chloropicrins +chloroplast +chloroplastic +chloroplasts +chloroprene +chloroprenes +chloroquine +chloroquines +chloroses +chlorosis +chlorothiazide +chlorothiazides +chlorotic +chlorous +chlorpromazine +chlorpromazines +chlorpropamide +chlorpropamides +chlortetracycline +chlortetracyclines +choana +choanae +choanocyte +choanocytes +chock +chockablock +chocked +chockful +chocking +chocks +chocoholic +chocoholics +chocolate +chocolates +chocolatey +chocolatier +chocolatiers +chocolaty +choice +choicely +choiceness +choicenesses +choicer +choices +choicest +choir +choirboy +choirboys +choired +choiring +choirmaster +choirmasters +choirs +choke +chokeberries +chokeberry +chokecherries +chokecherry +choked +choker +chokers +chokes +chokey +chokier +chokiest +choking +chokingly +choky +cholangiogram +cholangiograms +cholangiographic +cholangiographies +cholangiography +cholate +cholates +cholecalciferol +cholecalciferols +cholecystectomies +cholecystectomized +cholecystectomy +cholecystites +cholecystitides +cholecystitis +cholecystitises +cholecystokinin +cholecystokinins +cholelithiases +cholelithiasis +cholent +cholents +choler +cholera +choleras +choleric +cholerically +cholers +cholestases +cholestasis +cholestatic +cholesteric +cholesterol +cholesterols +cholestyramine +cholestyramines +choline +cholinergic +cholinergically +cholines +cholinesterase +cholinesterases +cholla +chollas +cholo +cholos +chomp +chomped +chomper +chompers +chomping +chomps +chon +chondriosome +chondriosomes +chondrite +chondrites +chondritic +chondrocrania +chondrocranium +chondrocraniums +chondroitin +chondroitins +chondrule +chondrules +chook +chooks +choose +chooser +choosers +chooses +choosey +choosier +choosiest +choosing +choosy +chop +chopfallen +chophouse +chophouses +chopin +chopine +chopines +chopins +choplogic +choplogics +chopped +chopper +choppered +choppering +choppers +choppier +choppiest +choppily +choppiness +choppinesses +chopping +choppy +chops +chopstick +chopsticks +choragi +choragic +choragus +choraguses +choral +chorale +chorales +chorally +chorals +chord +chordal +chordamesoderm +chordamesodermal +chordamesoderms +chordate +chordates +chorded +chording +chords +chore +chorea +choreal +choreas +chored +choregi +choregus +choreguses +choreic +choreiform +choreman +choremen +choreograph +choreographed +choreographer +choreographers +choreographic +choreographically +choreographies +choreographing +choreographs +choreography +choreoid +chores +chorial +choriamb +choriambs +choric +chorine +chorines +choring +chorioallantoic +chorioallantoides +chorioallantois +choriocarcinoma +choriocarcinomas +choriocarcinomata +chorioid +chorioids +chorion +chorionic +chorions +chorister +choristers +chorizo +chorizos +chorographer +chorographers +chorographic +chorographies +chorography +choroid +choroidal +choroids +chortle +chortled +chortler +chortlers +chortles +chortling +chorus +chorused +choruses +chorusing +chorussed +chorusses +chorussing +chose +chosen +choses +chott +chotts +chough +choughs +chouse +choused +chouser +chousers +chouses +choush +choushes +chousing +chow +chowchow +chowchows +chowder +chowdered +chowderhead +chowderheaded +chowderheads +chowdering +chowders +chowed +chowhound +chowhounds +chowing +chows +chowse +chowsed +chowses +chowsing +chowtime +chowtimes +chresard +chresards +chrestomathies +chrestomathy +chrism +chrisma +chrismal +chrismation +chrismations +chrismon +chrismons +chrisms +chrisom +chrisoms +christen +christened +christening +christenings +christens +christiania +christianias +christie +christies +christy +chroma +chromaffin +chromas +chromate +chromates +chromatic +chromatically +chromaticism +chromaticisms +chromaticities +chromaticity +chromatics +chromatid +chromatids +chromatin +chromatinic +chromatins +chromatogram +chromatograms +chromatograph +chromatographed +chromatographer +chromatographers +chromatographic +chromatographically +chromatographies +chromatographing +chromatographs +chromatography +chromatolyses +chromatolysis +chromatolytic +chromatophore +chromatophores +chrome +chromed +chromes +chromic +chromide +chromides +chrominance +chrominances +chroming +chromings +chromite +chromites +chromium +chromiums +chromize +chromized +chromizes +chromizing +chromo +chromocenter +chromocenters +chromodynamics +chromogen +chromogenic +chromogens +chromolithograph +chromolithographed +chromolithographer +chromolithographers +chromolithographic +chromolithographies +chromolithographing +chromolithographs +chromolithography +chromomere +chromomeres +chromomeric +chromonema +chromonemata +chromonematic +chromophil +chromophobe +chromophore +chromophores +chromophoric +chromoplast +chromoplasts +chromoprotein +chromoproteins +chromos +chromosomal +chromosomally +chromosome +chromosomes +chromosphere +chromospheres +chromospheric +chromous +chromyl +chromyls +chronaxie +chronaxies +chronaxy +chronic +chronically +chronicities +chronicity +chronicle +chronicled +chronicler +chroniclers +chronicles +chronicling +chronics +chronobiologic +chronobiological +chronobiologies +chronobiologist +chronobiologists +chronobiology +chronogram +chronograms +chronograph +chronographic +chronographies +chronographs +chronography +chronologer +chronologers +chronologic +chronological +chronologically +chronologies +chronologist +chronologists +chronology +chronometer +chronometers +chronometric +chronometrical +chronometrically +chronometries +chronometry +chronon +chronons +chronotherapies +chronotherapy +chrysalid +chrysalides +chrysalids +chrysalis +chrysalises +chrysanthemum +chrysanthemums +chrysarobin +chrysarobins +chrysoberyl +chrysoberyls +chrysolite +chrysolites +chrysomelid +chrysomelids +chrysophyte +chrysophytes +chrysoprase +chrysoprases +chrysotile +chrysotiles +chthonian +chthonic +chub +chubasco +chubascos +chubbier +chubbiest +chubbily +chubbiness +chubbinesses +chubby +chubs +chuck +chuckawalla +chuckawallas +chucked +chuckhole +chuckholes +chuckies +chucking +chuckle +chuckled +chucklehead +chuckleheaded +chuckleheads +chuckler +chucklers +chuckles +chucklesome +chuckling +chucklingly +chucks +chuckwalla +chuckwallas +chucky +chuddah +chuddahs +chuddar +chuddars +chudder +chudders +chufa +chufas +chuff +chuffed +chuffer +chuffest +chuffier +chuffiest +chuffing +chuffs +chuffy +chug +chugalug +chugalugged +chugalugging +chugalugs +chugged +chugger +chuggers +chugging +chugs +chukar +chukars +chukka +chukkar +chukkars +chukkas +chukker +chukkers +chum +chummed +chummier +chummiest +chummily +chumminess +chumminesses +chumming +chummy +chump +chumped +chumping +chumps +chums +chumship +chumships +chunk +chunked +chunkier +chunkiest +chunkily +chunking +chunks +chunky +chunter +chuntered +chuntering +chunters +church +churched +churches +churchgoer +churchgoers +churchgoing +churchgoings +churchianities +churchianity +churchier +churchiest +churching +churchings +churchless +churchlier +churchliest +churchliness +churchlinesses +churchly +churchman +churchmanship +churchmanships +churchmen +churchwarden +churchwardens +churchwoman +churchwomen +churchy +churchyard +churchyards +churl +churlish +churlishly +churlishness +churlishnesses +churls +churn +churned +churner +churners +churning +churnings +churns +churr +churred +churrigueresque +churring +churrs +chute +chuted +chutes +chuting +chutist +chutists +chutnee +chutnees +chutney +chutneys +chutzpa +chutzpah +chutzpahs +chutzpas +chyle +chyles +chylomicron +chylomicrons +chylous +chyme +chymes +chymic +chymics +chymist +chymists +chymosin +chymosins +chymotrypsin +chymotrypsinogen +chymotrypsinogens +chymotrypsins +chymotryptic +chymous +ciao +cibol +cibols +ciboria +ciborium +ciboule +ciboules +cicada +cicadae +cicadas +cicala +cicalas +cicale +cicatrices +cicatricial +cicatrix +cicatrixes +cicatrization +cicatrizations +cicatrize +cicatrized +cicatrizes +cicatrizing +cicelies +cicely +cicero +cicerone +cicerones +ciceroni +ciceros +cichlid +cichlidae +cichlids +cicisbei +cicisbeism +cicisbeisms +cicisbeo +cicisbeos +cicoree +cicorees +cider +ciders +cigar +cigaret +cigarets +cigarette +cigarettes +cigarillo +cigarillos +cigars +ciguatera +ciguateras +cilantro +cilantros +cilia +ciliary +ciliate +ciliated +ciliates +ciliation +ciliations +cilice +cilices +cilium +cimbalom +cimbaloms +cimetidine +cimetidines +cimex +cimices +cinch +cinched +cinches +cinching +cinchona +cinchonas +cinchonine +cinchonines +cinchonism +cinchonisms +cincture +cinctured +cinctures +cincturing +cinder +cindered +cindering +cinders +cindery +cine +cineast +cineaste +cineastes +cineasts +cinema +cinemagoer +cinemagoers +cinemas +cinematheque +cinematheques +cinematic +cinematically +cinematize +cinematized +cinematizes +cinematizing +cinematograph +cinematographer +cinematographers +cinematographic +cinematographically +cinematographies +cinematographs +cinematography +cineol +cineole +cineoles +cineols +cineraria +cinerarias +cinerarium +cinerary +cinereous +cinerin +cinerins +cines +cingula +cingulate +cingulum +cinnabar +cinnabarine +cinnabars +cinnamic +cinnamon +cinnamons +cinnamyl +cinnamyls +cinquain +cinquains +cinque +cinquecentist +cinquecentisti +cinquecentists +cinquecento +cinquecentos +cinquefoil +cinquefoils +cinques +cion +cions +cioppino +cioppinos +cipher +ciphered +ciphering +ciphers +ciphertext +ciphertexts +ciphonies +ciphony +cipolin +cipolins +circa +circadian +circinate +circinately +circle +circled +circler +circlers +circles +circlet +circlets +circling +circuit +circuital +circuited +circuities +circuiting +circuitous +circuitously +circuitousness +circuitousnesses +circuitries +circuitry +circuits +circuity +circular +circularise +circularised +circularises +circularising +circularities +circularity +circularization +circularizations +circularize +circularized +circularizes +circularizing +circularly +circularness +circularnesses +circulars +circulatable +circulate +circulated +circulates +circulating +circulation +circulations +circulative +circulator +circulators +circulatory +circumambient +circumambiently +circumambulate +circumambulated +circumambulates +circumambulating +circumambulation +circumambulations +circumcenter +circumcenters +circumcircle +circumcircles +circumcise +circumcised +circumciser +circumcisers +circumcises +circumcising +circumcision +circumcisions +circumference +circumferences +circumferential +circumflex +circumflexes +circumfluent +circumfluous +circumfuse +circumfused +circumfuses +circumfusing +circumfusion +circumfusions +circumjacent +circumlocution +circumlocutions +circumlocutory +circumlunar +circumnavigate +circumnavigated +circumnavigates +circumnavigating +circumnavigation +circumnavigations +circumnavigator +circumnavigators +circumpolar +circumscissile +circumscribe +circumscribed +circumscribes +circumscribing +circumscription +circumscriptions +circumspect +circumspection +circumspections +circumspectly +circumstance +circumstanced +circumstances +circumstantial +circumstantialities +circumstantiality +circumstantially +circumstantiate +circumstantiated +circumstantiates +circumstantiating +circumstellar +circumvallate +circumvallated +circumvallates +circumvallating +circumvallation +circumvallations +circumvent +circumvented +circumventing +circumvention +circumventions +circumvents +circumvolution +circumvolutions +circus +circuses +circusy +cire +cires +cirque +cirques +cirrate +cirrhoses +cirrhosis +cirrhotic +cirrhotics +cirri +cirriped +cirripeds +cirrocumuli +cirrocumulus +cirrose +cirrostrati +cirrostratus +cirrous +cirrus +cirsoid +cis +cisalpine +cisco +ciscoes +ciscos +cislunar +cisplatin +cisplatins +cissies +cissoid +cissoids +cissy +cist +cistern +cisterna +cisternae +cisternal +cisterns +cistron +cistronic +cistrons +cists +cistus +cistuses +citable +citadel +citadels +citation +citational +citations +citator +citators +citatory +cite +citeable +cited +citer +citers +cites +cithara +citharas +cither +cithern +citherns +cithers +cithren +cithrens +citied +cities +citification +citifications +citified +citifies +citify +citifying +citing +citizen +citizeness +citizenesses +citizenly +citizenries +citizenry +citizens +citizenship +citizenships +citola +citolas +citole +citoles +citral +citrals +citrate +citrated +citrates +citreous +citric +citriculture +citricultures +citriculturist +citriculturists +citrin +citrine +citrines +citrinin +citrinins +citrins +citron +citronella +citronellal +citronellals +citronellas +citronellol +citronellols +citrons +citrous +citrulline +citrullines +citrus +citruses +citrusy +cittern +citterns +city +cityfied +cityscape +cityscapes +cityward +citywide +civet +civets +civic +civically +civicism +civicisms +civics +civie +civies +civil +civilian +civilianization +civilianizations +civilianize +civilianized +civilianizes +civilianizing +civilians +civilisation +civilisations +civilise +civilised +civilises +civilising +civilities +civility +civilization +civilizational +civilizations +civilize +civilized +civilizer +civilizers +civilizes +civilizing +civilly +civism +civisms +civvies +civvy +clabber +clabbered +clabbering +clabbers +clach +clachan +clachans +clachs +clack +clacked +clacker +clackers +clacking +clacks +clad +cladding +claddings +clade +clades +cladist +cladistic +cladistically +cladistics +cladists +cladoceran +cladocerans +cladode +cladodes +cladodial +cladogeneses +cladogenesis +cladogenetic +cladogenetically +cladogram +cladograms +cladophyll +cladophylla +cladophylls +cladophyllum +clads +clag +clagged +clagging +clags +claim +claimable +claimant +claimants +claimed +claimer +claimers +claiming +claims +clairaudience +clairaudiences +clairaudient +clairaudiently +clairvoyance +clairvoyances +clairvoyant +clairvoyantly +clairvoyants +clam +clamant +clamantly +clambake +clambakes +clamber +clambered +clamberer +clamberers +clambering +clambers +clammed +clammer +clammers +clammier +clammiest +clammily +clamminess +clamminesses +clamming +clammy +clamor +clamored +clamorer +clamorers +clamoring +clamorous +clamorously +clamorousness +clamorousnesses +clamors +clamour +clamoured +clamouring +clamours +clamp +clampdown +clampdowns +clamped +clamper +clampers +clamping +clamps +clams +clamshell +clamshells +clamworm +clamworms +clan +clandestine +clandestinely +clandestineness +clandestinenesses +clandestinities +clandestinity +clang +clanged +clanger +clangers +clanging +clangor +clangored +clangoring +clangorous +clangorously +clangors +clangour +clangoured +clangouring +clangours +clangs +clank +clanked +clanking +clankingly +clanks +clannish +clannishly +clannishness +clannishnesses +clans +clansman +clansmen +clap +clapboard +clapboarded +clapboarding +clapboards +clapped +clapper +clapperclaw +clapperclawed +clapperclawing +clapperclaws +clappers +clapping +claps +clapt +claptrap +claptraps +claque +claquer +claquers +claques +claqueur +claqueurs +clarence +clarences +claret +clarets +claries +clarification +clarifications +clarified +clarifier +clarifiers +clarifies +clarify +clarifying +clarinet +clarinetist +clarinetists +clarinets +clarinettist +clarinettists +clarion +clarioned +clarioning +clarions +clarities +clarity +clarkia +clarkias +claro +claroes +claros +clary +clash +clashed +clasher +clashers +clashes +clashing +clasp +clasped +clasper +claspers +clasping +clasps +claspt +class +classed +classer +classers +classes +classic +classical +classicalities +classicality +classically +classicism +classicisms +classicist +classicistic +classicists +classicize +classicized +classicizes +classicizing +classico +classics +classier +classiest +classifiable +classification +classifications +classificatory +classified +classifier +classifiers +classifies +classify +classifying +classily +classiness +classinesses +classing +classis +classism +classisms +classist +classists +classless +classlessness +classlessnesses +classmate +classmates +classroom +classrooms +classy +clast +clastic +clastics +clasts +clathrate +clathrates +clatter +clattered +clatterer +clatterers +clattering +clatteringly +clatters +clattery +claucht +claudication +claudications +claught +claughted +claughting +claughts +clausal +clause +clauses +claustra +claustral +claustrophobe +claustrophobes +claustrophobia +claustrophobias +claustrophobic +claustrophobically +claustrum +clavate +clave +claver +clavered +clavering +clavers +claves +clavi +clavichord +clavichordist +clavichordists +clavichords +clavicle +clavicles +clavicular +clavier +clavierist +clavieristic +clavierists +claviers +clavus +claw +clawed +clawer +clawers +clawhammer +clawing +clawless +clawlike +claws +claxon +claxons +clay +claybank +claybanks +clayed +clayey +clayier +clayiest +claying +clayish +claylike +claymore +claymores +claypan +claypans +clays +clayware +claywares +clean +cleanabilities +cleanability +cleanable +cleaned +cleaner +cleaners +cleanest +cleanhanded +cleaning +cleanlier +cleanliest +cleanliness +cleanlinesses +cleanly +cleanness +cleannesses +cleans +cleanse +cleansed +cleanser +cleansers +cleanses +cleansing +cleanup +cleanups +clear +clearable +clearance +clearances +cleared +clearer +clearers +clearest +clearheaded +clearheadedly +clearheadedness +clearheadednesses +clearing +clearinghouse +clearinghouses +clearings +clearly +clearness +clearnesses +clears +clearstories +clearstory +clearwing +clearwings +cleat +cleated +cleating +cleats +cleavable +cleavage +cleavages +cleave +cleaved +cleaver +cleavers +cleaves +cleaving +cleek +cleeked +cleeking +cleeks +clef +clefs +cleft +clefted +clefting +clefts +cleidoic +cleistogamic +cleistogamies +cleistogamous +cleistogamously +cleistogamy +clematis +clematises +clemencies +clemency +clement +clemently +clench +clenched +clencher +clenchers +clenches +clenching +cleome +cleomes +clepe +cleped +clepes +cleping +clepsydra +clepsydrae +clepsydras +clept +clerestories +clerestory +clergies +clergy +clergyman +clergymen +clergywoman +clergywomen +cleric +clerical +clericalism +clericalisms +clericalist +clericalists +clerically +clericals +clerics +clerid +clerids +clerihew +clerihews +clerisies +clerisy +clerk +clerkdom +clerkdoms +clerked +clerking +clerkish +clerklier +clerkliest +clerkly +clerks +clerkship +clerkships +cleveite +cleveites +clever +cleverer +cleverest +cleverish +cleverly +cleverness +clevernesses +clevis +clevises +clew +clewed +clewing +clews +cliche +cliched +cliches +click +clicked +clicker +clickers +clicking +clicks +client +clientage +clientages +cliental +clientele +clienteles +clientless +clients +cliff +cliffhanger +cliffhangers +cliffier +cliffiest +cliffs +cliffy +clift +clifts +climacteric +climacterics +climactic +climactically +climatal +climate +climates +climatic +climatically +climatological +climatologically +climatologies +climatologist +climatologists +climatology +climax +climaxed +climaxes +climaxing +climaxless +climb +climbable +climbed +climber +climbers +climbing +climbs +clime +climes +clinal +clinally +clinch +clinched +clincher +clinchers +clinches +clinching +clinchingly +cline +clines +cling +clinged +clinger +clingers +clingier +clingiest +clinging +clings +clingstone +clingstones +clingy +clinic +clinical +clinically +clinician +clinicians +clinicopathologic +clinicopathological +clinicopathologically +clinics +clink +clinked +clinker +clinkered +clinkering +clinkers +clinking +clinks +clinometer +clinometers +clinquant +clinquants +clintonia +clintonias +cliometric +cliometrician +cliometricians +cliometrics +clip +clipboard +clipboards +clipped +clipper +clippers +clipping +clippings +clips +clipsheet +clipsheets +clipt +clique +cliqued +cliques +cliquey +cliquier +cliquiest +cliquing +cliquish +cliquishly +cliquishness +cliquishnesses +cliquy +clitella +clitellum +clitic +clitics +clitoral +clitorectomies +clitorectomy +clitoric +clitoridectomies +clitoridectomy +clitorides +clitoris +clitorises +clivers +clivia +clivias +cloaca +cloacae +cloacal +cloacas +cloak +cloaked +cloaking +cloakroom +cloakrooms +cloaks +clobber +clobbered +clobbering +clobbers +clochard +clochards +cloche +cloches +clock +clocked +clocker +clockers +clocking +clocklike +clocks +clockwise +clockwork +clockworks +clod +cloddier +cloddiest +cloddish +cloddishness +cloddishnesses +cloddy +clodhopper +clodhoppers +clodhopping +clodpate +clodpates +clodpole +clodpoles +clodpoll +clodpolls +clods +clofibrate +clofibrates +clog +clogged +clogger +cloggers +cloggier +cloggiest +clogging +cloggy +clogs +cloisonne +cloisonnes +cloister +cloistered +cloistering +cloisters +cloistral +cloistress +cloistresses +clomb +clomiphene +clomiphenes +clomp +clomped +clomping +clomps +clon +clonal +clonally +clone +cloned +cloner +cloners +clones +clonic +clonicities +clonicity +clonidine +clonidines +cloning +clonings +clonism +clonisms +clonk +clonked +clonking +clonks +clons +clonus +clonuses +cloot +cloots +clop +clopped +clopping +clops +cloque +cloques +closable +close +closeable +closed +closedown +closedowns +closefisted +closely +closemouthed +closeness +closenesses +closeout +closeouts +closer +closers +closes +closest +closestool +closestools +closet +closeted +closetful +closetfuls +closeting +closets +closing +closings +clostridia +clostridial +clostridium +closure +closured +closures +closuring +clot +cloth +clothbound +clothe +clothed +clothes +clotheshorse +clotheshorses +clothesline +clotheslined +clotheslines +clotheslining +clothespin +clothespins +clothespress +clothespresses +clothier +clothiers +clothing +clothings +cloths +clots +clotted +clotting +clotty +cloture +clotured +clotures +cloturing +cloud +cloudberries +cloudberry +cloudburst +cloudbursts +clouded +cloudier +cloudiest +cloudily +cloudiness +cloudinesses +clouding +cloudland +cloudlands +cloudless +cloudlessly +cloudlessness +cloudlessnesses +cloudlet +cloudlets +clouds +cloudscape +cloudscapes +cloudy +clough +cloughs +clour +cloured +clouring +clours +clout +clouted +clouter +clouters +clouting +clouts +clove +cloven +clover +cloverleaf +cloverleafs +cloverleaves +clovers +cloves +clowder +clowders +clown +clowned +clowneries +clownery +clowning +clownish +clownishly +clownishness +clownishnesses +clowns +cloxacillin +cloxacillins +cloy +cloyed +cloying +cloyingly +cloys +cloze +clozes +club +clubable +clubbable +clubbed +clubber +clubbers +clubbier +clubbiest +clubbiness +clubbinesses +clubbing +clubbish +clubby +clubfeet +clubfoot +clubfooted +clubhand +clubhands +clubhaul +clubhauled +clubhauling +clubhauls +clubhouse +clubhouses +clubman +clubmen +clubroom +clubrooms +clubroot +clubroots +clubs +cluck +clucked +clucking +clucks +clue +clued +clueing +clueless +clues +cluing +clumber +clumbers +clump +clumped +clumpier +clumpiest +clumping +clumpish +clumps +clumpy +clumsier +clumsiest +clumsily +clumsiness +clumsinesses +clumsy +clung +clunk +clunked +clunker +clunkers +clunkier +clunkiest +clunking +clunks +clunky +clupeid +clupeids +clupeoid +clupeoids +cluster +clustered +clustering +clusters +clustery +clutch +clutched +clutches +clutching +clutchy +clutter +cluttered +cluttering +clutters +cluttery +clypeal +clypeate +clypei +clypeus +clyster +clysters +cnidarian +cnidarians +coacervate +coacervates +coacervation +coacervations +coach +coachable +coached +coacher +coachers +coaches +coaching +coachman +coachmen +coachwork +coachworks +coact +coacted +coacting +coaction +coactions +coactive +coactor +coactors +coacts +coadaptation +coadaptations +coadapted +coadjutor +coadjutors +coadjutrices +coadjutrix +coadministration +coadministrations +coadmire +coadmired +coadmires +coadmiring +coadmit +coadmits +coadmitted +coadmitting +coaeval +coaevals +coagencies +coagency +coagent +coagents +coagula +coagulabilities +coagulability +coagulable +coagulant +coagulants +coagulase +coagulases +coagulate +coagulated +coagulates +coagulating +coagulation +coagulations +coagulum +coagulums +coal +coala +coalas +coalbin +coalbins +coalbox +coalboxes +coaled +coaler +coalers +coalesce +coalesced +coalescence +coalescences +coalescent +coalesces +coalescing +coalfield +coalfields +coalfish +coalfishes +coalhole +coalholes +coalier +coaliest +coalification +coalifications +coalified +coalifies +coalify +coalifying +coaling +coalition +coalitionist +coalitionists +coalitions +coalless +coalpit +coalpits +coals +coalsack +coalsacks +coalshed +coalsheds +coaly +coalyard +coalyards +coaming +coamings +coanchor +coanchored +coanchoring +coanchors +coannex +coannexed +coannexes +coannexing +coappear +coappeared +coappearing +coappears +coapt +coaptation +coaptations +coapted +coapting +coapts +coarctation +coarctations +coarse +coarsely +coarsen +coarsened +coarseness +coarsenesses +coarsening +coarsens +coarser +coarsest +coassist +coassisted +coassisting +coassists +coassume +coassumed +coassumes +coassuming +coast +coastal +coasted +coaster +coasters +coastguard +coastguardman +coastguardmen +coastguards +coastguardsman +coastguardsmen +coasting +coastings +coastland +coastlands +coastline +coastlines +coasts +coastward +coastwards +coastwise +coat +coatdress +coatdresses +coated +coatee +coatees +coater +coaters +coati +coatimundi +coatimundis +coating +coatings +coatis +coatless +coatrack +coatracks +coatroom +coatrooms +coats +coattail +coattails +coattend +coattended +coattending +coattends +coattest +coattested +coattesting +coattests +coauthor +coauthored +coauthoring +coauthors +coauthorship +coauthorships +coax +coaxal +coaxed +coaxer +coaxers +coaxes +coaxial +coaxially +coaxing +cob +cobalamin +cobalamins +cobalt +cobaltic +cobaltine +cobaltines +cobaltite +cobaltites +cobaltous +cobalts +cobb +cobber +cobbers +cobbier +cobbiest +cobble +cobbled +cobbler +cobblers +cobbles +cobblestone +cobblestoned +cobblestones +cobbling +cobbs +cobby +cobelligerent +cobelligerents +cobia +cobias +coble +cobles +cobnut +cobnuts +cobra +cobras +cobs +cobweb +cobwebbed +cobwebbier +cobwebbiest +cobwebbing +cobwebby +cobwebs +coca +cocain +cocaine +cocaines +cocainization +cocainizations +cocainize +cocainized +cocainizes +cocainizing +cocains +cocaptain +cocaptained +cocaptaining +cocaptains +cocarboxylase +cocarboxylases +cocarcinogen +cocarcinogenic +cocarcinogens +cocas +cocatalyst +cocatalysts +coccal +cocci +coccic +coccid +coccidia +coccidioidomycoses +coccidioidomycosis +coccidioses +coccidiosis +coccidium +coccids +coccoid +coccoids +coccous +coccus +coccygeal +coccyges +coccyx +coccyxes +cochair +cochaired +cochairing +cochairman +cochairmen +cochairperson +cochairpersons +cochairs +cochairwoman +cochairwomen +cochampion +cochampions +cochin +cochineal +cochineals +cochins +cochlea +cochleae +cochlear +cochleas +cocinera +cocineras +cock +cockade +cockaded +cockades +cockalorum +cockalorums +cockamamie +cockamamy +cockapoo +cockapoos +cockatiel +cockatiels +cockatoo +cockatoos +cockatrice +cockatrices +cockbill +cockbilled +cockbilling +cockbills +cockboat +cockboats +cockchafer +cockchafers +cockcrow +cockcrows +cocked +cocker +cockered +cockerel +cockerels +cockering +cockers +cockeye +cockeyed +cockeyedly +cockeyedness +cockeyednesses +cockeyes +cockfight +cockfighting +cockfightings +cockfights +cockhorse +cockhorses +cockier +cockiest +cockily +cockiness +cockinesses +cocking +cockish +cockle +cocklebur +cockleburs +cockled +cockles +cockleshell +cockleshells +cocklike +cockling +cockloft +cocklofts +cockney +cockneyfied +cockneyfies +cockneyfy +cockneyfying +cockneyish +cockneyism +cockneyisms +cockneys +cockpit +cockpits +cockroach +cockroaches +cocks +cockscomb +cockscombs +cocksfoot +cocksfoots +cockshies +cockshut +cockshuts +cockshy +cockspur +cockspurs +cocksucker +cocksuckers +cocksure +cocksurely +cocksureness +cocksurenesses +cocktail +cocktailed +cocktailing +cocktails +cockup +cockups +cocky +coco +cocoa +cocoanut +cocoanuts +cocoas +cocobola +cocobolas +cocobolo +cocobolos +cocomat +cocomats +cocomposer +cocomposers +coconspirator +coconspirators +coconut +coconuts +cocoon +cocooned +cocooning +cocoonings +cocoons +cocos +cocotte +cocottes +cocounsel +cocounseled +cocounseling +cocounselled +cocounselling +cocounsels +cocoyam +cocoyams +cocreate +cocreated +cocreates +cocreating +cocreator +cocreators +cocultivate +cocultivated +cocultivates +cocultivating +cocultivation +cocultivations +coculture +cocultured +cocultures +coculturing +cocurator +cocurators +cocurricular +cod +coda +codable +codas +codded +codder +codders +codding +coddle +coddled +coddler +coddlers +coddles +coddling +code +codebook +codebooks +codebtor +codebtors +codec +codecs +coded +codefendant +codefendants +codeia +codeias +codein +codeina +codeinas +codeine +codeines +codeins +codeless +coden +codens +codependence +codependences +codependencies +codependency +codependent +codependents +coder +coderive +coderived +coderives +coderiving +coders +codes +codesign +codesigned +codesigning +codesigns +codetermination +codeterminations +codevelop +codeveloped +codeveloper +codevelopers +codeveloping +codevelops +codex +codfish +codfishes +codger +codgers +codices +codicil +codicillary +codicils +codicological +codicologies +codicology +codifiabilities +codifiability +codification +codifications +codified +codifier +codifiers +codifies +codify +codifying +coding +codirect +codirected +codirecting +codirection +codirections +codirector +codirectors +codirects +codiscover +codiscovered +codiscoverer +codiscoverers +codiscovering +codiscovers +codlin +codling +codlings +codlins +codominant +codominants +codon +codons +codpiece +codpieces +codrive +codriven +codriver +codrivers +codrives +codriving +codrove +cods +codswallop +codswallops +coed +coedit +coedited +coediting +coeditor +coeditors +coedits +coeds +coeducation +coeducational +coeducationally +coeducations +coeffect +coeffects +coefficient +coefficients +coelacanth +coelacanths +coelentera +coelenterate +coelenterates +coelenteron +coeliac +coelom +coelomata +coelomate +coelomates +coelome +coelomes +coelomic +coeloms +coembodied +coembodies +coembody +coembodying +coemploy +coemployed +coemploying +coemploys +coempt +coempted +coempting +coempts +coenact +coenacted +coenacting +coenacts +coenamor +coenamored +coenamoring +coenamors +coendure +coendured +coendures +coenduring +coenobite +coenobites +coenocyte +coenocytes +coenocytic +coenure +coenures +coenuri +coenurus +coenzymatic +coenzymatically +coenzyme +coenzymes +coequal +coequalities +coequality +coequally +coequals +coequate +coequated +coequates +coequating +coerce +coerced +coercer +coercers +coerces +coercible +coercing +coercion +coercions +coercive +coercively +coerciveness +coercivenesses +coercivities +coercivity +coerect +coerected +coerecting +coerects +coesite +coesites +coetaneous +coeternal +coeval +coevalities +coevality +coevally +coevals +coevolution +coevolutionary +coevolutions +coevolve +coevolved +coevolves +coevolving +coexecutor +coexecutors +coexert +coexerted +coexerting +coexerts +coexist +coexisted +coexistence +coexistences +coexistent +coexisting +coexists +coextend +coextended +coextending +coextends +coextensive +coextensively +cofactor +cofactors +cofavorite +cofavorites +cofeature +cofeatured +cofeatures +cofeaturing +coff +coffee +coffeecake +coffeecakes +coffeehouse +coffeehouses +coffeemaker +coffeemakers +coffeepot +coffeepots +coffees +coffer +cofferdam +cofferdams +coffered +coffering +coffers +coffin +coffined +coffing +coffining +coffins +coffle +coffled +coffles +coffling +coffret +coffrets +coffs +cofinance +cofinanced +cofinances +cofinancing +cofound +cofounded +cofounder +cofounders +cofounding +cofounds +coft +cofunction +cofunctions +cog +cogencies +cogency +cogeneration +cogenerations +cogenerator +cogenerators +cogent +cogently +cogged +cogging +cogitable +cogitate +cogitated +cogitates +cogitating +cogitation +cogitations +cogitative +cogito +cogitos +cognac +cognacs +cognate +cognately +cognates +cognation +cognations +cognise +cognised +cognises +cognising +cognition +cognitional +cognitions +cognitive +cognitively +cognizable +cognizably +cognizance +cognizances +cognizant +cognize +cognized +cognizer +cognizers +cognizes +cognizing +cognomen +cognomens +cognomina +cognominal +cognoscente +cognoscenti +cognoscible +cognovit +cognovits +cogon +cogons +cogs +cogway +cogways +cogwheel +cogwheels +cohabit +cohabitant +cohabitants +cohabitation +cohabitations +cohabited +cohabiting +cohabits +cohead +coheaded +coheading +coheads +coheir +coheiress +coheiresses +coheirs +cohere +cohered +coherence +coherences +coherencies +coherency +coherent +coherently +coherer +coherers +coheres +cohering +cohesion +cohesionless +cohesions +cohesive +cohesively +cohesiveness +cohesivenesses +coho +cohobate +cohobated +cohobates +cohobating +cohog +cohogs +coholder +coholders +cohomological +cohomologies +cohomology +cohort +cohorts +cohos +cohosh +cohoshes +cohost +cohosted +cohostess +cohostessed +cohostesses +cohostessing +cohosting +cohosts +cohune +cohunes +coif +coifed +coiffe +coiffed +coiffes +coiffeur +coiffeurs +coiffeuse +coiffeuses +coiffing +coiffure +coiffured +coiffures +coiffuring +coifing +coifs +coign +coigne +coigned +coignes +coigning +coigns +coil +coilabilities +coilability +coiled +coiler +coilers +coiling +coils +coin +coinable +coinage +coinages +coincide +coincided +coincidence +coincidences +coincident +coincidental +coincidentally +coincidently +coincides +coinciding +coined +coiner +coiners +coinfer +coinferred +coinferring +coinfers +coinhere +coinhered +coinheres +coinhering +coining +coinmate +coinmates +coins +coinsurance +coinsurances +coinsure +coinsured +coinsurer +coinsurers +coinsures +coinsuring +cointer +cointerred +cointerring +cointers +coinvent +coinvented +coinventing +coinventor +coinventors +coinvents +coinvestigator +coinvestigators +coinvestor +coinvestors +coir +coirs +coistrel +coistrels +coistril +coistrils +coital +coitally +coition +coitional +coitions +coitus +coituses +cojoin +cojoined +cojoining +cojoins +coke +coked +cokehead +cokeheads +cokes +coking +col +cola +colander +colanders +colas +colatitude +colatitudes +colcannon +colcannons +colchicine +colchicines +colchicum +colchicums +cold +coldblood +coldcock +coldcocked +coldcocking +coldcocks +colder +coldest +coldhearted +coldheartedly +coldheartedness +coldheartednesses +coldish +coldly +coldness +coldnesses +colds +cole +colead +coleader +coleaders +coleading +coleads +coled +colemanite +colemanites +coleoptera +coleopteran +coleopterans +coleopterist +coleopterists +coleopterous +coleoptile +coleoptiles +coleorhiza +coleorhizae +coles +coleseed +coleseeds +coleslaw +coleslaws +colessee +colessees +colessor +colessors +coleus +coleuses +colewort +coleworts +colic +colicin +colicine +colicines +colicins +colicky +colicroot +colicroots +colics +colies +coliform +coliforms +colin +colinear +colinearities +colinearity +colins +coliphage +coliphages +coliseum +coliseums +colistin +colistins +colitic +colitis +colitises +collaborate +collaborated +collaborates +collaborating +collaboration +collaborationism +collaborationisms +collaborationist +collaborationists +collaborations +collaborative +collaboratively +collaboratives +collaborator +collaborators +collage +collaged +collagen +collagenase +collagenases +collagenous +collagens +collages +collaging +collagist +collagists +collapse +collapsed +collapses +collapsibilities +collapsibility +collapsible +collapsing +collar +collarbone +collarbones +collard +collards +collared +collaret +collarets +collaring +collarless +collars +collate +collated +collateral +collateralities +collaterality +collateralize +collateralized +collateralizes +collateralizing +collaterally +collaterals +collates +collating +collation +collations +collator +collators +colleague +colleagues +colleagueship +colleagueships +collect +collectable +collectables +collectanea +collected +collectedly +collectedness +collectednesses +collectible +collectibles +collecting +collection +collections +collective +collectively +collectives +collectivise +collectivised +collectivises +collectivising +collectivism +collectivisms +collectivist +collectivistic +collectivistically +collectivists +collectivities +collectivity +collectivization +collectivizations +collectivize +collectivized +collectivizes +collectivizing +collector +collectors +collectorship +collectorships +collects +colleen +colleens +college +colleger +collegers +colleges +collegia +collegial +collegialities +collegiality +collegially +collegian +collegians +collegiate +collegiately +collegium +collegiums +collembolan +collembolans +collembolous +collenchyma +collenchymas +collenchymata +collenchymatous +collet +colleted +colleting +collets +collide +collided +collider +colliders +collides +colliding +collie +collied +collier +collieries +colliers +colliery +collies +collieshangie +collieshangies +colligate +colligated +colligates +colligating +colligation +colligations +colligative +collimate +collimated +collimates +collimating +collimation +collimations +collimator +collimators +collinear +collinearities +collinearity +collins +collinses +collision +collisional +collisionally +collisions +collocate +collocated +collocates +collocating +collocation +collocational +collocations +collodion +collodions +collogue +collogued +collogues +colloguing +colloid +colloidal +colloidally +colloids +collop +collops +colloquia +colloquial +colloquialism +colloquialisms +colloquialities +colloquiality +colloquially +colloquials +colloquies +colloquist +colloquists +colloquium +colloquiums +colloquy +collotype +collotypes +collude +colluded +colluder +colluders +colludes +colluding +collusion +collusions +collusive +collusively +colluvia +colluvial +colluvium +colluviums +colly +collying +collyria +collyrium +collyriums +collywobbles +colobi +coloboma +colobomata +colobus +colocate +colocated +colocates +colocating +colocynth +colocynths +colog +cologarithm +cologarithms +cologne +cologned +colognes +cologs +colon +colone +colonel +colonelcies +colonelcy +colonels +colones +coloni +colonial +colonialism +colonialisms +colonialist +colonialistic +colonialists +colonialize +colonialized +colonializes +colonializing +colonially +colonialness +colonialnesses +colonials +colonic +colonics +colonies +colonisation +colonisations +colonise +colonised +colonises +colonising +colonist +colonists +colonization +colonizationist +colonizationists +colonizations +colonize +colonized +colonizer +colonizers +colonizes +colonizing +colonnade +colonnaded +colonnades +colons +colonus +colony +colophon +colophonies +colophons +colophony +color +colorable +colorably +colorado +colorant +colorants +coloration +colorations +coloratura +coloraturas +colorblind +colorblindness +colorblindnesses +colorbred +colorectal +colored +coloreds +colorer +colorers +colorfast +colorfastness +colorfastnesses +colorful +colorfully +colorfulness +colorfulnesses +colorific +colorimeter +colorimeters +colorimetric +colorimetrically +colorimetries +colorimetry +coloring +colorings +colorism +colorisms +colorist +coloristic +coloristically +colorists +colorization +colorizations +colorize +colorized +colorizes +colorizing +colorless +colorlessly +colorlessness +colorlessnesses +colorman +colormen +colorpoint +colorpoints +colors +colossal +colossally +colosseum +colosseums +colossi +colossus +colossuses +colostomies +colostomy +colostral +colostrum +colostrums +colotomies +colotomy +colour +coloured +colourer +colourers +colouring +colours +colpitis +colpitises +colportage +colportages +colporteur +colporteurs +cols +colt +colter +colters +coltish +coltishly +coltishness +coltishnesses +colts +coltsfoot +coltsfoots +colubrid +colubrids +colubrine +colugo +colugos +columbaria +columbarium +columbic +columbine +columbines +columbite +columbites +columbium +columbiums +columel +columella +columellae +columellar +columels +column +columnal +columnar +columned +columniation +columniations +columnist +columnistic +columnists +columns +colure +colures +coly +colza +colzas +coma +comade +comae +comake +comaker +comakers +comakes +comaking +comal +comanage +comanaged +comanagement +comanagements +comanager +comanagers +comanages +comanaging +comas +comate +comates +comatic +comatik +comatiks +comatose +comatula +comatulae +comb +combat +combatant +combatants +combated +combater +combaters +combating +combative +combatively +combativeness +combativenesses +combats +combatted +combatting +combe +combed +comber +combers +combes +combinable +combination +combinational +combinations +combinative +combinatorial +combinatorially +combinatorics +combinatory +combine +combined +combiner +combiners +combines +combing +combings +combining +comblike +combo +combos +combs +combust +combusted +combustibilities +combustibility +combustible +combustibles +combustibly +combusting +combustion +combustions +combustive +combustor +combustors +combusts +come +comeback +comebacks +comedian +comedians +comedic +comedically +comedienne +comediennes +comedies +comedo +comedones +comedos +comedown +comedowns +comedy +comelier +comeliest +comelily +comeliness +comelinesses +comely +comember +comembers +comer +comers +comes +comestible +comestibles +comet +cometary +cometh +comether +comethers +cometic +comets +comeuppance +comeuppances +comfier +comfiest +comfit +comfits +comfort +comfortable +comfortableness +comfortablenesses +comfortably +comforted +comforter +comforters +comforting +comfortingly +comfortless +comforts +comfrey +comfreys +comfy +comic +comical +comicalities +comicality +comically +comics +coming +comingle +comingled +comingles +comingling +comings +comitia +comitial +comities +comity +comix +comma +command +commandable +commandant +commandants +commanded +commandeer +commandeered +commandeering +commandeers +commander +commanderies +commanders +commandership +commanderships +commandery +commanding +commandingly +commandment +commandments +commando +commandoes +commandos +commands +commas +commata +commemorate +commemorated +commemorates +commemorating +commemoration +commemorations +commemorative +commemoratively +commemoratives +commemorator +commemorators +commence +commenced +commencement +commencements +commencer +commencers +commences +commencing +commend +commendable +commendably +commendation +commendations +commendatory +commended +commender +commenders +commending +commends +commensal +commensalism +commensalisms +commensally +commensals +commensurabilities +commensurability +commensurable +commensurably +commensurate +commensurately +commensuration +commensurations +comment +commentaries +commentary +commentate +commentated +commentates +commentating +commentator +commentators +commented +commenting +comments +commerce +commerced +commerces +commercial +commercialise +commercialised +commercialises +commercialising +commercialism +commercialisms +commercialist +commercialistic +commercialists +commercialities +commerciality +commercialization +commercializations +commercialize +commercialized +commercializes +commercializing +commercially +commercials +commercing +commie +commies +commination +comminations +comminatory +commingle +commingled +commingles +commingling +comminute +comminuted +comminutes +comminuting +comminution +comminutions +commiserate +commiserated +commiserates +commiserating +commiseratingly +commiseration +commiserations +commiserative +commissar +commissarial +commissariat +commissariats +commissaries +commissars +commissary +commission +commissionaire +commissionaires +commissioned +commissioner +commissioners +commissionership +commissionerships +commissioning +commissions +commissural +commissure +commissures +commit +commitment +commitments +commits +committable +committal +committals +committed +committee +committeeman +committeemen +committees +committeewoman +committeewomen +committing +commix +commixed +commixes +commixing +commixt +commixture +commixtures +commode +commodes +commodification +commodifications +commodified +commodifies +commodify +commodifying +commodious +commodiously +commodiousness +commodiousnesses +commodities +commodity +commodore +commodores +common +commonage +commonages +commonalities +commonality +commonalties +commonalty +commoner +commoners +commonest +commonly +commonness +commonnesses +commonplace +commonplaceness +commonplacenesses +commonplaces +commons +commonsense +commonsensible +commonsensical +commonsensically +commonweal +commonweals +commonwealth +commonwealths +commotion +commotions +commove +commoved +commoves +commoving +communal +communalism +communalisms +communalist +communalists +communalities +communality +communalize +communalized +communalizes +communalizing +communally +communard +communards +commune +communed +communes +communicabilities +communicability +communicable +communicableness +communicablenesses +communicably +communicant +communicants +communicate +communicated +communicatee +communicatees +communicates +communicating +communication +communicational +communications +communicative +communicatively +communicativeness +communicativenesses +communicator +communicators +communicatory +communing +communion +communions +communique +communiques +communise +communised +communises +communising +communism +communisms +communist +communistic +communistically +communists +communitarian +communitarianism +communitarianisms +communitarians +communities +community +communization +communizations +communize +communized +communizes +communizing +commutable +commutate +commutated +commutates +commutating +commutation +commutations +commutative +commutativities +commutativity +commutator +commutators +commute +commuted +commuter +commuters +commutes +commuting +commy +comonomer +comonomers +comose +comous +comp +compact +compacted +compacter +compacters +compactest +compactible +compacting +compaction +compactions +compactly +compactness +compactnesses +compactor +compactors +compacts +compadre +compadres +companied +companies +companion +companionabilities +companionability +companionable +companionableness +companionablenesses +companionably +companionate +companioned +companioning +companions +companionship +companionships +companionway +companionways +company +companying +comparabilities +comparability +comparable +comparableness +comparablenesses +comparably +comparatist +comparatists +comparative +comparatively +comparativeness +comparativenesses +comparatives +comparativist +comparativists +comparator +comparators +compare +compared +comparer +comparers +compares +comparing +comparison +comparisons +compart +comparted +comparting +compartment +compartmental +compartmentalise +compartmentalised +compartmentalises +compartmentalising +compartmentalization +compartmentalizations +compartmentalize +compartmentalized +compartmentalizes +compartmentalizing +compartmentation +compartmentations +compartmented +compartmenting +compartments +comparts +compass +compassable +compassed +compasses +compassing +compassion +compassionate +compassionated +compassionately +compassionateness +compassionatenesses +compassionates +compassionating +compassionless +compassions +compatibilities +compatibility +compatible +compatibleness +compatiblenesses +compatibles +compatibly +compatriot +compatriotic +compatriots +comped +compeer +compeered +compeering +compeers +compel +compellable +compellation +compellations +compelled +compelling +compellingly +compels +compend +compendia +compendious +compendiously +compendiousness +compendiousnesses +compendium +compendiums +compends +compensabilities +compensability +compensable +compensate +compensated +compensates +compensating +compensation +compensational +compensations +compensative +compensator +compensators +compensatory +compere +compered +comperes +compering +compete +competed +competence +competences +competencies +competency +competent +competently +competes +competing +competition +competitions +competitive +competitively +competitiveness +competitivenesses +competitor +competitors +compilation +compilations +compile +compiled +compiler +compilers +compiles +compiling +comping +complacence +complacences +complacencies +complacency +complacent +complacently +complain +complainant +complainants +complained +complainer +complainers +complaining +complainingly +complains +complaint +complaints +complaisance +complaisances +complaisant +complaisantly +compleat +complect +complected +complecting +complects +complement +complemental +complementaries +complementarily +complementariness +complementarinesses +complementarities +complementarity +complementary +complementation +complementations +complemented +complementing +complementizer +complementizers +complements +complete +completed +completely +completeness +completenesses +completer +completes +completest +completing +completion +completions +completist +completists +completive +complex +complexation +complexations +complexed +complexer +complexes +complexest +complexified +complexifies +complexify +complexifying +complexing +complexion +complexional +complexioned +complexions +complexities +complexity +complexly +complexness +complexnesses +compliance +compliances +compliancies +compliancy +compliant +compliantly +complicacies +complicacy +complicate +complicated +complicatedly +complicatedness +complicatednesses +complicates +complicating +complication +complications +complice +complices +complicit +complicities +complicitous +complicity +complied +complier +compliers +complies +compliment +complimentarily +complimentary +complimented +complimenting +compliments +complin +compline +complines +complins +complot +complots +complotted +complotting +comply +complying +compo +compone +component +componential +components +compony +comport +comported +comporting +comportment +comportments +comports +compos +compose +composed +composedly +composedness +composednesses +composer +composers +composes +composing +composite +composited +compositely +composites +compositing +composition +compositional +compositionally +compositions +compositor +compositors +compost +composted +composting +composts +composure +composures +compote +compotes +compound +compoundable +compounded +compounder +compounders +compounding +compounds +comprador +compradore +compradores +compradors +comprehend +comprehended +comprehendible +comprehending +comprehends +comprehensibilities +comprehensibility +comprehensible +comprehensibleness +comprehensiblenesses +comprehensibly +comprehension +comprehensions +comprehensive +comprehensively +comprehensiveness +comprehensivenesses +compress +compressed +compressedly +compresses +compressibilities +compressibility +compressible +compressing +compression +compressional +compressions +compressive +compressively +compressor +compressors +comprise +comprised +comprises +comprising +comprize +comprized +comprizes +comprizing +compromise +compromised +compromiser +compromisers +compromises +compromising +comps +compt +compted +compting +comptroller +comptrollers +comptrollership +comptrollerships +compts +compulsion +compulsions +compulsive +compulsively +compulsiveness +compulsivenesses +compulsivities +compulsivity +compulsorily +compulsory +compunction +compunctions +compunctious +compurgation +compurgations +compurgator +compurgators +computabilities +computability +computable +computation +computational +computationally +computations +compute +computed +computer +computerdom +computerdoms +computerese +computereses +computerise +computerised +computerises +computerising +computerist +computerists +computerizable +computerization +computerizations +computerize +computerized +computerizes +computerizing +computerless +computerlike +computernik +computerniks +computerphobe +computerphobes +computerphobia +computerphobias +computerphobic +computers +computes +computing +comrade +comradeliness +comradelinesses +comradely +comraderies +comradery +comrades +comradeship +comradeships +comsymp +comsymps +comte +comtes +con +conation +conations +conative +conatus +concanavalin +concanavalins +concatenate +concatenated +concatenates +concatenating +concatenation +concatenations +concave +concaved +concaves +concaving +concavities +concavity +conceal +concealable +concealed +concealer +concealers +concealing +concealingly +concealment +concealments +conceals +concede +conceded +concededly +conceder +conceders +concedes +conceding +conceit +conceited +conceitedly +conceitedness +conceitednesses +conceiting +conceits +conceivabilities +conceivability +conceivable +conceivableness +conceivablenesses +conceivably +conceive +conceived +conceiver +conceivers +conceives +conceiving +concelebrant +concelebrants +concelebrate +concelebrated +concelebrates +concelebrating +concelebration +concelebrations +concent +concenter +concentered +concentering +concenters +concentrate +concentrated +concentratedly +concentrates +concentrating +concentration +concentrations +concentrative +concentrator +concentrators +concentric +concentrically +concentricities +concentricity +concents +concept +conceptacle +conceptacles +conception +conceptional +conceptions +conceptive +concepts +conceptual +conceptualise +conceptualised +conceptualises +conceptualising +conceptualism +conceptualisms +conceptualist +conceptualistic +conceptualistically +conceptualists +conceptualities +conceptuality +conceptualization +conceptualizations +conceptualize +conceptualized +conceptualizer +conceptualizers +conceptualizes +conceptualizing +conceptually +conceptus +conceptuses +concern +concerned +concerning +concernment +concernments +concerns +concert +concerted +concertedly +concertedness +concertednesses +concertgoer +concertgoers +concertgoing +concertgoings +concerti +concertina +concertinas +concerting +concertino +concertinos +concertize +concertized +concertizes +concertizing +concertmaster +concertmasters +concertmeister +concertmeisters +concerto +concertos +concerts +concession +concessionaire +concessionaires +concessional +concessionary +concessioner +concessioners +concessions +concessive +concessively +conch +concha +conchae +conchal +conches +conchie +conchies +conchoid +conchoidal +conchoidally +conchoids +conchologies +conchologist +conchologists +conchology +conchs +conchy +concierge +concierges +conciliar +conciliarly +conciliate +conciliated +conciliates +conciliating +conciliation +conciliations +conciliative +conciliator +conciliators +conciliatory +concinnities +concinnity +concise +concisely +conciseness +concisenesses +conciser +concisest +concision +concisions +conclave +conclaves +conclude +concluded +concluder +concluders +concludes +concluding +conclusion +conclusionary +conclusions +conclusive +conclusively +conclusiveness +conclusivenesses +conclusory +concoct +concocted +concocter +concocters +concocting +concoction +concoctions +concoctive +concocts +concomitance +concomitances +concomitant +concomitantly +concomitants +concord +concordance +concordances +concordant +concordantly +concordat +concordats +concords +concourse +concourses +concrescence +concrescences +concrescent +concrete +concreted +concretely +concreteness +concretenesses +concretes +concreting +concretion +concretionary +concretions +concretism +concretisms +concretist +concretists +concretization +concretizations +concretize +concretized +concretizes +concretizing +concubinage +concubinages +concubine +concubines +concupiscence +concupiscences +concupiscent +concupiscible +concur +concurred +concurrence +concurrences +concurrencies +concurrency +concurrent +concurrently +concurrents +concurring +concurs +concuss +concussed +concusses +concussing +concussion +concussions +concussive +condemn +condemnable +condemnation +condemnations +condemnatory +condemned +condemner +condemners +condemning +condemnor +condemnors +condemns +condensable +condensate +condensates +condensation +condensational +condensations +condense +condensed +condenser +condensers +condenses +condensible +condensing +condescend +condescended +condescendence +condescendences +condescending +condescendingly +condescends +condescension +condescensions +condign +condignly +condiment +condimental +condiments +condition +conditionable +conditional +conditionalities +conditionality +conditionally +conditionals +conditioned +conditioner +conditioners +conditioning +conditions +condo +condoes +condolatory +condole +condoled +condolence +condolences +condoler +condolers +condoles +condoling +condom +condominium +condominiums +condoms +condonable +condonation +condonations +condone +condoned +condoner +condoners +condones +condoning +condor +condores +condors +condos +condottiere +condottieri +conduce +conduced +conducer +conducers +conduces +conducing +conducive +conduciveness +conducivenesses +conduct +conductance +conductances +conducted +conductibilities +conductibility +conductible +conductimetric +conducting +conduction +conductions +conductive +conductivities +conductivity +conductometric +conductor +conductorial +conductors +conductress +conductresses +conducts +conduit +conduits +conduplicate +condylar +condyle +condyles +condyloid +condyloma +condylomas +condylomata +condylomatous +cone +coned +coneflower +coneflowers +conelrad +conelrads +conenose +conenoses +conepate +conepates +conepatl +conepatls +cones +coney +coneys +confab +confabbed +confabbing +confabs +confabulate +confabulated +confabulates +confabulating +confabulation +confabulations +confabulator +confabulators +confabulatory +confect +confected +confecting +confection +confectionaries +confectionary +confectioner +confectioneries +confectioners +confectionery +confections +confects +confederacies +confederacy +confederal +confederate +confederated +confederates +confederating +confederation +confederations +confederative +confer +conferee +conferees +conference +conferences +conferencing +conferencings +conferential +conferment +conferments +conferrable +conferral +conferrals +conferred +conferrence +conferrences +conferrer +conferrers +conferring +confers +conferva +confervae +confervas +confess +confessable +confessed +confessedly +confesses +confessing +confession +confessional +confessionalism +confessionalisms +confessionalist +confessionalists +confessionally +confessionals +confessions +confessor +confessors +confetti +confetto +confidant +confidante +confidantes +confidants +confide +confided +confidence +confidences +confident +confidential +confidentialities +confidentiality +confidentially +confidently +confider +confiders +confides +confiding +confidingly +confidingness +confidingnesses +configuration +configurational +configurationally +configurations +configurative +configure +configured +configures +configuring +confine +confined +confinement +confinements +confiner +confiners +confines +confining +confirm +confirmabilities +confirmability +confirmable +confirmand +confirmands +confirmation +confirmational +confirmations +confirmatory +confirmed +confirmedly +confirmedness +confirmednesses +confirming +confirms +confiscable +confiscatable +confiscate +confiscated +confiscates +confiscating +confiscation +confiscations +confiscator +confiscators +confiscatory +confit +confiteor +confiteors +confits +confiture +confitures +conflagrant +conflagration +conflagrations +conflate +conflated +conflates +conflating +conflation +conflations +conflict +conflicted +conflictful +conflicting +conflictingly +confliction +conflictions +conflictive +conflicts +conflictual +confluence +confluences +confluent +confluents +conflux +confluxes +confocal +confocally +conform +conformable +conformably +conformal +conformance +conformances +conformation +conformational +conformations +conformed +conformer +conformers +conforming +conformism +conformisms +conformist +conformists +conformities +conformity +conforms +confound +confounded +confoundedly +confounder +confounders +confounding +confoundingly +confounds +confraternities +confraternity +confrere +confreres +confront +confrontal +confrontals +confrontation +confrontational +confrontationist +confrontationists +confrontations +confronted +confronter +confronters +confronting +confronts +confuse +confused +confusedly +confusedness +confusednesses +confuses +confusing +confusingly +confusion +confusional +confusions +confutation +confutations +confutative +confute +confuted +confuter +confuters +confutes +confuting +conga +congaed +congaing +congas +conge +congeal +congealed +congealing +congealment +congealments +congeals +congee +congeed +congeeing +congees +congelation +congelations +congener +congeneric +congenerous +congeners +congenial +congenialities +congeniality +congenially +congenital +congenitally +conger +congeries +congers +conges +congest +congested +congesting +congestion +congestions +congestive +congests +congii +congius +conglobate +conglobated +conglobates +conglobating +conglobation +conglobations +conglobe +conglobed +conglobes +conglobing +conglomerate +conglomerated +conglomerates +conglomerateur +conglomerateurs +conglomeratic +conglomerating +conglomeration +conglomerations +conglomerative +conglomerator +conglomerators +conglutinate +conglutinated +conglutinates +conglutinating +conglutination +conglutinations +congo +congoes +congos +congou +congous +congrats +congratulate +congratulated +congratulates +congratulating +congratulation +congratulations +congratulator +congratulators +congratulatory +congregant +congregants +congregate +congregated +congregates +congregating +congregation +congregational +congregationalism +congregationalisms +congregationalist +congregationalists +congregations +congregator +congregators +congress +congressed +congresses +congressing +congressional +congressionally +congressman +congressmen +congresspeople +congressperson +congresspersons +congresswoman +congresswomen +congruence +congruences +congruencies +congruency +congruent +congruently +congruities +congruity +congruous +congruously +congruousness +congruousnesses +coni +conic +conical +conically +conicities +conicity +conics +conidia +conidial +conidian +conidiophore +conidiophores +conidium +conies +conifer +coniferous +conifers +coniine +coniines +conin +conine +conines +coning +conins +conioses +coniosis +conium +coniums +conjectural +conjecturally +conjecture +conjectured +conjecturer +conjecturers +conjectures +conjecturing +conjoin +conjoined +conjoining +conjoins +conjoint +conjointly +conjugal +conjugalities +conjugality +conjugally +conjugant +conjugants +conjugate +conjugated +conjugately +conjugateness +conjugatenesses +conjugates +conjugating +conjugation +conjugational +conjugationally +conjugations +conjunct +conjunction +conjunctional +conjunctionally +conjunctions +conjunctiva +conjunctivae +conjunctival +conjunctivas +conjunctive +conjunctively +conjunctives +conjunctivites +conjunctivitides +conjunctivitis +conjunctivitises +conjuncts +conjuncture +conjunctures +conjuration +conjurations +conjure +conjured +conjurer +conjurers +conjures +conjuring +conjuror +conjurors +conk +conked +conker +conkers +conking +conks +conky +conn +connate +connately +connatural +connaturalities +connaturality +connaturally +connect +connectable +connected +connectedly +connectedness +connectednesses +connecter +connecters +connectible +connecting +connection +connectional +connections +connective +connectively +connectives +connectivities +connectivity +connector +connectors +connects +conned +conner +conners +connexion +connexions +conning +conniption +conniptions +connivance +connivances +connive +connived +connivent +conniver +connivers +connives +conniving +connoisseur +connoisseurs +connoisseurship +connoisseurships +connotation +connotational +connotations +connotative +connotatively +connote +connoted +connotes +connoting +conns +connubial +connubialism +connubialisms +connubialities +connubiality +connubially +conodont +conodonts +conoid +conoidal +conoids +conominee +conominees +conquer +conquered +conquering +conqueror +conquerors +conquers +conquest +conquests +conquian +conquians +conquistador +conquistadores +conquistadors +cons +consanguine +consanguineous +consanguineously +consanguinities +consanguinity +conscience +conscienceless +consciences +conscientious +conscientiously +conscientiousness +conscientiousnesses +conscionable +conscious +consciouses +consciously +consciousness +consciousnesses +conscribe +conscribed +conscribes +conscribing +conscript +conscripted +conscripting +conscription +conscriptions +conscripts +consecrate +consecrated +consecrates +consecrating +consecration +consecrations +consecrative +consecrator +consecrators +consecratory +consecution +consecutions +consecutive +consecutively +consecutiveness +consecutivenesses +consensual +consensually +consensus +consensuses +consent +consentaneous +consentaneously +consented +consenter +consenters +consenting +consentingly +consents +consequence +consequences +consequent +consequential +consequentialities +consequentiality +consequentially +consequentialness +consequentialnesses +consequently +consequents +conservancies +conservancy +conservation +conservational +conservationist +conservationists +conservations +conservatism +conservatisms +conservative +conservatively +conservativeness +conservativenesses +conservatives +conservatize +conservatized +conservatizes +conservatizing +conservatoire +conservatoires +conservator +conservatorial +conservatories +conservators +conservatorship +conservatorships +conservatory +conserve +conserved +conserver +conservers +conserves +conserving +consider +considerable +considerables +considerably +considerate +considerately +considerateness +consideratenesses +consideration +considerations +considered +considering +considers +consigliere +consiglieri +consign +consignable +consignation +consignations +consigned +consignee +consignees +consigning +consignment +consignments +consignor +consignors +consigns +consist +consisted +consistence +consistences +consistencies +consistency +consistent +consistently +consisting +consistorial +consistories +consistory +consists +consociate +consociated +consociates +consociating +consociation +consociational +consociations +consol +consolation +consolations +consolatory +console +consoled +consoler +consolers +consoles +consolidate +consolidated +consolidates +consolidating +consolidation +consolidations +consolidator +consolidators +consoling +consolingly +consols +consomme +consommes +consonance +consonances +consonancies +consonancy +consonant +consonantal +consonantly +consonants +consort +consorted +consortia +consorting +consortium +consortiums +consorts +conspecific +conspecifics +conspectus +conspectuses +conspicuities +conspicuity +conspicuous +conspicuously +conspicuousness +conspicuousnesses +conspiracies +conspiracy +conspiration +conspirational +conspirations +conspirator +conspiratorial +conspiratorially +conspirators +conspire +conspired +conspires +conspiring +constable +constables +constabularies +constabulary +constancies +constancy +constant +constantan +constantans +constantly +constants +constative +constatives +constellate +constellated +constellates +constellating +constellation +constellations +constellatory +consternate +consternated +consternates +consternating +consternation +consternations +constipate +constipated +constipates +constipating +constipation +constipations +constituencies +constituency +constituent +constituently +constituents +constitute +constituted +constitutes +constituting +constitution +constitutional +constitutionalism +constitutionalisms +constitutionalist +constitutionalists +constitutionalities +constitutionality +constitutionalization +constitutionalizations +constitutionalize +constitutionalized +constitutionalizes +constitutionalizing +constitutionally +constitutionals +constitutionless +constitutions +constitutive +constitutively +constrain +constrained +constrainedly +constraining +constrains +constraint +constraints +constrict +constricted +constricting +constriction +constrictions +constrictive +constrictor +constrictors +constricts +constringe +constringed +constringent +constringes +constringing +construable +construct +constructed +constructible +constructing +construction +constructional +constructionally +constructionist +constructionists +constructions +constructive +constructively +constructiveness +constructivenesses +constructivism +constructivisms +constructivist +constructivists +constructor +constructors +constructs +construe +construed +construes +construing +consubstantial +consubstantiation +consubstantiations +consuetude +consuetudes +consuetudinary +consul +consular +consulate +consulates +consuls +consulship +consulships +consult +consultancies +consultancy +consultant +consultants +consultantship +consultantships +consultation +consultations +consultative +consulted +consulter +consulters +consulting +consultive +consultor +consultors +consults +consumable +consumables +consume +consumed +consumedly +consumer +consumerism +consumerisms +consumerist +consumeristic +consumerists +consumers +consumership +consumerships +consumes +consuming +consummate +consummated +consummately +consummates +consummating +consummation +consummations +consummative +consummator +consummators +consummatory +consumption +consumptions +consumptive +consumptively +consumptives +contact +contacted +contacting +contacts +contagia +contagion +contagions +contagious +contagiously +contagiousness +contagiousnesses +contagium +contain +containable +contained +container +containerboard +containerboards +containerisation +containerisations +containerise +containerised +containerises +containerising +containerization +containerizations +containerize +containerized +containerizes +containerizing +containerless +containerport +containerports +containers +containership +containerships +containing +containment +containments +contains +contaminant +contaminants +contaminate +contaminated +contaminates +contaminating +contamination +contaminations +contaminative +contaminator +contaminators +conte +contemn +contemned +contemner +contemners +contemning +contemnor +contemnors +contemns +contemplate +contemplated +contemplates +contemplating +contemplation +contemplations +contemplative +contemplatively +contemplativeness +contemplativenesses +contemplatives +contemplator +contemplators +contemporaneities +contemporaneity +contemporaneous +contemporaneously +contemporaneousness +contemporaneousnesses +contemporaries +contemporarily +contemporary +contemporize +contemporized +contemporizes +contemporizing +contempt +contemptibilities +contemptibility +contemptible +contemptibleness +contemptiblenesses +contemptibly +contempts +contemptuous +contemptuously +contemptuousness +contemptuousnesses +contend +contended +contender +contenders +contending +contends +content +contented +contentedly +contentedness +contentednesses +contenting +contention +contentions +contentious +contentiously +contentiousness +contentiousnesses +contentment +contentments +contents +conterminous +conterminously +contes +contest +contestable +contestant +contestants +contestation +contestations +contested +contester +contesters +contesting +contests +context +contextless +contexts +contextual +contextualize +contextualized +contextualizes +contextualizing +contextually +contexture +contextures +contiguities +contiguity +contiguous +contiguously +contiguousness +contiguousnesses +continence +continences +continent +continental +continentally +continentals +continently +continents +contingence +contingences +contingencies +contingency +contingent +contingently +contingents +continua +continual +continually +continuance +continuances +continuant +continuants +continuate +continuation +continuations +continuative +continuator +continuators +continue +continued +continuer +continuers +continues +continuing +continuingly +continuities +continuity +continuo +continuos +continuous +continuously +continuousness +continuousnesses +continuum +continuums +conto +contort +contorted +contorting +contortion +contortionist +contortionistic +contortionists +contortions +contortive +contorts +contos +contour +contoured +contouring +contours +contra +contraband +contrabandist +contrabandists +contrabands +contrabass +contrabasses +contrabassist +contrabassists +contrabassoon +contrabassoons +contraception +contraceptions +contraceptive +contraceptives +contract +contracted +contractibilities +contractibility +contractible +contractile +contractilities +contractility +contracting +contraction +contractional +contractionary +contractions +contractive +contractor +contractors +contracts +contractual +contractually +contracture +contractures +contradict +contradictable +contradicted +contradicting +contradiction +contradictions +contradictious +contradictor +contradictories +contradictorily +contradictoriness +contradictorinesses +contradictors +contradictory +contradicts +contradistinction +contradistinctions +contradistinctive +contradistinctively +contradistinguish +contradistinguished +contradistinguishes +contradistinguishing +contrail +contrails +contraindicate +contraindicated +contraindicates +contraindicating +contraindication +contraindications +contralateral +contralto +contraltos +contraoctave +contraoctaves +contraposition +contrapositions +contrapositive +contrapositives +contraption +contraptions +contrapuntal +contrapuntally +contrapuntist +contrapuntists +contrarian +contrarians +contraries +contrarieties +contrariety +contrarily +contrariness +contrarinesses +contrarious +contrariwise +contrary +contras +contrast +contrastable +contrasted +contrasting +contrastive +contrastively +contrasts +contrasty +contravene +contravened +contravener +contraveners +contravenes +contravening +contravention +contraventions +contredanse +contredanses +contretemps +contribute +contributed +contributes +contributing +contribution +contributions +contributive +contributively +contributor +contributors +contributory +contrite +contritely +contriteness +contritenesses +contrition +contritions +contrivance +contrivances +contrive +contrived +contriver +contrivers +contrives +contriving +control +controllabilities +controllability +controllable +controlled +controller +controllers +controllership +controllerships +controlling +controlment +controlments +controls +controversial +controversialism +controversialisms +controversialist +controversialists +controversially +controversies +controversy +controvert +controverted +controverter +controverters +controvertible +controverting +controverts +contumacies +contumacious +contumaciously +contumacy +contumelies +contumelious +contumeliously +contumely +contuse +contused +contuses +contusing +contusion +contusions +conundrum +conundrums +conurbation +conurbations +conus +convalesce +convalesced +convalescence +convalescences +convalescent +convalescents +convalesces +convalescing +convect +convected +convecting +convection +convectional +convections +convective +convector +convectors +convects +convene +convened +convener +conveners +convenes +convenience +conveniences +conveniencies +conveniency +convenient +conveniently +convening +convenor +convenors +convent +convented +conventicle +conventicler +conventiclers +conventicles +conventing +convention +conventional +conventionalism +conventionalisms +conventionalist +conventionalists +conventionalities +conventionality +conventionalization +conventionalizations +conventionalize +conventionalized +conventionalizes +conventionalizing +conventionally +conventioneer +conventioneers +conventions +convents +conventual +conventually +conventuals +converge +converged +convergence +convergences +convergencies +convergency +convergent +converges +converging +conversable +conversance +conversances +conversancies +conversancy +conversant +conversation +conversational +conversationalist +conversationalists +conversationally +conversations +conversazione +conversaziones +conversazioni +converse +conversed +conversely +converser +conversers +converses +conversing +conversion +conversional +conversions +convert +convertaplane +convertaplanes +converted +converter +converters +convertibilities +convertibility +convertible +convertibleness +convertiblenesses +convertibles +convertibly +converting +convertiplane +convertiplanes +convertor +convertors +converts +convex +convexes +convexities +convexity +convexly +convey +conveyance +conveyancer +conveyancers +conveyances +conveyancing +conveyancings +conveyed +conveyer +conveyers +conveying +conveyor +conveyorise +conveyorised +conveyorises +conveyorising +conveyorization +conveyorizations +conveyorize +conveyorized +conveyorizes +conveyorizing +conveyors +conveys +convict +convicted +convicting +conviction +convictions +convicts +convince +convinced +convincer +convincers +convinces +convincing +convincingly +convincingness +convincingnesses +convivial +convivialities +conviviality +convivially +convocation +convocational +convocations +convoke +convoked +convoker +convokers +convokes +convoking +convolute +convoluted +convolutes +convoluting +convolution +convolutions +convolve +convolved +convolves +convolving +convolvuli +convolvulus +convolvuluses +convoy +convoyed +convoying +convoys +convulsant +convulsants +convulse +convulsed +convulses +convulsing +convulsion +convulsionary +convulsions +convulsive +convulsively +convulsiveness +convulsivenesses +cony +coo +cooch +cooches +coocoo +cooed +cooee +cooeed +cooeeing +cooees +cooer +cooers +cooey +cooeyed +cooeying +cooeys +coof +coofs +cooing +cooingly +cook +cookable +cookbook +cookbooks +cooked +cooker +cookeries +cookers +cookery +cookey +cookeys +cookhouse +cookhouses +cookie +cookies +cooking +cookings +cookless +cookout +cookouts +cooks +cookshack +cookshacks +cookshop +cookshops +cookstove +cookstoves +cooktop +cooktops +cookware +cookwares +cooky +cool +coolant +coolants +cooldown +cooldowns +cooled +cooler +coolers +coolest +coolheaded +coolie +coolies +cooling +coolish +coolly +coolness +coolnesses +cools +coolth +coolths +cooly +coomb +coombe +coombes +coombs +coon +cooncan +cooncans +coonhound +coonhounds +coons +coonskin +coonskins +coontie +coonties +coop +cooped +cooper +cooperage +cooperages +cooperate +cooperated +cooperates +cooperating +cooperation +cooperationist +cooperationists +cooperations +cooperative +cooperatively +cooperativeness +cooperativenesses +cooperatives +cooperator +cooperators +coopered +cooperies +coopering +coopers +coopery +cooping +coops +coopt +coopted +coopting +cooption +cooptions +coopts +coordinate +coordinated +coordinately +coordinateness +coordinatenesses +coordinates +coordinating +coordination +coordinations +coordinative +coordinator +coordinators +coos +coot +cooter +cooters +cootie +cooties +coots +cop +copacetic +copaiba +copaibas +copal +copalm +copalms +copals +coparcenaries +coparcenary +coparcener +coparceners +coparent +coparents +copartner +copartnered +copartnering +copartners +copartnership +copartnerships +copasetic +copastor +copastors +copatron +copatrons +copayment +copayments +cope +copeck +copecks +coped +copemate +copemates +copen +copens +copepod +copepods +coper +copers +copes +copesetic +copestone +copestones +copied +copier +copiers +copies +copihue +copihues +copilot +copilots +coping +copings +copingstone +copingstones +copious +copiously +copiousness +copiousnesses +coplanar +coplanarities +coplanarity +coplot +coplots +coplotted +coplotting +copolymer +copolymeric +copolymerization +copolymerizations +copolymerize +copolymerized +copolymerizes +copolymerizing +copolymers +copped +copper +copperah +copperahs +copperas +copperases +coppered +copperhead +copperheads +coppering +copperplate +copperplates +coppers +coppersmith +coppersmiths +coppery +coppice +coppiced +coppices +coppicing +copping +coppra +coppras +copra +coprah +coprahs +copras +copremia +copremias +copremic +copresent +copresented +copresenting +copresents +copresident +copresidents +coprince +coprinces +coprincipal +coprincipals +coprisoner +coprisoners +coprocessing +coprocessings +coprocessor +coprocessors +coproduce +coproduced +coproducer +coproducers +coproduces +coproducing +coproduct +coproduction +coproductions +coproducts +coprolite +coprolites +coprolitic +copromoter +copromoters +coprophagies +coprophagous +coprophagy +coprophilia +coprophiliac +coprophiliacs +coprophilias +coprophilous +coproprietor +coproprietors +coproprietorship +coproprietorships +coprosperities +coprosperity +cops +copse +copses +copter +copters +copublish +copublished +copublisher +copublishers +copublishes +copublishing +copula +copulae +copular +copulas +copulate +copulated +copulates +copulating +copulation +copulations +copulative +copulatives +copulatory +copurified +copurifies +copurify +copurifying +copy +copybook +copybooks +copyboy +copyboys +copycat +copycats +copycatted +copycatting +copydesk +copydesks +copyedit +copyedited +copyediting +copyedits +copyhold +copyholder +copyholders +copyholds +copying +copyist +copyists +copyread +copyreader +copyreaders +copyreading +copyreads +copyright +copyrightable +copyrighted +copyrighting +copyrights +copywriter +copywriters +coquet +coquetries +coquetry +coquets +coquette +coquetted +coquettes +coquetting +coquettish +coquettishly +coquettishness +coquettishnesses +coquille +coquilles +coquina +coquinas +coquito +coquitos +cor +coracle +coracles +coracoid +coracoids +coral +coralbells +coralberries +coralberry +coralline +corallines +coralloid +corals +coranto +corantoes +corantos +corban +corbans +corbeil +corbeille +corbeilles +corbeils +corbel +corbeled +corbeling +corbelings +corbelled +corbelling +corbels +corbicula +corbiculae +corbie +corbies +corbina +corbinas +corby +cord +cordage +cordages +cordate +cordately +corded +cordelle +cordelled +cordelles +cordelling +corder +corders +cordgrass +cordgrasses +cordial +cordialities +cordiality +cordially +cordialness +cordialnesses +cordials +cordierite +cordierites +cordiform +cordillera +cordilleran +cordilleras +cording +cordings +cordite +cordites +cordless +cordlike +cordoba +cordobas +cordon +cordoned +cordoning +cordons +cordovan +cordovans +cords +corduroy +corduroyed +corduroying +corduroys +cordwain +cordwainer +cordwaineries +cordwainers +cordwainery +cordwains +cordwood +cordwoods +core +corecipient +corecipients +cored +coredeem +coredeemed +coredeeming +coredeems +coreign +coreigns +corelate +corelated +corelates +corelating +coreless +coreligionist +coreligionists +coremia +coremium +coreopsis +corepressor +corepressors +corequisite +corequisites +corer +corers +cores +coresearcher +coresearchers +coresident +coresidential +coresidents +corespondent +corespondents +corf +corgi +corgis +coria +coriaceous +coriander +corianders +coring +corium +cork +corkage +corkages +corkboard +corkboards +corked +corker +corkers +corkier +corkiest +corkiness +corkinesses +corking +corklike +corks +corkscrew +corkscrewed +corkscrewing +corkscrews +corkwood +corkwoods +corky +corm +cormel +cormels +cormlike +cormoid +cormorant +cormorants +cormous +corms +corn +cornball +cornballs +cornbread +cornbreads +corncake +corncakes +corncob +corncobs +corncrake +corncrakes +corncrib +corncribs +cornea +corneal +corneas +corned +cornel +cornelian +cornelians +cornels +corneous +corner +cornerback +cornerbacks +cornered +cornering +cornerman +cornermen +corners +cornerstone +cornerstones +cornerways +cornerwise +cornet +cornetcies +cornetcy +cornetist +cornetists +cornets +cornettist +cornettists +cornfed +cornfield +cornfields +cornflakes +cornflower +cornflowers +cornhusk +cornhusker +cornhuskers +cornhusking +cornhuskings +cornhusks +cornice +corniced +cornices +corniche +corniches +cornicing +cornicle +cornicles +cornier +corniest +cornification +cornifications +cornily +corniness +corninesses +corning +cornmeal +cornmeals +cornpone +cornpones +cornrow +cornrowed +cornrowing +cornrows +corns +cornstalk +cornstalks +cornstarch +cornstarches +cornu +cornua +cornual +cornucopia +cornucopian +cornucopias +cornus +cornuses +cornute +cornuted +cornuto +cornutos +corny +corodies +corody +corolla +corollaries +corollary +corollas +corollate +coromandel +coromandels +corona +coronach +coronachs +coronae +coronagraph +coronagraphs +coronal +coronals +coronaries +coronary +coronas +coronate +coronated +coronates +coronating +coronation +coronations +coronel +coronels +coroner +coroners +coronet +coronets +coronograph +coronographs +coronoid +corotate +corotated +corotates +corotating +corotation +corotations +corpora +corporal +corporalities +corporality +corporally +corporals +corporate +corporately +corporation +corporations +corporatism +corporatisms +corporatist +corporative +corporativism +corporativisms +corporator +corporators +corporeal +corporealities +corporeality +corporeally +corporealness +corporealnesses +corporeities +corporeity +corposant +corposants +corps +corpse +corpses +corpsman +corpsmen +corpulence +corpulences +corpulencies +corpulency +corpulent +corpulently +corpus +corpuscle +corpuscles +corpuscular +corrade +corraded +corrades +corrading +corral +corralled +corralling +corrals +corrasion +corrasions +corrasive +correct +correctable +corrected +correcter +correctest +correcting +correction +correctional +corrections +correctitude +correctitudes +corrective +correctively +correctives +correctly +correctness +correctnesses +corrector +correctors +corrects +correlatable +correlate +correlated +correlates +correlating +correlation +correlational +correlations +correlative +correlatively +correlatives +correlator +correlators +correspond +corresponded +correspondence +correspondences +correspondencies +correspondency +correspondent +correspondents +corresponding +correspondingly +corresponds +corresponsive +corrida +corridas +corridor +corridors +corrie +corries +corrigenda +corrigendum +corrigibilities +corrigibility +corrigible +corrival +corrivals +corroborant +corroborate +corroborated +corroborates +corroborating +corroboration +corroborations +corroborative +corroborator +corroborators +corroboratory +corroboree +corroborees +corrode +corroded +corrodes +corrodible +corrodies +corroding +corrody +corrosion +corrosions +corrosive +corrosively +corrosiveness +corrosivenesses +corrosives +corrugate +corrugated +corrugates +corrugating +corrugation +corrugations +corrupt +corrupted +corrupter +corrupters +corruptest +corruptibilities +corruptibility +corruptible +corruptibly +corrupting +corruption +corruptionist +corruptionists +corruptions +corruptive +corruptively +corruptly +corruptness +corruptnesses +corruptor +corruptors +corrupts +corsac +corsacs +corsage +corsages +corsair +corsairs +corse +corselet +corselets +corselette +corselettes +corses +corset +corseted +corsetiere +corsetieres +corseting +corsetries +corsetry +corsets +corslet +corslets +cortege +corteges +cortex +cortexes +cortical +cortically +cortices +corticoid +corticoids +corticosteroid +corticosteroids +corticosterone +corticosterones +corticotrophin +corticotrophins +corticotropin +corticotropins +cortin +cortins +cortisol +cortisols +cortisone +cortisones +coruler +corulers +corundum +corundums +coruscant +coruscate +coruscated +coruscates +coruscating +coruscation +coruscations +corvee +corvees +corves +corvet +corvets +corvette +corvettes +corvina +corvinas +corvine +cory +corybant +corybantes +corybantic +corybants +corydalis +corydalises +corymb +corymbed +corymbose +corymbosely +corymbs +corynebacteria +corynebacterial +corynebacterium +coryneform +coryphaei +coryphaeus +coryphee +coryphees +coryza +coryzal +coryzas +cos +coscript +coscripted +coscripting +coscripts +cosec +cosecant +cosecants +cosecs +coses +coset +cosets +cosey +coseys +cosh +coshed +cosher +coshered +coshering +coshers +coshes +coshing +cosie +cosied +cosier +cosies +cosiest +cosign +cosignatories +cosignatory +cosigned +cosigner +cosigners +cosigning +cosigns +cosily +cosine +cosines +cosiness +cosinesses +cosmetic +cosmetically +cosmetician +cosmeticians +cosmeticize +cosmeticized +cosmeticizes +cosmeticizing +cosmetics +cosmetologies +cosmetologist +cosmetologists +cosmetology +cosmic +cosmical +cosmically +cosmism +cosmisms +cosmist +cosmists +cosmochemical +cosmochemist +cosmochemistries +cosmochemistry +cosmochemists +cosmogenic +cosmogonic +cosmogonical +cosmogonies +cosmogonist +cosmogonists +cosmogony +cosmographer +cosmographers +cosmographic +cosmographical +cosmographies +cosmography +cosmological +cosmologically +cosmologies +cosmologist +cosmologists +cosmology +cosmonaut +cosmonauts +cosmopolis +cosmopolises +cosmopolitan +cosmopolitanism +cosmopolitanisms +cosmopolitans +cosmopolite +cosmopolites +cosmopolitism +cosmopolitisms +cosmos +cosmoses +cosponsor +cosponsored +cosponsoring +cosponsors +cosponsorship +cosponsorships +coss +cossack +cossacks +cosset +cosseted +cosseting +cossets +cost +costa +costae +costal +costar +costard +costards +costarred +costarring +costars +costate +costed +coster +costermonger +costermongers +costers +costing +costive +costively +costiveness +costivenesses +costless +costlessly +costlier +costliest +costliness +costlinesses +costly +costmaries +costmary +costrel +costrels +costs +costume +costumed +costumer +costumeries +costumers +costumery +costumes +costumey +costumier +costumiers +costuming +cosurfactant +cosurfactants +cosy +cosying +cot +cotan +cotangent +cotangents +cotans +cote +coteau +coteaux +coted +cotenant +cotenants +coterie +coteries +coterminous +coterminously +cotes +cothurn +cothurni +cothurns +cothurnus +cotidal +cotillion +cotillions +cotillon +cotillons +coting +cotoneaster +cotoneasters +cotquean +cotqueans +cotransduce +cotransduced +cotransduces +cotransducing +cotransduction +cotransductions +cotransfer +cotransferred +cotransferring +cotransfers +cotransport +cotransported +cotransporting +cotransports +cotrustee +cotrustees +cots +cotta +cottae +cottage +cottager +cottagers +cottages +cottagey +cottar +cottars +cottas +cotter +cottered +cotterless +cotters +cottier +cottiers +cotton +cottoned +cottoning +cottonmouth +cottonmouths +cottons +cottonseed +cottonseeds +cottontail +cottontails +cottonweed +cottonweeds +cottonwood +cottonwoods +cottony +cotyledon +cotyledonary +cotyledons +cotyloid +cotylosaur +cotylosaurs +cotype +cotypes +couch +couchant +couched +coucher +couchers +couches +couching +couchings +coude +cougar +cougars +cough +coughed +cougher +coughers +coughing +coughs +could +couldest +couldst +coulee +coulees +coulis +coulises +coulisse +coulisses +couloir +couloirs +coulomb +coulombic +coulombs +coulometer +coulometers +coulometric +coulometrically +coulometries +coulometry +coulter +coulters +coumaric +coumarin +coumarins +coumarou +coumarous +council +councillor +councillors +councillorship +councillorships +councilman +councilmanic +councilmen +councilor +councilors +councils +councilwoman +councilwomen +counsel +counseled +counselee +counselees +counseling +counselings +counselled +counselling +counsellings +counsellor +counsellors +counselor +counselors +counselorship +counselorships +counsels +count +countabilities +countability +countable +countably +countdown +countdowns +counted +countenance +countenanced +countenancer +countenancers +countenances +countenancing +counter +counteraccusation +counteraccusations +counteract +counteracted +counteracting +counteraction +counteractions +counteractive +counteracts +counteradaptation +counteradaptations +counteradvertising +counteradvertisings +counteragent +counteragents +counteraggression +counteraggressions +counterargue +counterargued +counterargues +counterarguing +counterargument +counterarguments +counterassault +counterassaults +counterattack +counterattacked +counterattacker +counterattackers +counterattacking +counterattacks +counterbade +counterbalance +counterbalanced +counterbalances +counterbalancing +counterbid +counterbidden +counterbidding +counterbids +counterblast +counterblasts +counterblockade +counterblockaded +counterblockades +counterblockading +counterblow +counterblows +countercampaign +countercampaigns +counterchange +counterchanged +counterchanges +counterchanging +countercharge +countercharged +countercharges +countercharging +countercheck +counterchecked +counterchecking +counterchecks +counterclaim +counterclaimed +counterclaiming +counterclaims +counterclockwise +countercommercial +countercomplaint +countercomplaints +counterconditioning +counterconditionings +counterconspiracies +counterconspiracy +counterconvention +counterconventions +countercountermeasure +countercountermeasures +countercoup +countercoups +countercries +countercriticism +countercriticisms +countercry +countercultural +counterculturalism +counterculturalisms +counterculture +countercultures +counterculturist +counterculturists +countercurrent +countercurrently +countercurrents +countercyclical +countercyclically +counterdemand +counterdemands +counterdemonstrate +counterdemonstrated +counterdemonstrates +counterdemonstrating +counterdemonstration +counterdemonstrations +counterdemonstrator +counterdemonstrators +counterdeployment +counterdeployments +countered +countereducational +countereffort +counterefforts +counterespionage +counterespionages +counterevidence +counterevidences +counterexample +counterexamples +counterfactual +counterfeit +counterfeited +counterfeiter +counterfeiters +counterfeiting +counterfeits +counterfire +counterfired +counterfires +counterfiring +counterflow +counterflows +counterfoil +counterfoils +counterforce +counterforces +countergovernment +countergovernments +counterguerilla +counterguerillas +counterguerrilla +counterguerrillas +counterhypotheses +counterhypothesis +counterimage +counterimages +counterincentive +counterincentives +counterinflation +counterinflationary +counterinfluence +counterinfluenced +counterinfluences +counterinfluencing +countering +counterinstance +counterinstances +counterinstitution +counterinstitutions +counterinsurgencies +counterinsurgency +counterinsurgent +counterinsurgents +counterintelligence +counterintelligences +counterinterpretation +counterinterpretations +counterintuitive +counterintuitively +counterion +counterions +counterirritant +counterirritants +counterman +countermand +countermanded +countermanding +countermands +countermarch +countermarched +countermarches +countermarching +countermeasure +countermeasures +countermelodies +countermelody +countermemo +countermemos +countermen +countermine +countermined +countermines +countermining +countermobilization +countermobilizations +countermove +countermoved +countermovement +countermovements +countermoves +countermoving +countermyth +countermyths +counteroffensive +counteroffensives +counteroffer +counteroffers +counterorder +counterordered +counterordering +counterorders +counterpane +counterpanes +counterpart +counterparts +counterpetition +counterpetitioned +counterpetitioning +counterpetitions +counterpicket +counterpicketed +counterpicketing +counterpickets +counterplan +counterplans +counterplay +counterplayer +counterplayers +counterplays +counterplea +counterpleas +counterplot +counterplots +counterplotted +counterplotting +counterploy +counterploys +counterpoint +counterpointed +counterpointing +counterpoints +counterpoise +counterpoised +counterpoises +counterpoising +counterpose +counterposed +counterposes +counterposing +counterpower +counterpowers +counterpressure +counterpressures +counterproductive +counterprogramming +counterprogrammings +counterproject +counterprojects +counterpropaganda +counterpropagandas +counterproposal +counterproposals +counterprotest +counterprotests +counterpunch +counterpunched +counterpuncher +counterpunchers +counterpunches +counterpunching +counterquestion +counterquestioned +counterquestioning +counterquestions +counterraid +counterraided +counterraiding +counterraids +counterrallied +counterrallies +counterrally +counterrallying +counterreaction +counterreactions +counterreform +counterreformation +counterreformations +counterreformer +counterreformers +counterreforms +counterresponse +counterresponses +counterretaliation +counterretaliations +counterrevolution +counterrevolutionaries +counterrevolutionary +counterrevolutions +counters +counterscientific +countershading +countershadings +countershot +countershots +countersign +countersignature +countersignatures +countersigned +countersigning +countersigns +countersink +countersinking +countersinks +countersniper +countersnipers +counterspell +counterspells +counterspies +counterspy +counterstain +counterstained +counterstaining +counterstains +counterstate +counterstated +counterstatement +counterstatements +counterstates +counterstating +counterstep +counterstepped +counterstepping +countersteps +counterstrategies +counterstrategist +counterstrategists +counterstrategy +counterstream +counterstreams +counterstrike +counterstrikes +counterstroke +counterstrokes +counterstyle +counterstyles +countersue +countersued +countersues +countersuggestion +countersuggestions +countersuing +countersuit +countersuits +countersunk +countersurveillance +countersurveillances +countertactics +countertendencies +countertendency +countertenor +countertenors +counterterror +counterterrorism +counterterrorisms +counterterrorist +counterterrorists +counterterrors +counterthreat +counterthreats +counterthrust +counterthrusts +countertop +countertops +countertrade +countertrades +countertradition +countertraditions +countertransference +countertransferences +countertrend +countertrends +countervail +countervailed +countervailing +countervails +counterview +counterviews +counterviolence +counterviolences +counterweight +counterweighted +counterweighting +counterweights +counterworld +counterworlds +countess +countesses +countian +countians +counties +counting +countinghouse +countinghouses +countless +countlessly +countries +countrified +country +countryfied +countryish +countryman +countrymen +countryseat +countryseats +countryside +countrysides +countrywide +countrywoman +countrywomen +counts +county +coup +coupe +couped +coupes +couping +couple +coupled +couplement +couplements +coupler +couplers +couples +couplet +couplets +coupling +couplings +coupon +couponing +couponings +coupons +coups +courage +courageous +courageously +courageousness +courageousnesses +courages +courant +courante +courantes +couranto +courantoes +courantos +courants +courgette +courgettes +courier +couriers +courlan +courlans +course +coursed +courser +coursers +courses +courseware +coursewares +coursing +coursings +court +courted +courteous +courteously +courteousness +courteousnesses +courter +courters +courtesan +courtesans +courtesied +courtesies +courtesy +courtesying +courthouse +courthouses +courtier +courtiers +courting +courtlier +courtliest +courtliness +courtlinesses +courtly +courtroom +courtrooms +courts +courtship +courtships +courtside +courtsides +courtyard +courtyards +couscous +couscouses +cousin +cousinage +cousinages +cousinhood +cousinhoods +cousinly +cousinries +cousinry +cousins +cousinship +cousinships +couteau +couteaux +couter +couters +couth +couther +couthest +couthie +couthier +couthiest +couths +couture +coutures +couturier +couturiere +couturieres +couturiers +couvade +couvades +covalence +covalences +covalencies +covalency +covalent +covalently +covariance +covariances +covariant +covariation +covariations +cove +coved +covelline +covellines +covellite +covellites +coven +covenant +covenantal +covenanted +covenantee +covenantees +covenanter +covenanters +covenanting +covenantor +covenantors +covenants +covens +cover +coverable +coverage +coverages +coverall +coveralled +coveralls +covered +coverer +coverers +covering +coverings +coverless +coverlet +coverlets +coverlid +coverlids +covers +coverslip +coverslips +covert +covertly +covertness +covertnesses +coverts +coverture +covertures +coverup +coverups +coves +covet +covetable +coveted +coveter +coveters +coveting +covetingly +covetous +covetously +covetousness +covetousnesses +covets +covey +coveys +covin +coving +covings +covins +cow +cowage +cowages +coward +cowardice +cowardices +cowardliness +cowardlinesses +cowardly +cowards +cowbane +cowbanes +cowbell +cowbells +cowberries +cowberry +cowbind +cowbinds +cowbird +cowbirds +cowboy +cowboys +cowcatcher +cowcatchers +cowed +cowedly +cower +cowered +cowering +cowers +cowfish +cowfishes +cowflap +cowflaps +cowflop +cowflops +cowgirl +cowgirls +cowhage +cowhages +cowhand +cowhands +cowherb +cowherbs +cowherd +cowherds +cowhide +cowhided +cowhides +cowhiding +cowier +cowiest +cowing +cowinner +cowinners +cowl +cowled +cowlick +cowlicks +cowling +cowlings +cowls +cowlstaff +cowlstaffs +cowlstaves +cowman +cowmen +coworker +coworkers +cowpat +cowpats +cowpea +cowpeas +cowpie +cowpies +cowplop +cowplops +cowpoke +cowpokes +cowpox +cowpoxes +cowpuncher +cowpunchers +cowrie +cowries +cowrite +cowrites +cowriting +cowritten +cowrote +cowry +cows +cowshed +cowsheds +cowskin +cowskins +cowslip +cowslips +cowy +cox +coxa +coxae +coxal +coxalgia +coxalgias +coxalgic +coxalgies +coxalgy +coxcomb +coxcombical +coxcombries +coxcombry +coxcombs +coxed +coxes +coxing +coxitides +coxitis +coxswain +coxswained +coxswaining +coxswains +coy +coydog +coydogs +coyed +coyer +coyest +coying +coyish +coyly +coyness +coynesses +coyote +coyotes +coyotillo +coyotillos +coypou +coypous +coypu +coypus +coys +coz +cozen +cozenage +cozenages +cozened +cozener +cozeners +cozening +cozens +cozes +cozey +cozeys +cozie +cozied +cozier +cozies +coziest +cozily +coziness +cozinesses +cozy +cozying +cozzes +craal +craaled +craaling +craals +crab +crabbed +crabbedness +crabbednesses +crabber +crabbers +crabbier +crabbiest +crabbily +crabbing +crabby +crabgrass +crabgrasses +crabmeat +crabmeats +crabs +crabstick +crabsticks +crabwise +crack +crackajack +crackajacks +crackback +crackbacks +crackbrain +crackbrained +crackbrains +crackdown +crackdowns +cracked +cracker +crackerjack +crackerjacks +crackers +cracking +crackings +crackle +crackled +crackles +crackleware +cracklewares +cracklier +crackliest +crackling +cracklings +crackly +cracknel +cracknels +crackpot +crackpots +cracks +cracksman +cracksmen +crackup +crackups +cracky +cradle +cradled +cradler +cradlers +cradles +cradlesong +cradlesongs +cradling +craft +crafted +craftier +craftiest +craftily +craftiness +craftinesses +crafting +crafts +craftsman +craftsmanlike +craftsmanly +craftsmanship +craftsmanships +craftsmen +craftspeople +craftsperson +craftspersons +craftswoman +craftswomen +crafty +crag +cragged +craggier +craggiest +craggily +cragginess +cragginesses +craggy +crags +cragsman +cragsmen +crake +crakes +cram +crambe +crambes +crambo +cramboes +crambos +crammed +crammer +crammers +cramming +cramoisie +cramoisies +cramoisy +cramp +cramped +cramping +crampit +crampits +crampon +crampons +crampoon +crampoons +cramps +crams +cranberries +cranberry +cranch +cranched +cranches +cranching +crane +craned +cranes +cranesbill +cranesbills +crania +cranial +cranially +craniate +craniates +craning +craniocerebral +craniofacial +craniologies +craniology +craniometries +craniometry +craniosacral +craniotomies +craniotomy +cranium +craniums +crank +crankcase +crankcases +cranked +cranker +crankest +crankier +crankiest +crankily +crankiness +crankinesses +cranking +crankish +crankle +crankled +crankles +crankling +crankly +crankous +crankpin +crankpins +cranks +crankshaft +crankshafts +cranky +crannied +crannies +crannog +crannoge +crannoges +crannogs +cranny +cranreuch +cranreuchs +crap +crape +craped +crapes +craping +crapped +crapper +crappers +crappie +crappier +crappies +crappiest +crapping +crappy +craps +crapshoot +crapshooter +crapshooters +crapshoots +crapulous +crases +crash +crashed +crasher +crashers +crashes +crashing +crashingly +crashworthiness +crashworthinesses +crashworthy +crasis +crass +crasser +crassest +crassitude +crassitudes +crassly +crassness +crassnesses +cratch +cratches +crate +crated +crater +cratered +cratering +craterlet +craterlets +craterlike +craters +crates +crating +craton +cratonic +cratons +craunch +craunched +craunches +craunching +cravat +cravats +crave +craved +craven +cravened +cravening +cravenly +cravenness +cravennesses +cravens +craver +cravers +craves +craving +cravings +craw +crawdad +crawdads +crawfish +crawfished +crawfishes +crawfishing +crawl +crawled +crawler +crawlers +crawlier +crawliest +crawling +crawls +crawlspace +crawlspaces +crawlway +crawlways +crawly +craws +crayfish +crayfishes +crayon +crayoned +crayoning +crayonist +crayonists +crayons +craze +crazed +crazes +crazier +crazies +craziest +crazily +craziness +crazinesses +crazing +crazy +crazyweed +crazyweeds +creak +creaked +creakier +creakiest +creakily +creakiness +creakinesses +creaking +creaks +creaky +cream +creamcups +creamed +creamer +creameries +creamers +creamery +creamier +creamiest +creamily +creaminess +creaminesses +creaming +creampuff +creampuffs +creams +creamware +creamwares +creamy +crease +creased +creaseless +creaser +creasers +creases +creasier +creasiest +creasing +creasy +create +created +creates +creatin +creatine +creatines +creating +creatinine +creatinines +creatins +creation +creationism +creationisms +creationist +creationists +creations +creative +creatively +creativeness +creativenesses +creativities +creativity +creator +creators +creatural +creature +creaturehood +creaturehoods +creatureliness +creaturelinesses +creaturely +creatures +creche +creches +credal +credence +credences +credenda +credendum +credent +credential +credentialed +credentialing +credentialism +credentialisms +credentialled +credentialling +credentials +credenza +credenzas +credibilities +credibility +credible +credibly +credit +creditabilities +creditability +creditable +creditableness +creditablenesses +creditably +credited +crediting +creditor +creditors +credits +creditworthiness +creditworthinesses +creditworthy +credo +credos +credulities +credulity +credulous +credulously +credulousness +credulousnesses +creed +creedal +creeds +creek +creeks +creel +creeled +creeling +creels +creep +creepage +creepages +creeper +creepers +creepie +creepier +creepies +creepiest +creepily +creepiness +creepinesses +creeping +creeps +creepy +creese +creeses +creesh +creeshed +creeshes +creeshing +cremains +cremate +cremated +cremates +cremating +cremation +cremations +cremator +crematoria +crematories +crematorium +crematoriums +cremators +crematory +creme +cremes +crenate +crenated +crenation +crenations +crenel +crenelated +crenelation +crenelations +creneled +creneling +crenellated +crenellation +crenellations +crenelle +crenelled +crenelles +crenelling +crenels +crenulate +crenulated +crenulation +crenulations +creodont +creodonts +creole +creoles +creolise +creolised +creolises +creolising +creolization +creolizations +creolize +creolized +creolizes +creolizing +creosol +creosols +creosote +creosoted +creosotes +creosoting +crepe +creped +crepes +crepey +crepier +crepiest +creping +crepitant +crepitate +crepitated +crepitates +crepitating +crepitation +crepitations +crepon +crepons +crept +crepuscle +crepuscles +crepuscular +crepuscule +crepuscules +crepy +crescendi +crescendo +crescendoed +crescendoes +crescendoing +crescendos +crescent +crescentic +crescents +crescive +crescively +cresol +cresols +cress +cresses +cresset +cressets +crest +crestal +crested +crestfallen +crestfallenly +crestfallenness +crestfallennesses +cresting +crestings +crestless +crests +cresyl +cresylic +cresyls +cretic +cretics +cretin +cretinism +cretinisms +cretinous +cretins +cretonne +cretonnes +crevalle +crevalles +crevasse +crevassed +crevasses +crevassing +crevice +creviced +crevices +crew +crewed +crewel +crewels +crewelwork +crewelworks +crewing +crewless +crewman +crewmate +crewmates +crewmen +crewneck +crewnecks +crews +crib +cribbage +cribbages +cribbed +cribber +cribbers +cribbing +cribbings +cribbled +cribriform +cribrous +cribs +cribwork +cribworks +cricetid +cricetids +crick +cricked +cricket +cricketed +cricketer +cricketers +cricketing +crickets +crickey +cricking +cricks +cricoid +cricoids +cried +crier +criers +cries +crikey +crime +crimeless +crimes +criminal +criminalistics +criminalities +criminality +criminalization +criminalizations +criminalize +criminalized +criminalizes +criminalizing +criminally +criminals +criminate +criminated +criminates +criminating +crimination +criminations +criminological +criminologically +criminologies +criminologist +criminologists +criminology +criminous +crimmer +crimmers +crimp +crimped +crimper +crimpers +crimpier +crimpiest +crimping +crimple +crimpled +crimples +crimpling +crimps +crimpy +crimson +crimsoned +crimsoning +crimsons +cringe +cringed +cringer +cringers +cringes +cringing +cringle +cringles +crinite +crinites +crinkle +crinkled +crinkles +crinklier +crinkliest +crinkling +crinkly +crinoid +crinoids +crinoline +crinolined +crinolines +crinum +crinums +criollo +criollos +cripe +cripes +cripple +crippled +crippler +cripplers +cripples +crippling +cripplingly +cris +crises +crisic +crisis +crisp +crispate +crispbread +crispbreads +crisped +crispen +crispened +crispening +crispens +crisper +crispers +crispest +crispier +crispiest +crispily +crispiness +crispinesses +crisping +crisply +crispness +crispnesses +crisps +crispy +crissa +crissal +crisscross +crisscrossed +crisscrosses +crisscrossing +crissum +crista +cristae +cristate +criteria +criterion +criterions +criterium +criteriums +critic +critical +criticalities +criticality +critically +criticalness +criticalnesses +criticaster +criticasters +criticise +criticised +criticises +criticising +criticism +criticisms +criticizable +criticize +criticized +criticizer +criticizers +criticizes +criticizing +critics +critique +critiqued +critiques +critiquing +critter +critters +crittur +critturs +croak +croaked +croaker +croakers +croakier +croakiest +croakily +croaking +croaks +croaky +croc +crocein +croceine +croceines +croceins +crochet +crocheted +crocheter +crocheters +crocheting +crochets +croci +crocidolite +crocidolites +crocine +crock +crocked +crockeries +crockery +crocket +crocketed +crockets +crocking +crocks +crocodile +crocodiles +crocodilian +crocodilians +crocoite +crocoites +crocs +crocus +crocuses +croft +crofter +crofters +crofts +croissant +croissants +crojik +crojiks +cromlech +cromlechs +crone +crones +cronies +crony +cronyism +cronyisms +crook +crookback +crookbacked +crookbacks +crooked +crookeder +crookedest +crookedly +crookedness +crookednesses +crookeries +crookery +crooking +crookneck +crooknecks +crooks +croon +crooned +crooner +crooners +crooning +croons +crop +cropland +croplands +cropless +cropped +cropper +croppers +croppie +croppies +cropping +crops +croquet +croqueted +croqueting +croquets +croquette +croquettes +croquignole +croquignoles +croquis +crore +crores +crosier +crosiers +cross +crossabilities +crossability +crossable +crossarm +crossarms +crossbanded +crossbanding +crossbandings +crossbar +crossbarred +crossbarring +crossbars +crossbeam +crossbeams +crossbearer +crossbearers +crossbill +crossbills +crossbones +crossbow +crossbowman +crossbowmen +crossbows +crossbred +crossbreds +crossbreed +crossbreeding +crossbreeds +crosscourt +crosscurrent +crosscurrents +crosscut +crosscuts +crosscutting +crosscuttings +crosse +crossed +crosser +crossers +crosses +crossest +crossfire +crossfires +crosshair +crosshairs +crosshatch +crosshatched +crosshatches +crosshatching +crosshead +crossheads +crossing +crossings +crosslet +crosslets +crosslinguistic +crosslinguistically +crossly +crossness +crossnesses +crossopterygian +crossopterygians +crossover +crossovers +crosspatch +crosspatches +crosspiece +crosspieces +crossroad +crossroads +crossruff +crossruffed +crossruffing +crossruffs +crosstalk +crosstalks +crosstie +crossties +crosstown +crosstrees +crosswalk +crosswalks +crossway +crossways +crosswind +crosswinds +crosswise +crossword +crosswords +crotch +crotched +crotches +crotchet +crotchetiness +crotchetinesses +crotchets +crotchety +croton +crotons +crouch +crouched +crouches +crouching +croup +croupe +croupes +croupier +croupiers +croupiest +croupily +croupous +croups +croupy +crouse +crousely +croustade +croustades +crouton +croutons +crow +crowbar +crowbarred +crowbarring +crowbars +crowberries +crowberry +crowd +crowded +crowdedness +crowdednesses +crowder +crowders +crowdie +crowdies +crowding +crowds +crowdy +crowed +crower +crowers +crowfeet +crowfoot +crowfoots +crowing +crowkeeper +crowkeepers +crown +crowned +crowner +crowners +crownet +crownets +crowning +crownless +crowns +crows +crowstep +crowstepped +crowsteps +croze +crozer +crozers +crozes +crozier +croziers +cruces +crucial +crucially +crucian +crucians +cruciate +crucible +crucibles +crucifer +cruciferous +crucifers +crucified +crucifies +crucifix +crucifixes +crucifixion +crucifixions +cruciform +cruciforms +crucify +crucifying +cruck +crucks +crud +crudded +cruddier +cruddiest +crudding +cruddy +crude +crudely +crudeness +crudenesses +cruder +crudes +crudest +crudites +crudities +crudity +cruds +cruel +crueler +cruelest +crueller +cruellest +cruelly +cruelness +cruelnesses +cruelties +cruelty +cruet +cruets +cruise +cruised +cruiser +cruisers +cruiserweight +cruiserweights +cruises +cruising +cruisings +cruller +crullers +crumb +crumbed +crumber +crumbers +crumbier +crumbiest +crumbing +crumble +crumbled +crumbles +crumblier +crumbliest +crumbliness +crumblinesses +crumbling +crumblings +crumbly +crumbs +crumbum +crumbums +crumby +crumhorn +crumhorns +crummie +crummier +crummies +crummiest +crumminess +crumminesses +crummy +crump +crumped +crumpet +crumpets +crumping +crumple +crumpled +crumples +crumplier +crumpliest +crumpling +crumply +crumps +crunch +crunchable +crunched +cruncher +crunchers +crunches +crunchier +crunchiest +crunchily +crunchiness +crunchinesses +crunching +crunchy +crunodal +crunode +crunodes +cruor +cruors +crupper +cruppers +crura +crural +crus +crusade +crusaded +crusader +crusaders +crusades +crusading +crusado +crusadoes +crusados +cruse +cruses +cruset +crusets +crush +crushable +crushed +crusher +crushers +crushes +crushing +crushingly +crushproof +crusily +crust +crustacea +crustacean +crustaceans +crustaceous +crustal +crusted +crustier +crustiest +crustily +crustiness +crustinesses +crusting +crustless +crustose +crusts +crusty +crutch +crutched +crutches +crutching +crux +cruxes +cruzado +cruzadoes +cruzados +cruzeiro +cruzeiros +crwth +crwths +cry +crybabies +crybaby +crying +cryingly +cryobiological +cryobiologies +cryobiologist +cryobiologists +cryobiology +cryogen +cryogenic +cryogenically +cryogenics +cryogenies +cryogens +cryogeny +cryolite +cryolites +cryonic +cryonics +cryophilic +cryopreservation +cryopreservations +cryopreserve +cryopreserved +cryopreserves +cryopreserving +cryoprobe +cryoprobes +cryoprotectant +cryoprotectants +cryoprotective +cryoscope +cryoscopes +cryoscopic +cryoscopies +cryoscopy +cryostat +cryostatic +cryostats +cryosurgeon +cryosurgeons +cryosurgeries +cryosurgery +cryosurgical +cryotherapies +cryotherapy +cryotron +cryotrons +crypt +cryptal +cryptanalyses +cryptanalysis +cryptanalyst +cryptanalysts +cryptanalytic +cryptanalytical +cryptarithm +cryptarithms +cryptic +cryptically +crypto +cryptococcal +cryptococci +cryptococcoses +cryptococcosis +cryptococcus +cryptocrystalline +cryptogam +cryptogamic +cryptogamous +cryptogams +cryptogenic +cryptogram +cryptograms +cryptograph +cryptographer +cryptographers +cryptographic +cryptographically +cryptographies +cryptographs +cryptography +cryptologic +cryptological +cryptologies +cryptologist +cryptologists +cryptology +cryptomeria +cryptomerias +cryptonym +cryptonyms +cryptorchid +cryptorchidism +cryptorchidisms +cryptorchids +cryptorchism +cryptorchisms +cryptos +cryptozoologies +cryptozoologist +cryptozoologists +cryptozoology +crypts +crystal +crystalize +crystalized +crystalizes +crystalizing +crystalline +crystallinities +crystallinity +crystallise +crystallised +crystallises +crystallising +crystallite +crystallites +crystallizable +crystallization +crystallizations +crystallize +crystallized +crystallizer +crystallizers +crystallizes +crystallizing +crystallographer +crystallographers +crystallographic +crystallographically +crystallographies +crystallography +crystalloid +crystalloidal +crystalloids +crystals +ctenidia +ctenidium +ctenoid +ctenophoran +ctenophorans +ctenophore +ctenophores +cuadrilla +cuadrillas +cub +cubage +cubages +cubature +cubatures +cubbies +cubbish +cubby +cubbyhole +cubbyholes +cube +cubeb +cubebs +cubed +cuber +cubers +cubes +cubic +cubical +cubically +cubicities +cubicity +cubicle +cubicles +cubicly +cubics +cubicula +cubiculum +cubiform +cubing +cubism +cubisms +cubist +cubistic +cubists +cubit +cubital +cubits +cuboid +cuboidal +cuboids +cubs +cuckold +cuckolded +cuckolding +cuckoldries +cuckoldry +cuckolds +cuckoo +cuckooed +cuckooflower +cuckooflowers +cuckooing +cuckoopint +cuckoopints +cuckoos +cucullate +cucumber +cucumbers +cucurbit +cucurbits +cud +cudbear +cudbears +cuddie +cuddies +cuddle +cuddled +cuddler +cuddlers +cuddles +cuddlesome +cuddlier +cuddliest +cuddling +cuddly +cuddy +cudgel +cudgeled +cudgeler +cudgelers +cudgeling +cudgelled +cudgelling +cudgels +cuds +cudweed +cudweeds +cue +cued +cueing +cues +cuesta +cuestas +cuff +cuffed +cuffing +cuffless +cuffs +cuif +cuifs +cuing +cuirass +cuirassed +cuirasses +cuirassier +cuirassiers +cuirassing +cuish +cuishes +cuisine +cuisines +cuisse +cuisses +cuittle +cuittled +cuittles +cuittling +cuke +cukes +culch +culches +culet +culets +culex +culices +culicid +culicids +culicine +culicines +culinarian +culinarians +culinarily +culinary +cull +cullay +cullays +culled +cullender +cullenders +culler +cullers +cullet +cullets +cullied +cullies +culling +cullion +cullions +cullis +cullises +culls +cully +cullying +culm +culmed +culminant +culminate +culminated +culminates +culminating +culmination +culminations +culming +culms +culotte +culottes +culpa +culpabilities +culpability +culpable +culpableness +culpablenesses +culpably +culpae +culprit +culprits +cult +cultch +cultches +culti +cultic +cultigen +cultigens +cultish +cultishly +cultishness +cultishnesses +cultism +cultisms +cultist +cultists +cultivabilities +cultivability +cultivable +cultivar +cultivars +cultivatable +cultivate +cultivated +cultivates +cultivating +cultivation +cultivations +cultivator +cultivators +cultlike +cultrate +cults +cultural +culturally +culturati +culture +cultured +cultures +culturing +cultus +cultuses +culver +culverin +culverins +culvers +culvert +culverts +cum +cumarin +cumarins +cumber +cumberbund +cumberbunds +cumbered +cumberer +cumberers +cumbering +cumbers +cumbersome +cumbersomely +cumbersomeness +cumbersomenesses +cumbrous +cumbrously +cumbrousness +cumbrousnesses +cumin +cumins +cummer +cummerbund +cummerbunds +cummers +cummin +cummins +cumquat +cumquats +cumshaw +cumshaws +cumulate +cumulated +cumulates +cumulating +cumulation +cumulations +cumulative +cumulatively +cumulativeness +cumulativenesses +cumuli +cumuliform +cumulonimbi +cumulonimbus +cumulonimbuses +cumulous +cumulus +cunctation +cunctations +cunctative +cundum +cundums +cuneal +cuneate +cuneated +cuneatic +cuneiform +cuneiforms +cuniform +cuniforms +cunner +cunners +cunnilinctus +cunnilinctuses +cunnilingus +cunnilinguses +cunning +cunninger +cunningest +cunningly +cunningness +cunningnesses +cunnings +cunt +cunts +cup +cupbearer +cupbearers +cupboard +cupboards +cupcake +cupcakes +cupel +cupeled +cupeler +cupelers +cupeling +cupellation +cupellations +cupelled +cupeller +cupellers +cupelling +cupels +cupful +cupfuls +cupid +cupidities +cupidity +cupids +cuplike +cupola +cupolaed +cupolaing +cupolas +cuppa +cuppas +cupped +cupper +cuppers +cuppier +cuppiest +cupping +cuppings +cuppy +cupreous +cupric +cupriferous +cuprite +cuprites +cupronickel +cupronickels +cuprous +cuprum +cuprums +cups +cupsful +cupula +cupulae +cupular +cupulate +cupule +cupules +cur +curabilities +curability +curable +curableness +curablenesses +curably +curacao +curacaos +curacies +curacoa +curacoas +curacy +curagh +curaghs +curara +curaras +curare +curares +curari +curarine +curarines +curaris +curarization +curarizations +curarize +curarized +curarizes +curarizing +curassow +curassows +curate +curated +curates +curating +curative +curatively +curatives +curator +curatorial +curators +curatorship +curatorships +curb +curbable +curbed +curber +curbers +curbing +curbings +curbs +curbside +curbsides +curbstone +curbstones +curch +curches +curculio +curculios +curcuma +curcumas +curd +curded +curdier +curdiest +curding +curdle +curdled +curdler +curdlers +curdles +curdling +curds +curdy +cure +cured +cureless +curer +curers +cures +curet +curets +curettage +curettages +curette +curetted +curettement +curettements +curettes +curetting +curf +curfew +curfews +curfs +curia +curiae +curial +curie +curies +curing +curio +curios +curiosa +curiosities +curiosity +curious +curiouser +curiousest +curiously +curiousness +curiousnesses +curite +curites +curium +curiums +curl +curled +curler +curlers +curlew +curlews +curlicue +curlicued +curlicues +curlicuing +curlier +curliest +curlily +curliness +curlinesses +curling +curlings +curlpaper +curlpapers +curls +curly +curlycue +curlycues +curmudgeon +curmudgeonliness +curmudgeonlinesses +curmudgeonly +curmudgeons +curn +curns +curr +currach +currachs +curragh +curraghs +curran +currans +currant +currants +curred +currencies +currency +current +currently +currentness +currentnesses +currents +curricle +curricles +curricula +curricular +curriculum +curriculums +currie +curried +currier +currieries +curriers +curriery +curries +curring +currish +currishly +currs +curry +currycomb +currycombed +currycombing +currycombs +currying +curs +curse +cursed +curseder +cursedest +cursedly +cursedness +cursednesses +curser +cursers +curses +cursing +cursive +cursively +cursiveness +cursivenesses +cursives +cursor +cursorial +cursorily +cursoriness +cursorinesses +cursors +cursory +curst +curt +curtail +curtailed +curtailer +curtailers +curtailing +curtailment +curtailments +curtails +curtain +curtained +curtaining +curtainless +curtains +curtal +curtalax +curtalaxes +curtals +curtate +curter +curtesies +curtest +curtesy +curtilage +curtilages +curtly +curtness +curtnesses +curtsey +curtseyed +curtseying +curtseys +curtsied +curtsies +curtsy +curtsying +curule +curvaceous +curvacious +curvature +curvatures +curve +curveball +curveballed +curveballing +curveballs +curved +curvedly +curves +curvet +curveted +curveting +curvets +curvetted +curvetting +curvey +curvier +curviest +curvilinear +curvilinearities +curvilinearity +curving +curvy +cuscus +cuscuses +cusec +cusecs +cushat +cushats +cushaw +cushaws +cushier +cushiest +cushily +cushion +cushioned +cushioning +cushionless +cushions +cushiony +cushy +cusk +cusks +cusp +cuspate +cuspated +cusped +cuspid +cuspidal +cuspidate +cuspidation +cuspidations +cuspides +cuspidor +cuspidors +cuspids +cuspis +cusps +cuss +cussed +cussedly +cussedness +cussednesses +cusser +cussers +cusses +cussing +cusso +cussos +cussword +cusswords +custard +custards +custardy +custodes +custodial +custodian +custodians +custodianship +custodianships +custodies +custody +custom +customarily +customariness +customarinesses +customary +customer +customers +customhouse +customhouses +customise +customised +customises +customising +customization +customizations +customize +customized +customizer +customizers +customizes +customizing +customs +customshouse +customshouses +custos +custumal +custumals +cut +cutabilities +cutability +cutaneous +cutaneously +cutaway +cutaways +cutback +cutbacks +cutbank +cutbanks +cutch +cutcheries +cutchery +cutches +cutdown +cutdowns +cute +cutely +cuteness +cutenesses +cuter +cutes +cutesie +cutesier +cutesiest +cutest +cutesy +cutey +cuteys +cutgrass +cutgrasses +cuticle +cuticles +cuticula +cuticulae +cuticular +cutie +cuties +cutin +cutinise +cutinised +cutinises +cutinising +cutinize +cutinized +cutinizes +cutinizing +cutins +cutis +cutises +cutlas +cutlases +cutlass +cutlasses +cutler +cutleries +cutlers +cutlery +cutlet +cutlets +cutline +cutlines +cutoff +cutoffs +cutout +cutouts +cutover +cutovers +cutpurse +cutpurses +cuts +cuttable +cuttage +cuttages +cutter +cutters +cutthroat +cutthroats +cutties +cutting +cuttingly +cuttings +cuttle +cuttlebone +cuttlebones +cuttled +cuttlefish +cuttlefishes +cuttles +cuttling +cutty +cutup +cutups +cutwater +cutwaters +cutwork +cutworks +cutworm +cutworms +cuvette +cuvettes +cwm +cwms +cyan +cyanamid +cyanamide +cyanamides +cyanamids +cyanate +cyanates +cyanic +cyanid +cyanide +cyanided +cyanides +cyaniding +cyanids +cyanin +cyanine +cyanines +cyanins +cyanite +cyanites +cyanitic +cyano +cyanoacrylate +cyanoacrylates +cyanobacteria +cyanobacterium +cyanocobalamin +cyanocobalamine +cyanocobalamines +cyanocobalamins +cyanoethylate +cyanoethylated +cyanoethylates +cyanoethylating +cyanoethylation +cyanoethylations +cyanogen +cyanogeneses +cyanogenesis +cyanogenetic +cyanogenic +cyanogens +cyanohydrin +cyanohydrins +cyanosed +cyanoses +cyanosis +cyanotic +cyans +cybernated +cybernation +cybernations +cybernetic +cybernetical +cybernetically +cybernetician +cyberneticians +cyberneticist +cyberneticists +cybernetics +cyberpunk +cyberpunks +cyberspace +cyberspaces +cyborg +cyborgs +cycad +cycadeoid +cycadeoids +cycadophyte +cycadophytes +cycads +cycas +cycases +cycasin +cycasins +cyclamate +cyclamates +cyclamen +cyclamens +cyclase +cyclases +cyclazocine +cyclazocines +cycle +cyclecar +cyclecars +cycled +cycler +cycleries +cyclers +cyclery +cycles +cyclic +cyclical +cyclicalities +cyclicality +cyclically +cyclicals +cyclicities +cyclicity +cyclicly +cycling +cyclings +cyclist +cyclists +cyclitol +cyclitols +cyclization +cyclizations +cyclize +cyclized +cyclizes +cyclizing +cyclo +cycloaddition +cycloadditions +cycloaliphatic +cyclodextrin +cyclodextrins +cyclodiene +cyclodienes +cyclogeneses +cyclogenesis +cyclohexane +cyclohexanes +cyclohexanone +cyclohexanones +cycloheximide +cycloheximides +cyclohexylamine +cyclohexylamines +cycloid +cycloidal +cycloids +cyclometer +cyclometers +cyclonal +cyclone +cyclones +cyclonic +cyclonically +cycloolefin +cycloolefinic +cycloolefins +cyclopaedia +cyclopaedias +cycloparaffin +cycloparaffins +cyclopean +cyclopedia +cyclopedias +cyclopedic +cyclophosphamide +cyclophosphamides +cyclopropane +cyclopropanes +cyclops +cyclorama +cycloramas +cycloramic +cyclos +cycloserine +cycloserines +cycloses +cyclosis +cyclosporine +cyclosporines +cyclostome +cyclostomes +cyclostyle +cyclostyled +cyclostyles +cyclostyling +cyclothymia +cyclothymias +cyclothymic +cyclotomic +cyclotron +cyclotrons +cyder +cyders +cyeses +cyesis +cygnet +cygnets +cylices +cylinder +cylindered +cylindering +cylinders +cylindric +cylindrical +cylindrically +cylix +cyma +cymae +cymar +cymars +cymas +cymatia +cymatium +cymbal +cymbaler +cymbalers +cymbalist +cymbalists +cymbalom +cymbaloms +cymbals +cymbidia +cymbidium +cymbidiums +cymbling +cymblings +cyme +cymene +cymenes +cymes +cymlin +cymling +cymlings +cymlins +cymogene +cymogenes +cymoid +cymol +cymols +cymophane +cymophanes +cymose +cymosely +cymous +cynic +cynical +cynically +cynicism +cynicisms +cynics +cynosure +cynosures +cypher +cyphered +cyphering +cyphers +cypres +cypreses +cypress +cypresses +cyprian +cyprians +cyprinid +cyprinids +cypripedia +cypripedium +cypripediums +cyproheptadine +cyproheptadines +cyproterone +cyproterones +cyprus +cypruses +cypsela +cypselae +cyst +cysteamine +cysteamines +cystein +cysteine +cysteines +cysteins +cystic +cysticerci +cysticercoid +cysticercoids +cysticercoses +cysticercosis +cysticercus +cystine +cystines +cystinuria +cystinurias +cystitides +cystitis +cystocarp +cystocarps +cystoid +cystoids +cystolith +cystoliths +cystoscope +cystoscopes +cystoscopic +cystoscopies +cystoscopy +cysts +cytaster +cytasters +cytidine +cytidines +cytochalasin +cytochalasins +cytochemical +cytochemistries +cytochemistry +cytochrome +cytochromes +cytodifferentiation +cytodifferentiations +cytogenetic +cytogenetical +cytogenetically +cytogeneticist +cytogeneticists +cytogenetics +cytogenies +cytogeny +cytokine +cytokines +cytokineses +cytokinesis +cytokinetic +cytokinin +cytokinins +cytologic +cytological +cytologically +cytologies +cytologist +cytologists +cytology +cytolyses +cytolysin +cytolysins +cytolysis +cytolytic +cytomegalic +cytomegalovirus +cytomegaloviruses +cytomembrane +cytomembranes +cyton +cytons +cytopathic +cytopathogenic +cytopathogenicities +cytopathogenicity +cytophilic +cytophotometric +cytophotometries +cytophotometry +cytoplasm +cytoplasmic +cytoplasmically +cytoplasms +cytosine +cytosines +cytoskeletal +cytoskeleton +cytoskeletons +cytosol +cytosolic +cytosols +cytostatic +cytostatically +cytostatics +cytotaxonomic +cytotaxonomically +cytotaxonomies +cytotaxonomy +cytotechnologies +cytotechnologist +cytotechnologists +cytotechnology +cytotoxic +cytotoxicities +cytotoxicity +cytotoxin +cytotoxins +czar +czardas +czardases +czardom +czardoms +czarevitch +czarevitches +czarevna +czarevnas +czarina +czarinas +czarism +czarisms +czarist +czarists +czaritza +czaritzas +czars +dab +dabbed +dabber +dabbers +dabbing +dabble +dabbled +dabbler +dabblers +dabbles +dabbling +dabblings +dabchick +dabchicks +dabs +dabster +dabsters +dace +daces +dacha +dachas +dachshund +dachshunds +dacker +dackered +dackering +dackers +dacoit +dacoities +dacoits +dacoity +dactyl +dactyli +dactylic +dactylics +dactylologies +dactylology +dactyls +dactylus +dad +dada +dadaism +dadaisms +dadaist +dadaistic +dadaists +dadas +daddies +daddle +daddled +daddles +daddling +daddy +dado +dadoed +dadoes +dadoing +dados +dads +daedal +daemon +daemonic +daemons +daff +daffed +daffier +daffiest +daffily +daffing +daffodil +daffodils +daffs +daffy +daft +dafter +daftest +daftly +daftness +daftnesses +dag +dagga +daggas +dagger +daggered +daggering +daggerlike +daggers +daggle +daggled +daggles +daggling +daglock +daglocks +dago +dagoba +dagobas +dagoes +dagos +dags +daguerreotype +daguerreotyped +daguerreotypes +daguerreotypies +daguerreotyping +daguerreotypist +daguerreotypists +daguerreotypy +dagwood +dagwoods +dah +dahabeah +dahabeahs +dahabiah +dahabiahs +dahabieh +dahabiehs +dahabiya +dahabiyas +dahl +dahlia +dahlias +dahls +dahoon +dahoons +dahs +daiker +daikered +daikering +daikers +daikon +daikons +dailies +dailiness +dailinesses +daily +daimen +daimio +daimios +daimon +daimones +daimonic +daimons +daimyo +daimyos +daintier +dainties +daintiest +daintily +daintiness +daintinesses +dainty +daiquiri +daiquiris +dairies +dairy +dairying +dairyings +dairymaid +dairymaids +dairyman +dairymen +dais +daises +daishiki +daishikis +daisied +daisies +daisy +dak +dakerhen +dakerhens +dakoit +dakoities +dakoits +dakoity +daks +dal +dalapon +dalapons +dalasi +dalasis +dale +daledh +daledhs +dales +dalesman +dalesmen +daleth +daleths +dalles +dalliance +dalliances +dallied +dallier +dalliers +dallies +dally +dallying +dalmatian +dalmatians +dalmatic +dalmatics +dals +dalton +daltonic +daltons +dam +damage +damageabilities +damageability +damaged +damager +damagers +damages +damaging +damagingly +daman +damans +damar +damars +damascene +damascened +damascenes +damascening +damask +damasked +damasking +damasks +dame +dames +damewort +dameworts +dammar +dammars +dammed +dammer +dammers +damming +damn +damnable +damnableness +damnablenesses +damnably +damnation +damnations +damnatory +damndest +damndests +damned +damneder +damnedest +damnedests +damner +damners +damnified +damnifies +damnify +damnifying +damning +damningly +damns +damosel +damosels +damozel +damozels +damp +damped +dampen +dampened +dampener +dampeners +dampening +dampens +damper +dampers +dampest +damping +dampings +dampish +damply +dampness +dampnesses +damps +dams +damsel +damselfish +damselfishes +damselflies +damselfly +damsels +damson +damsons +dance +danceable +danced +dancer +dancers +dances +dancing +dandelion +dandelions +dander +dandered +dandering +danders +dandiacal +dandier +dandies +dandiest +dandification +dandifications +dandified +dandifies +dandify +dandifying +dandily +dandle +dandled +dandler +dandlers +dandles +dandling +dandriff +dandriffs +dandruff +dandruffs +dandruffy +dandy +dandyish +dandyishly +dandyism +dandyisms +danegeld +danegelds +daneweed +daneweeds +danewort +daneworts +dang +danged +danger +dangered +dangering +dangerous +dangerously +dangerousness +dangerousnesses +dangers +danging +dangle +dangled +dangler +danglers +dangles +dangling +dangs +danio +danios +danish +dank +danker +dankest +dankly +dankness +danknesses +danseur +danseurs +danseuse +danseuses +dap +daphne +daphnes +daphnia +daphnias +dapped +dapper +dapperer +dapperest +dapperly +dapperness +dappernesses +dapping +dapple +dappled +dapples +dappling +daps +dapsone +dapsones +darb +darbies +darbs +dare +dared +daredevil +daredevilries +daredevilry +daredevils +daredeviltries +daredeviltry +dareful +darer +darers +dares +daresay +daric +darics +daring +daringly +daringness +daringnesses +darings +dariole +darioles +dark +darked +darken +darkened +darkener +darkeners +darkening +darkens +darker +darkest +darkey +darkeys +darkie +darkies +darking +darkish +darkle +darkled +darkles +darklier +darkliest +darkling +darkly +darkness +darknesses +darkroom +darkrooms +darks +darksome +darky +darling +darlingly +darlingness +darlingnesses +darlings +darn +darndest +darndests +darned +darneder +darnedest +darnel +darnels +darner +darners +darning +darnings +darns +darshan +darshans +dart +dartboard +dartboards +darted +darter +darters +darting +dartle +dartled +dartles +dartling +darts +dash +dashboard +dashboards +dashed +dasheen +dasheens +dasher +dashers +dashes +dashi +dashier +dashiest +dashiki +dashikis +dashing +dashingly +dashis +dashpot +dashpots +dashy +dassie +dassies +dastard +dastardliness +dastardlinesses +dastardly +dastards +dasyure +dasyures +data +databank +databanks +database +databases +datable +dataries +datary +datcha +datchas +date +dateable +dated +datedly +datedness +datednesses +dateless +dateline +datelined +datelines +datelining +dater +daters +dates +dating +datival +dative +datively +datives +dato +datos +datto +dattos +datum +datums +datura +daturas +daturic +daub +daube +daubed +dauber +dauberies +daubers +daubery +daubes +daubier +daubiest +daubing +daubries +daubry +daubs +dauby +daughter +daughterless +daughters +daunder +daundered +daundering +daunders +daunomycin +daunomycins +daunorubicin +daunorubicins +daunt +daunted +daunter +daunters +daunting +dauntingly +dauntless +dauntlessly +dauntlessness +dauntlessnesses +daunts +dauphin +dauphine +dauphines +dauphins +daut +dauted +dautie +dauties +dauting +dauts +daven +davened +davening +davenport +davenports +davens +davies +davit +davits +davy +daw +dawdle +dawdled +dawdler +dawdlers +dawdles +dawdling +dawed +dawen +dawing +dawk +dawks +dawn +dawned +dawning +dawnlike +dawns +daws +dawsonite +dawsonites +dawt +dawted +dawtie +dawties +dawting +dawts +day +daybed +daybeds +daybook +daybooks +daybreak +daybreaks +daydream +daydreamed +daydreamer +daydreamers +daydreaming +daydreamlike +daydreams +daydreamt +dayflies +dayflower +dayflowers +dayfly +dayglow +dayglows +daylight +daylighted +daylighting +daylightings +daylights +daylilies +daylily +daylit +daylong +daymare +daymares +dayroom +dayrooms +days +dayside +daysides +daysman +daysmen +daystar +daystars +daytime +daytimes +daywork +dayworks +daze +dazed +dazedly +dazedness +dazednesses +dazes +dazing +dazzle +dazzled +dazzler +dazzlers +dazzles +dazzling +dazzlingly +de +deacidification +deacidifications +deacidified +deacidifies +deacidify +deacidifying +deacon +deaconed +deaconess +deaconesses +deaconing +deaconries +deaconry +deacons +deactivate +deactivated +deactivates +deactivating +deactivation +deactivations +deactivator +deactivators +dead +deadbeat +deadbeats +deadbolt +deadbolts +deaden +deadened +deadener +deadeners +deadening +deadeningly +deadenings +deadens +deader +deadest +deadeye +deadeyes +deadfall +deadfalls +deadhead +deadheaded +deadheading +deadheads +deadlier +deadliest +deadlift +deadlifted +deadlifting +deadlifts +deadlight +deadlights +deadline +deadlines +deadliness +deadlinesses +deadlock +deadlocked +deadlocking +deadlocks +deadly +deadness +deadnesses +deadpan +deadpanned +deadpanner +deadpanners +deadpanning +deadpans +deads +deadweight +deadweights +deadwood +deadwoods +deaerate +deaerated +deaerates +deaerating +deaeration +deaerations +deaerator +deaerators +deaf +deafen +deafened +deafening +deafeningly +deafens +deafer +deafest +deafish +deafly +deafness +deafnesses +deair +deaired +deairing +deairs +deal +dealate +dealated +dealates +dealation +dealations +dealer +dealers +dealership +dealerships +dealfish +dealfishes +dealing +dealings +deals +dealt +deaminase +deaminases +deaminate +deaminated +deaminates +deaminating +deamination +deaminations +dean +deaned +deaneries +deanery +deaning +deans +deanship +deanships +dear +dearer +dearest +dearie +dearies +dearly +dearness +dearnesses +dears +dearth +dearths +deary +deash +deashed +deashes +deashing +deasil +death +deathbed +deathbeds +deathblow +deathblows +deathcup +deathcups +deathful +deathless +deathlessly +deathlessness +deathlessnesses +deathly +deaths +deathsman +deathsmen +deathtrap +deathtraps +deathwatch +deathwatches +deathy +deave +deaved +deaves +deaving +deb +debacle +debacles +debar +debark +debarkation +debarkations +debarked +debarking +debarks +debarment +debarments +debarred +debarring +debars +debase +debased +debasement +debasements +debaser +debasers +debases +debasing +debatable +debate +debated +debatement +debatements +debater +debaters +debates +debating +debauch +debauched +debauchee +debauchees +debaucher +debaucheries +debauchers +debauchery +debauches +debauching +debeak +debeaked +debeaking +debeaks +debenture +debentures +debilitate +debilitated +debilitates +debilitating +debilitation +debilitations +debilities +debility +debit +debited +debiting +debits +debonair +debonairly +debonairness +debonairnesses +debone +deboned +deboner +deboners +debones +deboning +debouch +debouche +debouched +debouches +debouching +debouchment +debouchments +debride +debrided +debridement +debridements +debrides +debriding +debrief +debriefed +debriefing +debriefings +debriefs +debris +debruise +debruised +debruises +debruising +debs +debt +debtless +debtor +debtors +debts +debug +debugged +debugger +debuggers +debugging +debugs +debunk +debunked +debunker +debunkers +debunking +debunks +debut +debutant +debutante +debutantes +debutants +debuted +debuting +debuts +debye +debyes +decadal +decade +decadence +decadences +decadencies +decadency +decadent +decadently +decadents +decades +decaf +decaffeinate +decaffeinated +decaffeinates +decaffeinating +decaffeination +decaffeinations +decafs +decagon +decagons +decagram +decagrams +decahedra +decahedron +decahedrons +decal +decalcification +decalcifications +decalcified +decalcifies +decalcify +decalcifying +decalcomania +decalcomanias +decaliter +decaliters +decalog +decalogs +decalogue +decalogues +decals +decameter +decameters +decamethonium +decamethoniums +decametric +decamp +decamped +decamping +decampment +decampments +decamps +decanal +decane +decanes +decant +decantation +decantations +decanted +decanter +decanters +decanting +decants +decapitate +decapitated +decapitates +decapitating +decapitation +decapitations +decapitator +decapitators +decapod +decapodan +decapodans +decapodous +decapods +decarbonate +decarbonated +decarbonates +decarbonating +decarbonation +decarbonations +decarbonize +decarbonized +decarbonizer +decarbonizers +decarbonizes +decarbonizing +decarboxylase +decarboxylases +decarboxylate +decarboxylated +decarboxylates +decarboxylating +decarboxylation +decarboxylations +decarburization +decarburizations +decarburize +decarburized +decarburizes +decarburizing +decare +decares +decasualization +decasualizations +decasyllabic +decasyllabics +decasyllable +decasyllables +decathlete +decathletes +decathlon +decathlons +decay +decayed +decayer +decayers +decaying +decays +decease +deceased +deceases +deceasing +decedent +decedents +deceit +deceitful +deceitfully +deceitfulness +deceitfulnesses +deceits +deceivable +deceive +deceived +deceiver +deceivers +deceives +deceiving +deceivingly +decelerate +decelerated +decelerates +decelerating +deceleration +decelerations +decelerator +decelerators +decemvir +decemviral +decemvirate +decemvirates +decemviri +decemvirs +decenaries +decenary +decencies +decency +decennia +decennial +decennially +decennials +decennium +decenniums +decent +decenter +decentered +decentering +decenters +decentest +decently +decentralization +decentralizations +decentralize +decentralized +decentralizes +decentralizing +decentre +decentred +decentres +decentring +deception +deceptional +deceptions +deceptive +deceptively +deceptiveness +deceptivenesses +decerebrate +decerebrated +decerebrates +decerebrating +decerebration +decerebrations +decern +decerned +decerning +decerns +decertification +decertifications +decertified +decertifies +decertify +decertifying +dechlorinate +dechlorinated +dechlorinates +dechlorinating +dechlorination +dechlorinations +deciare +deciares +decibel +decibels +decidabilities +decidability +decidable +decide +decided +decidedly +decidedness +decidednesses +decider +deciders +decides +deciding +decidua +deciduae +decidual +deciduas +deciduate +deciduous +deciduousness +deciduousnesses +decigram +decigrams +decile +deciles +deciliter +deciliters +decillion +decillions +decimal +decimalization +decimalizations +decimalize +decimalized +decimalizes +decimalizing +decimally +decimals +decimate +decimated +decimates +decimating +decimation +decimations +decimeter +decimeters +decipher +decipherable +deciphered +decipherer +decipherers +deciphering +decipherment +decipherments +deciphers +decision +decisional +decisioned +decisioning +decisions +decisive +decisively +decisiveness +decisivenesses +deck +decked +deckel +deckels +decker +deckers +deckhand +deckhands +deckhouse +deckhouses +decking +deckings +deckle +deckles +decks +declaim +declaimed +declaimer +declaimers +declaiming +declaims +declamation +declamations +declamatory +declarable +declarant +declarants +declaration +declarations +declarative +declaratively +declaratory +declare +declared +declarer +declarers +declares +declaring +declass +declasse +declassed +declasses +declassification +declassifications +declassified +declassifies +declassify +declassifying +declassing +declaw +declawed +declawing +declaws +declension +declensional +declensions +declinable +declination +declinational +declinations +decline +declined +decliner +decliners +declines +declining +declivities +declivitous +declivity +deco +decoct +decocted +decocting +decoction +decoctions +decocts +decode +decoded +decoder +decoders +decodes +decoding +decollate +decollated +decollates +decollating +decollation +decollations +decolletage +decolletages +decollete +decolletes +decolonization +decolonizations +decolonize +decolonized +decolonizes +decolonizing +decolor +decolored +decoloring +decolorization +decolorizations +decolorize +decolorized +decolorizer +decolorizers +decolorizes +decolorizing +decolors +decolour +decoloured +decolouring +decolours +decommission +decommissioned +decommissioning +decommissions +decompensate +decompensated +decompensates +decompensating +decompensation +decompensations +decomposabilities +decomposability +decomposable +decompose +decomposed +decomposer +decomposers +decomposes +decomposing +decomposition +decompositions +decompound +decompress +decompressed +decompresses +decompressing +decompression +decompressions +deconcentrate +deconcentrated +deconcentrates +deconcentrating +deconcentration +deconcentrations +decondition +deconditioned +deconditioning +deconditions +decongest +decongestant +decongestants +decongested +decongesting +decongestion +decongestions +decongestive +decongests +deconsecrate +deconsecrated +deconsecrates +deconsecrating +deconsecration +deconsecrations +deconstruct +deconstructed +deconstructing +deconstruction +deconstructionist +deconstructionists +deconstructions +deconstructive +deconstructor +deconstructors +deconstructs +decontaminate +decontaminated +decontaminates +decontaminating +decontamination +decontaminations +decontaminator +decontaminators +decontrol +decontrolled +decontrolling +decontrols +decor +decorate +decorated +decorates +decorating +decoration +decorations +decorative +decoratively +decorativeness +decorativenesses +decorator +decorators +decorous +decorously +decorousness +decorousnesses +decors +decorticate +decorticated +decorticates +decorticating +decortication +decortications +decorticator +decorticators +decorum +decorums +decos +decoupage +decoupaged +decoupages +decoupaging +decouple +decoupled +decouples +decoupling +decoy +decoyed +decoyer +decoyers +decoying +decoys +decrease +decreased +decreases +decreasing +decreasingly +decree +decreed +decreeing +decreer +decreers +decrees +decrement +decremental +decremented +decrementing +decrements +decrepit +decrepitate +decrepitated +decrepitates +decrepitating +decrepitation +decrepitations +decrepitly +decrepitude +decrepitudes +decrescendo +decrescendos +decrescent +decretal +decretals +decretive +decretory +decrial +decrials +decried +decrier +decriers +decries +decriminalization +decriminalizations +decriminalize +decriminalized +decriminalizes +decriminalizing +decrown +decrowned +decrowning +decrowns +decry +decrying +decrypt +decrypted +decrypting +decryption +decryptions +decrypts +decuman +decumbent +decuple +decupled +decuples +decupling +decuries +decurion +decurions +decurrent +decurve +decurved +decurves +decurving +decury +decussate +decussated +decussates +decussating +decussation +decussations +dedal +dedans +dedicate +dedicated +dedicatedly +dedicatee +dedicatees +dedicates +dedicating +dedication +dedications +dedicator +dedicators +dedicatory +dedifferentiate +dedifferentiated +dedifferentiates +dedifferentiating +dedifferentiation +dedifferentiations +deduce +deduced +deduces +deducible +deducing +deduct +deducted +deductibilities +deductibility +deductible +deductibles +deducting +deduction +deductions +deductive +deductively +deducts +dee +deed +deeded +deedier +deediest +deeding +deedless +deeds +deedy +deejay +deejays +deem +deemed +deeming +deems +deemster +deemsters +deep +deepen +deepened +deepener +deepeners +deepening +deepens +deeper +deepest +deeply +deepness +deepnesses +deeps +deepwater +deer +deerberries +deerberry +deerflies +deerfly +deerhound +deerhounds +deerlike +deers +deerskin +deerskins +deerstalker +deerstalkers +deerweed +deerweeds +deeryard +deeryards +dees +deescalate +deescalated +deescalates +deescalating +deescalation +deescalations +deet +deets +deewan +deewans +deface +defaced +defacement +defacements +defacer +defacers +defaces +defacing +defalcate +defalcated +defalcates +defalcating +defalcation +defalcations +defalcator +defalcators +defamation +defamations +defamatory +defame +defamed +defamer +defamers +defames +defaming +defang +defanged +defanging +defangs +defat +defats +defatted +defatting +default +defaulted +defaulter +defaulters +defaulting +defaults +defeasance +defeasances +defeasibilities +defeasibility +defeasible +defeat +defeated +defeater +defeaters +defeating +defeatism +defeatisms +defeatist +defeatists +defeats +defeature +defeatures +defecate +defecated +defecates +defecating +defecation +defecations +defect +defected +defecting +defection +defections +defective +defectively +defectiveness +defectivenesses +defectives +defector +defectors +defects +defeminization +defeminizations +defeminize +defeminized +defeminizes +defeminizing +defence +defenceman +defencemen +defences +defend +defendable +defendant +defendants +defended +defender +defenders +defending +defends +defenestrate +defenestrated +defenestrates +defenestrating +defenestration +defenestrations +defense +defensed +defenseless +defenselessly +defenselessness +defenselessnesses +defenseman +defensemen +defenses +defensibilities +defensibility +defensible +defensibly +defensing +defensive +defensively +defensiveness +defensivenesses +defensives +defer +deference +deferences +deferent +deferential +deferentially +deferents +deferment +deferments +deferrable +deferrables +deferral +deferrals +deferred +deferrer +deferrers +deferring +defers +defervescence +defervescences +defi +defiance +defiances +defiant +defiantly +defibrillate +defibrillated +defibrillates +defibrillating +defibrillation +defibrillations +defibrillator +defibrillators +defibrinate +defibrinated +defibrinates +defibrinating +defibrination +defibrinations +deficiencies +deficiency +deficient +deficiently +deficients +deficit +deficits +defied +defier +defiers +defies +defilade +defiladed +defilades +defilading +defile +defiled +defilement +defilements +defiler +defilers +defiles +defiling +definable +definably +define +defined +definement +definements +definer +definers +defines +definienda +definiendum +definiens +definientia +defining +definite +definitely +definiteness +definitenesses +definition +definitional +definitions +definitive +definitively +definitiveness +definitivenesses +definitives +definitize +definitized +definitizes +definitizing +definitude +definitudes +defis +deflagrate +deflagrated +deflagrates +deflagrating +deflagration +deflagrations +deflate +deflated +deflater +deflaters +deflates +deflating +deflation +deflationary +deflations +deflator +deflators +deflea +defleaed +defleaing +defleas +deflect +deflectable +deflected +deflecting +deflection +deflections +deflective +deflector +deflectors +deflects +deflexed +defloration +deflorations +deflower +deflowered +deflowerer +deflowerers +deflowering +deflowers +defoam +defoamed +defoamer +defoamers +defoaming +defoams +defocus +defocused +defocuses +defocusing +defocussed +defocusses +defocussing +defog +defogged +defogger +defoggers +defogging +defogs +defoliant +defoliants +defoliate +defoliated +defoliates +defoliating +defoliation +defoliations +defoliator +defoliators +deforce +deforced +deforcement +deforcements +deforces +deforcing +deforest +deforestation +deforestations +deforested +deforesting +deforests +deform +deformable +deformalize +deformalized +deformalizes +deformalizing +deformation +deformational +deformations +deformative +deformed +deformer +deformers +deforming +deformities +deformity +deforms +defraud +defrauded +defrauder +defrauders +defrauding +defrauds +defray +defrayable +defrayal +defrayals +defrayed +defrayer +defrayers +defraying +defrays +defrock +defrocked +defrocking +defrocks +defrost +defrosted +defroster +defrosters +defrosting +defrosts +deft +defter +deftest +deftly +deftness +deftnesses +defunct +defund +defunded +defunding +defunds +defuse +defused +defuses +defusing +defuze +defuzed +defuzes +defuzing +defy +defying +degage +degame +degames +degami +degamis +degas +degases +degassed +degasser +degassers +degasses +degassing +degauss +degaussed +degausser +degaussers +degausses +degaussing +degeneracies +degeneracy +degenerate +degenerated +degenerately +degenerateness +degeneratenesses +degenerates +degenerating +degeneration +degenerations +degenerative +degerm +degermed +degerming +degerms +deglaciated +deglaciation +deglaciations +deglamorization +deglamorizations +deglamorize +deglamorized +deglamorizes +deglamorizing +deglaze +deglazed +deglazes +deglazing +deglutition +deglutitions +degradable +degradation +degradations +degradative +degrade +degraded +degradedly +degrader +degraders +degrades +degrading +degradingly +degranulation +degranulations +degrease +degreased +degreaser +degreasers +degreases +degreasing +degree +degreed +degrees +degressive +degressively +degringolade +degringolades +degum +degummed +degumming +degums +degust +degustation +degustations +degusted +degusting +degusts +dehisce +dehisced +dehiscence +dehiscences +dehiscent +dehisces +dehiscing +dehorn +dehorned +dehorner +dehorners +dehorning +dehorns +dehort +dehorted +dehorting +dehorts +dehumanization +dehumanizations +dehumanize +dehumanized +dehumanizes +dehumanizing +dehumidification +dehumidifications +dehumidified +dehumidifier +dehumidifiers +dehumidifies +dehumidify +dehumidifying +dehydrate +dehydrated +dehydrates +dehydrating +dehydration +dehydrations +dehydrator +dehydrators +dehydrochlorinase +dehydrochlorinases +dehydrochlorinate +dehydrochlorinated +dehydrochlorinates +dehydrochlorinating +dehydrochlorination +dehydrochlorinations +dehydrogenase +dehydrogenases +dehydrogenate +dehydrogenated +dehydrogenates +dehydrogenating +dehydrogenation +dehydrogenations +deice +deiced +deicer +deicers +deices +deicidal +deicide +deicides +deicing +deictic +deific +deifical +deification +deifications +deified +deifier +deifiers +deifies +deiform +deify +deifying +deign +deigned +deigning +deigns +deil +deils +deindustrialization +deindustrializations +deindustrialize +deindustrialized +deindustrializes +deindustrializing +deinonychus +deinonychuses +deinstitutionalization +deinstitutionalizations +deinstitutionalize +deinstitutionalized +deinstitutionalizes +deinstitutionalizing +deionization +deionizations +deionize +deionized +deionizer +deionizers +deionizes +deionizing +deism +deisms +deist +deistic +deistical +deistically +deists +deities +deity +deixis +deixises +deject +dejecta +dejected +dejectedly +dejectedness +dejectednesses +dejecting +dejection +dejections +dejects +dejeuner +dejeuners +dekagram +dekagrams +dekaliter +dekaliters +dekameter +dekameters +dekametric +dekare +dekares +deke +deked +dekes +deking +dekko +dekkos +del +delaine +delaines +delaminate +delaminated +delaminates +delaminating +delamination +delaminations +delate +delated +delates +delating +delation +delations +delator +delators +delay +delayed +delayer +delayers +delaying +delays +dele +delead +deleaded +deleading +deleads +deleave +deleaved +deleaves +deleaving +delectabilities +delectability +delectable +delectables +delectably +delectation +delectations +deled +delegable +delegacies +delegacy +delegate +delegated +delegatee +delegatees +delegates +delegating +delegation +delegations +delegator +delegators +delegitimation +delegitimations +deleing +deles +delete +deleted +deleterious +deleteriously +deleteriousness +deleteriousnesses +deletes +deleting +deletion +deletions +delf +delfs +delft +delfts +delftware +delftwares +deli +deliberate +deliberated +deliberately +deliberateness +deliberatenesses +deliberates +deliberating +deliberation +deliberations +deliberative +deliberatively +deliberativeness +deliberativenesses +delicacies +delicacy +delicate +delicately +delicates +delicatessen +delicatessens +delicious +deliciously +deliciousness +deliciousnesses +delict +delicts +delight +delighted +delightedly +delightedness +delightednesses +delighter +delighters +delightful +delightfully +delightfulness +delightfulnesses +delighting +delights +delightsome +delime +delimed +delimes +deliming +delimit +delimitation +delimitations +delimited +delimiter +delimiters +delimiting +delimits +delineate +delineated +delineates +delineating +delineation +delineations +delineative +delineator +delineators +delinquencies +delinquency +delinquent +delinquently +delinquents +deliquesce +deliquesced +deliquescence +deliquescences +deliquescent +deliquesces +deliquescing +deliria +delirious +deliriously +deliriousness +deliriousnesses +delirium +deliriums +delis +delist +delisted +delisting +delists +deliver +deliverabilities +deliverability +deliverable +deliverance +deliverances +delivered +deliverer +deliverers +deliveries +delivering +delivers +delivery +deliveryman +deliverymen +dell +dellies +dells +delly +delocalization +delocalizations +delocalize +delocalized +delocalizes +delocalizing +delouse +deloused +delouser +delousers +delouses +delousing +delphic +delphically +delphinium +delphiniums +dels +delta +deltaic +deltas +deltic +deltoid +deltoidei +deltoideus +deltoids +delude +deluded +deluder +deluders +deludes +deluding +deluge +deluged +deluges +deluging +delusion +delusional +delusionary +delusions +delusive +delusively +delusiveness +delusivenesses +delusory +deluster +delustered +delustering +delusters +deluxe +delve +delved +delver +delvers +delves +delving +demagnetization +demagnetizations +demagnetize +demagnetized +demagnetizer +demagnetizers +demagnetizes +demagnetizing +demagog +demagoged +demagogic +demagogically +demagogies +demagoging +demagogs +demagogue +demagogued +demagogueries +demagoguery +demagogues +demagoguing +demagogy +demand +demandable +demandant +demandants +demanded +demander +demanders +demanding +demandingly +demandingness +demandingnesses +demands +demantoid +demantoids +demarcate +demarcated +demarcates +demarcating +demarcation +demarcations +demarche +demarches +demark +demarked +demarking +demarks +demast +demasted +demasting +demasts +dematerialization +dematerializations +dematerialize +dematerialized +dematerializes +dematerializing +deme +demean +demeaned +demeaning +demeanor +demeanors +demeanour +demeanours +demeans +dement +demented +dementedly +dementedness +dementednesses +dementia +demential +dementias +dementing +dements +demerara +demeraras +demerge +demerged +demerger +demergered +demergering +demergers +demerges +demerging +demerit +demerited +demeriting +demerits +demersal +demes +demesne +demesnes +demeton +demetons +demies +demigod +demigoddess +demigoddesses +demigods +demijohn +demijohns +demilitarization +demilitarizations +demilitarize +demilitarized +demilitarizes +demilitarizing +demilune +demilunes +demimondaine +demimondaines +demimonde +demimondes +demineralization +demineralizations +demineralize +demineralized +demineralizer +demineralizers +demineralizes +demineralizing +demirep +demireps +demise +demised +demisemiquaver +demisemiquavers +demises +demising +demission +demissions +demit +demitasse +demitasses +demits +demitted +demitting +demiurge +demiurges +demiurgic +demiurgical +demivolt +demivolts +demiworld +demiworlds +demo +demob +demobbed +demobbing +demobilization +demobilizations +demobilize +demobilized +demobilizes +demobilizing +demobs +democracies +democracy +democrat +democratic +democratically +democratization +democratizations +democratize +democratized +democratizer +democratizers +democratizes +democratizing +democrats +demode +demoded +demodulate +demodulated +demodulates +demodulating +demodulation +demodulations +demodulator +demodulators +demographer +demographers +demographic +demographical +demographically +demographics +demographies +demography +demoiselle +demoiselles +demolish +demolished +demolisher +demolishers +demolishes +demolishing +demolishment +demolishments +demolition +demolitionist +demolitionists +demolitions +demon +demoness +demonesses +demonetization +demonetizations +demonetize +demonetized +demonetizes +demonetizing +demoniac +demoniacal +demoniacally +demoniacs +demonian +demonic +demonical +demonically +demonise +demonised +demonises +demonising +demonism +demonisms +demonist +demonists +demonization +demonizations +demonize +demonized +demonizes +demonizing +demonological +demonologies +demonologist +demonologists +demonology +demons +demonstrabilities +demonstrability +demonstrable +demonstrably +demonstrate +demonstrated +demonstrates +demonstrating +demonstration +demonstrational +demonstrations +demonstrative +demonstratively +demonstrativeness +demonstrativenesses +demonstratives +demonstrator +demonstrators +demoralization +demoralizations +demoralize +demoralized +demoralizer +demoralizers +demoralizes +demoralizing +demoralizingly +demos +demoses +demote +demoted +demotes +demotic +demotics +demoting +demotion +demotions +demotist +demotists +demount +demountable +demounted +demounting +demounts +dempster +dempsters +demulcent +demulcents +demultiplexer +demultiplexers +demur +demure +demurely +demureness +demurenesses +demurer +demurest +demurrage +demurrages +demurral +demurrals +demurred +demurrer +demurrers +demurring +demurs +demy +demyelinating +demyelination +demyelinations +demystification +demystifications +demystified +demystifies +demystify +demystifying +demythologization +demythologizations +demythologize +demythologized +demythologizer +demythologizers +demythologizes +demythologizing +den +denarii +denarius +denary +denationalization +denationalizations +denationalize +denationalized +denationalizes +denationalizing +denaturalization +denaturalizations +denaturalize +denaturalized +denaturalizes +denaturalizing +denaturant +denaturants +denaturation +denaturations +denature +denatured +denatures +denaturing +denazification +denazifications +denazified +denazifies +denazify +denazifying +dendriform +dendrite +dendrites +dendritic +dendrochronological +dendrochronologically +dendrochronologies +dendrochronologist +dendrochronologists +dendrochronology +dendrogram +dendrograms +dendroid +dendrologic +dendrological +dendrologies +dendrologist +dendrologists +dendrology +dendron +dendrons +dene +denegation +denegations +denervate +denervated +denervates +denervating +denervation +denervations +denes +dengue +dengues +deniabilities +deniability +deniable +deniably +denial +denials +denied +denier +deniers +denies +denigrate +denigrated +denigrates +denigrating +denigration +denigrations +denigrative +denigrator +denigrators +denigratory +denim +denims +denitrification +denitrifications +denitrified +denitrifier +denitrifiers +denitrifies +denitrify +denitrifying +denizen +denizened +denizening +denizens +denned +denning +denominal +denominate +denominated +denominates +denominating +denomination +denominational +denominationalism +denominationalisms +denominations +denominative +denominatives +denominator +denominators +denotation +denotations +denotative +denote +denoted +denotement +denotements +denotes +denoting +denotive +denouement +denouements +denounce +denounced +denouncement +denouncements +denouncer +denouncers +denounces +denouncing +dens +dense +densely +denseness +densenesses +denser +densest +densification +densifications +densified +densifies +densify +densifying +densities +densitometer +densitometers +densitometric +densitometries +densitometry +density +dent +dental +dentalia +dentalium +dentally +dentals +dentate +dentated +dented +denticle +denticles +denticulate +denticulated +denticulation +denticulations +dentiform +dentifrice +dentifrices +dentil +dentiled +dentils +dentin +dentinal +dentine +dentines +denting +dentins +dentist +dentistries +dentistry +dentists +dentition +dentitions +dentoid +dents +dentulous +dentural +denture +dentures +denturist +denturists +denuclearization +denuclearizations +denuclearize +denuclearized +denuclearizes +denuclearizing +denudate +denudated +denudates +denudating +denudation +denudations +denude +denuded +denudement +denudements +denuder +denuders +denudes +denuding +denumerabilities +denumerability +denumerable +denumerably +denunciation +denunciations +denunciative +denunciatory +deny +denying +denyingly +deodand +deodands +deodar +deodara +deodaras +deodars +deodorant +deodorants +deodorization +deodorizations +deodorize +deodorized +deodorizer +deodorizers +deodorizes +deodorizing +deontic +deontological +deontologies +deontologist +deontologists +deontology +deorbit +deorbited +deorbiting +deorbits +deoxidation +deoxidations +deoxidize +deoxidized +deoxidizer +deoxidizers +deoxidizes +deoxidizing +deoxy +deoxygenate +deoxygenated +deoxygenates +deoxygenating +deoxygenation +deoxygenations +deoxyribonuclease +deoxyribonucleases +deoxyribonucleotide +deoxyribonucleotides +deoxyribose +deoxyriboses +depaint +depainted +depainting +depaints +depart +departed +departee +departees +departing +department +departmental +departmentalization +departmentalizations +departmentalize +departmentalized +departmentalizes +departmentalizing +departmentally +departments +departs +departure +departures +depauperate +depend +dependabilities +dependability +dependable +dependableness +dependablenesses +dependably +dependance +dependances +dependant +dependants +depended +dependence +dependences +dependencies +dependency +dependent +dependently +dependents +depending +depends +deperm +depermed +deperming +deperms +depersonalization +depersonalizations +depersonalize +depersonalized +depersonalizes +depersonalizing +dephosphorylate +dephosphorylated +dephosphorylates +dephosphorylating +dephosphorylation +dephosphorylations +depict +depicted +depicter +depicters +depicting +depiction +depictions +depictor +depictors +depicts +depigmentation +depigmentations +depilate +depilated +depilates +depilating +depilation +depilations +depilatories +depilatory +deplane +deplaned +deplanes +deplaning +depletable +deplete +depleted +depletes +depleting +depletion +depletions +depletive +deplorable +deplorableness +deplorablenesses +deplorably +deplore +deplored +deplorer +deplorers +deplores +deploring +deploringly +deploy +deployable +deployed +deploying +deployment +deployments +deploys +deplume +deplumed +deplumes +depluming +depolarization +depolarizations +depolarize +depolarized +depolarizer +depolarizers +depolarizes +depolarizing +depolish +depolished +depolishes +depolishing +depoliticization +depoliticizations +depoliticize +depoliticized +depoliticizes +depoliticizing +depolymerization +depolymerizations +depolymerize +depolymerized +depolymerizes +depolymerizing +depone +deponed +deponent +deponents +depones +deponing +depopulate +depopulated +depopulates +depopulating +depopulation +depopulations +deport +deportable +deportation +deportations +deported +deportee +deportees +deporting +deportment +deportments +deports +deposal +deposals +depose +deposed +deposer +deposers +deposes +deposing +deposit +depositaries +depositary +deposited +depositing +deposition +depositional +depositions +depositor +depositories +depositors +depository +deposits +depot +depots +depravation +depravations +deprave +depraved +depravedly +depravedness +depravednesses +depravement +depravements +depraver +depravers +depraves +depraving +depravities +depravity +deprecate +deprecated +deprecates +deprecating +deprecatingly +deprecation +deprecations +deprecatorily +deprecatory +depreciable +depreciate +depreciated +depreciates +depreciating +depreciatingly +depreciation +depreciations +depreciative +depreciator +depreciators +depreciatory +depredate +depredated +depredates +depredating +depredation +depredations +depredator +depredators +depredatory +depress +depressant +depressants +depressed +depresses +depressible +depressing +depressingly +depression +depressions +depressive +depressively +depressives +depressor +depressors +depressurization +depressurizations +depressurize +depressurized +depressurizes +depressurizing +deprival +deprivals +deprivation +deprivations +deprive +deprived +depriver +deprivers +deprives +depriving +deprogram +deprogramed +deprograming +deprogrammed +deprogrammer +deprogrammers +deprogramming +deprograms +depside +depsides +depth +depthless +depths +depurate +depurated +depurates +depurating +deputation +deputations +depute +deputed +deputes +deputies +deputing +deputization +deputizations +deputize +deputized +deputizes +deputizing +deputy +deracinate +deracinated +deracinates +deracinating +deracination +deracinations +deraign +deraigned +deraigning +deraigns +derail +derailed +derailing +derailleur +derailleurs +derailment +derailments +derails +derange +deranged +derangement +derangements +deranges +deranging +derat +derate +derated +derates +derating +derats +deratted +deratting +deray +derays +derbies +derby +dere +derealization +derealizations +deregulate +deregulated +deregulates +deregulating +deregulation +deregulations +derelict +dereliction +derelictions +derelicts +derepress +derepressed +derepresses +derepressing +derepression +derepressions +deride +derided +derider +deriders +derides +deriding +deridingly +deringer +deringers +derision +derisions +derisive +derisively +derisiveness +derisivenesses +derisory +derivable +derivate +derivates +derivation +derivational +derivations +derivative +derivatively +derivativeness +derivativenesses +derivatives +derivatization +derivatizations +derivatize +derivatized +derivatizes +derivatizing +derive +derived +deriver +derivers +derives +deriving +derm +derma +dermabrasion +dermabrasions +dermal +dermas +dermatites +dermatitides +dermatitis +dermatitises +dermatogen +dermatogens +dermatoglyphic +dermatoglyphics +dermatologic +dermatological +dermatologies +dermatologist +dermatologists +dermatology +dermatomal +dermatome +dermatomes +dermatophyte +dermatophytes +dermatoses +dermatosis +dermestid +dermestids +dermic +dermis +dermises +dermoid +dermoids +derms +dernier +derogate +derogated +derogates +derogating +derogation +derogations +derogative +derogatively +derogatorily +derogatory +derrick +derricks +derriere +derrieres +derries +derringer +derringers +derris +derrises +derry +dervish +dervishes +desacralization +desacralizations +desacralize +desacralized +desacralizes +desacralizing +desalinate +desalinated +desalinates +desalinating +desalination +desalinations +desalinator +desalinators +desalinization +desalinizations +desalinize +desalinized +desalinizes +desalinizing +desalt +desalted +desalter +desalters +desalting +desalts +desand +desanded +desanding +desands +descant +descanted +descanting +descants +descend +descendant +descendants +descended +descendent +descendents +descender +descenders +descendible +descending +descends +descension +descensions +descent +descents +describable +describe +described +describer +describers +describes +describing +descried +descrier +descriers +descries +description +descriptions +descriptive +descriptively +descriptiveness +descriptivenesses +descriptor +descriptors +descry +descrying +desecrate +desecrated +desecrater +desecraters +desecrates +desecrating +desecration +desecrations +desecrator +desecrators +desegregate +desegregated +desegregates +desegregating +desegregation +desegregations +deselect +deselected +deselecting +deselects +desensitization +desensitizations +desensitize +desensitized +desensitizer +desensitizers +desensitizes +desensitizing +desert +deserted +deserter +deserters +desertic +desertification +desertifications +deserting +desertion +desertions +deserts +deserve +deserved +deservedly +deservedness +deservednesses +deserver +deservers +deserves +deserving +deservings +desex +desexed +desexes +desexing +desexualization +desexualizations +desexualize +desexualized +desexualizes +desexualizing +deshabille +deshabilles +desiccant +desiccants +desiccate +desiccated +desiccates +desiccating +desiccation +desiccations +desiccative +desiccator +desiccators +desiderata +desiderate +desiderated +desiderates +desiderating +desideration +desiderations +desiderative +desideratum +design +designate +designated +designates +designating +designation +designations +designative +designator +designators +designatory +designed +designedly +designee +designees +designer +designers +designing +designment +designments +designs +desilver +desilvered +desilvering +desilvers +desinent +desipramine +desipramines +desirabilities +desirability +desirable +desirableness +desirablenesses +desirables +desirably +desire +desired +desirer +desirers +desires +desiring +desirous +desirously +desirousness +desirousnesses +desist +desistance +desistances +desisted +desisting +desists +desk +deskbound +deskman +deskmen +desks +desktop +desktops +desman +desmans +desmid +desmids +desmoid +desmoids +desmosomal +desmosome +desmosomes +desolate +desolated +desolately +desolateness +desolatenesses +desolater +desolaters +desolates +desolating +desolatingly +desolation +desolations +desolator +desolators +desorb +desorbed +desorbing +desorbs +desorption +desorptions +desoxy +despair +despaired +despairer +despairers +despairing +despairingly +despairs +despatch +despatched +despatches +despatching +desperado +desperadoes +desperados +desperate +desperately +desperateness +desperatenesses +desperation +desperations +despicable +despicableness +despicablenesses +despicably +despiritualize +despiritualized +despiritualizes +despiritualizing +despise +despised +despisement +despisements +despiser +despisers +despises +despising +despite +despited +despiteful +despitefully +despitefulness +despitefulnesses +despiteous +despiteously +despites +despiting +despoil +despoiled +despoiler +despoilers +despoiling +despoilment +despoilments +despoils +despoliation +despoliations +despond +desponded +despondence +despondences +despondencies +despondency +despondent +despondently +desponding +desponds +despot +despotic +despotically +despotism +despotisms +despots +desquamate +desquamated +desquamates +desquamating +desquamation +desquamations +dessert +desserts +dessertspoon +dessertspoonful +dessertspoonfuls +dessertspoons +dessertspoonsful +destabilization +destabilizations +destabilize +destabilized +destabilizes +destabilizing +destain +destained +destaining +destains +destination +destinations +destine +destined +destines +destinies +destining +destiny +destitute +destituteness +destitutenesses +destitution +destitutions +destrier +destriers +destroy +destroyed +destroyer +destroyers +destroying +destroys +destruct +destructed +destructibilities +destructibility +destructible +destructing +destruction +destructionist +destructionists +destructions +destructive +destructively +destructiveness +destructivenesses +destructivities +destructivity +destructs +desuetude +desuetudes +desugar +desugared +desugaring +desugars +desulfur +desulfured +desulfuring +desulfurization +desulfurizations +desulfurize +desulfurized +desulfurizes +desulfurizing +desulfurs +desultorily +desultoriness +desultorinesses +desultory +detach +detachabilities +detachability +detachable +detachably +detached +detachedly +detachedness +detachednesses +detacher +detachers +detaches +detaching +detachment +detachments +detail +detailed +detailedly +detailedness +detailednesses +detailer +detailers +detailing +details +detain +detained +detainee +detainees +detainer +detainers +detaining +detainment +detainments +detains +detassel +detasseled +detasseling +detasselled +detasselling +detassels +detect +detectabilities +detectability +detectable +detected +detecter +detecters +detecting +detection +detections +detective +detectivelike +detectives +detector +detectors +detects +detent +detente +detentes +detention +detentions +detents +deter +deterge +deterged +detergencies +detergency +detergent +detergents +deterger +detergers +deterges +deterging +deteriorate +deteriorated +deteriorates +deteriorating +deterioration +deteriorations +deteriorative +determent +determents +determinable +determinableness +determinablenesses +determinably +determinacies +determinacy +determinant +determinantal +determinants +determinate +determinately +determinateness +determinatenesses +determination +determinations +determinative +determinatives +determinator +determinators +determine +determined +determinedly +determinedness +determinednesses +determiner +determiners +determines +determining +determinism +determinisms +determinist +deterministic +deterministically +determinists +deterrabilities +deterrability +deterrable +deterred +deterrence +deterrences +deterrent +deterrently +deterrents +deterrer +deterrers +deterring +deters +detersive +detersives +detest +detestable +detestableness +detestablenesses +detestably +detestation +detestations +detested +detester +detesters +detesting +detests +dethrone +dethroned +dethronement +dethronements +dethroner +dethroners +dethrones +dethroning +detick +deticked +deticker +detickers +deticking +deticks +detinue +detinues +detonabilities +detonability +detonable +detonatable +detonate +detonated +detonates +detonating +detonation +detonations +detonative +detonator +detonators +detour +detoured +detouring +detours +detox +detoxed +detoxes +detoxicant +detoxicants +detoxicate +detoxicated +detoxicates +detoxicating +detoxication +detoxications +detoxification +detoxifications +detoxified +detoxifies +detoxify +detoxifying +detoxing +detract +detracted +detracting +detraction +detractions +detractive +detractively +detractor +detractors +detracts +detrain +detrained +detraining +detrainment +detrainments +detrains +detribalization +detribalizations +detribalize +detribalized +detribalizes +detribalizing +detriment +detrimental +detrimentally +detrimentals +detriments +detrital +detrition +detritions +detritus +detrude +detruded +detrudes +detruding +detumescence +detumescences +detumescent +deuce +deuced +deucedly +deuces +deucing +deuteragonist +deuteragonists +deuteranomalies +deuteranomalous +deuteranomaly +deuteranope +deuteranopes +deuteranopia +deuteranopias +deuteranopic +deuterate +deuterated +deuterates +deuterating +deuteration +deuterations +deuteric +deuterium +deuteriums +deuterocanonical +deuteron +deuterons +deuterostome +deuterostomes +deutoplasm +deutoplasms +deutzia +deutzias +dev +deva +devaluate +devaluated +devaluates +devaluating +devaluation +devaluations +devalue +devalued +devalues +devaluing +devas +devastate +devastated +devastates +devastating +devastatingly +devastation +devastations +devastative +devastator +devastators +devein +deveined +deveining +deveins +devel +develed +develing +develop +developable +develope +developed +developer +developers +developes +developing +development +developmental +developmentally +developments +develops +devels +deverbal +deverbative +deverbatives +devest +devested +devesting +devests +deviance +deviances +deviancies +deviancy +deviant +deviants +deviate +deviated +deviates +deviating +deviation +deviationism +deviationisms +deviationist +deviationists +deviations +deviator +deviators +deviatory +device +devices +devil +deviled +devilfish +devilfishes +deviling +devilish +devilishly +devilishness +devilishnesses +devilkin +devilkins +devilled +devilling +devilment +devilments +devilries +devilry +devils +deviltries +deviltry +devilwood +devilwoods +devious +deviously +deviousness +deviousnesses +devisable +devisal +devisals +devise +devised +devisee +devisees +deviser +devisers +devises +devising +devisor +devisors +devitalize +devitalized +devitalizes +devitalizing +devitrification +devitrifications +devitrified +devitrifies +devitrify +devitrifying +devocalize +devocalized +devocalizes +devocalizing +devoice +devoiced +devoices +devoicing +devoid +devoir +devoirs +devolution +devolutionary +devolutionist +devolutionists +devolutions +devolve +devolved +devolves +devolving +devon +devons +devote +devoted +devotedly +devotedness +devotednesses +devotee +devotees +devotement +devotements +devotes +devoting +devotion +devotional +devotionally +devotionals +devotions +devour +devoured +devourer +devourers +devouring +devours +devout +devouter +devoutest +devoutly +devoutness +devoutnesses +devs +dew +dewan +dewans +dewar +dewars +dewater +dewatered +dewaterer +dewaterers +dewatering +dewaters +dewax +dewaxed +dewaxes +dewaxing +dewberries +dewberry +dewclaw +dewclaws +dewdrop +dewdrops +dewed +dewfall +dewfalls +dewier +dewiest +dewily +dewiness +dewinesses +dewing +dewlap +dewlapped +dewlaps +dewless +dewool +dewooled +dewooling +dewools +deworm +dewormed +dewormer +dewormers +deworming +deworms +dews +dewy +dex +dexamethasone +dexamethasones +dexes +dexie +dexies +dexter +dexterities +dexterity +dexterous +dexterously +dexterousness +dexterousnesses +dextral +dextran +dextranase +dextranases +dextrans +dextrin +dextrine +dextrines +dextrins +dextro +dextroamphetamine +dextroamphetamines +dextrorotary +dextrorotatory +dextrose +dextroses +dextrous +dexy +dey +deys +dezinc +dezinced +dezincing +dezincked +dezincking +dezincs +dhak +dhaks +dhal +dhals +dharma +dharmas +dharmic +dharna +dharnas +dhobi +dhobis +dhole +dholes +dhoolies +dhooly +dhoora +dhooras +dhooti +dhootie +dhooties +dhootis +dhoti +dhotis +dhourra +dhourras +dhow +dhows +dhurna +dhurnas +dhurrie +dhurries +dhuti +dhutis +diabase +diabases +diabasic +diabetes +diabetic +diabetics +diabetogenic +diabetologist +diabetologists +diablerie +diableries +diablery +diabolic +diabolical +diabolically +diabolicalness +diabolicalnesses +diabolism +diabolisms +diabolist +diabolists +diabolize +diabolized +diabolizes +diabolizing +diabolo +diabolos +diacetyl +diacetyls +diachronic +diachronically +diachronies +diachrony +diacid +diacidic +diacids +diaconal +diaconate +diaconates +diacritic +diacritical +diacritics +diadelphous +diadem +diademed +diademing +diadems +diadromous +diaereses +diaeresis +diaeretic +diageneses +diagenesis +diagenetic +diagenetically +diageotropic +diagnosable +diagnose +diagnoseable +diagnosed +diagnoses +diagnosing +diagnosis +diagnostic +diagnostical +diagnostically +diagnostician +diagnosticians +diagnostics +diagonal +diagonalizable +diagonalization +diagonalizations +diagonalize +diagonalized +diagonalizes +diagonalizing +diagonally +diagonals +diagram +diagramed +diagraming +diagrammable +diagrammatic +diagrammatical +diagrammatically +diagrammed +diagramming +diagrams +diagraph +diagraphs +diakineses +diakinesis +dial +dialect +dialectal +dialectally +dialectic +dialectical +dialectically +dialectician +dialecticians +dialectics +dialectological +dialectologically +dialectologies +dialectologist +dialectologists +dialectology +dialects +dialed +dialer +dialers +dialing +dialings +dialist +dialists +diallage +diallages +dialled +diallel +dialler +diallers +dialling +diallings +diallist +diallists +dialog +dialoged +dialoger +dialogers +dialogic +dialogical +dialogically +dialoging +dialogist +dialogistic +dialogists +dialogs +dialogue +dialogued +dialogues +dialoguing +dials +dialysate +dialysates +dialyse +dialysed +dialyser +dialysers +dialyses +dialysing +dialysis +dialytic +dialyzable +dialyzate +dialyzates +dialyze +dialyzed +dialyzer +dialyzers +dialyzes +dialyzing +diamagnetic +diamagnetism +diamagnetisms +diamante +diamantes +diameter +diameters +diametral +diametric +diametrical +diametrically +diamide +diamides +diamin +diamine +diamines +diamins +diamond +diamondback +diamondbacks +diamonded +diamondiferous +diamonding +diamonds +dianthus +dianthuses +diapason +diapasons +diapause +diapaused +diapauses +diapausing +diapedeses +diapedesis +diaper +diapered +diapering +diapers +diaphaneities +diaphaneity +diaphanous +diaphanously +diaphanousness +diaphanousnesses +diaphone +diaphones +diaphonies +diaphony +diaphorase +diaphorases +diaphoreses +diaphoresis +diaphoretic +diaphoretics +diaphragm +diaphragmatic +diaphragmatically +diaphragms +diaphyseal +diaphyses +diaphysial +diaphysis +diapir +diapiric +diapirs +diapositive +diapositives +diapsid +diarchic +diarchies +diarchy +diaries +diarist +diarists +diarrhea +diarrheal +diarrheas +diarrheic +diarrhetic +diarrhoea +diarrhoeas +diarthroses +diarthrosis +diary +diaspora +diasporas +diaspore +diaspores +diastase +diastases +diastatic +diastem +diastema +diastemata +diastems +diaster +diastereoisomer +diastereoisomeric +diastereoisomerism +diastereoisomerisms +diastereoisomers +diastereomer +diastereomeric +diastereomers +diasters +diastole +diastoles +diastolic +diastral +diastrophic +diastrophically +diastrophism +diastrophisms +diatessaron +diatessarons +diathermanous +diathermic +diathermies +diathermy +diatheses +diathesis +diathetic +diatom +diatomaceous +diatomic +diatomite +diatomites +diatoms +diatonic +diatonically +diatribe +diatribes +diatron +diatrons +diazepam +diazepams +diazin +diazine +diazines +diazinon +diazinons +diazins +diazo +diazole +diazoles +diazonium +diazoniums +diazotization +diazotizations +diazotize +diazotized +diazotizes +diazotizing +dib +dibasic +dibbed +dibber +dibbers +dibbing +dibble +dibbled +dibbler +dibblers +dibbles +dibbling +dibbuk +dibbukim +dibbuks +dibenzofuran +dibenzofurans +dibs +dicarboxylic +dicast +dicastic +dicasts +dice +diced +dicentra +dicentras +dicentric +dicentrics +dicer +dicers +dices +dicey +dichasia +dichasium +dichlorobenzene +dichlorobenzenes +dichlorodifluoromethane +dichlorodifluoromethanes +dichloroethane +dichloroethanes +dichlorvos +dichlorvoses +dichogamies +dichogamous +dichogamy +dichondra +dichondras +dichotic +dichotically +dichotomies +dichotomist +dichotomists +dichotomization +dichotomizations +dichotomize +dichotomized +dichotomizes +dichotomizing +dichotomous +dichotomously +dichotomousness +dichotomousnesses +dichotomy +dichroic +dichroism +dichroisms +dichromat +dichromate +dichromates +dichromatic +dichromatism +dichromatisms +dichromats +dichroscope +dichroscopes +dicier +diciest +dicing +dick +dickcissel +dickcissels +dicked +dickens +dickenses +dicker +dickered +dickering +dickers +dickey +dickeys +dickie +dickier +dickies +dickiest +dicking +dicks +dicky +diclinies +diclinous +dicliny +dicot +dicots +dicotyl +dicotyledon +dicotyledonous +dicotyledons +dicotyls +dicoumarin +dicoumarins +dicoumarol +dicoumarols +dicrotal +dicrotic +dicrotism +dicrotisms +dicta +dictate +dictated +dictates +dictating +dictation +dictations +dictator +dictatorial +dictatorially +dictatorialness +dictatorialnesses +dictators +dictatorship +dictatorships +dictier +dictiest +diction +dictional +dictionally +dictionaries +dictionary +dictions +dictum +dictums +dicty +dictyosome +dictyosomes +dictyostele +dictyosteles +dicumarol +dicumarols +dicyclic +dicyclies +dicycly +dicynodont +dicynodonts +did +didact +didactic +didactical +didactically +didacticism +didacticisms +didactics +didacts +didactyl +didapper +didappers +diddle +diddled +diddler +diddlers +diddles +diddley +diddleys +diddlies +diddling +diddly +diddlysquat +didgeridoo +didgeridoos +didie +didies +didjeridoo +didjeridoos +dido +didoes +didos +didst +didy +didymium +didymiums +didymous +didynamies +didynamy +die +dieback +diebacks +diecious +died +dieffenbachia +dieffenbachias +diehard +diehards +dieing +diel +dieldrin +dieldrins +dielectric +dielectrics +diemaker +diemakers +diencephala +diencephalic +diencephalon +diencephalons +diene +dienes +diereses +dieresis +dieretic +dies +diesel +dieseled +dieseling +dieselings +dieselization +dieselizations +dieselize +dieselized +dieselizes +dieselizing +diesels +dieses +diesis +diester +diesters +diestock +diestocks +diestrous +diestrum +diestrums +diestrus +diestruses +diet +dietaries +dietarily +dietary +dieted +dieter +dieters +dietetic +dietetically +dietetics +diether +diethers +diethylcarbamazine +diethylcarbamazines +diethylstilbestrol +diethylstilbestrols +dietician +dieticians +dieting +dietitian +dietitians +diets +differ +differed +difference +differenced +differences +differencing +different +differentia +differentiabilities +differentiability +differentiable +differentiae +differential +differentially +differentials +differentiate +differentiated +differentiates +differentiating +differentiation +differentiations +differently +differentness +differentnesses +differing +differs +difficile +difficult +difficulties +difficultly +difficulty +diffidence +diffidences +diffident +diffidently +diffract +diffracted +diffracting +diffraction +diffractions +diffractometer +diffractometers +diffractometric +diffractometries +diffractometry +diffracts +diffuse +diffused +diffusely +diffuseness +diffusenesses +diffuser +diffusers +diffuses +diffusible +diffusing +diffusion +diffusional +diffusionism +diffusionisms +diffusionist +diffusionists +diffusions +diffusive +diffusively +diffusiveness +diffusivenesses +diffusivities +diffusivity +diffusor +diffusors +difunctional +dig +digamies +digamist +digamists +digamma +digammas +digamous +digamy +digastric +digenetic +digest +digested +digester +digesters +digestibilities +digestibility +digestible +digesting +digestion +digestions +digestive +digestively +digestives +digestor +digestors +digests +digged +digger +diggers +digging +diggings +dight +dighted +dighting +dights +digit +digital +digitalin +digitalins +digitalis +digitalises +digitalization +digitalizations +digitalize +digitalized +digitalizes +digitalizing +digitally +digitals +digitate +digitately +digitigrade +digitization +digitizations +digitize +digitized +digitizer +digitizers +digitizes +digitizing +digitonin +digitonins +digitoxigenin +digitoxigenins +digitoxin +digitoxins +digits +diglot +diglots +diglyceride +diglycerides +dignified +dignifies +dignify +dignifying +dignitaries +dignitary +dignities +dignity +digoxin +digoxins +digraph +digraphic +digraphically +digraphs +digress +digressed +digresses +digressing +digression +digressional +digressionary +digressions +digressive +digressively +digressiveness +digressivenesses +digs +dihedral +dihedrals +dihedron +dihedrons +dihybrid +dihybrids +dihydric +dihydroergotamine +dihydroergotamines +dihydroxyacetone +dihydroxyacetones +dikdik +dikdiks +dike +diked +diker +dikers +dikes +dikey +diking +diktat +diktats +dilapidate +dilapidated +dilapidates +dilapidating +dilapidation +dilapidations +dilatabilities +dilatability +dilatable +dilatancies +dilatancy +dilatant +dilatants +dilatate +dilatation +dilatational +dilatations +dilate +dilated +dilater +dilaters +dilates +dilating +dilation +dilations +dilative +dilatometer +dilatometers +dilatometric +dilatometries +dilatometry +dilator +dilatorily +dilatoriness +dilatorinesses +dilators +dilatory +dildo +dildoe +dildoes +dildos +dilemma +dilemmas +dilemmatic +dilemmic +dilettante +dilettantes +dilettanti +dilettantish +dilettantism +dilettantisms +diligence +diligences +diligent +diligently +dill +dilled +dillies +dills +dilly +dillydallied +dillydallies +dillydally +dillydallying +diluent +diluents +dilute +diluted +diluteness +dilutenesses +diluter +diluters +dilutes +diluting +dilution +dilutions +dilutive +dilutor +dilutors +diluvia +diluvial +diluvian +diluvion +diluvions +diluvium +diluviums +dim +dime +dimenhydrinate +dimenhydrinates +dimension +dimensional +dimensionalities +dimensionality +dimensionally +dimensioned +dimensioning +dimensionless +dimensions +dimer +dimercaprol +dimercaprols +dimeric +dimerism +dimerisms +dimerization +dimerizations +dimerize +dimerized +dimerizes +dimerizing +dimerous +dimers +dimes +dimeter +dimeters +dimethoate +dimethoates +dimethyl +dimethylhydrazine +dimethylhydrazines +dimethylnitrosamine +dimethylnitrosamines +dimethyls +dimethyltryptamine +dimethyltryptamines +dimetric +diminish +diminishable +diminished +diminishes +diminishing +diminishment +diminishments +diminuendo +diminuendos +diminution +diminutions +diminutive +diminutively +diminutiveness +diminutivenesses +diminutives +dimities +dimity +dimly +dimmable +dimmed +dimmer +dimmers +dimmest +dimming +dimness +dimnesses +dimorph +dimorphic +dimorphism +dimorphisms +dimorphous +dimorphs +dimout +dimouts +dimple +dimpled +dimples +dimplier +dimpliest +dimpling +dimply +dims +dimwit +dimwits +dimwitted +din +dinar +dinars +dindle +dindled +dindles +dindling +dine +dined +diner +dineric +dinero +dineros +diners +dines +dinette +dinettes +ding +dingbat +dingbats +dingdong +dingdonged +dingdonging +dingdongs +dinge +dinged +dinger +dingers +dinges +dingey +dingeys +dinghies +dinghy +dingier +dingies +dingiest +dingily +dinginess +dinginesses +dinging +dingle +dingleberries +dingleberry +dingles +dingo +dingoes +dings +dingus +dinguses +dingy +dining +dinitro +dinitrobenzene +dinitrobenzenes +dinitrophenol +dinitrophenols +dink +dinked +dinkey +dinkeys +dinkier +dinkies +dinkiest +dinking +dinkly +dinks +dinkum +dinkums +dinky +dinned +dinner +dinnerless +dinners +dinnertime +dinnertimes +dinnerware +dinnerwares +dinning +dinoflagellate +dinoflagellates +dinosaur +dinosaurian +dinosaurs +dins +dint +dinted +dinting +dints +dinucleotide +dinucleotides +diobol +diobolon +diobolons +diobols +diocesan +diocesans +diocese +dioceses +diode +diodes +dioecies +dioecious +dioecism +dioecisms +dioecy +dioicous +diol +diolefin +diolefins +diols +diopside +diopsides +diopsidic +dioptase +dioptases +diopter +diopters +dioptral +dioptre +dioptres +dioptric +diorama +dioramas +dioramic +diorite +diorites +dioritic +dioxan +dioxane +dioxanes +dioxans +dioxid +dioxide +dioxides +dioxids +dioxin +dioxins +dip +dipeptidase +dipeptidases +dipeptide +dipeptides +diphase +diphasic +diphenhydramine +diphenhydramines +diphenyl +diphenylamine +diphenylamines +diphenylhydantoin +diphenylhydantoins +diphenyls +diphosgene +diphosgenes +diphosphate +diphosphates +diphtheria +diphtherial +diphtherias +diphtheritic +diphtheroid +diphtheroids +diphthong +diphthongal +diphthongization +diphthongizations +diphthongize +diphthongized +diphthongizes +diphthongizing +diphthongs +diphyletic +diphyodont +diplegia +diplegias +diplex +diplexer +diplexers +diploblastic +diplococci +diplococcus +diplodocus +diplodocuses +diploe +diploes +diploic +diploid +diploidies +diploids +diploidy +diploma +diplomacies +diplomacy +diplomaed +diplomaing +diplomas +diplomat +diplomata +diplomate +diplomates +diplomatic +diplomatically +diplomatist +diplomatists +diplomats +diplont +diplontic +diplonts +diplophase +diplophases +diplopia +diplopias +diplopic +diplopod +diplopods +diploses +diplosis +diplotene +diplotenes +dipnet +dipnets +dipnetted +dipnetting +dipnoan +dipnoans +dipodic +dipodies +dipody +dipolar +dipole +dipoles +dippable +dipped +dipper +dipperful +dipperfuls +dippers +dippier +dippiest +dipping +dippy +dips +dipsades +dipsas +dipso +dipsomania +dipsomaniac +dipsomaniacal +dipsomaniacs +dipsomanias +dipsos +dipstick +dipsticks +dipt +diptera +dipteral +dipteran +dipterans +dipterocarp +dipterocarps +dipteron +dipterous +diptyca +diptycas +diptych +diptychs +diquat +diquats +dirdum +dirdums +dire +direct +directed +directedness +directednesses +directer +directest +directing +direction +directional +directionalities +directionality +directionless +directionlessness +directionlessnesses +directions +directive +directives +directivities +directivity +directly +directness +directnesses +director +directorate +directorates +directorial +directories +directors +directorship +directorships +directory +directress +directresses +directrice +directrices +directrix +directrixes +directs +direful +direfully +direly +direness +direnesses +direr +direst +dirge +dirgeful +dirgelike +dirges +dirham +dirhams +dirigible +dirigibles +dirigisme +dirigismes +dirigiste +diriment +dirk +dirked +dirking +dirks +dirl +dirled +dirling +dirls +dirndl +dirndls +dirt +dirtbag +dirtbags +dirtied +dirtier +dirties +dirtiest +dirtily +dirtiness +dirtinesses +dirts +dirty +dirtying +dis +disabilities +disability +disable +disabled +disablement +disablements +disables +disabling +disabuse +disabused +disabuses +disabusing +disaccharidase +disaccharidases +disaccharide +disaccharides +disaccord +disaccorded +disaccording +disaccords +disaccustom +disaccustomed +disaccustoming +disaccustoms +disadvantage +disadvantaged +disadvantagedness +disadvantagednesses +disadvantageous +disadvantageously +disadvantageousness +disadvantageousnesses +disadvantages +disadvantaging +disaffect +disaffected +disaffecting +disaffection +disaffections +disaffects +disaffiliate +disaffiliated +disaffiliates +disaffiliating +disaffiliation +disaffiliations +disaffirm +disaffirmance +disaffirmances +disaffirmed +disaffirming +disaffirms +disaggregate +disaggregated +disaggregates +disaggregating +disaggregation +disaggregations +disaggregative +disagree +disagreeable +disagreeableness +disagreeablenesses +disagreeably +disagreed +disagreeing +disagreement +disagreements +disagrees +disallow +disallowance +disallowances +disallowed +disallowing +disallows +disambiguate +disambiguated +disambiguates +disambiguating +disambiguation +disambiguations +disannul +disannulled +disannulling +disannuls +disappear +disappearance +disappearances +disappeared +disappearing +disappears +disappoint +disappointed +disappointedly +disappointing +disappointingly +disappointment +disappointments +disappoints +disapprobation +disapprobations +disapproval +disapprovals +disapprove +disapproved +disapprover +disapprovers +disapproves +disapproving +disapprovingly +disarm +disarmament +disarmaments +disarmed +disarmer +disarmers +disarming +disarmingly +disarms +disarrange +disarranged +disarrangement +disarrangements +disarranges +disarranging +disarray +disarrayed +disarraying +disarrays +disarticulate +disarticulated +disarticulates +disarticulating +disarticulation +disarticulations +disassemble +disassembled +disassembles +disassemblies +disassembling +disassembly +disassociate +disassociated +disassociates +disassociating +disassociation +disassociations +disaster +disasters +disastrous +disastrously +disavow +disavowable +disavowal +disavowals +disavowed +disavowing +disavows +disband +disbanded +disbanding +disbandment +disbandments +disbands +disbar +disbarment +disbarments +disbarred +disbarring +disbars +disbelief +disbeliefs +disbelieve +disbelieved +disbeliever +disbelievers +disbelieves +disbelieving +disbenefit +disbenefits +disbosom +disbosomed +disbosoming +disbosoms +disbound +disbowel +disboweled +disboweling +disbowelled +disbowelling +disbowels +disbud +disbudded +disbudding +disbuds +disburden +disburdened +disburdening +disburdenment +disburdenments +disburdens +disburse +disbursed +disbursement +disbursements +disburser +disbursers +disburses +disbursing +disc +discalced +discant +discanted +discanting +discants +discard +discardable +discarded +discarder +discarders +discarding +discards +discarnate +discase +discased +discases +discasing +disced +discept +discepted +discepting +discepts +discern +discernable +discerned +discerner +discerners +discernible +discernibly +discerning +discerningly +discernment +discernments +discerns +discharge +dischargeable +discharged +dischargee +dischargees +discharger +dischargers +discharges +discharging +disci +disciform +discing +disciple +discipled +disciples +discipleship +discipleships +disciplinable +disciplinal +disciplinarian +disciplinarians +disciplinarily +disciplinarities +disciplinarity +disciplinary +discipline +disciplined +discipliner +discipliners +disciplines +discipling +disciplining +disclaim +disclaimed +disclaimer +disclaimers +disclaiming +disclaims +disclamation +disclamations +disclike +disclimax +disclimaxes +disclose +disclosed +discloser +disclosers +discloses +disclosing +disclosure +disclosures +disco +discoed +discographer +discographers +discographic +discographical +discographies +discography +discoid +discoidal +discoids +discoing +discolor +discoloration +discolorations +discolored +discoloring +discolors +discombobulate +discombobulated +discombobulates +discombobulating +discombobulation +discombobulations +discomfit +discomfited +discomfiting +discomfits +discomfiture +discomfitures +discomfort +discomfortable +discomforted +discomforting +discomforts +discommend +discommended +discommending +discommends +discommode +discommoded +discommodes +discommoding +discompose +discomposed +discomposes +discomposing +discomposure +discomposures +disconcert +disconcerted +disconcerting +disconcertingly +disconcertment +disconcertments +disconcerts +disconfirm +disconfirmed +disconfirming +disconfirms +disconformities +disconformity +disconnect +disconnected +disconnectedly +disconnectedness +disconnectednesses +disconnecting +disconnection +disconnections +disconnects +disconsolate +disconsolately +disconsolateness +disconsolatenesses +disconsolation +disconsolations +discontent +discontented +discontentedly +discontentedness +discontentednesses +discontenting +discontentment +discontentments +discontents +discontinuance +discontinuances +discontinuation +discontinuations +discontinue +discontinued +discontinues +discontinuing +discontinuities +discontinuity +discontinuous +discontinuously +discophile +discophiles +discord +discordance +discordances +discordancies +discordancy +discordant +discordantly +discorded +discording +discords +discos +discotheque +discotheques +discount +discountable +discounted +discountenance +discountenanced +discountenances +discountenancing +discounter +discounters +discounting +discounts +discourage +discourageable +discouraged +discouragement +discouragements +discourager +discouragers +discourages +discouraging +discouragingly +discourse +discoursed +discourser +discoursers +discourses +discoursing +discourteous +discourteously +discourteousness +discourteousnesses +discourtesies +discourtesy +discover +discoverable +discovered +discoverer +discoverers +discoveries +discovering +discovers +discovery +discredit +discreditable +discreditably +discredited +discrediting +discredits +discreet +discreeter +discreetest +discreetly +discreetness +discreetnesses +discrepancies +discrepancy +discrepant +discrepantly +discrete +discretely +discreteness +discretenesses +discretion +discretionary +discretions +discriminabilities +discriminability +discriminable +discriminably +discriminant +discriminants +discriminate +discriminated +discriminates +discriminating +discriminatingly +discrimination +discriminational +discriminations +discriminative +discriminator +discriminatorily +discriminators +discriminatory +discrown +discrowned +discrowning +discrowns +discs +discursive +discursively +discursiveness +discursivenesses +discus +discuses +discuss +discussable +discussant +discussants +discussed +discusser +discussers +discusses +discussible +discussing +discussion +discussions +disdain +disdained +disdainful +disdainfully +disdainfulness +disdainfulnesses +disdaining +disdains +disease +diseased +diseases +diseasing +diseconomies +diseconomy +disembark +disembarkation +disembarkations +disembarked +disembarking +disembarks +disembarrass +disembarrassed +disembarrasses +disembarrassing +disembodied +disembodies +disembody +disembodying +disembogue +disembogued +disembogues +disemboguing +disembowel +disemboweled +disemboweling +disembowelled +disembowelling +disembowelment +disembowelments +disembowels +disenchant +disenchanted +disenchanter +disenchanters +disenchanting +disenchantingly +disenchantment +disenchantments +disenchants +disencumber +disencumbered +disencumbering +disencumbers +disendow +disendowed +disendower +disendowers +disendowing +disendowment +disendowments +disendows +disenfranchise +disenfranchised +disenfranchisement +disenfranchisements +disenfranchises +disenfranchising +disengage +disengaged +disengagement +disengagements +disengages +disengaging +disentail +disentailed +disentailing +disentails +disentangle +disentangled +disentanglement +disentanglements +disentangles +disentangling +disenthral +disenthrall +disenthralled +disenthralling +disenthralls +disenthrals +disentitle +disentitled +disentitles +disentitling +disequilibrate +disequilibrated +disequilibrates +disequilibrating +disequilibration +disequilibrations +disequilibria +disequilibrium +disequilibriums +disestablish +disestablished +disestablishes +disestablishing +disestablishment +disestablishmentarian +disestablishmentarians +disestablishments +disesteem +disesteemed +disesteeming +disesteems +diseuse +diseuses +disfavor +disfavored +disfavoring +disfavors +disfigure +disfigured +disfigurement +disfigurements +disfigures +disfiguring +disfranchise +disfranchised +disfranchisement +disfranchisements +disfranchises +disfranchising +disfrock +disfrocked +disfrocking +disfrocks +disfunction +disfunctional +disfunctions +disfurnish +disfurnished +disfurnishes +disfurnishing +disfurnishment +disfurnishments +disgorge +disgorged +disgorges +disgorging +disgrace +disgraced +disgraceful +disgracefully +disgracefulness +disgracefulnesses +disgracer +disgracers +disgraces +disgracing +disgruntle +disgruntled +disgruntlement +disgruntlements +disgruntles +disgruntling +disguise +disguised +disguisedly +disguisement +disguisements +disguiser +disguisers +disguises +disguising +disgust +disgusted +disgustedly +disgustful +disgustfully +disgusting +disgustingly +disgusts +dish +dishabille +dishabilles +disharmonies +disharmonious +disharmonize +disharmonized +disharmonizes +disharmonizing +disharmony +dishcloth +dishcloths +dishclout +dishclouts +dishearten +disheartened +disheartening +dishearteningly +disheartenment +disheartenments +disheartens +dished +dishelm +dishelmed +dishelming +dishelms +disherit +disherited +disheriting +disherits +dishes +dishevel +disheveled +disheveling +dishevelled +dishevelling +dishevels +dishful +dishfuls +dishier +dishiest +dishing +dishlike +dishonest +dishonesties +dishonestly +dishonesty +dishonor +dishonorable +dishonorableness +dishonorablenesses +dishonorably +dishonored +dishonorer +dishonorers +dishonoring +dishonors +dishpan +dishpans +dishrag +dishrags +dishtowel +dishtowels +dishware +dishwares +dishwasher +dishwashers +dishwater +dishwaters +dishy +disillusion +disillusioned +disillusioning +disillusionment +disillusionments +disillusions +disincentive +disincentives +disinclination +disinclinations +disincline +disinclined +disinclines +disinclining +disinfect +disinfectant +disinfectants +disinfected +disinfecting +disinfection +disinfections +disinfects +disinfest +disinfestant +disinfestants +disinfestation +disinfestations +disinfested +disinfesting +disinfests +disinflation +disinflationary +disinflations +disinformation +disinformations +disingenuous +disingenuously +disingenuousness +disingenuousnesses +disinherit +disinheritance +disinheritances +disinherited +disinheriting +disinherits +disinhibit +disinhibited +disinhibiting +disinhibition +disinhibitions +disinhibits +disintegrate +disintegrated +disintegrates +disintegrating +disintegration +disintegrations +disintegrative +disintegrator +disintegrators +disinter +disinterest +disinterested +disinterestedly +disinterestedness +disinterestednesses +disinteresting +disinterests +disintermediation +disintermediations +disinterment +disinterments +disinterred +disinterring +disinters +disintoxicate +disintoxicated +disintoxicates +disintoxicating +disintoxication +disintoxications +disinvest +disinvested +disinvesting +disinvestment +disinvestments +disinvests +disinvite +disinvited +disinvites +disinviting +disject +disjected +disjecting +disjects +disjoin +disjoined +disjoining +disjoins +disjoint +disjointed +disjointedly +disjointedness +disjointednesses +disjointing +disjoints +disjunct +disjunction +disjunctions +disjunctive +disjunctively +disjunctives +disjuncts +disjuncture +disjunctures +disk +disked +diskette +diskettes +disking +disklike +disks +dislikable +dislike +dislikeable +disliked +disliker +dislikers +dislikes +disliking +dislimn +dislimned +dislimning +dislimns +dislocate +dislocated +dislocates +dislocating +dislocation +dislocations +dislodge +dislodged +dislodgement +dislodgements +dislodges +dislodging +dislodgment +dislodgments +disloyal +disloyally +disloyalties +disloyalty +dismal +dismaler +dismalest +dismally +dismalness +dismalnesses +dismals +dismantle +dismantled +dismantlement +dismantlements +dismantles +dismantling +dismast +dismasted +dismasting +dismasts +dismay +dismayed +dismaying +dismayingly +dismays +disme +dismember +dismembered +dismembering +dismemberment +dismemberments +dismembers +dismes +dismiss +dismissal +dismissals +dismissed +dismisses +dismissing +dismission +dismissions +dismissive +dismissively +dismount +dismounted +dismounting +dismounts +disobedience +disobediences +disobedient +disobediently +disobey +disobeyed +disobeyer +disobeyers +disobeying +disobeys +disoblige +disobliged +disobliges +disobliging +disomic +disorder +disordered +disorderedly +disorderedness +disorderednesses +disordering +disorderliness +disorderlinesses +disorderly +disorders +disorganization +disorganizations +disorganize +disorganized +disorganizes +disorganizing +disorient +disorientate +disorientated +disorientates +disorientating +disorientation +disorientations +disoriented +disorienting +disorients +disown +disowned +disowning +disownment +disownments +disowns +disparage +disparaged +disparagement +disparagements +disparager +disparagers +disparages +disparaging +disparagingly +disparate +disparately +disparateness +disparatenesses +disparities +disparity +dispart +disparted +disparting +disparts +dispassion +dispassionate +dispassionately +dispassionateness +dispassionatenesses +dispassions +dispatch +dispatched +dispatcher +dispatchers +dispatches +dispatching +dispel +dispelled +dispelling +dispels +dispend +dispended +dispending +dispends +dispensabilities +dispensability +dispensable +dispensaries +dispensary +dispensation +dispensational +dispensations +dispensatories +dispensatory +dispense +dispensed +dispenser +dispensers +dispenses +dispensing +dispeople +dispeopled +dispeoples +dispeopling +dispersal +dispersals +dispersant +dispersants +disperse +dispersed +dispersedly +disperser +dispersers +disperses +dispersible +dispersing +dispersion +dispersions +dispersive +dispersively +dispersiveness +dispersivenesses +dispersoid +dispersoids +dispirit +dispirited +dispiritedly +dispiritedness +dispiritednesses +dispiriting +dispirits +dispiteous +displace +displaceable +displaced +displacement +displacements +displaces +displacing +displant +displanted +displanting +displants +display +displayable +displayed +displaying +displays +displease +displeased +displeases +displeasing +displeasure +displeasures +displode +disploded +displodes +disploding +displosion +displosions +displume +displumed +displumes +displuming +disport +disported +disporting +disportment +disportments +disports +disposabilities +disposability +disposable +disposables +disposal +disposals +dispose +disposed +disposer +disposers +disposes +disposing +disposition +dispositional +dispositions +dispositive +dispossess +dispossessed +dispossesses +dispossessing +dispossession +dispossessions +dispossessor +dispossessors +disposure +disposures +dispraise +dispraised +dispraiser +dispraisers +dispraises +dispraising +dispraisingly +dispread +dispreading +dispreads +disprize +disprized +disprizes +disprizing +disproof +disproofs +disproportion +disproportional +disproportionate +disproportionated +disproportionately +disproportionates +disproportionating +disproportionation +disproportionations +disproportioned +disproportioning +disproportions +disprovable +disprove +disproved +disproven +disproves +disproving +disputable +disputably +disputant +disputants +disputation +disputations +disputatious +disputatiously +disputatiousness +disputatiousnesses +dispute +disputed +disputer +disputers +disputes +disputing +disqualification +disqualifications +disqualified +disqualifies +disqualify +disqualifying +disquantitied +disquantities +disquantity +disquantitying +disquiet +disquieted +disquieting +disquietingly +disquietly +disquiets +disquietude +disquietudes +disquisition +disquisitions +disrate +disrated +disrates +disrating +disregard +disregarded +disregardful +disregarding +disregards +disrelated +disrelation +disrelations +disrelish +disrelished +disrelishes +disrelishing +disremember +disremembered +disremembering +disremembers +disrepair +disrepairs +disreputabilities +disreputability +disreputable +disreputableness +disreputablenesses +disreputably +disrepute +disreputes +disrespect +disrespectabilities +disrespectability +disrespectable +disrespected +disrespectful +disrespectfully +disrespectfulness +disrespectfulnesses +disrespecting +disrespects +disrobe +disrobed +disrober +disrobers +disrobes +disrobing +disroot +disrooted +disrooting +disroots +disrupt +disrupted +disrupter +disrupters +disrupting +disruption +disruptions +disruptive +disruptively +disruptiveness +disruptivenesses +disrupts +diss +dissatisfaction +dissatisfactions +dissatisfactory +dissatisfied +dissatisfies +dissatisfy +dissatisfying +dissave +dissaved +dissaves +dissaving +disseat +disseated +disseating +disseats +dissect +dissected +dissecting +dissection +dissections +dissector +dissectors +dissects +dissed +disseise +disseised +disseises +disseisin +disseising +disseisins +disseisor +disseisors +disseize +disseized +disseizes +disseizin +disseizing +disseizins +dissemble +dissembled +dissembler +dissemblers +dissembles +dissembling +disseminate +disseminated +disseminates +disseminating +dissemination +disseminations +disseminator +disseminators +disseminule +disseminules +dissension +dissensions +dissensus +dissensuses +dissent +dissented +dissenter +dissenters +dissentient +dissentients +dissenting +dissention +dissentions +dissentious +dissents +dissepiment +dissepiments +dissert +dissertate +dissertated +dissertates +dissertating +dissertation +dissertational +dissertations +dissertator +dissertators +disserted +disserting +disserts +disserve +disserved +disserves +disservice +disserviceable +disservices +disserving +disses +dissever +disseverance +disseverances +dissevered +dissevering +disseverment +disseverments +dissevers +dissidence +dissidences +dissident +dissidents +dissimilar +dissimilarities +dissimilarity +dissimilarly +dissimilars +dissimilate +dissimilated +dissimilates +dissimilating +dissimilation +dissimilations +dissimilatory +dissimilitude +dissimilitudes +dissimulate +dissimulated +dissimulates +dissimulating +dissimulation +dissimulations +dissimulator +dissimulators +dissing +dissipate +dissipated +dissipatedly +dissipatedness +dissipatednesses +dissipater +dissipaters +dissipates +dissipating +dissipation +dissipations +dissipative +dissociabilities +dissociability +dissociable +dissocial +dissociate +dissociated +dissociates +dissociating +dissociation +dissociations +dissociative +dissoluble +dissolute +dissolutely +dissoluteness +dissolutenesses +dissolution +dissolutions +dissolvable +dissolve +dissolved +dissolvent +dissolvents +dissolver +dissolvers +dissolves +dissolving +dissonance +dissonances +dissonant +dissonantly +dissuade +dissuaded +dissuader +dissuaders +dissuades +dissuading +dissuasion +dissuasions +dissuasive +dissuasively +dissuasiveness +dissuasivenesses +dissyllable +dissyllables +dissymmetric +dissymmetries +dissymmetry +distaff +distaffs +distain +distained +distaining +distains +distal +distally +distance +distanced +distances +distancing +distant +distantly +distantness +distantnesses +distaste +distasted +distasteful +distastefully +distastefulness +distastefulnesses +distastes +distasting +distaves +distelfink +distelfinks +distemper +distemperate +distemperature +distemperatures +distempered +distempering +distempers +distend +distended +distending +distends +distensibilities +distensibility +distensible +distension +distensions +distent +distention +distentions +distich +distichous +distichs +distil +distill +distillate +distillates +distillation +distillations +distilled +distiller +distilleries +distillers +distillery +distilling +distills +distils +distinct +distincter +distinctest +distinction +distinctions +distinctive +distinctively +distinctiveness +distinctivenesses +distinctly +distinctness +distinctnesses +distingue +distinguish +distinguishabilities +distinguishability +distinguishable +distinguishably +distinguished +distinguishes +distinguishing +distome +distomes +distort +distorted +distorter +distorters +distorting +distortion +distortional +distortions +distorts +distract +distractable +distracted +distractedly +distractibilities +distractibility +distractible +distracting +distractingly +distraction +distractions +distractive +distracts +distrain +distrainable +distrained +distrainer +distrainers +distraining +distrainor +distrainors +distrains +distraint +distraints +distrait +distraite +distraught +distraughtly +distress +distressed +distresses +distressful +distressfully +distressfulness +distressfulnesses +distressing +distressingly +distributaries +distributary +distribute +distributed +distributee +distributees +distributes +distributing +distribution +distributional +distributions +distributive +distributively +distributivities +distributivity +distributor +distributors +distributorship +distributorships +district +districted +districting +districts +distrust +distrusted +distrustful +distrustfully +distrustfulness +distrustfulnesses +distrusting +distrusts +disturb +disturbance +disturbances +disturbed +disturber +disturbers +disturbing +disturbingly +disturbs +disubstituted +disulfid +disulfide +disulfides +disulfids +disulfiram +disulfirams +disulfoton +disulfotons +disunion +disunionist +disunionists +disunions +disunite +disunited +disunites +disunities +disuniting +disunity +disuse +disused +disuses +disusing +disutilities +disutility +disvalue +disvalued +disvalues +disvaluing +disyllabic +disyllable +disyllables +disyoke +disyoked +disyokes +disyoking +dit +dita +ditas +ditch +ditchdigger +ditchdiggers +ditched +ditcher +ditchers +ditches +ditching +dite +dites +ditheism +ditheisms +ditheist +ditheists +dither +dithered +ditherer +ditherers +dithering +dithers +dithery +dithiocarbamate +dithiocarbamates +dithiol +dithyramb +dithyrambic +dithyrambically +dithyrambs +ditransitive +ditransitives +dits +ditsier +ditsiest +ditsy +dittanies +dittany +ditties +ditto +dittoed +dittoing +dittos +ditty +ditz +ditzes +ditzier +ditziest +ditzy +diureses +diuresis +diuretic +diuretically +diuretics +diurnal +diurnally +diurnals +diuron +diurons +diva +divagate +divagated +divagates +divagating +divagation +divagations +divalent +divan +divans +divaricate +divaricated +divaricates +divaricating +divarication +divarications +divas +dive +divebomb +divebombed +divebombing +divebombs +dived +diver +diverge +diverged +divergence +divergences +divergencies +divergency +divergent +divergently +diverges +diverging +divers +diverse +diversely +diverseness +diversenesses +diversification +diversifications +diversified +diversifier +diversifiers +diversifies +diversify +diversifying +diversion +diversionary +diversionist +diversionists +diversions +diversities +diversity +divert +diverted +diverter +diverters +diverticula +diverticular +diverticulites +diverticulitides +diverticulitis +diverticulitises +diverticuloses +diverticulosis +diverticulosises +diverticulum +divertimenti +divertimento +divertimentos +diverting +divertissement +divertissements +diverts +dives +divest +divested +divesting +divestiture +divestitures +divestment +divestments +divests +dividable +divide +divided +dividedly +dividedness +dividednesses +dividend +dividendless +dividends +divider +dividers +divides +dividing +dividual +divination +divinations +divinatory +divine +divined +divinely +diviner +diviners +divines +divinest +diving +divining +divinise +divinised +divinises +divinising +divinities +divinity +divinize +divinized +divinizes +divinizing +divisibilities +divisibility +divisible +division +divisional +divisionism +divisionisms +divisionist +divisionists +divisions +divisive +divisively +divisiveness +divisivenesses +divisor +divisors +divorce +divorced +divorcee +divorcees +divorcement +divorcements +divorcer +divorcers +divorces +divorcing +divot +divots +divulge +divulged +divulgence +divulgences +divulger +divulgers +divulges +divulging +divvied +divvies +divvy +divvying +diwan +diwans +dixit +dixits +dizen +dizened +dizening +dizens +dizygotic +dizygous +dizzied +dizzier +dizzies +dizziest +dizzily +dizziness +dizzinesses +dizzy +dizzying +dizzyingly +djebel +djebels +djellaba +djellabah +djellabahs +djellabas +djin +djinn +djinni +djinns +djinny +djins +do +doable +doat +doated +doating +doats +dobber +dobbers +dobbies +dobbin +dobbins +dobby +dobie +dobies +dobla +doblas +doblon +doblones +doblons +dobra +dobras +dobson +dobsonflies +dobsonfly +dobsons +doby +doc +docent +docents +docetic +docile +docilely +docilities +docility +dock +dockage +dockages +docked +docker +dockers +docket +docketed +docketing +dockets +dockhand +dockhands +docking +dockland +docklands +dockmaster +dockmasters +docks +dockside +docksides +dockworker +dockworkers +dockyard +dockyards +docs +doctor +doctoral +doctorate +doctorates +doctored +doctoring +doctorless +doctors +doctorship +doctorships +doctrinaire +doctrinaires +doctrinairism +doctrinairisms +doctrinal +doctrinally +doctrine +doctrines +docudrama +docudramas +document +documentable +documental +documentalist +documentalists +documentarian +documentarians +documentaries +documentarily +documentarist +documentarists +documentary +documentation +documentational +documentations +documented +documenter +documenters +documenting +documents +dodder +doddered +dodderer +dodderers +doddering +dodders +doddery +dodecagon +dodecagons +dodecahedra +dodecahedral +dodecahedron +dodecahedrons +dodecaphonic +dodecaphonically +dodecaphonies +dodecaphonist +dodecaphonists +dodecaphony +dodge +dodgeball +dodgeballs +dodged +dodgem +dodgems +dodger +dodgeries +dodgers +dodgery +dodges +dodgier +dodgiest +dodginess +dodginesses +dodging +dodgy +dodo +dodoes +dodoism +dodoisms +dodos +doe +doer +doers +does +doeskin +doeskins +doest +doeth +doff +doffed +doffer +doffers +doffing +doffs +dog +dogbane +dogbanes +dogberries +dogberry +dogcart +dogcarts +dogcatcher +dogcatchers +dogdom +dogdoms +doge +dogear +dogeared +dogearing +dogears +dogedom +dogedoms +doges +dogeship +dogeships +dogey +dogeys +dogface +dogfaces +dogfight +dogfighting +dogfights +dogfish +dogfishes +dogfought +dogged +doggedly +doggedness +doggednesses +dogger +doggerel +doggerels +doggeries +doggers +doggery +doggie +doggier +doggies +doggiest +dogging +doggish +doggishly +doggishness +doggishnesses +doggo +doggone +doggoned +doggoneder +doggonedest +doggoner +doggones +doggonest +doggoning +doggrel +doggrels +doggy +doghouse +doghouses +dogie +dogies +dogleg +doglegged +doglegging +doglegs +doglike +dogma +dogmas +dogmata +dogmatic +dogmatical +dogmatically +dogmaticalness +dogmaticalnesses +dogmatics +dogmatism +dogmatisms +dogmatist +dogmatists +dogmatization +dogmatizations +dogmatize +dogmatized +dogmatizer +dogmatizers +dogmatizes +dogmatizing +dognap +dognaped +dognaper +dognapers +dognaping +dognapped +dognapper +dognappers +dognapping +dognaps +dogs +dogsbodies +dogsbody +dogsled +dogsledded +dogsledder +dogsledders +dogsledding +dogsleds +dogteeth +dogtooth +dogtrot +dogtrots +dogtrotted +dogtrotting +dogvane +dogvanes +dogwatch +dogwatches +dogwood +dogwoods +dogy +doiled +doilies +doily +doing +doings +doit +doited +doits +dojo +dojos +dol +dolce +dolci +doldrums +dole +doled +doleful +dolefuller +dolefullest +dolefully +dolefulness +dolefulnesses +dolerite +dolerites +doleritic +doles +dolesome +dolichocephalic +dolichocephalies +dolichocephaly +doling +doll +dollar +dollars +dolled +dollhouse +dollhouses +dollied +dollies +dolling +dollish +dollishly +dollishness +dollishnesses +dollop +dolloped +dolloping +dollops +dolls +dolly +dollying +dolma +dolmades +dolman +dolmans +dolmas +dolmen +dolmens +dolomite +dolomites +dolomitic +dolomitization +dolomitizations +dolomitize +dolomitized +dolomitizes +dolomitizing +dolor +doloroso +dolorous +dolorously +dolorousness +dolorousnesses +dolors +dolour +dolours +dolphin +dolphinfish +dolphinfishes +dolphins +dols +dolt +doltish +doltishly +doltishness +doltishnesses +dolts +dom +domain +domains +domal +dome +domed +domelike +domes +domesday +domesdays +domestic +domestically +domesticate +domesticated +domesticates +domesticating +domestication +domestications +domesticities +domesticity +domestics +domic +domical +domicil +domicile +domiciled +domiciles +domiciliary +domiciliate +domiciliated +domiciliates +domiciliating +domiciliation +domiciliations +domiciling +domicils +dominance +dominances +dominant +dominantly +dominants +dominate +dominated +dominates +dominating +domination +dominations +dominative +dominator +dominators +dominatrices +dominatrix +dominatrixes +domine +domineer +domineered +domineering +domineeringly +domineeringness +domineeringnesses +domineers +domines +doming +dominical +dominick +dominicker +dominickers +dominicks +dominie +dominies +dominion +dominions +dominique +dominiques +dominium +dominiums +domino +dominoes +dominos +doms +don +dona +donas +donate +donated +donates +donating +donation +donations +donative +donatives +donator +donators +done +donee +donees +doneness +donenesses +dong +donga +dongas +dongola +dongolas +dongs +donjon +donjons +donkey +donkeys +donkeywork +donkeyworks +donna +donnas +donne +donned +donnee +donnees +donnerd +donnered +donnert +donnicker +donnickers +donniker +donnikers +donning +donnish +donnishly +donnishness +donnishnesses +donnybrook +donnybrooks +donor +donors +dons +donsie +donsy +donut +donuts +donzel +donzels +doodad +doodads +doodle +doodlebug +doodlebugs +doodled +doodler +doodlers +doodles +doodling +doofus +doofuses +doohickey +doohickeys +doohickies +doolee +doolees +doolie +doolies +dooly +doom +doomed +doomful +doomfully +doomily +dooming +dooms +doomsayer +doomsayers +doomsaying +doomsayings +doomsday +doomsdayer +doomsdayers +doomsdays +doomster +doomsters +doomy +door +doorbell +doorbells +doorjamb +doorjambs +doorkeeper +doorkeepers +doorknob +doorknobs +doorless +doorman +doormat +doormats +doormen +doornail +doornails +doorplate +doorplates +doorpost +doorposts +doors +doorsill +doorsills +doorstep +doorsteps +doorstop +doorstops +doorway +doorways +dooryard +dooryards +doozer +doozers +doozie +doozies +doozy +dopa +dopamine +dopaminergic +dopamines +dopant +dopants +dopas +dope +doped +dopehead +dopeheads +doper +dopers +dopes +dopester +dopesters +dopey +dopier +dopiest +dopiness +dopinesses +doping +doppelganger +doppelgangers +dopy +dor +dorado +dorados +dorbug +dorbugs +dore +dorhawk +dorhawks +dories +dork +dorkier +dorkiest +dorks +dorky +dorm +dormancies +dormancy +dormant +dormer +dormers +dormice +dormie +dormient +dormin +dormins +dormitories +dormitory +dormouse +dorms +dormy +dorneck +dornecks +dornick +dornicks +dornock +dornocks +doronicum +doronicums +dorp +dorper +dorpers +dorps +dorr +dorrs +dors +dorsa +dorsad +dorsal +dorsally +dorsals +dorsel +dorsels +dorser +dorsers +dorsiventral +dorsiventralities +dorsiventrality +dorsiventrally +dorsolateral +dorsoventral +dorsoventralities +dorsoventrality +dorsoventrally +dorsum +dorty +dory +dos +dosage +dosages +dose +dosed +doser +dosers +doses +dosimeter +dosimeters +dosimetric +dosimetries +dosimetry +dosing +doss +dossal +dossals +dossed +dossel +dossels +dosser +dosseret +dosserets +dossers +dosses +dossier +dossiers +dossil +dossils +dossing +dost +dot +dotage +dotages +dotal +dotard +dotardly +dotards +dotation +dotations +dote +doted +doter +doters +dotes +doth +dotier +dotiest +doting +dotingly +dots +dotted +dottel +dottels +dotter +dotterel +dotterels +dotters +dottier +dottiest +dottily +dottiness +dottinesses +dotting +dottle +dottles +dottrel +dottrels +dotty +doty +double +doubled +doubleheader +doubleheaders +doubleness +doublenesses +doubler +doublers +doubles +doublespeak +doublespeaker +doublespeakers +doublespeaks +doublet +doublethink +doublethinks +doubleton +doubletons +doublets +doubling +doubloon +doubloons +doublure +doublures +doubly +doubt +doubtable +doubted +doubter +doubters +doubtful +doubtfully +doubtfulness +doubtfulnesses +doubting +doubtingly +doubtless +doubtlessly +doubtlessness +doubtlessnesses +doubts +douce +doucely +douceur +douceurs +douche +douched +douches +douching +dough +doughboy +doughboys +doughface +doughfaces +doughier +doughiest +doughlike +doughnut +doughnutlike +doughnuts +doughs +dought +doughtier +doughtiest +doughtily +doughtiness +doughtinesses +doughty +doughy +doum +douma +doumas +doums +doupioni +doupionis +dour +doura +dourah +dourahs +douras +dourer +dourest +dourine +dourines +dourly +dourness +dournesses +douroucouli +douroucoulis +douse +doused +douser +dousers +douses +dousing +doux +douzeper +douzepers +dove +dovecot +dovecote +dovecotes +dovecots +dovekey +dovekeys +dovekie +dovekies +dovelike +doven +dovened +dovening +dovens +doves +dovetail +dovetailed +dovetailing +dovetails +dovish +dovishness +dovishnesses +dow +dowable +dowager +dowagers +dowdier +dowdies +dowdiest +dowdily +dowdiness +dowdinesses +dowdy +dowdyish +dowed +dowel +doweled +doweling +dowelled +dowelling +dowels +dower +dowered +doweries +dowering +dowers +dowery +dowie +dowing +dowitcher +dowitchers +down +downbeat +downbeats +downburst +downbursts +downcast +downcasts +downcome +downcomes +downcourt +downdraft +downdrafts +downed +downer +downers +downfall +downfallen +downfalls +downfield +downgrade +downgraded +downgrades +downgrading +downhaul +downhauls +downhearted +downheartedly +downheartedness +downheartednesses +downhill +downhiller +downhillers +downhills +downier +downiest +downing +downland +downlands +downlink +downlinks +download +downloadable +downloaded +downloading +downloads +downpipe +downpipes +downplay +downplayed +downplaying +downplays +downpour +downpours +downrange +downright +downrightly +downrightness +downrightnesses +downriver +downs +downscale +downscaled +downscales +downscaling +downshift +downshifted +downshifting +downshifts +downside +downsides +downsize +downsized +downsizes +downsizing +downslide +downslides +downslope +downspout +downspouts +downstage +downstages +downstairs +downstate +downstater +downstaters +downstates +downstream +downstroke +downstrokes +downswing +downswings +downtick +downticks +downtime +downtimes +downtown +downtowner +downtowners +downtowns +downtrend +downtrends +downtrod +downtrodden +downturn +downturns +downward +downwardly +downwardness +downwardnesses +downwards +downwash +downwashes +downwind +downy +dowries +dowry +dows +dowsabel +dowsabels +dowse +dowsed +dowser +dowsers +dowses +dowsing +doxie +doxies +doxologies +doxology +doxorubicin +doxorubicins +doxy +doxycycline +doxycyclines +doyen +doyenne +doyennes +doyens +doyley +doyleys +doylies +doyly +doze +dozed +dozen +dozened +dozening +dozens +dozenth +dozenths +dozer +dozers +dozes +dozier +doziest +dozily +doziness +dozinesses +dozing +dozy +drab +drabbed +drabber +drabbest +drabbet +drabbets +drabbing +drabble +drabbled +drabbles +drabbling +drably +drabness +drabnesses +drabs +dracaena +dracaenas +drachm +drachma +drachmae +drachmai +drachmas +drachms +draconian +draconic +draff +draffier +draffiest +draffish +draffs +draffy +draft +draftable +drafted +draftee +draftees +drafter +drafters +draftier +draftiest +draftily +draftiness +draftinesses +drafting +draftings +drafts +draftsman +draftsmanship +draftsmanships +draftsmen +draftsperson +draftspersons +drafty +drag +dragee +dragees +dragged +dragger +draggers +draggier +draggiest +dragging +draggingly +draggle +draggled +draggles +draggling +draggy +dragline +draglines +dragnet +dragnets +dragoman +dragomans +dragomen +dragon +dragonet +dragonets +dragonflies +dragonfly +dragonhead +dragonheads +dragonish +dragons +dragoon +dragooned +dragooning +dragoons +dragrope +dragropes +drags +dragster +dragsters +drail +drails +drain +drainage +drainages +drained +drainer +drainers +draining +drainpipe +drainpipes +drains +drake +drakes +dram +drama +dramas +dramatic +dramatically +dramatics +dramatisation +dramatisations +dramatise +dramatised +dramatises +dramatising +dramatist +dramatists +dramatizable +dramatization +dramatizations +dramatize +dramatized +dramatizes +dramatizing +dramaturg +dramaturge +dramaturges +dramaturgic +dramaturgical +dramaturgically +dramaturgies +dramaturgs +dramaturgy +dramedies +dramedy +drammed +dramming +drammock +drammocks +drams +dramshop +dramshops +drank +drapabilities +drapability +drapable +drape +drapeabilities +drapeability +drapeable +draped +draper +draperies +drapers +drapery +drapes +drapey +draping +drastic +drastically +drat +drats +dratted +dratting +draught +draughted +draughtier +draughtiest +draughting +draughts +draughtsman +draughtsmen +draughty +drave +draw +drawable +drawback +drawbacks +drawbar +drawbars +drawbore +drawbores +drawbridge +drawbridges +drawdown +drawdowns +drawee +drawees +drawer +drawerful +drawerfuls +drawers +drawing +drawings +drawknife +drawknives +drawl +drawled +drawler +drawlers +drawlier +drawliest +drawling +drawlingly +drawls +drawly +drawn +drawnwork +drawnworks +drawplate +drawplates +draws +drawshave +drawshaves +drawstring +drawstrings +drawtube +drawtubes +dray +drayage +drayages +drayed +draying +drayman +draymen +drays +dread +dreaded +dreadful +dreadfully +dreadfulness +dreadfulnesses +dreadfuls +dreading +dreadlock +dreadlocks +dreadnought +dreadnoughts +dreads +dream +dreamed +dreamer +dreamers +dreamful +dreamfully +dreamfulness +dreamfulnesses +dreamier +dreamiest +dreamily +dreaminess +dreaminesses +dreaming +dreamland +dreamlands +dreamless +dreamlessly +dreamlessness +dreamlessnesses +dreamlike +dreams +dreamt +dreamtime +dreamtimes +dreamworld +dreamworlds +dreamy +drear +drearier +drearies +dreariest +drearily +dreariness +drearinesses +drears +dreary +dreck +drecks +drecky +dredge +dredged +dredger +dredgers +dredges +dredging +dredgings +dree +dreed +dreeing +drees +dreg +dreggier +dreggiest +dreggish +dreggy +dregs +dreich +dreidel +dreidels +dreidl +dreidls +dreigh +drek +dreks +drench +drenched +drencher +drenchers +drenches +drenching +dress +dressage +dressages +dressed +dresser +dressers +dresses +dressier +dressiest +dressily +dressiness +dressinesses +dressing +dressings +dressmaker +dressmakers +dressmaking +dressmakings +dressy +drest +drew +drib +dribbed +dribbing +dribble +dribbled +dribbler +dribblers +dribbles +dribblet +dribblets +dribbling +dribbly +driblet +driblets +dribs +dried +driegh +drier +driers +dries +driest +drift +driftage +driftages +drifted +drifter +drifters +driftier +driftiest +drifting +driftingly +driftpin +driftpins +drifts +driftwood +driftwoods +drifty +drill +drillabilities +drillability +drillable +drilled +driller +drillers +drilling +drillings +drillmaster +drillmasters +drills +drily +drink +drinkabilities +drinkability +drinkable +drinkables +drinker +drinkers +drinking +drinks +drip +dripless +dripped +dripper +drippers +drippier +drippiest +dripping +drippings +drippy +drips +dripstone +dripstones +dript +drivabilities +drivability +drivable +drive +driveabilities +driveability +driveable +drivel +driveled +driveler +drivelers +driveline +drivelines +driveling +drivelled +drivelling +drivels +driven +drivenness +drivennesses +driver +driverless +drivers +drives +driveshaft +driveshafts +drivetrain +drivetrains +driveway +driveways +driving +drivings +drizzle +drizzled +drizzles +drizzlier +drizzliest +drizzling +drizzlingly +drizzly +drogue +drogues +droit +droits +droll +drolled +droller +drolleries +drollery +drollest +drolling +drollness +drollnesses +drolls +drolly +dromedaries +dromedary +dromon +dromond +dromonds +dromons +drone +droned +droner +droners +drones +drongo +drongos +droning +droningly +dronish +drool +drooled +drooling +drools +droop +drooped +droopier +droopiest +droopily +drooping +droopingly +droops +droopy +drop +dropcloth +dropcloths +drophead +dropheads +dropkick +dropkicker +dropkickers +dropkicks +droplet +droplets +droplight +droplights +dropout +dropouts +droppable +dropped +dropper +dropperful +dropperfuls +droppers +droppersful +dropping +droppings +drops +dropshot +dropshots +dropsical +dropsied +dropsies +dropsy +dropt +dropwort +dropworts +drosera +droseras +droshkies +droshky +droskies +drosky +drosophila +drosophilas +dross +drosses +drossier +drossiest +drossy +drought +droughtier +droughtiest +droughtiness +droughtinesses +droughts +droughty +drouk +drouked +drouking +drouks +drouth +drouthier +drouthiest +drouths +drouthy +drove +droved +drover +drovers +droves +droving +drown +drownd +drownded +drownding +drownds +drowned +drowner +drowners +drowning +drowns +drowse +drowsed +drowses +drowsier +drowsiest +drowsily +drowsiness +drowsinesses +drowsing +drowsy +drub +drubbed +drubber +drubbers +drubbing +drubbings +drubs +drudge +drudged +drudger +drudgeries +drudgers +drudgery +drudges +drudging +drudgingly +drug +drugged +drugget +druggets +druggie +druggier +druggies +druggiest +drugging +druggist +druggists +druggy +drugmaker +drugmakers +drugs +drugstore +drugstores +druid +druidess +druidesses +druidic +druidical +druidism +druidisms +druids +drum +drumbeat +drumbeater +drumbeaters +drumbeating +drumbeatings +drumbeats +drumble +drumbled +drumbles +drumbling +drumfire +drumfires +drumfish +drumfishes +drumhead +drumheads +drumlier +drumliest +drumlike +drumlin +drumlins +drumly +drummed +drummer +drummers +drumming +drumroll +drumrolls +drums +drumstick +drumsticks +drunk +drunkard +drunkards +drunken +drunkenly +drunkenness +drunkennesses +drunker +drunkest +drunks +drupaceous +drupe +drupelet +drupelets +drupes +druse +druses +druthers +dry +dryable +dryad +dryades +dryadic +dryads +dryasdust +dryasdusts +dryer +dryers +dryest +drying +dryish +dryland +drylot +drylots +dryly +dryness +drynesses +dryopithecine +dryopithecines +drypoint +drypoints +drys +drysalter +drysalteries +drysalters +drysaltery +drystone +drywall +drywalls +duad +duads +dual +dualism +dualisms +dualist +dualistic +dualistically +dualists +dualities +duality +dualize +dualized +dualizes +dualizing +dually +duals +dub +dubbed +dubber +dubbers +dubbin +dubbing +dubbings +dubbins +dubieties +dubiety +dubious +dubiously +dubiousness +dubiousnesses +dubitable +dubitation +dubitations +dubonnet +dubonnets +dubs +ducal +ducally +ducat +ducats +duce +duces +duchess +duchesses +duchies +duchy +duci +duck +duckbill +duckbills +duckboard +duckboards +ducked +ducker +duckers +duckie +duckier +duckies +duckiest +ducking +duckling +ducklings +duckpin +duckpins +ducks +ducktail +ducktails +duckwalk +duckwalked +duckwalking +duckwalks +duckweed +duckweeds +ducky +duct +ductal +ducted +ductile +ductilities +ductility +ducting +ductings +ductless +ducts +ductule +ductules +ductwork +ductworks +dud +duddie +duddy +dude +duded +dudeen +dudeens +dudes +dudgeon +dudgeons +duding +dudish +dudishly +duds +due +duecento +duecentos +duel +dueled +dueler +duelers +dueling +duelist +duelists +duelled +dueller +duellers +duelli +duelling +duellist +duellists +duello +duellos +duels +duende +duendes +dueness +duenesses +duenna +duennas +duennaship +duennaships +dues +duet +duets +duetted +duetting +duettist +duettists +duff +duffel +duffels +duffer +duffers +duffle +duffles +duffs +dug +dugong +dugongs +dugout +dugouts +dugs +dui +duiker +duikers +duit +duits +duke +duked +dukedom +dukedoms +dukes +duking +dulcet +dulcetly +dulcets +dulciana +dulcianas +dulcified +dulcifies +dulcify +dulcifying +dulcimer +dulcimers +dulcimore +dulcimores +dulcinea +dulcineas +dulia +dulias +dull +dullard +dullards +dulled +duller +dullest +dulling +dullish +dullishly +dullness +dullnesses +dulls +dullsville +dullsvilles +dully +dulness +dulnesses +dulse +dulses +duly +duma +dumas +dumb +dumbbell +dumbbells +dumbcane +dumbcanes +dumbed +dumber +dumbest +dumbfound +dumbfounded +dumbfounder +dumbfoundered +dumbfoundering +dumbfounders +dumbfounding +dumbfounds +dumbhead +dumbheads +dumbing +dumbly +dumbness +dumbnesses +dumbs +dumbstruck +dumbwaiter +dumbwaiters +dumdum +dumdums +dumfound +dumfounded +dumfounding +dumfounds +dumka +dumky +dummied +dummies +dummkopf +dummkopfs +dummy +dummying +dumortierite +dumortierites +dump +dumpcart +dumpcarts +dumped +dumper +dumpers +dumpier +dumpiest +dumpily +dumpiness +dumpinesses +dumping +dumpings +dumpish +dumpling +dumplings +dumps +dumpy +dun +dunam +dunams +dunce +dunces +dunch +dunches +duncical +duncish +dunderhead +dunderheaded +dunderheads +dundrearies +dune +duneland +dunelands +dunelike +dunes +dung +dungaree +dungarees +dunged +dungeon +dungeoned +dungeoning +dungeons +dunghill +dunghills +dungier +dungiest +dunging +dungs +dungy +dunite +dunites +dunitic +dunk +dunked +dunker +dunkers +dunking +dunks +dunlin +dunlins +dunnage +dunnages +dunned +dunner +dunness +dunnesses +dunnest +dunning +dunnite +dunnites +duns +dunt +dunted +dunting +dunts +duo +duodecillion +duodecillions +duodecimal +duodecimals +duodecimo +duodecimos +duodena +duodenal +duodenum +duodenums +duolog +duologs +duologue +duologues +duomi +duomo +duomos +duopolies +duopolistic +duopoly +duopsonies +duopsony +duos +duotone +duotones +dup +dupable +dupe +duped +duper +duperies +dupers +dupery +dupes +duping +duple +duplex +duplexed +duplexer +duplexers +duplexes +duplexing +duplicate +duplicated +duplicates +duplicating +duplication +duplications +duplicative +duplicator +duplicators +duplicities +duplicitous +duplicitously +duplicity +dupped +dupping +dups +dura +durabilities +durability +durable +durableness +durablenesses +durables +durably +dural +duralumin +duralumins +duramen +duramens +durance +durances +duras +duration +durations +durative +duratives +durbar +durbars +dure +dured +dures +duress +duresses +durian +durians +during +durion +durions +durmast +durmasts +durn +durndest +durned +durneder +durnedest +durning +durns +duro +duroc +durocs +durometer +durometers +duros +durr +durra +durras +durrie +durries +durrs +durst +durum +durums +dusk +dusked +duskier +duskiest +duskily +duskiness +duskinesses +dusking +duskish +dusks +dusky +dust +dustbin +dustbins +dustcover +dustcovers +dusted +duster +dusters +dustheap +dustheaps +dustier +dustiest +dustily +dustiness +dustinesses +dusting +dustless +dustlike +dustman +dustmen +dustoff +dustoffs +dustpan +dustpans +dustrag +dustrags +dusts +dustup +dustups +dusty +dutch +dutchman +dutchmen +duteous +dutiable +duties +dutiful +dutifully +dutifulness +dutifulnesses +duty +duumvir +duumvirate +duumvirates +duumviri +duumvirs +duvet +duvetine +duvetines +duvets +duvetyn +duvetyne +duvetynes +duvetyns +duxelles +dwarf +dwarfed +dwarfer +dwarfest +dwarfing +dwarfish +dwarfishly +dwarfishness +dwarfishnesses +dwarfism +dwarfisms +dwarflike +dwarfness +dwarfnesses +dwarfs +dwarves +dweeb +dweebs +dwell +dwelled +dweller +dwellers +dwelling +dwellings +dwells +dwelt +dwindle +dwindled +dwindles +dwindling +dwine +dwined +dwines +dwining +dyable +dyad +dyadic +dyadically +dyadics +dyads +dyarchic +dyarchies +dyarchy +dybbuk +dybbukim +dybbuks +dye +dyeabilities +dyeability +dyeable +dyed +dyeing +dyeings +dyer +dyers +dyes +dyestuff +dyestuffs +dyeweed +dyeweeds +dyewood +dyewoods +dying +dyings +dyke +dyked +dykes +dykey +dyking +dynamic +dynamical +dynamically +dynamics +dynamism +dynamisms +dynamist +dynamistic +dynamists +dynamite +dynamited +dynamiter +dynamiters +dynamites +dynamitic +dynamiting +dynamo +dynamometer +dynamometers +dynamometric +dynamometries +dynamometry +dynamos +dynamotor +dynamotors +dynast +dynastic +dynastically +dynasties +dynasts +dynasty +dynatron +dynatrons +dyne +dynein +dynel +dynels +dynes +dynode +dynodes +dysarthria +dysarthrias +dyscrasia +dyscrasias +dysenteric +dysenteries +dysentery +dysfunction +dysfunctional +dysfunctions +dysgeneses +dysgenesis +dysgenic +dyskinesia +dyskinesias +dyskinetic +dyslexia +dyslexias +dyslexic +dyslexics +dyslogistic +dyslogistically +dysmenorrhea +dysmenorrheas +dysmenorrheic +dyspepsia +dyspepsias +dyspepsies +dyspepsy +dyspeptic +dyspeptically +dyspeptics +dysphagia +dysphagias +dysphasia +dysphasias +dysphasic +dysphasics +dysphemism +dysphemisms +dysphemistic +dysphonia +dysphonias +dysphoria +dysphorias +dysphoric +dysplasia +dysplasias +dysplastic +dyspnea +dyspneal +dyspneas +dyspneic +dyspnoea +dyspnoeas +dyspnoic +dysprosium +dysprosiums +dysrhythmia +dysrhythmias +dysrhythmic +dystaxia +dystaxias +dystocia +dystocias +dystonia +dystonias +dystonic +dystopia +dystopian +dystopias +dystrophic +dystrophies +dystrophy +dysuria +dysurias +dysuric +dyvour +dyvours +each +eager +eagerer +eagerest +eagerly +eagerness +eagernesses +eagers +eagle +eagles +eaglet +eaglets +eagre +eagres +ealdorman +ealdormen +eanling +eanlings +ear +earache +earaches +eardrop +eardrops +eardrum +eardrums +eared +earflap +earflaps +earful +earfuls +earing +earings +earl +earlap +earlaps +earldom +earldoms +earless +earlier +earliest +earliness +earlinesses +earlobe +earlobes +earlock +earlocks +earls +earlship +earlships +early +earlywood +earlywoods +earmark +earmarked +earmarking +earmarks +earmuff +earmuffs +earn +earned +earner +earners +earnest +earnestly +earnestness +earnestnesses +earnests +earning +earnings +earns +earphone +earphones +earpiece +earpieces +earplug +earplugs +earring +earrings +ears +earshot +earshots +earsplitting +earstone +earstones +earth +earthborn +earthbound +earthed +earthen +earthenware +earthenwares +earthier +earthiest +earthily +earthiness +earthinesses +earthing +earthlier +earthliest +earthlight +earthlights +earthlike +earthliness +earthlinesses +earthling +earthlings +earthly +earthman +earthmen +earthmover +earthmovers +earthmoving +earthmovings +earthnut +earthnuts +earthpea +earthpeas +earthquake +earthquakes +earthrise +earthrises +earths +earthset +earthsets +earthshaker +earthshakers +earthshaking +earthshakingly +earthshine +earthshines +earthstar +earthstars +earthward +earthwards +earthwork +earthworks +earthworm +earthworms +earthy +earwax +earwaxes +earwig +earwigged +earwigging +earwigs +earwitness +earwitnesses +earworm +earworms +ease +eased +easeful +easefully +easel +easels +easement +easements +eases +easier +easies +easiest +easily +easiness +easinesses +easing +east +eastbound +easter +easterlies +easterly +eastern +easterner +easterners +easternmost +easters +easting +eastings +easts +eastward +eastwards +easy +easygoing +easygoingness +easygoingnesses +eat +eatable +eatables +eaten +eater +eateries +eaters +eatery +eath +eating +eatings +eats +eau +eaux +eave +eaved +eaves +eavesdrop +eavesdropped +eavesdropper +eavesdroppers +eavesdropping +eavesdrops +ebb +ebbed +ebbet +ebbets +ebbing +ebbs +ebon +ebonies +ebonise +ebonised +ebonises +ebonising +ebonite +ebonites +ebonize +ebonized +ebonizes +ebonizing +ebons +ebony +ebullience +ebulliences +ebulliencies +ebulliency +ebullient +ebulliently +ebullition +ebullitions +ecarte +ecartes +ecaudate +ecbolic +ecbolics +eccentric +eccentrically +eccentricities +eccentricity +eccentrics +ecchymoses +ecchymosis +ecchymotic +ecclesia +ecclesiae +ecclesial +ecclesiastic +ecclesiastical +ecclesiastically +ecclesiasticism +ecclesiasticisms +ecclesiastics +ecclesiological +ecclesiologies +ecclesiologist +ecclesiologists +ecclesiology +eccrine +ecdyses +ecdysial +ecdysiast +ecdysiasts +ecdysis +ecdyson +ecdysone +ecdysones +ecdysons +ecesis +ecesises +echard +echards +eche +eched +echelle +echelles +echelon +echeloned +echeloning +echelons +eches +echeveria +echeverias +echidna +echidnae +echidnas +echinate +eching +echini +echinococci +echinococcoses +echinococcosis +echinococcus +echinoderm +echinodermatous +echinoderms +echinoid +echinoids +echinus +echiuroid +echiuroids +echo +echocardiogram +echocardiograms +echocardiographer +echocardiographers +echocardiographic +echocardiographies +echocardiography +echoed +echoer +echoers +echoes +echoey +echogram +echograms +echoic +echoing +echoism +echoisms +echolalia +echolalias +echolalic +echoless +echolocation +echolocations +echos +echovirus +echoviruses +eclair +eclaircissement +eclaircissements +eclairs +eclampsia +eclampsias +eclamptic +eclat +eclats +eclectic +eclectically +eclecticism +eclecticisms +eclectics +eclipse +eclipsed +eclipses +eclipsing +eclipsis +eclipsises +ecliptic +ecliptics +eclogite +eclogites +eclogue +eclogues +eclosion +eclosions +ecocatastrophe +ecocatastrophes +ecocidal +ecocide +ecocides +ecofreak +ecofreaks +ecologic +ecological +ecologically +ecologies +ecologist +ecologists +ecology +econobox +econoboxes +econometric +econometrically +econometrician +econometricians +econometrics +econometrist +econometrists +economic +economical +economically +economics +economies +economise +economised +economises +economising +economist +economists +economize +economized +economizer +economizers +economizes +economizing +economy +ecophysiological +ecophysiologies +ecophysiology +ecospecies +ecosphere +ecospheres +ecosystem +ecosystems +ecotonal +ecotone +ecotones +ecotourism +ecotourisms +ecotourist +ecotourists +ecotype +ecotypes +ecotypic +ecraseur +ecraseurs +ecru +ecrus +ecstasies +ecstasy +ecstatic +ecstatically +ecstatics +ectases +ectasis +ectatic +ecthyma +ecthymata +ectoderm +ectodermal +ectoderms +ectomere +ectomeres +ectomorph +ectomorphic +ectomorphs +ectoparasite +ectoparasites +ectoparasitic +ectopia +ectopias +ectopic +ectopically +ectoplasm +ectoplasmic +ectoplasms +ectosarc +ectosarcs +ectotherm +ectothermic +ectotherms +ectotrophic +ectozoa +ectozoan +ectozoans +ectozoon +ectypal +ectype +ectypes +ecu +ecumenic +ecumenical +ecumenicalism +ecumenicalisms +ecumenically +ecumenicism +ecumenicisms +ecumenicist +ecumenicists +ecumenicities +ecumenicity +ecumenics +ecumenism +ecumenisms +ecumenist +ecumenists +ecus +eczema +eczemas +eczematous +ed +edacious +edacities +edacity +edaphic +edaphically +eddied +eddies +eddo +eddoes +eddy +eddying +edelweiss +edelweisses +edema +edemas +edemata +edematous +edenic +edentate +edentates +edentulous +edge +edged +edgeless +edger +edgers +edges +edgeways +edgewise +edgier +edgiest +edgily +edginess +edginesses +edging +edgings +edgy +edh +edhs +edibilities +edibility +edible +edibleness +ediblenesses +edibles +edict +edictal +edicts +edification +edifications +edifice +edifices +edified +edifier +edifiers +edifies +edify +edifying +edile +ediles +edit +editable +edited +editing +edition +editions +editor +editorial +editorialist +editorialists +editorialization +editorializations +editorialize +editorialized +editorializer +editorializers +editorializes +editorializing +editorially +editorials +editors +editorship +editorships +editress +editresses +edits +educabilities +educability +educable +educables +educate +educated +educatedness +educatednesses +educates +educating +education +educational +educationalist +educationalists +educationally +educationese +educationeses +educationist +educationists +educations +educative +educator +educators +educe +educed +educes +educible +educing +educt +eduction +eductions +eductive +eductor +eductors +educts +edulcorate +edulcorated +edulcorates +edulcorating +edutainment +edutainments +eel +eelgrass +eelgrasses +eelier +eeliest +eellike +eelpout +eelpouts +eels +eelworm +eelworms +eely +eerie +eerier +eeriest +eerily +eeriness +eerinesses +eery +ef +eff +effable +efface +effaceable +effaced +effacement +effacements +effacer +effacers +effaces +effacing +effect +effected +effecter +effecters +effecting +effective +effectively +effectiveness +effectivenesses +effectives +effectivities +effectivity +effector +effectors +effects +effectual +effectualities +effectuality +effectually +effectualness +effectualnesses +effectuate +effectuated +effectuates +effectuating +effectuation +effectuations +effeminacies +effeminacy +effeminate +effeminately +effeminates +effendi +effendis +efferent +efferently +efferents +effervesce +effervesced +effervescence +effervescences +effervescent +effervescently +effervesces +effervescing +effete +effetely +effeteness +effetenesses +efficacies +efficacious +efficaciously +efficaciousness +efficaciousnesses +efficacities +efficacity +efficacy +efficiencies +efficiency +efficient +efficiently +effigial +effigies +effigy +effloresce +effloresced +efflorescence +efflorescences +efflorescent +effloresces +efflorescing +effluence +effluences +effluent +effluents +effluvia +effluvium +effluviums +efflux +effluxes +effluxion +effluxions +effort +effortful +effortfully +effortfulness +effortfulnesses +effortless +effortlessly +effortlessness +effortlessnesses +efforts +effronteries +effrontery +effs +effulge +effulged +effulgence +effulgences +effulgent +effulges +effulging +effuse +effused +effuses +effusing +effusion +effusions +effusive +effusively +effusiveness +effusivenesses +efs +eft +efts +eftsoon +eftsoons +egad +egads +egal +egalitarian +egalitarianism +egalitarianisms +egalitarians +egalite +egalites +eger +egers +egest +egesta +egested +egesting +egestion +egestions +egestive +egests +egg +eggar +eggars +eggbeater +eggbeaters +eggcup +eggcups +egged +egger +eggers +egghead +eggheaded +eggheadedness +eggheadednesses +eggheads +egging +eggless +eggnog +eggnogs +eggplant +eggplants +eggs +eggshell +eggshells +eggy +egis +egises +eglantine +eglantines +eglatere +eglateres +eglomise +ego +egocentric +egocentrically +egocentricities +egocentricity +egocentrics +egocentrism +egocentrisms +egoism +egoisms +egoist +egoistic +egoistical +egoistically +egoists +egoless +egomania +egomaniac +egomaniacal +egomaniacally +egomaniacs +egomanias +egos +egotism +egotisms +egotist +egotistic +egotistical +egotistically +egotists +egregious +egregiously +egregiousness +egregiousnesses +egress +egressed +egresses +egressing +egression +egressions +egret +egrets +egyptian +egyptians +eh +eicosanoid +eicosanoids +eide +eider +eiderdown +eiderdowns +eiders +eidetic +eidetically +eidola +eidolic +eidolon +eidolons +eidos +eigenmode +eigenmodes +eigenvalue +eigenvalues +eigenvector +eigenvectors +eight +eighteen +eighteens +eighteenth +eighteenths +eightfold +eighth +eighthly +eighths +eighties +eightieth +eightieths +eights +eightvo +eightvos +eighty +eikon +eikones +eikons +einkorn +einkorns +einstein +einsteinium +einsteiniums +einsteins +eirenic +eisegeses +eisegesis +eisteddfod +eisteddfodau +eisteddfodic +eisteddfods +eiswein +eisweins +either +ejaculate +ejaculated +ejaculates +ejaculating +ejaculation +ejaculations +ejaculator +ejaculators +ejaculatory +eject +ejecta +ejectable +ejected +ejecting +ejection +ejections +ejective +ejectives +ejectment +ejectments +ejector +ejectors +ejects +eke +eked +ekes +eking +ekistic +ekistics +ekpwele +ekpweles +ektexine +ektexines +ekuele +el +elaborate +elaborated +elaborately +elaborateness +elaboratenesses +elaborates +elaborating +elaboration +elaborations +elaborative +elain +elains +elan +eland +elands +elans +elaphine +elapid +elapids +elapine +elapse +elapsed +elapses +elapsing +elasmobranch +elasmobranchs +elastase +elastases +elastic +elastically +elasticities +elasticity +elasticized +elastics +elastin +elastins +elastomer +elastomeric +elastomers +elate +elated +elatedly +elatedness +elatednesses +elater +elaterid +elaterids +elaterin +elaterins +elaterite +elaterites +elaters +elates +elating +elation +elations +elative +elatives +elbow +elbowed +elbowing +elbowroom +elbowrooms +elbows +eld +elder +elderberries +elderberry +elderlies +elderliness +elderlinesses +elderly +elders +eldership +elderships +eldest +eldress +eldresses +eldrich +eldritch +elds +elecampane +elecampanes +elect +electabilities +electability +electable +elected +electee +electees +electing +election +electioneer +electioneered +electioneerer +electioneerers +electioneering +electioneers +elections +elective +electively +electiveness +electivenesses +electives +elector +electoral +electorally +electorate +electorates +electors +electress +electresses +electret +electrets +electric +electrical +electrically +electrician +electricians +electricities +electricity +electrics +electrification +electrifications +electrified +electrifies +electrify +electrifying +electro +electroacoustic +electroacoustics +electroanalyses +electroanalysis +electroanalytical +electrocardiogram +electrocardiograms +electrocardiograph +electrocardiographic +electrocardiographically +electrocardiographies +electrocardiographs +electrocardiography +electrochemical +electrochemically +electrochemistries +electrochemistry +electroconvulsive +electrocorticogram +electrocorticograms +electrocute +electrocuted +electrocutes +electrocuting +electrocution +electrocutions +electrode +electrodeposit +electrodeposited +electrodepositing +electrodeposition +electrodepositions +electrodeposits +electrodermal +electrodes +electrodesiccation +electrodesiccations +electrodialyses +electrodialysis +electrodialytic +electrodynamic +electrodynamics +electrodynamometer +electrodynamometers +electroed +electroencephalogram +electroencephalograms +electroencephalograph +electroencephalographer +electroencephalographers +electroencephalographic +electroencephalographically +electroencephalographies +electroencephalographs +electroencephalography +electrofishing +electrofishings +electroform +electroformed +electroforming +electroforms +electrogeneses +electrogenesis +electrogenic +electrogram +electrograms +electrohydraulic +electroing +electrojet +electrojets +electrokinetic +electrokinetics +electroless +electrologies +electrologist +electrologists +electrology +electroluminescence +electroluminescences +electroluminescent +electrolyses +electrolysis +electrolyte +electrolytes +electrolytic +electrolytically +electrolyze +electrolyzed +electrolyzes +electrolyzing +electromagnet +electromagnetic +electromagnetically +electromagnetism +electromagnetisms +electromagnets +electromechanical +electromechanically +electrometallurgies +electrometallurgy +electrometer +electrometers +electromyogram +electromyograms +electromyograph +electromyographic +electromyographically +electromyographies +electromyographs +electromyography +electron +electronegative +electronegativities +electronegativity +electronic +electronically +electronics +electrons +electrooculogram +electrooculograms +electrooculographies +electrooculography +electroosmoses +electroosmosis +electroosmotic +electropherogram +electropherograms +electrophile +electrophiles +electrophilic +electrophilicities +electrophilicity +electrophorese +electrophoresed +electrophoreses +electrophoresing +electrophoresis +electrophoretic +electrophoretically +electrophoretogram +electrophoretograms +electrophori +electrophorus +electrophotographic +electrophotographies +electrophotography +electrophysiologic +electrophysiological +electrophysiologically +electrophysiologies +electrophysiologist +electrophysiologists +electrophysiology +electroplate +electroplated +electroplates +electroplating +electropositive +electroretinogram +electroretinograms +electroretinograph +electroretinographic +electroretinographies +electroretinographs +electroretinography +electros +electroscope +electroscopes +electroshock +electroshocks +electrostatic +electrostatically +electrostatics +electrosurgeries +electrosurgery +electrosurgical +electrotherapies +electrotherapy +electrothermal +electrothermally +electrotonic +electrotonically +electrotonus +electrotonuses +electrotype +electrotyped +electrotyper +electrotypers +electrotypes +electrotyping +electroweak +electrowinning +electrowinnings +electrum +electrums +elects +electuaries +electuary +eledoisin +eledoisins +eleemosynary +elegance +elegances +elegancies +elegancy +elegant +elegantly +elegiac +elegiacal +elegiacally +elegiacs +elegies +elegise +elegised +elegises +elegising +elegist +elegists +elegit +elegits +elegize +elegized +elegizes +elegizing +elegy +element +elemental +elementally +elementals +elementarily +elementariness +elementarinesses +elementary +elements +elemi +elemis +elenchi +elenchic +elenchus +elenctic +elephant +elephantiases +elephantiasis +elephantine +elephants +elevate +elevated +elevateds +elevates +elevating +elevation +elevations +elevator +elevators +eleven +elevens +elevenses +eleventh +elevenths +elevon +elevons +elf +elfin +elfins +elfish +elfishly +elflike +elflock +elflocks +elhi +elicit +elicitation +elicitations +elicited +eliciting +elicitor +elicitors +elicits +elide +elided +elides +elidible +eliding +eligibilities +eligibility +eligible +eligibles +eligibly +eliminate +eliminated +eliminates +eliminating +elimination +eliminations +eliminative +eliminator +eliminators +elint +elints +elision +elisions +elite +elites +elitism +elitisms +elitist +elitists +elixir +elixirs +elk +elkhound +elkhounds +elks +ell +ellipse +ellipses +ellipsis +ellipsoid +ellipsoidal +ellipsoids +elliptic +elliptical +elliptically +ellipticals +ellipticities +ellipticity +ells +elm +elmier +elmiest +elms +elmy +elocution +elocutionary +elocutionist +elocutionists +elocutions +elodea +elodeas +eloign +eloigned +eloigner +eloigners +eloigning +eloigns +eloin +eloined +eloiner +eloiners +eloining +eloins +elongate +elongated +elongates +elongating +elongation +elongations +elope +eloped +elopement +elopements +eloper +elopers +elopes +eloping +eloquence +eloquences +eloquent +eloquently +els +else +elsewhere +eluant +eluants +eluate +eluates +elucidate +elucidated +elucidates +elucidating +elucidation +elucidations +elucidative +elucidator +elucidators +elucubrate +elucubrated +elucubrates +elucubrating +elucubration +elucubrations +elude +eluded +eluder +eluders +eludes +eluding +eluent +eluents +elusion +elusions +elusive +elusively +elusiveness +elusivenesses +elusory +elute +eluted +elutes +eluting +elution +elutions +elutriate +elutriated +elutriates +elutriating +elutriation +elutriations +elutriator +elutriators +eluvia +eluvial +eluviate +eluviated +eluviates +eluviating +eluviation +eluviations +eluvium +eluviums +elver +elvers +elves +elvish +elvishly +elysian +elytra +elytroid +elytron +elytrous +elytrum +em +emaciate +emaciated +emaciates +emaciating +emaciation +emaciations +emalangeni +emanate +emanated +emanates +emanating +emanation +emanations +emanative +emanator +emanators +emancipate +emancipated +emancipates +emancipating +emancipation +emancipationist +emancipationists +emancipations +emancipator +emancipators +emarginate +emargination +emarginations +emasculate +emasculated +emasculates +emasculating +emasculation +emasculations +emasculator +emasculators +embalm +embalmed +embalmer +embalmers +embalming +embalmment +embalmments +embalms +embank +embanked +embanking +embankment +embankments +embanks +embar +embarcadero +embarcaderos +embargo +embargoed +embargoes +embargoing +embark +embarkation +embarkations +embarked +embarking +embarkment +embarkments +embarks +embarrass +embarrassable +embarrassed +embarrassedly +embarrasses +embarrassing +embarrassingly +embarrassment +embarrassments +embarred +embarring +embars +embassage +embassages +embassies +embassy +embattle +embattled +embattlement +embattlements +embattles +embattling +embay +embayed +embaying +embayment +embayments +embays +embed +embedded +embedding +embeddings +embedment +embedments +embeds +embellish +embellished +embellisher +embellishers +embellishes +embellishing +embellishment +embellishments +ember +embers +embezzle +embezzled +embezzlement +embezzlements +embezzler +embezzlers +embezzles +embezzling +embitter +embittered +embittering +embitterment +embitterments +embitters +emblaze +emblazed +emblazer +emblazers +emblazes +emblazing +emblazon +emblazoned +emblazoner +emblazoners +emblazoning +emblazonment +emblazonments +emblazonries +emblazonry +emblazons +emblem +emblematic +emblematical +emblematically +emblematize +emblematized +emblematizes +emblematizing +emblemed +emblements +embleming +emblems +embodied +embodier +embodiers +embodies +embodiment +embodiments +embody +embodying +embolden +emboldened +emboldening +emboldens +embolectomies +embolectomy +emboli +embolic +embolies +embolism +embolismic +embolisms +embolization +embolizations +embolus +emboly +embonpoint +embonpoints +emborder +embordered +embordering +emborders +embosk +embosked +embosking +embosks +embosom +embosomed +embosoming +embosoms +emboss +embossable +embossed +embosser +embossers +embosses +embossing +embossment +embossments +embouchure +embouchures +embourgeoisement +embourgeoisements +embow +embowed +embowel +emboweled +emboweling +embowelled +embowelling +embowels +embower +embowered +embowering +embowers +embowing +embows +embrace +embraceable +embraced +embracement +embracements +embraceor +embraceors +embracer +embraceries +embracers +embracery +embraces +embracing +embracingly +embracive +embrangle +embrangled +embranglement +embranglements +embrangles +embrangling +embrasure +embrasures +embrittle +embrittled +embrittlement +embrittlements +embrittles +embrittling +embrocation +embrocations +embroider +embroidered +embroiderer +embroiderers +embroideries +embroidering +embroiders +embroidery +embroil +embroiled +embroiling +embroilment +embroilments +embroils +embrown +embrowned +embrowning +embrowns +embrue +embrued +embrues +embruing +embrute +embruted +embrutes +embruting +embryo +embryogeneses +embryogenesis +embryogenetic +embryogenic +embryogenies +embryogeny +embryoid +embryoids +embryological +embryologically +embryologies +embryologist +embryologists +embryology +embryon +embryonal +embryonated +embryonic +embryonically +embryons +embryophyte +embryophytes +embryos +emcee +emceed +emceeing +emcees +eme +emeer +emeerate +emeerates +emeers +emend +emendable +emendate +emendated +emendates +emendating +emendation +emendations +emended +emender +emenders +emending +emends +emerald +emeralds +emerge +emerged +emergence +emergences +emergencies +emergency +emergent +emergents +emerges +emerging +emeries +emerita +emeritae +emeriti +emeritus +emerod +emerods +emeroid +emeroids +emersed +emersion +emersions +emery +emes +emeses +emesis +emetic +emetically +emetics +emetin +emetine +emetines +emetins +emeu +emeus +emeute +emeutes +emf +emfs +emic +emigrant +emigrants +emigrate +emigrated +emigrates +emigrating +emigration +emigrations +emigre +emigres +eminence +eminences +eminencies +eminency +eminent +eminently +emir +emirate +emirates +emirs +emissaries +emissary +emission +emissions +emissive +emissivities +emissivity +emit +emits +emittance +emittances +emitted +emitter +emitters +emitting +emmenagogue +emmenagogues +emmer +emmers +emmet +emmets +emodin +emodins +emollient +emollients +emolument +emoluments +emote +emoted +emoter +emoters +emotes +emoting +emotion +emotional +emotionalism +emotionalisms +emotionalist +emotionalistic +emotionalists +emotionalities +emotionality +emotionalize +emotionalized +emotionalizes +emotionalizing +emotionally +emotionless +emotionlessly +emotionlessness +emotionlessnesses +emotions +emotive +emotively +emotivities +emotivity +empale +empaled +empaler +empalers +empales +empaling +empanada +empanadas +empanel +empaneled +empaneling +empanelled +empanelling +empanels +empathetic +empathetically +empathic +empathically +empathies +empathise +empathised +empathises +empathising +empathize +empathized +empathizes +empathizing +empathy +empennage +empennages +emperies +emperor +emperors +emperorship +emperorships +empery +emphases +emphasis +emphasise +emphasised +emphasises +emphasising +emphasize +emphasized +emphasizes +emphasizing +emphatic +emphatically +emphysema +emphysemas +emphysematous +emphysemic +empire +empires +empiric +empirical +empirically +empiricism +empiricisms +empiricist +empiricists +empirics +emplace +emplaced +emplacement +emplacements +emplaces +emplacing +emplane +emplaned +emplanes +emplaning +employ +employabilities +employability +employable +employables +employe +employed +employee +employees +employer +employers +employes +employing +employment +employments +employs +empoison +empoisoned +empoisoning +empoisonment +empoisonments +empoisons +emporia +emporium +emporiums +empower +empowered +empowering +empowerment +empowerments +empowers +empress +empressement +empressements +empresses +emprise +emprises +emprize +emprizes +emptied +emptier +emptiers +empties +emptiest +emptily +emptiness +emptinesses +emptings +emptins +empty +emptying +empurple +empurpled +empurples +empurpling +empyema +empyemas +empyemata +empyemic +empyreal +empyrean +empyreans +ems +emu +emulate +emulated +emulates +emulating +emulation +emulations +emulative +emulatively +emulator +emulators +emulous +emulously +emulousness +emulousnesses +emulsifiable +emulsification +emulsifications +emulsified +emulsifier +emulsifiers +emulsifies +emulsify +emulsifying +emulsion +emulsions +emulsive +emulsoid +emulsoidal +emulsoids +emus +emyd +emyde +emydes +emyds +en +enable +enabled +enabler +enablers +enables +enabling +enact +enacted +enacting +enactive +enactment +enactments +enactor +enactors +enactory +enacts +enamel +enameled +enameler +enamelers +enameling +enamelist +enamelists +enamelled +enamelling +enamels +enamelware +enamelwares +enamine +enamines +enamor +enamoration +enamorations +enamored +enamoring +enamors +enamour +enamoured +enamouring +enamours +enantiomer +enantiomeric +enantiomers +enantiomorph +enantiomorphic +enantiomorphism +enantiomorphisms +enantiomorphous +enantiomorphs +enate +enates +enatic +enation +enations +encaenia +encage +encaged +encages +encaging +encamp +encamped +encamping +encampment +encampments +encamps +encapsulate +encapsulated +encapsulates +encapsulating +encapsulation +encapsulations +encapsule +encapsuled +encapsules +encapsuling +encase +encased +encasement +encasements +encases +encash +encashable +encashed +encashes +encashing +encashment +encashments +encasing +encaustic +encaustics +enceinte +enceintes +encephala +encephalitic +encephalitides +encephalitis +encephalitogen +encephalitogenic +encephalitogens +encephalogram +encephalograms +encephalograph +encephalographies +encephalographs +encephalography +encephalomyelitides +encephalomyelitis +encephalomyocarditis +encephalomyocarditises +encephalon +encephalopathic +encephalopathies +encephalopathy +enchain +enchained +enchaining +enchainment +enchainments +enchains +enchant +enchanted +enchanter +enchanters +enchanting +enchantingly +enchantment +enchantments +enchantress +enchantresses +enchants +enchase +enchased +enchaser +enchasers +enchases +enchasing +enchilada +enchiladas +enchiridia +enchiridion +enchiridions +enchoric +encina +encinal +encinas +encipher +enciphered +encipherer +encipherers +enciphering +encipherment +encipherments +enciphers +encircle +encircled +encirclement +encirclements +encircles +encircling +enclasp +enclasped +enclasping +enclasps +enclave +enclaves +enclitic +enclitics +enclose +enclosed +encloser +enclosers +encloses +enclosing +enclosure +enclosures +encode +encoded +encoder +encoders +encodes +encoding +encomia +encomiast +encomiastic +encomiasts +encomium +encomiums +encompass +encompassed +encompasses +encompassing +encompassment +encompassments +encore +encored +encores +encoring +encounter +encountered +encountering +encounters +encourage +encouraged +encouragement +encouragements +encourager +encouragers +encourages +encouraging +encouragingly +encrimson +encrimsoned +encrimsoning +encrimsons +encroach +encroached +encroacher +encroachers +encroaches +encroaching +encroachment +encroachments +encrust +encrustation +encrustations +encrusted +encrusting +encrusts +encrypt +encrypted +encrypting +encryption +encryptions +encrypts +encumber +encumbered +encumbering +encumbers +encumbrance +encumbrancer +encumbrancers +encumbrances +encyclic +encyclical +encyclicals +encyclics +encyclopaedia +encyclopaedias +encyclopaedic +encyclopedia +encyclopedias +encyclopedic +encyclopedically +encyclopedism +encyclopedisms +encyclopedist +encyclopedists +encyst +encysted +encysting +encystment +encystments +encysts +end +endamage +endamaged +endamages +endamaging +endameba +endamebae +endamebas +endamoeba +endamoebae +endamoebas +endanger +endangered +endangering +endangerment +endangerments +endangers +endarch +endarchies +endarchy +endarterectomies +endarterectomy +endbrain +endbrains +endear +endeared +endearing +endearingly +endearment +endearments +endears +endeavor +endeavored +endeavoring +endeavors +endeavour +endeavoured +endeavouring +endeavours +ended +endemial +endemic +endemically +endemicities +endemicity +endemics +endemism +endemisms +ender +endergonic +endermic +enders +endexine +endexines +endgame +endgames +ending +endings +endite +endited +endites +enditing +endive +endives +endleaf +endleaves +endless +endlessly +endlessness +endlessnesses +endlong +endmost +endnote +endnotes +endobiotic +endocardia +endocardial +endocarditis +endocarditises +endocardium +endocarp +endocarps +endocast +endocasts +endochondral +endocrine +endocrines +endocrinologic +endocrinological +endocrinologies +endocrinologist +endocrinologists +endocrinology +endocytoses +endocytosis +endocytosises +endocytotic +endoderm +endodermal +endodermis +endodermises +endoderms +endodontic +endodontically +endodontics +endodontist +endodontists +endoenzyme +endoenzymes +endoergic +endogamies +endogamous +endogamy +endogen +endogenic +endogenies +endogenous +endogenously +endogens +endogeny +endolithic +endolymph +endolymphatic +endolymphs +endometria +endometrial +endometrioses +endometriosis +endometriosises +endometrites +endometritides +endometritis +endometritises +endometrium +endomitoses +endomitosis +endomitotic +endomixis +endomixises +endomorph +endomorphic +endomorphies +endomorphism +endomorphisms +endomorphs +endomorphy +endonuclease +endonucleases +endonucleolytic +endoparasite +endoparasites +endoparasitic +endoparasitism +endoparasitisms +endopeptidase +endopeptidases +endoperoxide +endoperoxides +endophyte +endophytes +endophytic +endoplasm +endoplasmic +endoplasms +endopod +endopodite +endopodites +endopods +endopolyploid +endopolyploidies +endopolyploidy +endorphin +endorphins +endorsable +endorse +endorsed +endorsee +endorsees +endorsement +endorsements +endorser +endorsers +endorses +endorsing +endorsor +endorsors +endosarc +endosarcs +endoscope +endoscopes +endoscopic +endoscopically +endoscopies +endoscopy +endoskeletal +endoskeleton +endoskeletons +endosmos +endosmoses +endosome +endosomes +endosperm +endosperms +endospore +endospores +endostea +endosteal +endosteally +endosteum +endostyle +endostyles +endosulfan +endosulfans +endosymbiont +endosymbionts +endosymbioses +endosymbiosis +endosymbiotic +endothecia +endothecium +endothelia +endothelial +endothelioma +endotheliomas +endotheliomata +endothelium +endotherm +endothermic +endothermies +endotherms +endothermy +endotoxic +endotoxin +endotoxins +endotracheal +endotrophic +endow +endowed +endower +endowers +endowing +endowment +endowments +endows +endozoic +endpaper +endpapers +endplate +endplates +endpoint +endpoints +endrin +endrins +ends +endue +endued +endues +enduing +endurable +endurably +endurance +endurances +endure +endured +endures +enduring +enduringly +enduringness +enduringnesses +enduro +enduros +endways +endwise +enema +enemas +enemata +enemies +enemy +energetic +energetically +energetics +energid +energids +energies +energise +energised +energises +energising +energization +energizations +energize +energized +energizer +energizers +energizes +energizing +energy +enervate +enervated +enervates +enervating +enervation +enervations +enface +enfaced +enfaces +enfacing +enfeeble +enfeebled +enfeeblement +enfeeblements +enfeebles +enfeebling +enfeoff +enfeoffed +enfeoffing +enfeoffment +enfeoffments +enfeoffs +enfetter +enfettered +enfettering +enfetters +enfever +enfevered +enfevering +enfevers +enfilade +enfiladed +enfilades +enfilading +enflame +enflamed +enflames +enflaming +enfleurage +enfleurages +enfold +enfolded +enfolder +enfolders +enfolding +enfolds +enforce +enforceabilities +enforceability +enforceable +enforced +enforcement +enforcements +enforcer +enforcers +enforces +enforcing +enframe +enframed +enframement +enframements +enframes +enframing +enfranchise +enfranchised +enfranchisement +enfranchisements +enfranchises +enfranchising +eng +engage +engaged +engagement +engagements +engager +engagers +engages +engaging +engagingly +engarland +engarlanded +engarlanding +engarlands +engender +engendered +engendering +engenders +engild +engilded +engilding +engilds +engine +engined +engineer +engineered +engineering +engineerings +engineers +engineries +enginery +engines +engining +enginous +engird +engirded +engirding +engirdle +engirdled +engirdles +engirdling +engirds +engirt +english +englished +englishes +englishing +englut +engluts +englutted +englutting +engorge +engorged +engorgement +engorgements +engorges +engorging +engraft +engrafted +engrafting +engraftment +engraftments +engrafts +engrail +engrailed +engrailing +engrails +engrain +engrained +engraining +engrains +engram +engramme +engrammes +engrams +engrave +engraved +engraver +engravers +engraves +engraving +engravings +engross +engrossed +engrosser +engrossers +engrosses +engrossing +engrossingly +engrossment +engrossments +engs +engulf +engulfed +engulfing +engulfment +engulfments +engulfs +enhalo +enhaloed +enhaloes +enhaloing +enhalos +enhance +enhanced +enhancement +enhancements +enhancer +enhancers +enhances +enhancing +enharmonic +enharmonically +enigma +enigmas +enigmata +enigmatic +enigmatical +enigmatically +enisle +enisled +enisles +enisling +enjambed +enjambement +enjambements +enjambment +enjambments +enjoin +enjoined +enjoiner +enjoiners +enjoining +enjoins +enjoy +enjoyable +enjoyableness +enjoyablenesses +enjoyably +enjoyed +enjoyer +enjoyers +enjoying +enjoyment +enjoyments +enjoys +enkephalin +enkephalins +enkindle +enkindled +enkindles +enkindling +enlace +enlaced +enlacement +enlacements +enlaces +enlacing +enlarge +enlargeable +enlarged +enlargement +enlargements +enlarger +enlargers +enlarges +enlarging +enlighten +enlightened +enlightening +enlightenment +enlightenments +enlightens +enlist +enlisted +enlistee +enlistees +enlister +enlisters +enlisting +enlistment +enlistments +enlists +enliven +enlivened +enlivening +enlivens +enmesh +enmeshed +enmeshes +enmeshing +enmeshment +enmeshments +enmities +enmity +ennead +enneadic +enneads +enneagon +enneagons +ennoble +ennobled +ennoblement +ennoblements +ennobler +ennoblers +ennobles +ennobling +ennui +ennuis +ennuye +ennuyee +enoki +enokidake +enokidakes +enokis +enol +enolase +enolases +enolic +enological +enologies +enologist +enologists +enology +enols +enorm +enormities +enormity +enormous +enormously +enormousness +enormousnesses +enosis +enosises +enough +enoughs +enounce +enounced +enounces +enouncing +enow +enows +enplane +enplaned +enplanes +enplaning +enquire +enquired +enquires +enquiries +enquiring +enquiry +enrage +enraged +enrages +enraging +enrapt +enrapture +enraptured +enraptures +enrapturing +enravish +enravished +enravishes +enravishing +enregister +enregistered +enregistering +enregisters +enrich +enriched +enricher +enrichers +enriches +enriching +enrichment +enrichments +enrobe +enrobed +enrober +enrobers +enrobes +enrobing +enrol +enroll +enrolled +enrollee +enrollees +enroller +enrollers +enrolling +enrollment +enrollments +enrolls +enrols +enroot +enrooted +enrooting +enroots +ens +ensample +ensamples +ensanguine +ensanguined +ensanguines +ensanguining +ensconce +ensconced +ensconces +ensconcing +enscroll +enscrolled +enscrolling +enscrolls +ensemble +ensembles +enserf +enserfed +enserfing +enserfment +enserfments +enserfs +ensheath +ensheathe +ensheathed +ensheathes +ensheathing +ensheaths +enshrine +enshrined +enshrinee +enshrinees +enshrinement +enshrinements +enshrines +enshrining +enshroud +enshrouded +enshrouding +enshrouds +ensiform +ensign +ensigncies +ensigncy +ensigns +ensilage +ensilaged +ensilages +ensilaging +ensile +ensiled +ensiles +ensiling +enskied +enskies +ensky +enskyed +enskying +enslave +enslaved +enslavement +enslavements +enslaver +enslavers +enslaves +enslaving +ensnare +ensnared +ensnarer +ensnarers +ensnares +ensnaring +ensnarl +ensnarled +ensnarling +ensnarls +ensorcel +ensorceled +ensorceling +ensorcell +ensorcelled +ensorcelling +ensorcellment +ensorcellments +ensorcells +ensorcels +ensoul +ensouled +ensouling +ensouls +ensphere +ensphered +enspheres +ensphering +ensue +ensued +ensues +ensuing +ensure +ensured +ensurer +ensurers +ensures +ensuring +enswathe +enswathed +enswathes +enswathing +entablature +entablatures +entail +entailed +entailer +entailers +entailing +entailment +entailments +entails +entameba +entamebae +entamebas +entamoeba +entamoebae +entamoebas +entangle +entangled +entanglement +entanglements +entangler +entanglers +entangles +entangling +entases +entasia +entasias +entasis +entastic +entelechies +entelechy +entellus +entelluses +entente +ententes +enter +entera +enterable +enteral +enterally +entered +enterer +enterers +enteric +entering +enteritides +enteritis +enteritises +enterobacteria +enterobacterial +enterobacterium +enterobiases +enterobiasis +enterochromaffin +enterococcal +enterococci +enterococcus +enterocoel +enterocoele +enterocoeles +enterocoelic +enterocoelous +enterocoels +enterocolitis +enterocolitises +enterogastrone +enterogastrones +enterokinase +enterokinases +enteron +enterons +enteropathies +enteropathogenic +enteropathy +enterostomal +enterostomies +enterostomy +enterotoxin +enterotoxins +enteroviral +enterovirus +enteroviruses +enterprise +enterpriser +enterprisers +enterprises +enterprising +enters +entertain +entertained +entertainer +entertainers +entertaining +entertainingly +entertainment +entertainments +entertains +enthalpies +enthalpy +enthetic +enthral +enthrall +enthralled +enthralling +enthrallment +enthrallments +enthralls +enthrals +enthrone +enthroned +enthronement +enthronements +enthrones +enthroning +enthuse +enthused +enthuses +enthusiasm +enthusiasms +enthusiast +enthusiastic +enthusiastically +enthusiasts +enthusing +enthymeme +enthymemes +entia +entice +enticed +enticement +enticements +enticer +enticers +entices +enticing +enticingly +entire +entirely +entireness +entirenesses +entires +entireties +entirety +entities +entitle +entitled +entitlement +entitlements +entitles +entitling +entity +entoderm +entodermal +entodermic +entoderms +entoil +entoiled +entoiling +entoils +entomb +entombed +entombing +entombment +entombments +entombs +entomofauna +entomofaunae +entomofaunas +entomological +entomologically +entomologies +entomologist +entomologists +entomology +entomophagous +entomophilies +entomophilous +entomophily +entopic +entoproct +entoprocts +entourage +entourages +entozoa +entozoal +entozoan +entozoans +entozoic +entozoon +entrails +entrain +entrained +entrainer +entrainers +entraining +entrainment +entrainments +entrains +entrance +entranced +entrancement +entrancements +entrances +entranceway +entranceways +entrancing +entrant +entrants +entrap +entrapment +entrapments +entrapped +entrapping +entraps +entreat +entreated +entreaties +entreating +entreatingly +entreatment +entreatments +entreats +entreaty +entrechat +entrechats +entrecote +entrecotes +entree +entrees +entremets +entrench +entrenched +entrenches +entrenching +entrenchment +entrenchments +entrepot +entrepots +entrepreneur +entrepreneurial +entrepreneurialism +entrepreneurialisms +entrepreneurially +entrepreneurs +entrepreneurship +entrepreneurships +entresol +entresols +entries +entropic +entropically +entropies +entropion +entropions +entropy +entrust +entrusted +entrusting +entrustment +entrustments +entrusts +entry +entryway +entryways +entwine +entwined +entwines +entwining +entwist +entwisted +entwisting +entwists +enucleate +enucleated +enucleates +enucleating +enucleation +enucleations +enumerabilities +enumerability +enumerable +enumerate +enumerated +enumerates +enumerating +enumeration +enumerations +enumerative +enumerator +enumerators +enunciable +enunciate +enunciated +enunciates +enunciating +enunciation +enunciations +enunciator +enunciators +enure +enured +enures +enuresis +enuresises +enuretic +enuretics +enuring +envelop +envelope +enveloped +envelopes +enveloping +envelopment +envelopments +envelops +envenom +envenomed +envenoming +envenomization +envenomizations +envenoms +enviable +enviableness +enviablenesses +enviably +envied +envier +enviers +envies +envious +enviously +enviousness +enviousnesses +environ +environed +environing +environment +environmental +environmentalism +environmentalisms +environmentalist +environmentalists +environmentally +environments +environs +envisage +envisaged +envisages +envisaging +envision +envisioned +envisioning +envisions +envoi +envois +envoy +envoys +envy +envying +envyingly +enwheel +enwheeled +enwheeling +enwheels +enwind +enwinding +enwinds +enwomb +enwombed +enwombing +enwombs +enwound +enwrap +enwrapped +enwrapping +enwraps +enwreathe +enwreathed +enwreathes +enwreathing +enzootic +enzootics +enzym +enzymatic +enzymatically +enzyme +enzymes +enzymic +enzymically +enzymologies +enzymologist +enzymologists +enzymology +enzyms +eobiont +eobionts +eohippus +eohippuses +eolian +eolipile +eolipiles +eolith +eolithic +eoliths +eolopile +eolopiles +eon +eonian +eonism +eonisms +eons +eosin +eosine +eosines +eosinic +eosinophil +eosinophilia +eosinophilias +eosinophilic +eosinophils +eosins +epact +epacts +eparch +eparchies +eparchs +eparchy +epaulet +epaulets +epaulette +epauletted +epaulettes +epazote +epazotes +epee +epeeist +epeeists +epees +epeiric +epeirogenic +epeirogenically +epeirogenies +epeirogeny +ependyma +ependymas +epentheses +epenthesis +epenthetic +epergne +epergnes +epexegeses +epexegesis +epexegetic +epexegetical +epexegetically +epha +ephah +ephahs +ephas +ephebe +ephebes +ephebi +ephebic +epheboi +ephebos +ephebus +ephedra +ephedras +ephedrin +ephedrine +ephedrines +ephedrins +ephemera +ephemerae +ephemeral +ephemeralities +ephemerality +ephemerally +ephemerals +ephemeras +ephemerid +ephemerides +ephemerids +ephemeris +ephemeron +ephod +ephods +ephor +ephoral +ephorate +ephorates +ephori +ephors +epiblast +epiblastic +epiblasts +epibolic +epibolies +epiboly +epic +epical +epically +epicalyces +epicalyx +epicalyxes +epicardia +epicardial +epicardium +epicarp +epicarps +epicedia +epicedium +epicene +epicenes +epicenism +epicenisms +epicenter +epicenters +epicentral +epichlorohydrin +epichlorohydrins +epiclike +epicontinental +epicotyl +epicotyls +epicritic +epics +epicure +epicurean +epicureanism +epicureanisms +epicureans +epicures +epicurism +epicurisms +epicuticle +epicuticles +epicuticular +epicycle +epicycles +epicyclic +epicycloid +epicycloidal +epicycloids +epidemic +epidemical +epidemically +epidemicities +epidemicity +epidemics +epidemiologic +epidemiological +epidemiologically +epidemiologies +epidemiologist +epidemiologists +epidemiology +epidendrum +epidendrums +epiderm +epidermal +epidermic +epidermis +epidermises +epidermoid +epiderms +epidiascope +epidiascopes +epididymal +epididymides +epididymis +epididymites +epididymitides +epididymitis +epididymitises +epidote +epidotes +epidotic +epidural +epifauna +epifaunae +epifaunal +epifaunas +epifocal +epigastric +epigeal +epigean +epigeic +epigene +epigeneses +epigenesis +epigenetic +epigenetically +epigenic +epigeous +epiglottal +epiglottic +epiglottides +epiglottis +epiglottises +epigon +epigone +epigones +epigoni +epigonic +epigonism +epigonisms +epigonous +epigons +epigonus +epigram +epigrammatic +epigrammatically +epigrammatism +epigrammatisms +epigrammatist +epigrammatists +epigrammatize +epigrammatized +epigrammatizer +epigrammatizers +epigrammatizes +epigrammatizing +epigrams +epigraph +epigrapher +epigraphers +epigraphic +epigraphical +epigraphically +epigraphies +epigraphist +epigraphists +epigraphs +epigraphy +epigynies +epigynous +epigyny +epilation +epilations +epilepsies +epilepsy +epileptic +epileptically +epileptics +epileptiform +epileptogenic +epileptoid +epilimnion +epilimnions +epilog +epilogs +epilogue +epilogued +epilogues +epiloguing +epimer +epimerase +epimerases +epimere +epimeres +epimeric +epimers +epimysia +epimysium +epinaoi +epinaos +epinasties +epinasty +epinephrin +epinephrine +epinephrines +epinephrins +epineuria +epineurium +epineuriums +epipelagic +epiphanic +epiphanies +epiphanous +epiphany +epiphenomena +epiphenomenal +epiphenomenalism +epiphenomenalisms +epiphenomenally +epiphenomenon +epiphragm +epiphragms +epiphyseal +epiphyses +epiphysial +epiphysis +epiphyte +epiphytes +epiphytic +epiphytically +epiphytism +epiphytisms +epiphytologies +epiphytology +epiphytotic +epiphytotics +episcia +episcias +episcopacies +episcopacy +episcopal +episcopally +episcopate +episcopates +episcope +episcopes +episiotomies +episiotomy +episode +episodes +episodic +episodical +episodically +episomal +episomally +episome +episomes +epistases +epistasies +epistasis +epistasy +epistatic +epistaxes +epistaxis +epistemic +epistemically +epistemological +epistemologically +epistemologies +epistemologist +epistemologists +epistemology +epistle +epistler +epistlers +epistles +epistolaries +epistolary +epistoler +epistolers +epistome +epistomes +epistrophe +epistrophes +epistyle +epistyles +epitaph +epitaphial +epitaphic +epitaphs +epitases +epitasis +epitaxial +epitaxially +epitaxic +epitaxies +epitaxy +epithalamia +epithalamic +epithalamion +epithalamium +epithalamiums +epithelia +epithelial +epithelialization +epithelializations +epithelialize +epithelialized +epithelializes +epithelializing +epithelioid +epithelioma +epitheliomas +epitheliomata +epitheliomatous +epithelium +epitheliums +epithelization +epithelizations +epithelize +epithelized +epithelizes +epithelizing +epithet +epithetic +epithetical +epithets +epitome +epitomes +epitomic +epitomical +epitomise +epitomised +epitomises +epitomising +epitomize +epitomized +epitomizes +epitomizing +epitope +epitopes +epizoa +epizoic +epizoism +epizoisms +epizoite +epizoites +epizoon +epizootic +epizootics +epizooties +epizootiologic +epizootiological +epizootiologies +epizootiology +epizooty +epoch +epochal +epochally +epochs +epode +epodes +eponym +eponymic +eponymies +eponymous +eponyms +eponymy +epopee +epopees +epopoeia +epopoeias +epos +eposes +epoxidation +epoxidations +epoxide +epoxides +epoxidize +epoxidized +epoxidizes +epoxidizing +epoxied +epoxies +epoxy +epoxyed +epoxying +epsilon +epsilonic +epsilons +equabilities +equability +equable +equableness +equablenesses +equably +equal +equaled +equaling +equalise +equalised +equaliser +equalisers +equalises +equalising +equalitarian +equalitarianism +equalitarianisms +equalitarians +equalities +equality +equalization +equalizations +equalize +equalized +equalizer +equalizers +equalizes +equalizing +equalled +equalling +equally +equals +equanimities +equanimity +equate +equated +equates +equating +equation +equational +equationally +equations +equator +equatorial +equators +equatorward +equerries +equerry +equestrian +equestrians +equestrienne +equestriennes +equiangular +equicaloric +equid +equidistant +equidistantly +equids +equilateral +equilibrant +equilibrants +equilibrate +equilibrated +equilibrates +equilibrating +equilibration +equilibrations +equilibrator +equilibrators +equilibratory +equilibria +equilibrist +equilibristic +equilibrists +equilibrium +equilibriums +equimolar +equine +equinely +equines +equinities +equinity +equinoctial +equinoctials +equinox +equinoxes +equip +equipage +equipages +equipment +equipments +equipoise +equipoised +equipoises +equipoising +equipollence +equipollences +equipollent +equipollently +equipollents +equiponderant +equipotential +equipped +equipper +equippers +equipping +equiprobable +equips +equiseta +equisetum +equisetums +equitabilities +equitability +equitable +equitableness +equitablenesses +equitably +equitant +equitation +equitations +equites +equities +equity +equivalence +equivalences +equivalencies +equivalency +equivalent +equivalently +equivalents +equivocal +equivocalities +equivocality +equivocally +equivocalness +equivocalnesses +equivocate +equivocated +equivocates +equivocating +equivocation +equivocations +equivocator +equivocators +equivoke +equivokes +equivoque +equivoques +er +era +eradiate +eradiated +eradiates +eradiating +eradicable +eradicate +eradicated +eradicates +eradicating +eradication +eradications +eradicator +eradicators +eras +erasabilities +erasability +erasable +erase +erased +eraser +erasers +erases +erasing +erasion +erasions +erasure +erasures +erbium +erbiums +ere +erect +erectable +erected +erecter +erecters +erectile +erectilities +erectility +erecting +erection +erections +erective +erectly +erectness +erectnesses +erector +erectors +erects +erelong +eremite +eremites +eremitic +eremitical +eremitism +eremitisms +eremuri +eremurus +erenow +erepsin +erepsins +erethic +erethism +erethisms +erewhile +erewhiles +erg +ergastic +ergastoplasm +ergastoplasmic +ergastoplasms +ergate +ergates +ergative +ergo +ergodic +ergodicities +ergodicity +ergograph +ergographs +ergometer +ergometers +ergometric +ergonomic +ergonomically +ergonomics +ergonomist +ergonomists +ergonovine +ergonovines +ergosterol +ergosterols +ergot +ergotamine +ergotamines +ergotic +ergotism +ergotisms +ergotized +ergots +ergs +erica +ericaceous +ericas +ericoid +erigeron +erigerons +eringo +eringoes +eringos +eriophyid +eriophyids +eristic +eristical +eristically +eristics +erlking +erlkings +ermine +ermined +ermines +ern +erne +ernes +erns +erode +eroded +erodent +erodes +erodibilities +erodibility +erodible +eroding +erogenic +erogenous +eros +erose +erosely +eroses +erosible +erosion +erosional +erosionally +erosions +erosive +erosiveness +erosivenesses +erosivities +erosivity +erotic +erotica +erotical +erotically +eroticism +eroticisms +eroticist +eroticists +eroticization +eroticizations +eroticize +eroticized +eroticizes +eroticizing +erotics +erotism +erotisms +erotization +erotizations +erotize +erotized +erotizes +erotizing +erotogenic +err +errancies +errancy +errand +errands +errant +errantly +errantries +errantry +errants +errata +erratas +erratic +erratical +erratically +erraticism +erraticisms +erratics +erratum +erred +errhine +errhines +erring +erringly +erroneous +erroneously +erroneousness +erroneousnesses +error +errorless +errors +errs +ers +ersatz +ersatzes +erses +erst +erstwhile +eruct +eructate +eructated +eructates +eructating +eructation +eructations +eructed +eructing +eructs +erudite +eruditely +erudition +eruditions +erugo +erugos +erumpent +erupt +erupted +eruptible +erupting +eruption +eruptions +eruptive +eruptively +eruptives +erupts +ervil +ervils +eryngo +eryngoes +eryngos +erysipelas +erysipelases +erythema +erythemas +erythematous +erythorbate +erythorbates +erythremia +erythremias +erythrism +erythrismal +erythrisms +erythristic +erythrite +erythrites +erythroblast +erythroblastic +erythroblastoses +erythroblastosis +erythroblasts +erythrocyte +erythrocytes +erythrocytic +erythroid +erythromycin +erythromycins +erythron +erythrons +erythropoieses +erythropoiesis +erythropoietic +erythropoietin +erythropoietins +erythrosin +erythrosine +erythrosines +erythrosins +es +escadrille +escadrilles +escalade +escaladed +escalader +escaladers +escalades +escalading +escalate +escalated +escalates +escalating +escalation +escalations +escalator +escalators +escalatory +escallop +escalloped +escalloping +escallops +escalop +escaloped +escaloping +escalops +escapade +escapades +escape +escaped +escapee +escapees +escapement +escapements +escaper +escapers +escapes +escaping +escapism +escapisms +escapist +escapists +escapologies +escapologist +escapologists +escapology +escar +escargot +escargots +escarole +escaroles +escarp +escarped +escarping +escarpment +escarpments +escarps +escars +eschalot +eschalots +eschar +escharotic +escharotics +eschars +eschatological +eschatologically +eschatologies +eschatology +escheat +escheatable +escheated +escheating +escheats +eschew +eschewal +eschewals +eschewed +eschewing +eschews +escolar +escolars +escort +escorted +escorting +escorts +escot +escoted +escoting +escots +escritoire +escritoires +escrow +escrowed +escrowing +escrows +escuage +escuages +escudo +escudos +esculent +esculents +escutcheon +escutcheons +esemplastic +eserine +eserines +eses +eskar +eskars +esker +eskers +esophageal +esophagi +esophagus +esoteric +esoterica +esoterically +esotericism +esotericisms +espadrille +espadrilles +espalier +espaliered +espaliering +espaliers +espanol +espanoles +esparto +espartos +especial +especially +esperance +esperances +espial +espials +espied +espiegle +espieglerie +espiegleries +espies +espionage +espionages +esplanade +esplanades +espousal +espousals +espouse +espoused +espouser +espousers +espouses +espousing +espresso +espressos +esprit +esprits +espy +espying +esquire +esquired +esquires +esquiring +ess +essay +essayed +essayer +essayers +essaying +essayist +essayistic +essayists +essays +essence +essences +essential +essentialism +essentialisms +essentialist +essentialists +essentialities +essentiality +essentialize +essentialized +essentializes +essentializing +essentially +essentialness +essentialnesses +essentials +esses +essoin +essoins +essonite +essonites +establish +establishable +established +establisher +establishers +establishes +establishing +establishment +establishmentarian +establishmentarianism +establishmentarianisms +establishmentarians +establishments +estaminet +estaminets +estancia +estancias +estate +estated +estates +estating +esteem +esteemed +esteeming +esteems +ester +esterase +esterases +esterification +esterifications +esterified +esterifies +esterify +esterifying +esters +estheses +esthesia +esthesias +esthesis +esthesises +esthete +esthetes +esthetic +esthetician +estheticians +estheticism +estheticisms +esthetics +estimable +estimableness +estimablenesses +estimably +estimate +estimated +estimates +estimating +estimation +estimations +estimative +estimator +estimators +estival +estivate +estivated +estivates +estivating +estivation +estivations +estop +estopped +estoppel +estoppels +estopping +estops +estovers +estradiol +estradiols +estragon +estragons +estral +estrange +estranged +estrangement +estrangements +estranger +estrangers +estranges +estranging +estray +estrayed +estraying +estrays +estreat +estreated +estreating +estreats +estrin +estrins +estriol +estriols +estrogen +estrogenic +estrogenically +estrogens +estrone +estrones +estrous +estrual +estrum +estrums +estrus +estruses +estuarial +estuaries +estuarine +estuary +esurience +esuriences +esurient +esuriently +et +eta +etagere +etageres +etalon +etalons +etamin +etamine +etamines +etamins +etape +etapes +etas +etatism +etatisms +etatist +etcetera +etceteras +etch +etchant +etchants +etched +etcher +etchers +etches +etching +etchings +eternal +eternalize +eternalized +eternalizes +eternalizing +eternally +eternalness +eternalnesses +eternals +eterne +eternise +eternised +eternises +eternising +eternities +eternity +eternization +eternizations +eternize +eternized +eternizes +eternizing +etesian +etesians +eth +ethambutol +ethambutols +ethane +ethanes +ethanol +ethanolamine +ethanolamines +ethanols +ethene +ethenes +ethephon +ethephons +ether +ethereal +etherealities +ethereality +etherealization +etherealizations +etherealize +etherealized +etherealizes +etherealizing +ethereally +etherealness +etherealnesses +etheric +etherified +etherifies +etherify +etherifying +etherish +etherization +etherizations +etherize +etherized +etherizer +etherizers +etherizes +etherizing +ethers +ethic +ethical +ethicalities +ethicality +ethically +ethicalness +ethicalnesses +ethicals +ethician +ethicians +ethicist +ethicists +ethicize +ethicized +ethicizes +ethicizing +ethics +ethinyl +ethinyls +ethion +ethionamide +ethionamides +ethionine +ethionines +ethions +ethmoid +ethmoidal +ethmoids +ethnarch +ethnarchs +ethnic +ethnical +ethnically +ethnicities +ethnicity +ethnics +ethnobotanical +ethnobotanies +ethnobotanist +ethnobotanists +ethnobotany +ethnocentric +ethnocentricities +ethnocentricity +ethnocentrism +ethnocentrisms +ethnographer +ethnographers +ethnographic +ethnographical +ethnographically +ethnographies +ethnography +ethnohistorian +ethnohistorians +ethnohistoric +ethnohistorical +ethnohistories +ethnohistory +ethnologic +ethnological +ethnologies +ethnologist +ethnologists +ethnology +ethnomethodologies +ethnomethodologist +ethnomethodologists +ethnomethodology +ethnomusicological +ethnomusicologies +ethnomusicologist +ethnomusicologists +ethnomusicology +ethnos +ethnoscience +ethnosciences +ethnoses +ethological +ethologies +ethologist +ethologists +ethology +ethos +ethoses +ethoxies +ethoxy +ethoxyl +ethoxyls +eths +ethyl +ethylate +ethylated +ethylates +ethylating +ethylbenzene +ethylbenzenes +ethylene +ethylenediaminetetraacetate +ethylenediaminetetraacetates +ethylenes +ethylenic +ethylic +ethyls +ethyne +ethynes +ethynyl +ethynyls +etic +etiolate +etiolated +etiolates +etiolating +etiolation +etiolations +etiologic +etiological +etiologically +etiologies +etiology +etiquette +etiquettes +etna +etnas +etoile +etoiles +etouffee +etouffees +etude +etudes +etui +etuis +etwee +etwees +etyma +etymological +etymologically +etymologies +etymologise +etymologised +etymologises +etymologising +etymologist +etymologists +etymologize +etymologized +etymologizes +etymologizing +etymology +etymon +etymons +eucaine +eucaines +eucalypt +eucalypti +eucalyptol +eucalyptole +eucalyptoles +eucalyptols +eucalypts +eucalyptus +eucalyptuses +eucaryote +eucaryotes +eucharis +eucharises +eucharistic +euchre +euchred +euchres +euchring +euchromatic +euchromatin +euchromatins +euclase +euclases +euclidean +euclidian +eucrite +eucrites +eucritic +eudaemon +eudaemonism +eudaemonisms +eudaemonist +eudaemonistic +eudaemonists +eudaemons +eudaimonism +eudaimonisms +eudemon +eudemons +eudiometer +eudiometers +eudiometric +eudiometrically +eugenia +eugenias +eugenic +eugenically +eugenicist +eugenicists +eugenics +eugenist +eugenists +eugenol +eugenols +eugeosynclinal +eugeosyncline +eugeosynclines +euglena +euglenas +euglenoid +euglenoids +euglobulin +euglobulins +euhemerism +euhemerisms +euhemerist +euhemeristic +euhemerists +eukaryote +eukaryotes +eukaryotic +eulachan +eulachans +eulachon +eulachons +eulogia +eulogiae +eulogias +eulogies +eulogise +eulogised +eulogises +eulogising +eulogist +eulogistic +eulogistically +eulogists +eulogium +eulogiums +eulogize +eulogized +eulogizer +eulogizers +eulogizes +eulogizing +eulogy +eunuch +eunuchism +eunuchisms +eunuchoid +eunuchoids +eunuchs +euonymus +euonymuses +eupatrid +eupatridae +eupatrids +eupepsia +eupepsias +eupepsies +eupepsy +eupeptic +euphausiid +euphausiids +euphemise +euphemised +euphemises +euphemising +euphemism +euphemisms +euphemist +euphemistic +euphemistically +euphemists +euphemize +euphemized +euphemizer +euphemizers +euphemizes +euphemizing +euphenic +euphenics +euphonic +euphonically +euphonies +euphonious +euphoniously +euphoniousness +euphoniousnesses +euphonium +euphoniums +euphony +euphorbia +euphorbias +euphoria +euphoriant +euphoriants +euphorias +euphoric +euphorically +euphotic +euphrasies +euphrasy +euphroe +euphroes +euphuism +euphuisms +euphuist +euphuistic +euphuistically +euphuists +euploid +euploidies +euploids +euploidy +eupnea +eupneas +eupneic +eupnoea +eupnoeas +eupnoeic +eureka +eurhythmic +eurhythmics +eurhythmies +eurhythmy +euripi +euripus +euro +eurokies +eurokous +euroky +europium +europiums +euros +eurybath +eurybathic +eurybaths +euryhaline +euryokies +euryoky +eurypterid +eurypterids +eurythermal +eurythermic +eurythermous +eurythmic +eurythmics +eurythmies +eurythmy +eurytopic +eustacies +eustacy +eustatic +eustele +eusteles +eutaxies +eutaxy +eutectic +eutectics +eutectoid +eutectoids +euthanasia +euthanasias +euthanasic +euthanatize +euthanatized +euthanatizes +euthanatizing +euthanize +euthanized +euthanizes +euthanizing +euthenics +euthenist +euthenists +eutherian +eutherians +euthyroid +eutrophic +eutrophication +eutrophications +eutrophies +eutrophy +euxenite +euxenites +evacuant +evacuants +evacuate +evacuated +evacuates +evacuating +evacuation +evacuations +evacuative +evacuee +evacuees +evadable +evade +evaded +evader +evaders +evades +evadible +evading +evagination +evaginations +evaluate +evaluated +evaluates +evaluating +evaluation +evaluations +evaluative +evaluator +evaluators +evanesce +evanesced +evanescence +evanescences +evanescent +evanesces +evanescing +evangel +evangelic +evangelical +evangelically +evangelism +evangelisms +evangelist +evangelistic +evangelistically +evangelists +evangelization +evangelizations +evangelize +evangelized +evangelizes +evangelizing +evangels +evanish +evanished +evanishes +evanishing +evaporate +evaporated +evaporates +evaporating +evaporation +evaporations +evaporative +evaporator +evaporators +evaporite +evaporites +evaporitic +evapotranspiration +evapotranspirations +evasion +evasions +evasive +evasively +evasiveness +evasivenesses +eve +evection +evections +even +evened +evener +eveners +evenest +evenfall +evenfalls +evenhanded +evenhandedly +evenhandedness +evenhandednesses +evening +evenings +evenly +evenness +evennesses +evens +evensong +evensongs +event +eventful +eventfully +eventfulness +eventfulnesses +eventide +eventides +eventless +events +eventual +eventualities +eventuality +eventually +eventuate +eventuated +eventuates +eventuating +ever +everblooming +everduring +everglade +everglades +evergreen +evergreens +everlasting +everlastingly +everlastingness +everlastingnesses +everlastings +evermore +eversible +eversion +eversions +evert +everted +everting +evertor +evertors +everts +every +everybody +everyday +everydayness +everydaynesses +everyman +everymen +everyone +everyplace +everything +everyway +everywhere +everywoman +everywomen +eves +evict +evicted +evictee +evictees +evicting +eviction +evictions +evictor +evictors +evicts +evidence +evidenced +evidences +evidencing +evident +evidential +evidentially +evidentiary +evidently +evil +evildoer +evildoers +evildoing +evildoings +eviler +evilest +eviller +evillest +evilly +evilness +evilnesses +evils +evince +evinced +evinces +evincible +evincing +evincive +eviscerate +eviscerated +eviscerates +eviscerating +evisceration +eviscerations +evitable +evite +evited +evites +eviting +evocable +evocation +evocations +evocative +evocatively +evocativeness +evocativenesses +evocator +evocators +evoke +evoked +evoker +evokers +evokes +evoking +evolute +evolutes +evolution +evolutionarily +evolutionary +evolutionism +evolutionisms +evolutionist +evolutionists +evolutions +evolvable +evolve +evolved +evolvement +evolvements +evolver +evolvers +evolves +evolving +evonymus +evonymuses +evulsion +evulsions +evzone +evzones +ewe +ewer +ewers +ewes +ex +exacerbate +exacerbated +exacerbates +exacerbating +exacerbation +exacerbations +exact +exacta +exactable +exactas +exacted +exacter +exacters +exactest +exacting +exactingly +exactingness +exactingnesses +exaction +exactions +exactitude +exactitudes +exactly +exactness +exactnesses +exactor +exactors +exacts +exaggerate +exaggerated +exaggeratedly +exaggeratedness +exaggeratednesses +exaggerates +exaggerating +exaggeration +exaggerations +exaggerative +exaggerator +exaggerators +exaggeratory +exalt +exaltation +exaltations +exalted +exaltedly +exalter +exalters +exalting +exalts +exam +examen +examens +examinable +examinant +examinants +examination +examinational +examinations +examine +examined +examinee +examinees +examiner +examiners +examines +examining +example +exampled +examples +exampling +exams +exanimate +exanthem +exanthema +exanthemas +exanthemata +exanthematic +exanthematous +exanthems +exarch +exarchal +exarchate +exarchates +exarchies +exarchs +exarchy +exasperate +exasperated +exasperatedly +exasperates +exasperating +exasperatingly +exasperation +exasperations +excavate +excavated +excavates +excavating +excavation +excavational +excavations +excavator +excavators +exceed +exceeded +exceeder +exceeders +exceeding +exceedingly +exceeds +excel +excelled +excellence +excellences +excellencies +excellency +excellent +excellently +excelling +excels +excelsior +excelsiors +except +excepted +excepting +exception +exceptionabilities +exceptionability +exceptionable +exceptionably +exceptional +exceptionalism +exceptionalisms +exceptionalities +exceptionality +exceptionally +exceptionalness +exceptionalnesses +exceptions +exceptive +excepts +excerpt +excerpted +excerpter +excerpters +excerpting +excerption +excerptions +excerptor +excerptors +excerpts +excess +excessed +excesses +excessing +excessive +excessively +excessiveness +excessivenesses +exchange +exchangeabilities +exchangeability +exchangeable +exchanged +exchanger +exchangers +exchanges +exchanging +exchequer +exchequers +excide +excided +excides +exciding +excimer +excimers +excipient +excipients +exciple +exciples +excisable +excise +excised +exciseman +excisemen +excises +excising +excision +excisional +excisions +excitabilities +excitability +excitable +excitableness +excitablenesses +excitant +excitants +excitation +excitations +excitative +excitatory +excite +excited +excitedly +excitement +excitements +exciter +exciters +excites +exciting +excitingly +exciton +excitonic +excitons +excitor +excitors +exclaim +exclaimed +exclaimer +exclaimers +exclaiming +exclaims +exclamation +exclamations +exclamatory +exclave +exclaves +excludabilities +excludability +excludable +exclude +excluded +excluder +excluders +excludes +excludible +excluding +exclusion +exclusionary +exclusionist +exclusionists +exclusions +exclusive +exclusively +exclusiveness +exclusivenesses +exclusives +exclusivism +exclusivisms +exclusivist +exclusivists +exclusivities +exclusivity +excogitate +excogitated +excogitates +excogitating +excogitation +excogitations +excogitative +excommunicate +excommunicated +excommunicates +excommunicating +excommunication +excommunications +excommunicative +excommunicator +excommunicators +excoriate +excoriated +excoriates +excoriating +excoriation +excoriations +excrement +excremental +excrementitious +excrements +excrescence +excrescences +excrescencies +excrescency +excrescent +excrescently +excreta +excretal +excrete +excreted +excreter +excreters +excretes +excreting +excretion +excretions +excretory +excruciate +excruciated +excruciates +excruciating +excruciatingly +excruciation +excruciations +exculpate +exculpated +exculpates +exculpating +exculpation +exculpations +exculpatory +excurrent +excursion +excursionist +excursionists +excursions +excursive +excursively +excursiveness +excursivenesses +excursus +excursuses +excusable +excusableness +excusablenesses +excusably +excusatory +excuse +excused +excuser +excusers +excuses +excusing +exec +execrable +execrableness +execrablenesses +execrably +execrate +execrated +execrates +execrating +execration +execrations +execrative +execrator +execrators +execs +executable +executables +executant +executants +execute +executed +executer +executers +executes +executing +execution +executioner +executioners +executions +executive +executives +executor +executorial +executors +executorship +executorships +executory +executrices +executrix +executrixes +exedra +exedrae +exegeses +exegesis +exegete +exegetes +exegetic +exegetical +exegetist +exegetists +exempla +exemplar +exemplarily +exemplariness +exemplarinesses +exemplarities +exemplarity +exemplars +exemplary +exemplification +exemplifications +exemplified +exemplifies +exemplify +exemplifying +exemplum +exempt +exempted +exempting +exemption +exemptions +exempts +exenterate +exenterated +exenterates +exenterating +exenteration +exenterations +exequial +exequies +exequy +exercisable +exercise +exercised +exerciser +exercisers +exercises +exercising +exercitation +exercitations +exergonic +exergual +exergue +exergues +exert +exerted +exerting +exertion +exertions +exertive +exerts +exes +exeunt +exfoliate +exfoliated +exfoliates +exfoliating +exfoliation +exfoliations +exfoliative +exhalant +exhalants +exhalation +exhalations +exhale +exhaled +exhalent +exhalents +exhales +exhaling +exhaust +exhausted +exhauster +exhausters +exhaustibilities +exhaustibility +exhaustible +exhausting +exhaustion +exhaustions +exhaustive +exhaustively +exhaustiveness +exhaustivenesses +exhaustivities +exhaustivity +exhaustless +exhaustlessly +exhaustlessness +exhaustlessnesses +exhausts +exhibit +exhibited +exhibiting +exhibition +exhibitioner +exhibitioners +exhibitionism +exhibitionisms +exhibitionist +exhibitionistic +exhibitionistically +exhibitionists +exhibitions +exhibitive +exhibitor +exhibitors +exhibitory +exhibits +exhilarate +exhilarated +exhilarates +exhilarating +exhilaratingly +exhilaration +exhilarations +exhilarative +exhort +exhortation +exhortations +exhortative +exhortatory +exhorted +exhorter +exhorters +exhorting +exhorts +exhumation +exhumations +exhume +exhumed +exhumer +exhumers +exhumes +exhuming +exigence +exigences +exigencies +exigency +exigent +exigently +exigible +exiguities +exiguity +exiguous +exiguously +exiguousness +exiguousnesses +exile +exiled +exiles +exilian +exilic +exiling +eximious +exine +exines +exist +existed +existence +existences +existent +existential +existentialism +existentialisms +existentialist +existentialistic +existentialistically +existentialists +existentially +existents +existing +exists +exit +exited +exiting +exitless +exits +exobiological +exobiologies +exobiologist +exobiologists +exobiology +exocarp +exocarps +exocrine +exocrines +exocyclic +exocytoses +exocytosis +exocytotic +exoderm +exodermis +exodermises +exoderms +exodoi +exodontia +exodontias +exodontist +exodontists +exodos +exodus +exoduses +exoenzyme +exoenzymes +exoergic +exoerythrocytic +exogamic +exogamies +exogamous +exogamy +exogen +exogenous +exogenously +exogens +exon +exonerate +exonerated +exonerates +exonerating +exoneration +exonerations +exonerative +exonic +exons +exonuclease +exonucleases +exonumia +exopeptidase +exopeptidases +exophthalmic +exophthalmos +exophthalmoses +exophthalmus +exophthalmuses +exorable +exorbitance +exorbitances +exorbitant +exorbitantly +exorcise +exorcised +exorciser +exorcisers +exorcises +exorcising +exorcism +exorcisms +exorcist +exorcistic +exorcistical +exorcists +exorcize +exorcized +exorcizes +exorcizing +exordia +exordial +exordium +exordiums +exoskeletal +exoskeleton +exoskeletons +exosmic +exosmose +exosmoses +exosphere +exospheres +exospheric +exospore +exospores +exostoses +exostosis +exoteric +exoterically +exothermal +exothermally +exothermic +exothermically +exothermicities +exothermicity +exotic +exotica +exotically +exoticism +exoticisms +exoticness +exoticnesses +exotics +exotism +exotisms +exotoxic +exotoxin +exotoxins +expand +expandabilities +expandability +expandable +expanded +expander +expanders +expanding +expandor +expandors +expands +expanse +expanses +expansibilities +expansibility +expansible +expansion +expansional +expansionary +expansionism +expansionisms +expansionist +expansionistic +expansionists +expansions +expansive +expansively +expansiveness +expansivenesses +expansivities +expansivity +expat +expatiate +expatiated +expatiates +expatiating +expatiation +expatiations +expatriate +expatriated +expatriates +expatriating +expatriation +expatriations +expatriatism +expatriatisms +expats +expect +expectable +expectably +expectance +expectances +expectancies +expectancy +expectant +expectantly +expectants +expectation +expectational +expectations +expectative +expected +expectedly +expectedness +expectednesses +expecting +expectorant +expectorants +expectorate +expectorated +expectorates +expectorating +expectoration +expectorations +expects +expedience +expediences +expediencies +expediency +expedient +expediential +expediently +expedients +expedite +expedited +expediter +expediters +expedites +expediting +expedition +expeditionary +expeditions +expeditious +expeditiously +expeditiousness +expeditiousnesses +expeditor +expeditors +expel +expellable +expelled +expellee +expellees +expeller +expellers +expelling +expels +expend +expendabilities +expendability +expendable +expendables +expended +expender +expenders +expending +expenditure +expenditures +expends +expense +expensed +expenses +expensing +expensive +expensively +expensiveness +expensivenesses +experience +experienced +experiences +experiencing +experiential +experientially +experiment +experimental +experimentalism +experimentalisms +experimentalist +experimentalists +experimentally +experimentation +experimentations +experimented +experimenter +experimenters +experimenting +experiments +expert +experted +experting +expertise +expertises +expertism +expertisms +expertize +expertized +expertizes +expertizing +expertly +expertness +expertnesses +experts +expiable +expiate +expiated +expiates +expiating +expiation +expiations +expiator +expiators +expiatory +expiration +expirations +expiratory +expire +expired +expirer +expirers +expires +expiries +expiring +expiry +explain +explainable +explained +explainer +explainers +explaining +explains +explanation +explanations +explanative +explanatively +explanatorily +explanatory +explant +explantation +explantations +explanted +explanting +explants +expletive +expletives +expletory +explicable +explicably +explicate +explicated +explicates +explicating +explication +explications +explicative +explicatively +explicator +explicators +explicatory +explicit +explicitly +explicitness +explicitnesses +explicits +explode +exploded +exploder +exploders +explodes +exploding +exploit +exploitable +exploitation +exploitations +exploitative +exploitatively +exploited +exploiter +exploiters +exploiting +exploitive +exploits +exploration +explorational +explorations +explorative +exploratively +exploratory +explore +explored +explorer +explorers +explores +exploring +explosion +explosions +explosive +explosively +explosiveness +explosivenesses +explosives +expo +exponent +exponential +exponentially +exponentials +exponentiation +exponentiations +exponents +export +exportabilities +exportability +exportable +exportation +exportations +exported +exporter +exporters +exporting +exports +expos +exposal +exposals +expose +exposed +exposer +exposers +exposes +exposing +exposit +exposited +expositing +exposition +expositional +expositions +expositive +expositor +expositors +expository +exposits +expostulate +expostulated +expostulates +expostulating +expostulation +expostulations +expostulatory +exposure +exposures +expound +expounded +expounder +expounders +expounding +expounds +express +expressage +expressages +expressed +expresser +expressers +expresses +expressible +expressing +expression +expressional +expressionism +expressionisms +expressionist +expressionistic +expressionistically +expressionists +expressionless +expressionlessly +expressionlessness +expressionlessnesses +expressions +expressive +expressively +expressiveness +expressivenesses +expressivities +expressivity +expressly +expressman +expressmen +expresso +expressos +expressway +expressways +expropriate +expropriated +expropriates +expropriating +expropriation +expropriations +expropriator +expropriators +expulse +expulsed +expulses +expulsing +expulsion +expulsions +expulsive +expunction +expunctions +expunge +expunged +expunger +expungers +expunges +expunging +expurgate +expurgated +expurgates +expurgating +expurgation +expurgations +expurgator +expurgatorial +expurgators +expurgatory +exquisite +exquisitely +exquisiteness +exquisitenesses +exquisites +exsanguinate +exsanguinated +exsanguinates +exsanguinating +exsanguination +exsanguinations +exscind +exscinded +exscinding +exscinds +exsecant +exsecants +exsect +exsected +exsecting +exsects +exsert +exserted +exsertile +exserting +exsertion +exsertions +exserts +exsiccate +exsiccated +exsiccates +exsiccating +exsiccation +exsiccations +exsolution +exsolutions +extant +extemporal +extemporally +extemporaneities +extemporaneity +extemporaneous +extemporaneously +extemporaneousness +extemporaneousnesses +extemporarily +extemporary +extempore +extemporisation +extemporisations +extemporise +extemporised +extemporises +extemporising +extemporization +extemporizations +extemporize +extemporized +extemporizer +extemporizers +extemporizes +extemporizing +extend +extendabilities +extendability +extendable +extended +extendedly +extendedness +extendednesses +extender +extenders +extendible +extending +extends +extensibilities +extensibility +extensible +extensile +extension +extensional +extensionalities +extensionality +extensionally +extensions +extensities +extensity +extensive +extensively +extensiveness +extensivenesses +extensometer +extensometers +extensor +extensors +extent +extents +extenuate +extenuated +extenuates +extenuating +extenuation +extenuations +extenuator +extenuators +extenuatory +exterior +exteriorise +exteriorised +exteriorises +exteriorising +exteriorities +exteriority +exteriorization +exteriorizations +exteriorize +exteriorized +exteriorizes +exteriorizing +exteriorly +exteriors +exterminate +exterminated +exterminates +exterminating +extermination +exterminations +exterminator +exterminators +exterminatory +extermine +extermined +extermines +extermining +extern +external +externalisation +externalisations +externalise +externalised +externalises +externalising +externalism +externalisms +externalities +externality +externalization +externalizations +externalize +externalized +externalizes +externalizing +externally +externals +externe +externes +externs +externship +externships +exteroceptive +exteroceptor +exteroceptors +exterritorial +exterritorialities +exterritoriality +extinct +extincted +extincting +extinction +extinctions +extinctive +extincts +extinguish +extinguishable +extinguished +extinguisher +extinguishers +extinguishes +extinguishing +extinguishment +extinguishments +extirpate +extirpated +extirpates +extirpating +extirpation +extirpations +extirpator +extirpators +extol +extoll +extolled +extoller +extollers +extolling +extolls +extolment +extolments +extols +extort +extorted +extorter +extorters +extorting +extortion +extortionary +extortionate +extortionately +extortioner +extortioners +extortionist +extortionists +extortions +extortive +extorts +extra +extracellular +extracellularly +extrachromosomal +extracorporeal +extracorporeally +extracranial +extract +extractabilities +extractability +extractable +extracted +extracting +extraction +extractions +extractive +extractively +extractives +extractor +extractors +extracts +extracurricular +extracurriculars +extraditable +extradite +extradited +extradites +extraditing +extradition +extraditions +extrados +extradoses +extraembryonic +extragalactic +extrahepatic +extrajudicial +extrajudicially +extralegal +extralegally +extralimital +extralinguistic +extralinguistically +extraliterary +extralities +extrality +extralogical +extramarital +extramundane +extramural +extramurally +extramusical +extraneous +extraneously +extraneousness +extraneousnesses +extranuclear +extraordinaire +extraordinarily +extraordinariness +extraordinarinesses +extraordinary +extrapolate +extrapolated +extrapolates +extrapolating +extrapolation +extrapolations +extrapolative +extrapolator +extrapolators +extrapyramidal +extras +extrasensory +extrasystole +extrasystoles +extraterrestrial +extraterrestrials +extraterritorial +extraterritorialities +extraterritoriality +extratextual +extrauterine +extravagance +extravagances +extravagancies +extravagancy +extravagant +extravagantly +extravaganza +extravaganzas +extravagate +extravagated +extravagates +extravagating +extravasate +extravasated +extravasates +extravasating +extravasation +extravasations +extravascular +extravehicular +extraversion +extraversions +extravert +extraverted +extraverts +extrema +extreme +extremely +extremeness +extremenesses +extremer +extremes +extremest +extremism +extremisms +extremist +extremists +extremities +extremity +extremum +extricable +extricate +extricated +extricates +extricating +extrication +extrications +extrinsic +extrinsically +extrorse +extroversion +extroversions +extrovert +extroverted +extroverts +extrudabilities +extrudability +extrudable +extrude +extruded +extruder +extruders +extrudes +extruding +extrusion +extrusions +extrusive +extubate +extubated +extubates +extubating +exuberance +exuberances +exuberant +exuberantly +exuberate +exuberated +exuberates +exuberating +exudate +exudates +exudation +exudations +exudative +exude +exuded +exudes +exuding +exult +exultance +exultances +exultancies +exultancy +exultant +exultantly +exultation +exultations +exulted +exulting +exultingly +exults +exurb +exurban +exurbanite +exurbanites +exurbia +exurbias +exurbs +exuvia +exuviae +exuvial +exuviate +exuviated +exuviates +exuviating +exuviation +exuviations +exuvium +eyas +eyases +eye +eyeable +eyeball +eyeballed +eyeballing +eyeballs +eyebar +eyebars +eyebeam +eyebeams +eyebolt +eyebolts +eyebright +eyebrights +eyebrow +eyebrows +eyecup +eyecups +eyed +eyedness +eyednesses +eyedropper +eyedroppers +eyedrops +eyeful +eyefuls +eyeglass +eyeglasses +eyehole +eyeholes +eyehook +eyehooks +eyeing +eyelash +eyelashes +eyeless +eyelet +eyelets +eyeletted +eyeletting +eyelid +eyelids +eyelike +eyeliner +eyeliners +eyen +eyepiece +eyepieces +eyepoint +eyepoints +eyepopper +eyepoppers +eyer +eyers +eyes +eyeshade +eyeshades +eyeshot +eyeshots +eyesight +eyesights +eyesome +eyesore +eyesores +eyespot +eyespots +eyestalk +eyestalks +eyestone +eyestones +eyestrain +eyestrains +eyestrings +eyeteeth +eyetooth +eyewash +eyewashes +eyewater +eyewaters +eyewear +eyewink +eyewinks +eyewitness +eyewitnesses +eying +eyne +eyra +eyras +eyre +eyres +eyrie +eyries +eyrir +eyry +fa +fable +fabled +fabler +fablers +fables +fabliau +fabliaux +fabling +fabric +fabricant +fabricants +fabricate +fabricated +fabricates +fabricating +fabrication +fabrications +fabricator +fabricators +fabrics +fabular +fabulist +fabulistic +fabulists +fabulous +fabulously +fabulousness +fabulousnesses +facade +facades +face +faceable +facecloth +facecloths +faced +facedown +facedowns +faceless +facelessness +facelessnesses +faceplate +faceplates +facer +facers +faces +facet +facete +faceted +facetely +facetiae +faceting +facetious +facetiously +facetiousness +facetiousnesses +facets +facetted +facetting +faceup +facia +facial +facially +facials +facias +faciend +faciends +facies +facile +facilely +facileness +facilenesses +facilitate +facilitated +facilitates +facilitating +facilitation +facilitations +facilitative +facilitator +facilitators +facilitatory +facilities +facility +facing +facings +facsimile +facsimiles +fact +factful +facticities +facticity +faction +factional +factionalism +factionalisms +factionally +factions +factious +factiously +factiousness +factiousnesses +factitious +factitiously +factitiousness +factitiousnesses +factitive +factitively +factoid +factoids +factor +factorable +factorage +factorages +factored +factorial +factorials +factories +factoring +factorization +factorizations +factorize +factorized +factorizes +factorizing +factors +factorship +factorships +factory +factorylike +factotum +factotums +facts +factual +factualism +factualisms +factualist +factualists +factualities +factuality +factually +factualness +factualnesses +facture +factures +facula +faculae +facular +facultative +facultatively +faculties +faculty +fad +fadable +faddier +faddiest +faddish +faddishness +faddishnesses +faddism +faddisms +faddist +faddists +faddy +fade +fadeaway +fadeaways +faded +fadedly +fadeless +fader +faders +fades +fadge +fadged +fadges +fadging +fading +fadings +fado +fados +fads +faecal +faeces +faena +faenas +faerie +faeries +faery +fag +fagged +fagging +faggot +faggoted +faggoting +faggotings +faggotries +faggotry +faggots +faggoty +faggy +fagin +fagins +fagot +fagoted +fagoter +fagoters +fagoting +fagotings +fagots +fags +fahlband +fahlbands +faience +faiences +fail +failed +failing +failingly +failings +faille +failles +fails +failure +failures +fain +faineant +faineants +fainer +fainest +faint +fainted +fainter +fainters +faintest +fainthearted +faintheartedly +faintheartedness +faintheartednesses +fainting +faintish +faintishness +faintishnesses +faintly +faintness +faintnesses +faints +fair +faired +fairer +fairest +fairground +fairgrounds +fairies +fairing +fairings +fairish +fairishly +fairlead +fairleader +fairleaders +fairleads +fairly +fairness +fairnesses +fairs +fairway +fairways +fairy +fairyism +fairyisms +fairyland +fairylands +fairylike +faith +faithed +faithful +faithfully +faithfulness +faithfulnesses +faithfuls +faithing +faithless +faithlessly +faithlessness +faithlessnesses +faiths +faitour +faitours +fajita +fajitas +fake +faked +fakeer +fakeers +faker +fakeries +fakers +fakery +fakes +fakey +faking +fakir +fakirs +falafel +falbala +falbalas +falcate +falcated +falces +falchion +falchions +falciform +falcon +falconer +falconers +falconet +falconets +falconine +falconries +falconry +falcons +falderal +falderals +falderol +falderols +faldstool +faldstools +fall +fallacies +fallacious +fallaciously +fallaciousness +fallaciousnesses +fallacy +fallal +fallaleries +fallalery +fallals +fallaway +fallaways +fallback +fallbacks +fallen +faller +fallers +fallfish +fallfishes +fallibilities +fallibility +fallible +fallibly +falling +falloff +falloffs +fallout +fallouts +fallow +fallowed +fallowing +fallowness +fallownesses +fallows +falls +false +falsehood +falsehoods +falsely +falseness +falsenesses +falser +falsest +falsetto +falsettos +falsework +falseworks +falsie +falsies +falsifiabilities +falsifiability +falsifiable +falsification +falsifications +falsified +falsifier +falsifiers +falsifies +falsify +falsifying +falsities +falsity +faltboat +faltboats +falter +faltered +falterer +falterers +faltering +falteringly +falters +falx +fame +famed +fameless +fames +familial +familiar +familiarise +familiarised +familiarises +familiarising +familiarities +familiarity +familiarization +familiarizations +familiarize +familiarized +familiarizes +familiarizing +familiarly +familiarness +familiarnesses +familiars +families +familism +familisms +familistic +family +famine +famines +faming +famish +famished +famishes +famishing +famishment +famishments +famous +famously +famousness +famousnesses +famuli +famulus +fan +fanatic +fanatical +fanatically +fanaticalness +fanaticalnesses +fanaticism +fanaticisms +fanaticize +fanaticized +fanaticizes +fanaticizing +fanatics +fancied +fancier +fanciers +fancies +fanciest +fancified +fancifies +fanciful +fancifully +fancifulness +fancifulnesses +fancify +fancifying +fancily +fanciness +fancinesses +fancy +fancying +fancywork +fancyworks +fandango +fandangos +fandom +fandoms +fane +fanega +fanegada +fanegadas +fanegas +fanes +fanfare +fanfares +fanfaron +fanfaronade +fanfaronades +fanfarons +fanfold +fanfolded +fanfolding +fanfolds +fang +fanga +fangas +fanged +fangless +fanglike +fangs +fanion +fanions +fanjet +fanjets +fanlight +fanlights +fanlike +fanned +fanner +fanners +fannies +fanning +fanny +fano +fanon +fanons +fanos +fans +fantabulous +fantail +fantails +fantasia +fantasias +fantasie +fantasied +fantasies +fantasise +fantasised +fantasises +fantasising +fantasist +fantasists +fantasize +fantasized +fantasizer +fantasizers +fantasizes +fantasizing +fantasm +fantasms +fantast +fantastic +fantastical +fantasticalities +fantasticality +fantastically +fantasticalness +fantasticalnesses +fantasticate +fantasticated +fantasticates +fantasticating +fantastication +fantastications +fantastico +fantasticoes +fantastics +fantasts +fantasy +fantasying +fantasyland +fantasylands +fantoccini +fantod +fantods +fantom +fantoms +fanum +fanums +fanwise +fanwort +fanworts +fanzine +fanzines +faqir +faqirs +faquir +faquirs +far +farad +faradaic +faraday +faradays +faradic +faradise +faradised +faradises +faradising +faradism +faradisms +faradize +faradized +faradizes +faradizing +farads +farandole +farandoles +faraway +farce +farced +farcer +farcers +farces +farceur +farceurs +farci +farcical +farcicalities +farcicality +farcically +farcie +farcies +farcing +farcy +fard +farded +fardel +fardels +farding +fards +fare +fared +farer +farers +fares +farewell +farewelled +farewelling +farewells +farfal +farfals +farfel +farfels +farfetchedness +farfetchednesses +farina +farinaceous +farinas +faring +farinha +farinhas +farinose +farkleberries +farkleberry +farl +farle +farles +farls +farm +farmable +farmed +farmer +farmerette +farmerettes +farmers +farmhand +farmhands +farmhouse +farmhouses +farming +farmings +farmland +farmlands +farms +farmstead +farmsteads +farmwife +farmwives +farmwork +farmworker +farmworkers +farmworks +farmyard +farmyards +farnesol +farnesols +farness +farnesses +faro +faros +farouche +farraginous +farrago +farragoes +farrier +farrieries +farriers +farriery +farrow +farrowed +farrowing +farrows +farseeing +farside +farsides +farsighted +farsightedly +farsightedness +farsightednesses +fart +farted +farther +farthermost +farthest +farthing +farthingale +farthingales +farthings +farting +farts +fas +fasces +fascia +fasciae +fascial +fascias +fasciate +fasciated +fasciation +fasciations +fascicle +fascicled +fascicles +fascicular +fascicularly +fasciculate +fasciculated +fasciculation +fasciculations +fascicule +fascicules +fasciculi +fasciculus +fascinate +fascinated +fascinates +fascinating +fascinatingly +fascination +fascinations +fascinator +fascinators +fascine +fascines +fascioliases +fascioliasis +fascism +fascisms +fascist +fascistic +fascistically +fascists +fash +fashed +fashes +fashing +fashion +fashionabilities +fashionability +fashionable +fashionableness +fashionablenesses +fashionables +fashionably +fashioned +fashioner +fashioners +fashioning +fashionmonger +fashionmongers +fashions +fashious +fast +fastback +fastbacks +fastball +fastballer +fastballers +fastballs +fasted +fasten +fastened +fastener +fasteners +fastening +fastenings +fastens +faster +fastest +fastidious +fastidiously +fastidiousness +fastidiousnesses +fastigiate +fasting +fastings +fastness +fastnesses +fasts +fastuous +fat +fatal +fatalism +fatalisms +fatalist +fatalistic +fatalistically +fatalists +fatalities +fatality +fatally +fatback +fatbacks +fatbird +fatbirds +fate +fated +fateful +fatefully +fatefulness +fatefulnesses +fates +fathead +fatheaded +fatheadedly +fatheadedness +fatheadednesses +fatheads +father +fathered +fatherhood +fatherhoods +fathering +fatherland +fatherlands +fatherless +fatherlike +fatherliness +fatherlinesses +fatherly +fathers +fathom +fathomable +fathomed +fathoming +fathomless +fathomlessly +fathomlessness +fathomlessnesses +fathoms +fatidic +fatidical +fatigabilities +fatigability +fatigable +fatigue +fatigued +fatigues +fatiguing +fatiguingly +fating +fatless +fatlike +fatling +fatlings +fatly +fatness +fatnesses +fats +fatshedera +fatshederas +fatso +fatsoes +fatsos +fatstock +fatstocks +fatted +fatten +fattened +fattener +fatteners +fattening +fattens +fatter +fattest +fattier +fatties +fattiest +fattily +fattiness +fattinesses +fatting +fattish +fatty +fatuities +fatuity +fatuous +fatuously +fatuousness +fatuousnesses +fatwa +fatwas +fatwood +fatwoods +faubourg +faubourgs +faucal +faucals +fauces +faucet +faucets +faucial +faugh +fauld +faulds +fault +faulted +faultfinder +faultfinders +faultfinding +faultfindings +faultier +faultiest +faultily +faultiness +faultinesses +faulting +faultless +faultlessly +faultlessness +faultlessnesses +faults +faulty +faun +fauna +faunae +faunal +faunally +faunas +faunistic +faunistically +faunlike +fauns +fauteuil +fauteuils +fauve +fauves +fauvism +fauvisms +fauvist +fauvists +faux +fava +favas +fave +favela +favelas +favella +favellas +faves +favism +favisms +favonian +favor +favorable +favorableness +favorablenesses +favorably +favored +favorer +favorers +favoring +favorite +favorites +favoritism +favoritisms +favors +favour +favoured +favourer +favourers +favouring +favours +favus +favuses +fawn +fawned +fawner +fawners +fawnier +fawniest +fawning +fawningly +fawnlike +fawns +fawny +fax +faxed +faxes +faxing +fay +fayalite +fayalites +fayed +faying +fays +faze +fazed +fazenda +fazendas +fazes +fazing +feal +fealties +fealty +fear +feared +fearer +fearers +fearful +fearfuller +fearfullest +fearfully +fearfulness +fearfulnesses +fearing +fearless +fearlessly +fearlessness +fearlessnesses +fears +fearsome +fearsomely +fearsomeness +fearsomenesses +feasance +feasances +fease +feased +feases +feasibilities +feasibility +feasible +feasibly +feasing +feast +feasted +feaster +feasters +feastful +feasting +feasts +feat +feater +featest +feather +featherbed +featherbedded +featherbedding +featherbeddings +featherbeds +featherbrain +featherbrained +featherbrains +feathered +featheredge +featheredged +featheredges +featheredging +featherhead +featherheaded +featherheads +featherier +featheriest +feathering +featherings +featherless +featherlight +feathers +featherstitch +featherstitched +featherstitches +featherstitching +featherweight +featherweights +feathery +featlier +featliest +featly +feats +feature +featured +featureless +features +featurette +featurettes +featuring +feaze +feazed +feazes +feazing +febrific +febrifuge +febrifuges +febrile +fecal +feces +fecial +fecials +feck +feckless +fecklessly +fecklessness +fecklessnesses +feckly +fecks +fecula +feculae +feculence +feculences +feculent +fecund +fecundate +fecundated +fecundates +fecundating +fecundation +fecundations +fecundities +fecundity +fed +fedayee +fedayeen +federacies +federacy +federal +federalese +federaleses +federalism +federalisms +federalist +federalists +federalization +federalizations +federalize +federalized +federalizes +federalizing +federally +federals +federate +federated +federates +federating +federation +federations +federative +federatively +fedora +fedoras +feds +fee +feeble +feebleminded +feeblemindedly +feeblemindedness +feeblemindednesses +feebleness +feeblenesses +feebler +feeblest +feeblish +feebly +feed +feedable +feedback +feedbacks +feedbag +feedbags +feedbox +feedboxes +feeder +feeders +feedhole +feedholes +feeding +feedlot +feedlots +feeds +feedstock +feedstocks +feedstuff +feedstuffs +feeing +feel +feeler +feelers +feeless +feeling +feelingly +feelingness +feelingnesses +feelings +feels +fees +feet +feetfirst +feetless +feeze +feezed +feezes +feezing +feh +fehs +feign +feigned +feigner +feigners +feigning +feigns +feijoa +feijoas +feint +feinted +feinting +feints +feirie +feist +feistier +feistiest +feistiness +feistinesses +feists +feisty +felafel +feldsher +feldshers +feldspar +feldspars +feldspathic +felicific +felicitate +felicitated +felicitates +felicitating +felicitation +felicitations +felicitator +felicitators +felicities +felicitous +felicitously +felicitousness +felicitousnesses +felicity +felid +felids +feline +felinely +felines +felinities +felinity +fell +fella +fellable +fellah +fellaheen +fellahin +fellahs +fellas +fellate +fellated +fellates +fellating +fellatio +fellation +fellations +fellatios +fellator +fellators +felled +feller +fellers +fellest +fellies +felling +fellmonger +fellmongered +fellmongeries +fellmongering +fellmongerings +fellmongers +fellmongery +fellness +fellnesses +felloe +felloes +fellow +fellowed +fellowing +fellowly +fellowman +fellowmen +fellows +fellowship +fellowshiped +fellowshiping +fellowshipped +fellowshipping +fellowships +fells +felly +felon +felonies +felonious +feloniously +feloniousness +feloniousnesses +felonries +felonry +felons +felony +felsite +felsites +felsitic +felspar +felspars +felstone +felstones +felt +felted +felting +feltings +feltlike +felts +felucca +feluccas +felwort +felworts +fem +female +femaleness +femalenesses +females +feme +femes +feminacies +feminacy +feminie +feminine +femininely +feminineness +femininenesses +feminines +femininities +femininity +feminise +feminised +feminises +feminising +feminism +feminisms +feminist +feministic +feminists +feminities +feminity +feminization +feminizations +feminize +feminized +feminizes +feminizing +femme +femmes +femora +femoral +fems +femtosecond +femtoseconds +femur +femurs +fen +fenagle +fenagled +fenagles +fenagling +fence +fenced +fenceless +fencelessness +fencelessnesses +fencer +fencerow +fencerows +fencers +fences +fencible +fencibles +fencing +fencings +fend +fended +fender +fendered +fenderless +fenders +fending +fends +fenestra +fenestrae +fenestral +fenestrate +fenestrated +fenestration +fenestrations +fenland +fenlands +fennec +fennecs +fennel +fennels +fenny +fens +fenthion +fenthions +fenugreek +fenugreeks +fenuron +fenurons +feod +feodaries +feodary +feods +feoff +feoffed +feoffee +feoffees +feoffer +feoffers +feoffing +feoffment +feoffments +feoffor +feoffors +feoffs +fer +feracities +feracity +feral +ferbam +ferbams +fere +feres +feretories +feretory +feria +feriae +ferial +ferias +ferine +ferities +ferity +ferlie +ferlies +ferly +fermata +fermatas +fermate +ferment +fermentable +fermentation +fermentations +fermentative +fermented +fermenter +fermenters +fermenting +fermentor +fermentors +ferments +fermi +fermion +fermions +fermis +fermium +fermiums +fern +ferneries +fernery +fernier +ferniest +fernless +fernlike +ferns +ferny +ferocious +ferociously +ferociousness +ferociousnesses +ferocities +ferocity +ferrate +ferrates +ferredoxin +ferredoxins +ferrel +ferreled +ferreling +ferrelled +ferrelling +ferrels +ferreous +ferret +ferreted +ferreter +ferreters +ferreting +ferretings +ferrets +ferrety +ferriage +ferriages +ferric +ferricyanide +ferricyanides +ferried +ferries +ferriferous +ferrimagnet +ferrimagnetic +ferrimagnetically +ferrimagnetism +ferrimagnetisms +ferrimagnets +ferrite +ferrites +ferritic +ferritin +ferritins +ferrocene +ferrocenes +ferroconcrete +ferroconcretes +ferrocyanide +ferrocyanides +ferroelectric +ferroelectricities +ferroelectricity +ferroelectrics +ferromagnesian +ferromagnet +ferromagnetic +ferromagnetism +ferromagnetisms +ferromagnets +ferromanganese +ferromanganeses +ferrosilicon +ferrosilicons +ferrotype +ferrotypes +ferrous +ferruginous +ferrule +ferruled +ferrules +ferruling +ferrum +ferrums +ferry +ferryboat +ferryboats +ferrying +ferryman +ferrymen +fertile +fertilely +fertileness +fertilenesses +fertilities +fertility +fertilizable +fertilization +fertilizations +fertilize +fertilized +fertilizer +fertilizers +fertilizes +fertilizing +ferula +ferulae +ferulas +ferule +feruled +ferules +feruling +fervencies +fervency +fervent +fervently +fervid +fervidly +fervidness +fervidnesses +fervor +fervors +fervour +fervours +fescennine +fescue +fescues +fess +fesse +fessed +fesses +fessing +fesswise +festal +festally +fester +festered +festering +festers +festinate +festinated +festinately +festinates +festinating +festival +festivalgoer +festivalgoers +festivals +festive +festively +festiveness +festivenesses +festivities +festivity +festoon +festooned +festooneries +festoonery +festooning +festoons +fet +feta +fetal +fetas +fetation +fetations +fetch +fetched +fetcher +fetchers +fetches +fetching +fetchingly +fete +feted +feterita +feteritas +fetes +fetial +fetiales +fetialis +fetials +fetich +fetiches +fetichism +fetichisms +feticide +feticides +fetid +fetidly +fetidness +fetidnesses +feting +fetish +fetishes +fetishism +fetishisms +fetishist +fetishistic +fetishistically +fetishists +fetlock +fetlocks +fetologies +fetologist +fetologists +fetology +fetoprotein +fetoproteins +fetor +fetors +fetoscope +fetoscopes +fetoscopies +fetoscopy +fets +fetted +fetter +fettered +fetterer +fetterers +fettering +fetters +fetting +fettle +fettled +fettles +fettling +fettlings +fettuccine +fettuccini +fettucine +fettucini +fetus +fetuses +feu +feuar +feuars +feud +feudal +feudalism +feudalisms +feudalist +feudalistic +feudalists +feudalities +feudality +feudalization +feudalizations +feudalize +feudalized +feudalizes +feudalizing +feudally +feudaries +feudary +feudatories +feudatory +feuded +feuding +feudist +feudists +feuds +feued +feuilleton +feuilletonism +feuilletonisms +feuilletonist +feuilletonists +feuilletons +feuing +feus +fever +fevered +feverfew +feverfews +fevering +feverish +feverishly +feverishness +feverishnesses +feverous +fevers +feverwort +feverworts +few +fewer +fewest +fewness +fewnesses +fewtrils +fey +feyer +feyest +feyly +feyness +feynesses +fez +fezes +fezzed +fezzes +fiacre +fiacres +fiance +fiancee +fiancees +fiances +fianchetti +fianchetto +fianchettoed +fianchettoing +fianchettos +fiar +fiars +fiaschi +fiasco +fiascoes +fiascos +fiat +fiats +fib +fibbed +fibber +fibbers +fibbing +fiber +fiberboard +fiberboards +fibered +fiberfill +fiberfills +fiberglass +fiberglassed +fiberglasses +fiberglassing +fiberization +fiberizations +fiberize +fiberized +fiberizes +fiberizing +fibers +fiberscope +fiberscopes +fibranne +fibrannes +fibre +fibreboard +fibreboards +fibrefill +fibrefills +fibreglass +fibreglasses +fibres +fibril +fibrilla +fibrillae +fibrillar +fibrillate +fibrillated +fibrillates +fibrillating +fibrillation +fibrillations +fibrils +fibrin +fibrinogen +fibrinogens +fibrinoid +fibrinoids +fibrinolyses +fibrinolysin +fibrinolysins +fibrinolysis +fibrinolytic +fibrinopeptide +fibrinopeptides +fibrins +fibroblast +fibroblastic +fibroblasts +fibrocystic +fibroid +fibroids +fibroin +fibroins +fibroma +fibromas +fibromata +fibromatous +fibronectin +fibronectins +fibrosarcoma +fibrosarcomas +fibrosarcomata +fibroses +fibrosis +fibrosites +fibrositides +fibrositis +fibrositises +fibrotic +fibrous +fibrovascular +fibs +fibula +fibulae +fibular +fibulas +fice +fices +fiche +fiches +fichu +fichus +ficin +ficins +fickle +fickleness +ficklenesses +fickler +ficklest +fickly +fico +ficoes +fictile +fiction +fictional +fictionalise +fictionalised +fictionalises +fictionalising +fictionalities +fictionality +fictionalization +fictionalizations +fictionalize +fictionalized +fictionalizes +fictionalizing +fictionally +fictioneer +fictioneering +fictioneerings +fictioneers +fictionist +fictionists +fictionization +fictionizations +fictionize +fictionized +fictionizes +fictionizing +fictions +fictitious +fictitiously +fictitiousness +fictitiousnesses +fictive +fictively +fictiveness +fictivenesses +ficus +ficuses +fid +fiddle +fiddleback +fiddlebacks +fiddled +fiddlehead +fiddleheads +fiddler +fiddlers +fiddles +fiddlestick +fiddlesticks +fiddling +fiddly +fideism +fideisms +fideist +fideistic +fideists +fidelities +fidelity +fidge +fidged +fidges +fidget +fidgeted +fidgeter +fidgeters +fidgetiness +fidgetinesses +fidgeting +fidgets +fidgety +fidging +fido +fidos +fids +fiducial +fiducially +fiduciaries +fiduciary +fie +fief +fiefdom +fiefdoms +fiefs +field +fielded +fielder +fielders +fieldfare +fieldfares +fielding +fieldpiece +fieldpieces +fields +fieldstone +fieldstones +fieldstrip +fieldstripped +fieldstripping +fieldstrips +fieldstript +fieldwork +fieldworks +fiend +fiendish +fiendishly +fiendishness +fiendishnesses +fiends +fierce +fiercely +fierceness +fiercenesses +fiercer +fiercest +fierier +fieriest +fierily +fieriness +fierinesses +fiery +fiesta +fiestas +fife +fifed +fifer +fifers +fifes +fifing +fifteen +fifteens +fifteenth +fifteenths +fifth +fifthly +fifths +fifties +fiftieth +fiftieths +fifty +fiftyish +fig +figeater +figeaters +figged +figging +fight +fighter +fighters +fighting +fightings +fights +figment +figments +figs +figuline +figulines +figural +figurant +figurants +figurate +figuration +figurations +figurative +figuratively +figurativeness +figurativenesses +figure +figured +figurehead +figureheads +figurer +figurers +figures +figurine +figurines +figuring +figwort +figworts +fil +fila +filagree +filagreed +filagreeing +filagrees +filament +filamentary +filamentous +filaments +filar +filaree +filarees +filaria +filariae +filarial +filarian +filariases +filariasis +filariid +filariids +filature +filatures +filbert +filberts +filch +filched +filcher +filchers +filches +filching +file +fileable +filed +filefish +filefishes +filemot +filer +filers +files +filet +fileted +fileting +filets +filial +filially +filiate +filiated +filiates +filiating +filiation +filiations +filibeg +filibegs +filibuster +filibustered +filibusterer +filibusterers +filibustering +filibusters +filicide +filicides +filiform +filigree +filigreed +filigreeing +filigrees +filing +filings +filiopietistic +filister +filisters +fill +fille +filled +filler +fillers +filles +fillet +filleted +filleting +fillets +fillies +filling +fillings +fillip +filliped +filliping +fillips +fillo +fillos +fills +filly +film +filmable +filmcard +filmcards +filmdom +filmdoms +filmed +filmer +filmers +filmgoer +filmgoers +filmic +filmically +filmier +filmiest +filmily +filminess +filminesses +filming +filmland +filmlands +filmmaker +filmmakers +filmmaking +filmmakings +filmographies +filmography +films +filmset +filmsets +filmsetter +filmsetters +filmsetting +filmsettings +filmstrip +filmstrips +filmy +filo +filos +filose +fils +filter +filterabilities +filterability +filterable +filtered +filterer +filterers +filtering +filters +filth +filthier +filthiest +filthily +filthiness +filthinesses +filths +filthy +filtrable +filtrate +filtrated +filtrates +filtrating +filtration +filtrations +filum +fimble +fimbles +fimbria +fimbriae +fimbrial +fimbriate +fimbriated +fimbriation +fimbriations +fin +finable +finagle +finagled +finagler +finaglers +finagles +finagling +final +finale +finales +finalis +finalise +finalised +finalises +finalising +finalism +finalisms +finalist +finalists +finalities +finality +finalization +finalizations +finalize +finalized +finalizes +finalizing +finally +finals +finance +financed +finances +financial +financially +financier +financiers +financing +financings +finback +finbacks +finch +finches +find +findable +finder +finders +finding +findings +finds +fine +fineable +fined +finely +fineness +finenesses +finer +fineries +finery +fines +finespun +finesse +finessed +finesses +finessing +finest +finfish +finfishes +finfoot +finfoots +finger +fingerboard +fingerboards +fingered +fingerer +fingerers +fingerhold +fingerholds +fingering +fingerings +fingerlike +fingerling +fingerlings +fingernail +fingernails +fingerpick +fingerpicked +fingerpicking +fingerpickings +fingerpicks +fingerpost +fingerposts +fingerprint +fingerprinted +fingerprinting +fingerprintings +fingerprints +fingers +fingertip +fingertips +finial +finialed +finials +finical +finically +finicalness +finicalnesses +finickier +finickiest +finickin +finickiness +finickinesses +finicking +finicky +finikin +finiking +fining +finings +finis +finises +finish +finished +finisher +finishers +finishes +finishing +finite +finitely +finiteness +finitenesses +finites +finitude +finitudes +fink +finked +finking +finks +finless +finlike +finmark +finmarks +finned +finnickier +finnickiest +finnicky +finnier +finniest +finning +finnmark +finnmarks +finny +fino +finochio +finochios +finos +fins +fiord +fiords +fioritura +fioriture +fipple +fipples +fique +fiques +fir +fire +fireable +firearm +firearms +fireback +firebacks +fireball +fireballer +fireballers +fireballing +fireballs +firebase +firebases +firebird +firebirds +fireboat +fireboats +firebomb +firebombed +firebombing +firebombs +firebox +fireboxes +firebrand +firebrands +firebrat +firebrats +firebreak +firebreaks +firebrick +firebricks +firebug +firebugs +fireclay +fireclays +firecracker +firecrackers +fired +firedamp +firedamps +firedog +firedogs +firedrake +firedrakes +firefang +firefanged +firefanging +firefangs +firefight +firefighter +firefighters +firefights +fireflies +firefly +fireguard +fireguards +firehall +firehalls +firehouse +firehouses +fireless +firelight +firelights +firelit +firelock +firelocks +fireman +firemanic +firemen +firepan +firepans +firepink +firepinks +fireplace +fireplaced +fireplaces +fireplug +fireplugs +firepot +firepots +firepower +firepowers +fireproof +fireproofed +fireproofing +fireproofs +firer +fireroom +firerooms +firers +fires +fireside +firesides +firestone +firestones +firestorm +firestorms +firethorn +firethorns +firetrap +firetraps +firewater +firewaters +fireweed +fireweeds +firewood +firewoods +firework +fireworks +fireworm +fireworms +firing +firings +firkin +firkins +firm +firmament +firmamental +firmaments +firman +firmans +firmed +firmer +firmers +firmest +firming +firmly +firmness +firmnesses +firms +firmware +firmwares +firn +firns +firry +firs +first +firstborn +firstborns +firstfruits +firsthand +firstling +firstlings +firstly +firsts +firth +firths +fisc +fiscal +fiscally +fiscals +fiscs +fish +fishabilities +fishability +fishable +fishbolt +fishbolts +fishbone +fishbones +fishbowl +fishbowls +fished +fisher +fisherfolk +fisheries +fisherman +fishermen +fishers +fisherwoman +fisherwomen +fishery +fishes +fisheye +fisheyes +fishgig +fishgigs +fishhook +fishhooks +fishier +fishiest +fishily +fishing +fishings +fishless +fishlike +fishline +fishlines +fishmeal +fishmeals +fishmonger +fishmongers +fishnet +fishnets +fishplate +fishplates +fishpole +fishpoles +fishpond +fishponds +fishtail +fishtailed +fishtailing +fishtails +fishway +fishways +fishwife +fishwives +fishworm +fishworms +fishy +fissate +fissile +fissilities +fissility +fission +fissionabilities +fissionability +fissionable +fissionables +fissional +fissioned +fissioning +fissions +fissiparous +fissiparousness +fissiparousnesses +fissiped +fissipeds +fissure +fissured +fissures +fissuring +fist +fisted +fistfight +fistfights +fistful +fistfuls +fistic +fisticuffs +fisting +fistnote +fistnotes +fists +fistula +fistulae +fistular +fistulas +fistulous +fit +fitch +fitchee +fitches +fitchet +fitchets +fitchew +fitchews +fitchy +fitful +fitfully +fitfulness +fitfulnesses +fitly +fitment +fitments +fitness +fitnesses +fits +fittable +fitted +fitter +fitters +fittest +fitting +fittingly +fittingness +fittingnesses +fittings +five +fivefold +fivepins +fiver +fivers +fives +fix +fixable +fixate +fixated +fixates +fixatif +fixatifs +fixating +fixation +fixations +fixative +fixatives +fixed +fixedly +fixedness +fixednesses +fixer +fixers +fixes +fixing +fixings +fixit +fixities +fixity +fixt +fixture +fixtures +fixure +fixures +fiz +fizgig +fizgigs +fizz +fizzed +fizzer +fizzers +fizzes +fizzier +fizziest +fizzing +fizzle +fizzled +fizzles +fizzling +fizzy +fjeld +fjelds +fjord +fjords +flab +flabbergast +flabbergasted +flabbergasting +flabbergastingly +flabbergasts +flabbier +flabbiest +flabbily +flabbiness +flabbinesses +flabby +flabella +flabellate +flabelliform +flabellum +flabs +flaccid +flaccidities +flaccidity +flaccidly +flack +flacked +flackeries +flackery +flacking +flacks +flacon +flacons +flag +flagella +flagellant +flagellantism +flagellantisms +flagellants +flagellar +flagellate +flagellated +flagellates +flagellating +flagellation +flagellations +flagellin +flagellins +flagellum +flagellums +flageolet +flageolets +flagged +flagger +flaggers +flaggier +flaggiest +flagging +flaggingly +flaggings +flaggy +flagitious +flagitiously +flagitiousness +flagitiousnesses +flagless +flagman +flagmen +flagon +flagons +flagpole +flagpoles +flagrance +flagrances +flagrancies +flagrancy +flagrant +flagrantly +flags +flagship +flagships +flagstaff +flagstaffs +flagstaves +flagstick +flagsticks +flagstone +flagstones +flail +flailed +flailing +flails +flair +flairs +flak +flake +flaked +flaker +flakers +flakes +flakey +flakier +flakiest +flakily +flakiness +flakinesses +flaking +flaky +flam +flambe +flambeau +flambeaus +flambeaux +flambee +flambeed +flambeing +flambes +flamboyance +flamboyances +flamboyancies +flamboyancy +flamboyant +flamboyantly +flamboyants +flame +flamed +flamen +flamenco +flamencos +flamens +flameout +flameouts +flameproof +flameproofed +flameproofer +flameproofers +flameproofing +flameproofs +flamer +flamers +flames +flamethrower +flamethrowers +flamier +flamiest +flamines +flaming +flamingly +flamingo +flamingoes +flamingos +flammabilities +flammability +flammable +flammables +flammed +flamming +flams +flamy +flan +flancard +flancards +flanerie +flaneries +flanes +flaneur +flaneurs +flange +flanged +flanger +flangers +flanges +flanging +flank +flanked +flanken +flanker +flankers +flanking +flanks +flannel +flanneled +flannelette +flannelettes +flanneling +flannelled +flannelling +flannelly +flannelmouthed +flannels +flans +flap +flapdoodle +flapdoodles +flapjack +flapjacks +flapless +flappable +flapped +flapper +flappers +flappier +flappiest +flapping +flappy +flaps +flare +flared +flares +flaring +flaringly +flash +flashback +flashbacks +flashboard +flashboards +flashbulb +flashbulbs +flashcard +flashcards +flashcube +flashcubes +flashed +flasher +flashers +flashes +flashgun +flashguns +flashier +flashiest +flashily +flashiness +flashinesses +flashing +flashings +flashlamp +flashlamps +flashlight +flashlights +flashover +flashovers +flashtube +flashtubes +flashy +flask +flasket +flaskets +flasks +flat +flatbed +flatbeds +flatboat +flatboats +flatcap +flatcaps +flatcar +flatcars +flatfeet +flatfish +flatfishes +flatfoot +flatfooted +flatfooting +flatfoots +flathead +flatheads +flatiron +flatirons +flatland +flatlander +flatlanders +flatlands +flatlet +flatlets +flatling +flatlings +flatlong +flatly +flatmate +flatmates +flatness +flatnesses +flats +flatted +flatten +flattened +flattener +flatteners +flattening +flattens +flatter +flattered +flatterer +flatterers +flatteries +flattering +flatteringly +flatters +flattery +flattest +flatting +flattish +flattop +flattops +flatulence +flatulences +flatulencies +flatulency +flatulent +flatulently +flatus +flatuses +flatware +flatwares +flatwash +flatwashes +flatways +flatwise +flatwork +flatworks +flatworm +flatworms +flaunt +flaunted +flaunter +flaunters +flauntier +flauntiest +flaunting +flauntingly +flaunts +flaunty +flautist +flautists +flavanol +flavanols +flavanone +flavanones +flavin +flavine +flavines +flavins +flavone +flavones +flavonoid +flavonoids +flavonol +flavonols +flavoprotein +flavoproteins +flavor +flavored +flavorer +flavorers +flavorful +flavorfully +flavoring +flavorings +flavorist +flavorists +flavorless +flavors +flavorsome +flavory +flavour +flavoured +flavouring +flavours +flavoury +flaw +flawed +flawier +flawiest +flawing +flawless +flawlessly +flawlessness +flawlessnesses +flaws +flawy +flax +flaxen +flaxes +flaxier +flaxiest +flaxseed +flaxseeds +flaxy +flay +flayed +flayer +flayers +flaying +flays +flea +fleabag +fleabags +fleabane +fleabanes +fleabite +fleabites +fleahopper +fleahoppers +fleam +fleams +fleapit +fleapits +fleas +fleawort +fleaworts +fleche +fleches +flechette +flechettes +fleck +flecked +flecking +flecks +flecky +flection +flections +fled +fledge +fledged +fledges +fledgier +fledgiest +fledging +fledgling +fledglings +fledgy +flee +fleece +fleeced +fleecer +fleecers +fleeces +fleech +fleeched +fleeches +fleeching +fleecier +fleeciest +fleecily +fleecing +fleecy +fleeing +fleer +fleered +fleering +fleeringly +fleers +flees +fleet +fleeted +fleeter +fleetest +fleeting +fleetingly +fleetingness +fleetingnesses +fleetly +fleetness +fleetnesses +fleets +fleishig +flemish +flemished +flemishes +flemishing +flench +flenched +flenches +flenching +flense +flensed +flenser +flensers +flenses +flensing +flesh +fleshed +flesher +fleshers +fleshes +fleshier +fleshiest +fleshiness +fleshinesses +fleshing +fleshings +fleshlier +fleshliest +fleshly +fleshment +fleshments +fleshpot +fleshpots +fleshy +fletch +fletched +fletcher +fletchers +fletches +fletching +fletchings +fleury +flew +flews +flex +flexagon +flexagons +flexed +flexes +flexibilities +flexibility +flexible +flexibly +flexile +flexing +flexion +flexions +flexitime +flexitimes +flexographic +flexographically +flexographies +flexography +flexor +flexors +flextime +flextimes +flexuose +flexuous +flexural +flexure +flexures +fley +fleyed +fleying +fleys +flibbertigibbet +flibbertigibbets +flibbertigibbety +flic +flichter +flichtered +flichtering +flichters +flick +flicked +flicker +flickered +flickering +flickeringly +flickers +flickery +flicking +flicks +flics +flied +flier +fliers +flies +fliest +flight +flighted +flightier +flightiest +flightily +flightiness +flightinesses +flighting +flightless +flights +flighty +flimflam +flimflammed +flimflammer +flimflammeries +flimflammers +flimflammery +flimflamming +flimflams +flimsier +flimsies +flimsiest +flimsily +flimsiness +flimsinesses +flimsy +flinch +flinched +flincher +flinchers +flinches +flinching +flinder +flinders +fling +flinger +flingers +flinging +flings +flinkite +flinkites +flint +flinted +flintier +flintiest +flintily +flintiness +flintinesses +flinting +flintlike +flintlock +flintlocks +flints +flinty +flip +flippancies +flippancy +flippant +flippantly +flipped +flipper +flippers +flippest +flipping +flippy +flips +flirt +flirtation +flirtations +flirtatious +flirtatiously +flirtatiousness +flirtatiousnesses +flirted +flirter +flirters +flirtier +flirtiest +flirting +flirts +flirty +flit +flitch +flitched +flitches +flitching +flite +flited +flites +fliting +flits +flitted +flitter +flittered +flittering +flitters +flitting +flivver +flivvers +float +floatage +floatages +floatation +floatations +floated +floatel +floatels +floater +floaters +floatier +floatiest +floating +floatplane +floatplanes +floats +floaty +floc +flocced +flocci +floccing +floccose +flocculant +flocculants +flocculate +flocculated +flocculates +flocculating +flocculation +flocculations +flocculator +flocculators +floccule +flocculent +floccules +flocculi +flocculus +floccus +flock +flocked +flockier +flockiest +flocking +flockings +flocks +flocky +flocs +floe +floes +flog +flogged +flogger +floggers +flogging +floggings +flogs +flokati +flokatis +flong +flongs +flood +flooded +flooder +flooders +floodgate +floodgates +flooding +floodlight +floodlighted +floodlighting +floodlights +floodlit +floodplain +floodplains +floods +floodwater +floodwaters +floodway +floodways +flooey +flooie +floor +floorage +floorages +floorboard +floorboards +floorcloth +floorcloths +floored +floorer +floorers +flooring +floorings +floors +floorwalker +floorwalkers +floosie +floosies +floosy +floozie +floozies +floozy +flop +flophouse +flophouses +flopover +flopovers +flopped +flopper +floppers +floppier +floppies +floppiest +floppily +floppiness +floppinesses +flopping +floppy +flops +flora +florae +floral +florally +florals +floras +florence +florences +florescence +florescences +florescent +floret +florets +floriated +floriation +floriations +floribunda +floribundas +floricultural +floriculture +floricultures +floriculturist +floriculturists +florid +floridities +floridity +floridly +floridness +floridnesses +floriferous +floriferousness +floriferousnesses +florigen +florigenic +florigens +florilegia +florilegium +florin +florins +florist +floristic +floristically +floristries +floristry +florists +floruit +floruits +floss +flossed +flosses +flossie +flossier +flossies +flossiest +flossily +flossing +flossy +flota +flotage +flotages +flotas +flotation +flotations +flotilla +flotillas +flotsam +flotsams +flounce +flounced +flounces +flouncier +flounciest +flouncing +flouncings +flouncy +flounder +floundered +floundering +flounders +flour +floured +flouring +flourish +flourished +flourisher +flourishers +flourishes +flourishing +flourishingly +flourless +flours +floury +flout +flouted +flouter +flouters +flouting +flouts +flow +flowage +flowages +flowchart +flowcharting +flowchartings +flowcharts +flowed +flower +flowerage +flowerages +flowered +flowerer +flowerers +floweret +flowerets +flowerette +flowerettes +flowerful +flowerier +floweriest +flowerily +floweriness +flowerinesses +flowering +flowerless +flowerlike +flowerpot +flowerpots +flowers +flowery +flowing +flowingly +flowmeter +flowmeters +flown +flows +flowstone +flowstones +flu +flub +flubbed +flubber +flubbers +flubbing +flubdub +flubdubs +flubs +fluctuant +fluctuate +fluctuated +fluctuates +fluctuating +fluctuation +fluctuational +fluctuations +flue +flued +fluegelhorn +fluegelhorns +fluencies +fluency +fluent +fluently +flueric +fluerics +flues +fluff +fluffed +fluffier +fluffiest +fluffily +fluffiness +fluffinesses +fluffing +fluffs +fluffy +flugelhorn +flugelhornist +flugelhornists +flugelhorns +fluid +fluidal +fluidally +fluidextract +fluidextracts +fluidic +fluidics +fluidise +fluidised +fluidises +fluidising +fluidities +fluidity +fluidization +fluidizations +fluidize +fluidized +fluidizer +fluidizers +fluidizes +fluidizing +fluidly +fluidness +fluidnesses +fluidram +fluidrams +fluids +fluke +fluked +flukes +flukey +flukier +flukiest +fluking +fluky +flume +flumed +flumes +fluming +flummeries +flummery +flummox +flummoxed +flummoxes +flummoxing +flump +flumped +flumping +flumps +flung +flunk +flunked +flunker +flunkers +flunkey +flunkeys +flunkies +flunking +flunks +flunky +fluor +fluorene +fluorenes +fluoresce +fluoresced +fluorescein +fluoresceins +fluorescence +fluorescences +fluorescent +fluorescents +fluorescer +fluorescers +fluoresces +fluorescing +fluoric +fluorid +fluoridate +fluoridated +fluoridates +fluoridating +fluoridation +fluoridations +fluoride +fluorides +fluorids +fluorimeter +fluorimeters +fluorimetric +fluorimetries +fluorimetry +fluorin +fluorinate +fluorinated +fluorinates +fluorinating +fluorination +fluorinations +fluorine +fluorines +fluorins +fluorite +fluorites +fluorocarbon +fluorocarbons +fluorochrome +fluorochromes +fluorographic +fluorographies +fluorography +fluorometer +fluorometers +fluorometric +fluorometries +fluorometry +fluoroscope +fluoroscoped +fluoroscopes +fluoroscopic +fluoroscopically +fluoroscopies +fluoroscoping +fluoroscopist +fluoroscopists +fluoroscopy +fluoroses +fluorosis +fluorotic +fluorouracil +fluorouracils +fluors +fluorspar +fluorspars +fluphenazine +fluphenazines +flurried +flurries +flurry +flurrying +flus +flush +flushable +flushed +flusher +flushers +flushes +flushest +flushing +flushness +flushnesses +fluster +flustered +flusteredly +flustering +flusters +flute +fluted +flutelike +fluter +fluters +flutes +flutey +flutier +flutiest +fluting +flutings +flutist +flutists +flutter +flutterboard +flutterboards +fluttered +flutterer +flutterers +fluttering +flutters +fluttery +fluty +fluvial +fluviatile +flux +fluxed +fluxes +fluxgate +fluxgates +fluxing +fluxion +fluxional +fluxions +fluyt +fluyts +fly +flyable +flyaway +flyaways +flybelt +flybelts +flyblew +flyblow +flyblowing +flyblown +flyblows +flyboat +flyboats +flyboy +flyboys +flybridge +flybridges +flyby +flybys +flycatcher +flycatchers +flyer +flyers +flying +flyings +flyleaf +flyleaves +flyless +flyman +flymen +flyoff +flyoffs +flyover +flyovers +flypaper +flypapers +flypast +flypasts +flysch +flysches +flyspeck +flyspecked +flyspecking +flyspecks +flyswatter +flyswatters +flyte +flyted +flytes +flytier +flytiers +flyting +flytings +flytrap +flytraps +flyway +flyways +flyweight +flyweights +flywheel +flywheels +foal +foaled +foaling +foals +foam +foamable +foamed +foamer +foamers +foamflower +foamflowers +foamier +foamiest +foamily +foaminess +foaminesses +foaming +foamless +foamlike +foams +foamy +fob +fobbed +fobbing +fobs +focaccia +focaccias +focal +focalise +focalised +focalises +focalising +focalization +focalizations +focalize +focalized +focalizes +focalizing +focally +foci +focus +focusable +focused +focuser +focusers +focuses +focusing +focusless +focussed +focusses +focussing +fodder +foddered +foddering +fodders +fodgel +foe +foehn +foehns +foeman +foemen +foes +foetal +foetid +foetor +foetors +foetus +foetuses +fog +fogbound +fogbow +fogbows +fogdog +fogdogs +fogey +fogeys +fogfruit +fogfruits +foggage +foggages +fogged +fogger +foggers +foggier +foggiest +foggily +fogginess +fogginesses +fogging +foggy +foghorn +foghorns +fogie +fogies +fogless +fogs +fogy +fogyish +fogyism +fogyisms +foh +fohn +fohns +foible +foibles +foil +foilable +foiled +foiling +foils +foilsman +foilsmen +foin +foined +foining +foins +foison +foisons +foist +foisted +foisting +foists +folacin +folacins +folate +folates +fold +foldable +foldaway +foldboat +foldboats +folded +folder +folderol +folderols +folders +folding +foldout +foldouts +folds +folia +foliaceous +foliage +foliaged +foliages +foliar +foliate +foliated +foliates +foliating +foliation +foliations +folio +folioed +folioing +folios +foliose +folious +folium +foliums +folk +folkie +folkies +folkish +folkishness +folkishnesses +folklife +folklike +folklives +folklore +folklores +folkloric +folklorish +folklorist +folkloristic +folklorists +folkmoot +folkmoots +folkmot +folkmote +folkmotes +folkmots +folks +folksier +folksiest +folksily +folksiness +folksinesses +folksinger +folksingers +folksinging +folksingings +folksy +folktale +folktales +folkway +folkways +folky +folles +follicle +follicles +follicular +folliculites +folliculitides +folliculitis +folliculitises +follies +follis +follow +followed +follower +followers +followership +followerships +following +followings +follows +folly +foment +fomentation +fomentations +fomented +fomenter +fomenters +fomenting +foments +fomite +fomites +fon +fond +fondant +fondants +fonded +fonder +fondest +fonding +fondle +fondled +fondler +fondlers +fondles +fondling +fondlings +fondly +fondness +fondnesses +fonds +fondu +fondue +fondues +fondus +fons +font +fontal +fontanel +fontanelle +fontanelles +fontanels +fontina +fontinas +fonts +food +foodie +foodies +foodless +foodlessness +foodlessnesses +foods +foodstuff +foodstuffs +foodways +foofaraw +foofaraws +fool +fooled +fooleries +foolery +foolfish +foolfishes +foolhardier +foolhardiest +foolhardily +foolhardiness +foolhardinesses +foolhardy +fooling +foolish +foolisher +foolishest +foolishly +foolishness +foolishnesses +foolproof +fools +foolscap +foolscaps +foot +footage +footages +football +footballer +footballers +footballs +footbath +footbaths +footboard +footboards +footboy +footboys +footbridge +footbridges +footcloth +footcloths +footdragger +footdraggers +footed +footer +footers +footfall +footfalls +footfault +footfaulted +footfaulting +footfaults +footgear +footgears +foothill +foothills +foothold +footholds +footie +footier +footies +footiest +footing +footings +footlambert +footlamberts +footle +footled +footler +footlers +footles +footless +footlessly +footlessness +footlessnesses +footlights +footlike +footling +footlocker +footlockers +footloose +footman +footmark +footmarks +footmen +footnote +footnoted +footnotes +footnoting +footpace +footpaces +footpad +footpads +footpath +footpaths +footprint +footprints +footrace +footraces +footrest +footrests +footrope +footropes +foots +footsie +footsies +footslog +footslogged +footslogger +footsloggers +footslogging +footslogs +footsore +footsoreness +footsorenesses +footstep +footsteps +footstone +footstones +footstool +footstools +footsy +footwall +footwalls +footway +footways +footwear +footwork +footworks +footworn +footy +foozle +foozled +foozler +foozlers +foozles +foozling +fop +fopped +fopperies +foppery +fopping +foppish +foppishly +foppishness +foppishnesses +fops +for +fora +forage +foraged +forager +foragers +forages +foraging +foram +foramen +foramens +foramina +foraminal +foraminifer +foraminifera +foraminiferal +foraminiferan +foraminiferans +foraminifers +foraminous +forams +foray +forayed +forayer +forayers +foraying +forays +forb +forbad +forbade +forbear +forbearance +forbearances +forbearer +forbearers +forbearing +forbears +forbid +forbidal +forbidals +forbiddance +forbiddances +forbidden +forbidder +forbidders +forbidding +forbiddingly +forbids +forbode +forboded +forbodes +forboding +forbore +forborne +forbs +forby +forbye +force +forced +forcedly +forceful +forcefully +forcefulness +forcefulnesses +forceless +forcemeat +forcemeats +forceps +forcepslike +forcer +forcers +forces +forcible +forcibleness +forciblenesses +forcibly +forcing +forcipes +ford +fordable +forded +fordid +fording +fordless +fordo +fordoes +fordoing +fordone +fords +fore +forearm +forearmed +forearming +forearms +forebay +forebays +forebear +forebears +forebode +foreboded +foreboder +foreboders +forebodes +forebodies +foreboding +forebodingly +forebodingness +forebodingnesses +forebodings +forebody +foreboom +forebooms +forebrain +forebrains +foreby +forebye +forecaddie +forecaddies +forecast +forecastable +forecasted +forecaster +forecasters +forecasting +forecastle +forecastles +forecasts +forecheck +forechecked +forechecker +forecheckers +forechecking +forechecks +foreclose +foreclosed +forecloses +foreclosing +foreclosure +foreclosures +forecourt +forecourts +foredate +foredated +foredates +foredating +foredeck +foredecks +foredid +foredo +foredoes +foredoing +foredone +foredoom +foredoomed +foredooming +foredooms +foreface +forefaces +forefather +forefathers +forefeel +forefeeling +forefeels +forefeet +forefelt +forefend +forefended +forefending +forefends +forefinger +forefingers +forefoot +forefront +forefronts +foregather +foregathered +foregathering +foregathers +forego +foregoer +foregoers +foregoes +foregoing +foregone +foreground +foregrounded +foregrounding +foregrounds +foregut +foreguts +forehand +forehanded +forehandedly +forehandedness +forehandednesses +forehands +forehead +foreheads +forehoof +forehoofs +forehooves +foreign +foreigner +foreigners +foreignism +foreignisms +foreignness +foreignnesses +forejudge +forejudged +forejudges +forejudging +foreknew +foreknow +foreknowing +foreknowledge +foreknowledges +foreknown +foreknows +foreladies +forelady +foreland +forelands +foreleg +forelegs +forelimb +forelimbs +forelock +forelocked +forelocking +forelocks +foreman +foremanship +foremanships +foremast +foremasts +foremen +foremilk +foremilks +foremost +foremother +foremothers +forename +forenamed +forenames +forenoon +forenoons +forensic +forensically +forensics +foreordain +foreordained +foreordaining +foreordains +foreordination +foreordinations +forepart +foreparts +forepassed +forepast +forepaw +forepaws +forepeak +forepeaks +foreplay +foreplays +forequarter +forequarters +foreran +forerank +foreranks +forereach +forereached +forereaches +forereaching +forerun +forerunner +forerunners +forerunning +foreruns +fores +foresaid +foresail +foresails +foresaw +foresee +foreseeabilities +foreseeability +foreseeable +foreseeing +foreseen +foreseer +foreseers +foresees +foreshadow +foreshadowed +foreshadower +foreshadowers +foreshadowing +foreshadows +foreshank +foreshanks +foresheet +foresheets +foreshock +foreshocks +foreshore +foreshores +foreshorten +foreshortened +foreshortening +foreshortens +foreshow +foreshowed +foreshowing +foreshown +foreshows +foreside +foresides +foresight +foresighted +foresightedly +foresightedness +foresightednesses +foresightful +foresights +foreskin +foreskins +forespeak +forespeaking +forespeaks +forespoke +forespoken +forest +forestage +forestages +forestal +forestall +forestalled +forestaller +forestallers +forestalling +forestallment +forestallments +forestalls +forestation +forestations +forestay +forestays +forestaysail +forestaysails +forested +forester +foresters +forestial +foresting +forestland +forestlands +forestries +forestry +forests +foreswear +foreswearing +foreswears +foreswore +foresworn +foretaste +foretasted +foretastes +foretasting +foretell +foreteller +foretellers +foretelling +foretells +forethought +forethoughtful +forethoughtfully +forethoughtfulness +forethoughtfulnesses +forethoughts +foretime +foretimes +foretoken +foretokened +foretokening +foretokens +foretold +foretop +foretopman +foretopmen +foretops +forever +forevermore +foreverness +forevernesses +forevers +forewarn +forewarned +forewarning +forewarns +forewent +forewing +forewings +forewoman +forewomen +foreword +forewords +foreworn +foreyard +foreyards +forfeit +forfeitable +forfeited +forfeiter +forfeiters +forfeiting +forfeits +forfeiture +forfeitures +forfend +forfended +forfending +forfends +forgat +forgather +forgathered +forgathering +forgathers +forgave +forge +forgeabilities +forgeability +forgeable +forged +forger +forgeries +forgers +forgery +forges +forget +forgetful +forgetfully +forgetfulness +forgetfulnesses +forgetive +forgets +forgettable +forgetter +forgetters +forgetting +forging +forgings +forgivable +forgivably +forgive +forgiven +forgiveness +forgivenesses +forgiver +forgivers +forgives +forgiving +forgivingly +forgivingness +forgivingnesses +forgo +forgoer +forgoers +forgoes +forgoing +forgone +forgot +forgotten +forint +forints +forjudge +forjudged +forjudges +forjudging +fork +forkball +forkballs +forked +forkedly +forker +forkers +forkful +forkfuls +forkier +forkiest +forking +forkless +forklift +forklifted +forklifting +forklifts +forklike +forks +forksful +forky +forlorn +forlorner +forlornest +forlornly +forlornness +forlornnesses +form +formabilities +formability +formable +formal +formaldehyde +formaldehydes +formalin +formalins +formalise +formalised +formalises +formalising +formalism +formalisms +formalist +formalistic +formalists +formalities +formality +formalizable +formalization +formalizations +formalize +formalized +formalizer +formalizers +formalizes +formalizing +formally +formalness +formalnesses +formals +formamide +formamides +formant +formants +format +formate +formates +formation +formations +formative +formatively +formatives +formats +formatted +formatter +formatters +formatting +forme +formed +formee +former +formerly +formers +formes +formfitting +formful +formic +formicaries +formicary +formidabilities +formidability +formidable +formidableness +formidablenesses +formidably +forming +formless +formlessly +formlessness +formlessnesses +formol +formols +forms +formula +formulae +formulaic +formulaically +formularies +formularization +formularizations +formularize +formularized +formularizer +formularizers +formularizes +formularizing +formulary +formulas +formulate +formulated +formulates +formulating +formulation +formulations +formulator +formulators +formulize +formulized +formulizes +formulizing +formwork +formworks +formyl +formyls +fornical +fornicate +fornicated +fornicates +fornicating +fornication +fornications +fornicator +fornicators +fornices +fornix +forrader +forrarder +forrit +forsake +forsaken +forsaker +forsakers +forsakes +forsaking +forsook +forsooth +forspent +forswear +forswearing +forswears +forswore +forsworn +forsythia +forsythias +fort +fortalice +fortalices +forte +fortepiano +fortepianos +fortes +forth +forthcoming +forthright +forthrightly +forthrightness +forthrightnesses +forthrights +forthwith +forties +fortieth +fortieths +fortification +fortifications +fortified +fortifier +fortifiers +fortifies +fortify +fortifying +fortis +fortissimi +fortissimo +fortissimos +fortitude +fortitudes +fortnight +fortnightlies +fortnightly +fortnights +fortress +fortressed +fortresses +fortressing +fortresslike +forts +fortuities +fortuitous +fortuitously +fortuitousness +fortuitousnesses +fortuity +fortunate +fortunately +fortunateness +fortunatenesses +fortune +fortuned +fortunes +fortuneteller +fortunetellers +fortunetelling +fortunetellings +fortuning +forty +fortyish +forum +forums +forward +forwarded +forwarder +forwarders +forwardest +forwarding +forwardly +forwardness +forwardnesses +forwards +forwent +forwhy +forworn +forzando +forzandos +foss +fossa +fossae +fossas +fossate +fosse +fosses +fossette +fossettes +fossick +fossicked +fossicker +fossickers +fossicking +fossicks +fossil +fossiliferous +fossilise +fossilised +fossilises +fossilising +fossilization +fossilizations +fossilize +fossilized +fossilizes +fossilizing +fossils +fossorial +foster +fosterage +fosterages +fostered +fosterer +fosterers +fostering +fosterling +fosterlings +fosters +fou +fouette +fouettes +fought +foughten +foul +foulard +foulards +foulbrood +foulbroods +fouled +fouler +foulest +fouling +foulings +foully +foulmouthed +foulness +foulnesses +fouls +found +foundation +foundational +foundationally +foundationless +foundations +founded +founder +foundered +foundering +founders +founding +foundling +foundlings +foundries +foundry +founds +fount +fountain +fountained +fountainhead +fountainheads +fountaining +fountains +founts +four +fourchee +fourdrinier +fourdriniers +fourfold +fourgon +fourgons +fourplex +fourplexes +fourragere +fourrageres +fours +fourscore +foursome +foursomes +foursquare +fourteen +fourteener +fourteeners +fourteens +fourteenth +fourteenths +fourth +fourthly +fourths +fovea +foveae +foveal +foveas +foveate +foveated +foveola +foveolae +foveolar +foveolas +foveole +foveoles +foveolet +foveolets +fowl +fowled +fowler +fowlers +fowling +fowlings +fowlpox +fowlpoxes +fowls +fox +foxed +foxes +foxfire +foxfires +foxfish +foxfishes +foxglove +foxgloves +foxhole +foxholes +foxhound +foxhounds +foxhunt +foxhunted +foxhunter +foxhunters +foxhunting +foxhuntings +foxhunts +foxier +foxiest +foxily +foxiness +foxinesses +foxing +foxings +foxlike +foxskin +foxskins +foxtail +foxtails +foxtrot +foxtrots +foxtrotted +foxtrotting +foxy +foy +foyer +foyers +foys +fozier +foziest +foziness +fozinesses +fozy +frabjous +fracas +fracases +fractal +fractals +fracted +fracti +fraction +fractional +fractionalization +fractionalizations +fractionalize +fractionalized +fractionalizes +fractionalizing +fractionally +fractionate +fractionated +fractionates +fractionating +fractionation +fractionations +fractionator +fractionators +fractioned +fractioning +fractions +fractious +fractiously +fractiousness +fractiousnesses +fractur +fracture +fractured +fractures +fracturing +fracturs +fractus +frae +fraena +fraenum +fraenums +frag +fragged +fragging +fraggings +fragile +fragilities +fragility +fragment +fragmental +fragmentally +fragmentarily +fragmentariness +fragmentarinesses +fragmentary +fragmentate +fragmentated +fragmentates +fragmentating +fragmentation +fragmentations +fragmented +fragmenting +fragmentize +fragmentized +fragmentizes +fragmentizing +fragments +fragrance +fragrances +fragrancies +fragrancy +fragrant +fragrantly +frags +frail +frailer +frailest +frailly +frailness +frailnesses +frails +frailties +frailty +fraise +fraises +fraktur +frakturs +framable +frambesia +frambesias +framboise +framboises +frame +frameable +framed +framer +framers +frames +frameshift +frameshifts +framework +frameworks +framing +framings +franc +franchise +franchised +franchisee +franchisees +franchiser +franchisers +franchises +franchising +franchisor +franchisors +francium +franciums +francolin +francolins +francophone +francs +frangibilities +frangibility +frangible +frangipane +frangipanes +frangipani +frangipanis +frangipanni +franglais +frank +frankable +franked +franker +frankers +frankest +frankfurt +frankfurter +frankfurters +frankfurts +frankincense +frankincenses +franking +franklin +franklinite +franklinites +franklins +frankly +frankness +franknesses +frankpledge +frankpledges +franks +frantic +frantically +franticness +franticnesses +frap +frappe +frapped +frappes +frapping +fraps +frass +frasses +frat +frater +fraternal +fraternalism +fraternalisms +fraternally +fraternities +fraternity +fraternization +fraternizations +fraternize +fraternized +fraternizer +fraternizers +fraternizes +fraternizing +fraters +fratricidal +fratricide +fratricides +frats +fraud +frauds +fraudulence +fraudulences +fraudulent +fraudulently +fraudulentness +fraudulentnesses +fraught +fraughted +fraughting +fraughts +fraulein +frauleins +fraxinella +fraxinellas +fray +frayed +fraying +frayings +frays +frazil +frazils +frazzle +frazzled +frazzles +frazzling +freak +freaked +freakier +freakiest +freakily +freakiness +freakinesses +freaking +freakish +freakishly +freakishness +freakishnesses +freakout +freakouts +freaks +freaky +freckle +freckled +freckles +frecklier +freckliest +freckling +freckly +free +freebase +freebased +freebaser +freebasers +freebases +freebasing +freebee +freebees +freebie +freebies +freeboard +freeboards +freeboot +freebooted +freebooter +freebooters +freebooting +freeboots +freeborn +freed +freedman +freedmen +freedom +freedoms +freedwoman +freedwomen +freeform +freehand +freehanded +freehandedly +freehandedness +freehandednesses +freehearted +freeheartedly +freehold +freeholder +freeholders +freeholds +freeing +freelance +freelanced +freelancer +freelancers +freelances +freelancing +freeload +freeloaded +freeloader +freeloaders +freeloading +freeloads +freely +freeman +freemartin +freemartins +freemasonries +freemasonry +freemen +freeness +freenesses +freer +freers +frees +freesia +freesias +freest +freestanding +freestone +freestones +freestyle +freestyler +freestylers +freestyles +freethinker +freethinkers +freethinking +freethinkings +freeway +freeways +freewheel +freewheeled +freewheeler +freewheelers +freewheeling +freewheelingly +freewheels +freewill +freewriting +freewritings +freeze +freezer +freezers +freezes +freezing +freezingly +freight +freightage +freightages +freighted +freighter +freighters +freighting +freights +fremd +fremitus +fremituses +frena +french +frenched +frenches +frenchification +frenchifications +frenchified +frenchifies +frenchify +frenchifying +frenching +frenetic +frenetically +freneticism +freneticisms +frenetics +frenula +frenulum +frenulums +frenum +frenums +frenzied +frenziedly +frenzies +frenzily +frenzy +frenzying +frequence +frequences +frequencies +frequency +frequent +frequentation +frequentations +frequentative +frequentatives +frequented +frequenter +frequenters +frequentest +frequenting +frequently +frequentness +frequentnesses +frequents +frere +freres +fresco +frescoed +frescoer +frescoers +frescoes +frescoing +frescos +fresh +freshed +freshen +freshened +freshener +fresheners +freshening +freshens +fresher +freshes +freshest +freshet +freshets +freshing +freshly +freshman +freshmen +freshness +freshnesses +freshwater +freshwaters +fresnel +fresnels +fret +fretful +fretfully +fretfulness +fretfulnesses +fretless +frets +fretsaw +fretsaws +fretsome +fretted +fretter +fretters +frettier +frettiest +fretting +fretty +fretwork +fretworks +friabilities +friability +friable +friar +friaries +friarly +friars +friary +fribble +fribbled +fribbler +fribblers +fribbles +fribbling +fricandeau +fricandeaus +fricandeaux +fricando +fricandoes +fricassee +fricasseed +fricasseeing +fricassees +fricative +fricatives +friction +frictional +frictionally +frictionless +frictionlessly +frictions +fridge +fridges +fried +friedcake +friedcakes +friend +friended +friending +friendless +friendlessness +friendlessnesses +friendlier +friendlies +friendliest +friendlily +friendliness +friendlinesses +friendly +friends +friendship +friendships +frier +friers +fries +frieze +friezelike +friezes +frig +frigate +frigates +frigged +frigging +fright +frighted +frighten +frightened +frightening +frighteningly +frightens +frightful +frightfully +frightfulness +frightfulnesses +frighting +frights +frigid +frigidities +frigidity +frigidly +frigidness +frigidnesses +frigorific +frigs +frijol +frijole +frijoles +frill +frilled +friller +frillers +frillier +frilliest +frilling +frillings +frills +frilly +fringe +fringed +fringes +fringier +fringiest +fringing +fringy +fripperies +frippery +frise +frises +frisette +frisettes +friseur +friseurs +frisk +frisked +frisker +friskers +frisket +friskets +friskier +friskiest +friskily +friskiness +friskinesses +frisking +frisks +frisky +frisson +frissons +frit +frith +friths +fritillaria +fritillarias +fritillaries +fritillary +frits +fritt +frittata +frittatas +fritted +fritter +frittered +fritterer +fritterers +frittering +fritters +fritting +fritts +fritz +fritzes +frivol +frivoled +frivoler +frivolers +frivoling +frivolities +frivolity +frivolled +frivoller +frivollers +frivolling +frivolous +frivolously +frivolousness +frivolousnesses +frivols +friz +frized +frizer +frizers +frizes +frizette +frizettes +frizing +frizz +frizzed +frizzer +frizzers +frizzes +frizzier +frizziest +frizzily +frizziness +frizzinesses +frizzing +frizzle +frizzled +frizzler +frizzlers +frizzles +frizzlier +frizzliest +frizzling +frizzly +frizzy +fro +frock +frocked +frocking +frocks +froe +froes +frog +frogeye +frogeyed +frogeyes +frogfish +frogfishes +frogged +froggier +froggiest +frogging +froggy +froghopper +froghoppers +froglike +frogman +frogmen +frogs +frolic +frolicked +frolicking +frolicky +frolics +frolicsome +from +fromage +fromages +fromenties +fromenty +frond +fronded +frondeur +frondeurs +frondose +fronds +frons +front +frontage +frontages +frontal +frontalities +frontality +frontally +frontals +frontcourt +frontcourts +fronted +fronter +frontes +frontier +frontiers +frontiersman +frontiersmen +fronting +frontispiece +frontispieces +frontless +frontlet +frontlets +frontline +frontogeneses +frontogenesis +frontolyses +frontolysis +fronton +frontons +frontrunner +frontrunners +fronts +frontward +frontwards +frore +frosh +frost +frostbit +frostbite +frostbites +frostbiting +frostbitings +frostbitten +frosted +frosteds +frostier +frostiest +frostily +frostiness +frostinesses +frosting +frostings +frosts +frostwork +frostworks +frosty +froth +frothed +frothier +frothiest +frothily +frothiness +frothinesses +frothing +froths +frothy +frottage +frottages +frotteur +frotteurs +froufrou +froufrous +frounce +frounced +frounces +frouncing +frouzier +frouziest +frouzy +frow +froward +frowardly +frowardness +frowardnesses +frown +frowned +frowner +frowners +frowning +frowningly +frowns +frows +frowsier +frowsiest +frowst +frowsted +frowstier +frowstiest +frowsting +frowsts +frowsty +frowsy +frowzier +frowziest +frowzily +frowzy +froze +frozen +frozenly +frozenness +frozennesses +fructification +fructifications +fructified +fructifies +fructify +fructifying +fructose +fructoses +fructuous +frug +frugal +frugalities +frugality +frugally +frugged +frugging +frugivore +frugivores +frugivorous +frugs +fruit +fruitage +fruitages +fruitarian +fruitarians +fruitcake +fruitcakes +fruited +fruiter +fruiterer +fruiterers +fruiters +fruitful +fruitfuller +fruitfullest +fruitfully +fruitfulness +fruitfulnesses +fruitier +fruitiest +fruitily +fruitiness +fruitinesses +fruiting +fruition +fruitions +fruitless +fruitlessly +fruitlessness +fruitlessnesses +fruitlet +fruitlets +fruits +fruitwood +fruitwoods +fruity +frumenties +frumenty +frump +frumpier +frumpiest +frumpily +frumpish +frumps +frumpy +frusta +frustrate +frustrated +frustrates +frustrating +frustratingly +frustration +frustrations +frustule +frustules +frustum +frustums +frutescent +fruticose +fry +fryer +fryers +frying +frypan +frypans +fub +fubbed +fubbing +fubs +fubsier +fubsiest +fubsy +fuchsia +fuchsias +fuchsin +fuchsine +fuchsines +fuchsins +fuci +fuck +fucked +fucker +fuckers +fucking +fucks +fuckup +fuckups +fucoid +fucoidal +fucoids +fucose +fucoses +fucous +fucoxanthin +fucoxanthins +fucus +fucuses +fud +fuddle +fuddled +fuddles +fuddling +fudge +fudged +fudges +fudging +fuds +fuehrer +fuehrers +fuel +fueled +fueler +fuelers +fueling +fuelled +fueller +fuellers +fuelling +fuels +fuelwood +fuelwoods +fug +fugacious +fugacities +fugacity +fugal +fugally +fugato +fugatos +fugged +fuggier +fuggiest +fuggily +fugging +fuggy +fugio +fugios +fugitive +fugitively +fugitiveness +fugitivenesses +fugitives +fugle +fugled +fugleman +fuglemen +fugles +fugling +fugs +fugu +fugue +fugued +fugues +fuguing +fuguist +fuguists +fugus +fuhrer +fuhrers +fuji +fujis +fulcra +fulcrum +fulcrums +fulfil +fulfill +fulfilled +fulfiller +fulfillers +fulfilling +fulfillment +fulfillments +fulfills +fulfils +fulgent +fulgently +fulgid +fulgurant +fulgurate +fulgurated +fulgurates +fulgurating +fulguration +fulgurations +fulgurite +fulgurites +fulgurous +fulham +fulhams +fuliginous +fuliginously +full +fullam +fullams +fullback +fullbacks +fulled +fuller +fullered +fullerene +fullerenes +fulleries +fullering +fullers +fullery +fullest +fullface +fullfaces +fulling +fullmouthed +fullness +fullnesses +fulls +fully +fulmar +fulmars +fulminant +fulminate +fulminated +fulminates +fulminating +fulmination +fulminations +fulmine +fulmined +fulmines +fulminic +fulmining +fulness +fulnesses +fulsome +fulsomely +fulsomeness +fulsomenesses +fulvous +fumarase +fumarases +fumarate +fumarates +fumaric +fumarole +fumaroles +fumarolic +fumatories +fumatory +fumble +fumbled +fumbler +fumblers +fumbles +fumbling +fumblingly +fume +fumed +fumeless +fumelike +fumer +fumers +fumes +fumet +fumets +fumette +fumettes +fumier +fumiest +fumigant +fumigants +fumigate +fumigated +fumigates +fumigating +fumigation +fumigations +fumigator +fumigators +fuming +fumingly +fumitories +fumitory +fumuli +fumulus +fumy +fun +funambulism +funambulisms +funambulist +funambulists +function +functional +functionalism +functionalisms +functionalist +functionalistic +functionalists +functionalities +functionality +functionally +functionaries +functionary +functioned +functioning +functionless +functions +functor +functors +fund +fundament +fundamental +fundamentalism +fundamentalisms +fundamentalist +fundamentalistic +fundamentalists +fundamentally +fundamentals +fundaments +funded +fundi +fundic +funding +fundraiser +fundraisers +fundraising +fundraisings +funds +fundus +funeral +funerals +funerary +funereal +funereally +funest +funfair +funfairs +fungal +fungals +fungi +fungibilities +fungibility +fungible +fungibles +fungic +fungicidal +fungicidally +fungicide +fungicides +fungiform +fungistatic +fungo +fungoes +fungoid +fungoids +fungous +fungus +funguses +funicle +funicles +funicular +funiculars +funiculi +funiculus +funk +funked +funker +funkers +funkia +funkias +funkier +funkiest +funkiness +funkinesses +funking +funks +funky +funned +funnel +funneled +funnelform +funneling +funnelled +funnelling +funnels +funner +funnest +funnier +funnies +funniest +funnily +funniness +funninesses +funning +funny +funnyman +funnymen +funs +fur +furan +furane +furanes +furanose +furanoses +furanoside +furanosides +furans +furazolidone +furazolidones +furbearer +furbearers +furbelow +furbelowed +furbelowing +furbelows +furbish +furbished +furbisher +furbishers +furbishes +furbishing +furcate +furcated +furcates +furcating +furcation +furcations +furcraea +furcraeas +furcula +furculae +furcular +furculum +furfur +furfural +furfurals +furfuran +furfurans +furfures +furibund +furies +furioso +furious +furiously +furl +furlable +furled +furler +furlers +furless +furling +furlong +furlongs +furlough +furloughed +furloughing +furloughs +furls +furmenties +furmenty +furmeties +furmety +furmities +furmity +furnace +furnaced +furnaces +furnacing +furnish +furnished +furnisher +furnishers +furnishes +furnishing +furnishings +furniture +furnitures +furor +furore +furores +furors +furosemide +furosemides +furred +furrier +furrieries +furriers +furriery +furriest +furrily +furriner +furriners +furring +furrings +furrow +furrowed +furrower +furrowers +furrowing +furrows +furrowy +furry +furs +further +furtherance +furtherances +furthered +furtherer +furtherers +furthering +furthermore +furthermost +furthers +furthest +furtive +furtively +furtiveness +furtivenesses +furuncle +furuncles +furunculoses +furunculosis +fury +furze +furzes +furzier +furziest +furzy +fusain +fusains +fuscous +fuse +fused +fusee +fusees +fusel +fuselage +fuselages +fuseless +fusels +fuses +fusibilities +fusibility +fusible +fusibly +fusiform +fusil +fusile +fusileer +fusileers +fusilier +fusiliers +fusillade +fusillades +fusilli +fusillis +fusils +fusing +fusion +fusionist +fusionists +fusions +fuss +fussbudget +fussbudgets +fussbudgety +fussed +fusser +fussers +fusses +fussier +fussiest +fussily +fussiness +fussinesses +fussing +fusspot +fusspots +fussy +fustian +fustians +fustic +fustics +fustier +fustiest +fustigate +fustigated +fustigates +fustigating +fustigation +fustigations +fustily +fustiness +fustinesses +fusty +fusulinid +fusulinids +futharc +futharcs +futhark +futharks +futhorc +futhorcs +futhork +futhorks +futile +futilely +futileness +futilenesses +futilitarian +futilitarianism +futilitarianisms +futilitarians +futilities +futility +futon +futons +futtock +futtocks +futural +future +futureless +futurelessness +futurelessnesses +futures +futurism +futurisms +futurist +futuristic +futuristically +futuristics +futurists +futurities +futurity +futurological +futurologies +futurologist +futurologists +futurology +futz +futzed +futzes +futzing +fuze +fuzed +fuzee +fuzees +fuzes +fuzil +fuzils +fuzing +fuzz +fuzzed +fuzzes +fuzzier +fuzziest +fuzzily +fuzziness +fuzzinesses +fuzzing +fuzzy +fyce +fyces +fyke +fykes +fylfot +fylfots +fytte +fyttes +gab +gabardine +gabardines +gabbard +gabbards +gabbart +gabbarts +gabbed +gabber +gabbers +gabbier +gabbiest +gabbing +gabble +gabbled +gabbler +gabblers +gabbles +gabbling +gabbro +gabbroic +gabbroid +gabbros +gabby +gabelle +gabelled +gabelles +gaberdine +gaberdines +gabfest +gabfests +gabies +gabion +gabions +gable +gabled +gables +gabling +gaboon +gaboons +gabs +gaby +gad +gadabout +gadabouts +gadarene +gadded +gadder +gadders +gaddi +gadding +gaddis +gadflies +gadfly +gadget +gadgeteer +gadgeteers +gadgetries +gadgetry +gadgets +gadgety +gadi +gadid +gadids +gadis +gadoid +gadoids +gadolinite +gadolinites +gadolinium +gadoliniums +gadroon +gadrooned +gadrooning +gadroonings +gadroons +gads +gadwall +gadwalls +gadzookeries +gadzookery +gadzooks +gae +gaed +gaeing +gaen +gaes +gaff +gaffe +gaffed +gaffer +gaffers +gaffes +gaffing +gaffs +gag +gaga +gagaku +gagakus +gage +gaged +gager +gagers +gages +gagged +gagger +gaggers +gagging +gaggle +gaggled +gaggles +gaggling +gaging +gagman +gagmen +gags +gagster +gagsters +gahnite +gahnites +gaieties +gaiety +gaijin +gaillardia +gaillardias +gaily +gain +gainable +gained +gainer +gainers +gainful +gainfully +gainfulness +gainfulnesses +gaingiving +gaingivings +gaining +gainless +gainlier +gainliest +gainly +gains +gainsaid +gainsay +gainsayer +gainsayers +gainsaying +gainsays +gainst +gait +gaited +gaiter +gaiters +gaiting +gaits +gal +gala +galabia +galabias +galabieh +galabiehs +galabiya +galabiyas +galactic +galactorrhea +galactorrheas +galactosamine +galactosamines +galactose +galactosemia +galactosemias +galactosemic +galactoses +galactosidase +galactosidases +galactoside +galactosides +galactosyl +galactosyls +galago +galagos +galah +galahs +galangal +galangals +galantine +galantines +galas +galatea +galateas +galavant +galavanted +galavanting +galavants +galax +galaxes +galaxies +galaxy +galbanum +galbanums +gale +galea +galeae +galeas +galeate +galeated +galena +galenas +galenic +galenical +galenicals +galenite +galenites +galere +galeres +gales +galilee +galilees +galingale +galingales +galiot +galiots +galipot +galipots +galivant +galivanted +galivanting +galivants +gall +gallamine +gallamines +gallant +gallanted +gallanting +gallantly +gallantries +gallantry +gallants +gallate +gallates +gallbladder +gallbladders +galleass +galleasses +galled +gallein +galleins +galleon +galleons +galleria +gallerias +galleried +galleries +gallery +gallerygoer +gallerygoers +gallerying +galleryite +galleryites +gallet +galleta +galletas +galleted +galleting +gallets +galley +galleys +gallflies +gallfly +galliard +galliards +galliass +galliasses +gallic +gallican +gallicism +gallicisms +gallicization +gallicizations +gallicize +gallicized +gallicizes +gallicizing +gallied +gallies +galligaskins +gallimaufries +gallimaufry +gallinaceous +galling +gallingly +gallinipper +gallinippers +gallinule +gallinules +galliot +galliots +gallipot +gallipots +gallium +galliums +gallivant +gallivanted +gallivanting +gallivants +gallnut +gallnuts +gallon +gallonage +gallonages +gallons +galloon +galloons +galloot +galloots +gallop +gallopade +gallopades +galloped +galloper +gallopers +galloping +gallops +gallous +gallowglass +gallowglasses +gallows +gallowses +galls +gallstone +gallstones +gallus +gallused +galluses +gally +gallying +galoot +galoots +galop +galopade +galopades +galoped +galoping +galops +galore +galores +galosh +galoshe +galoshed +galoshes +gals +galumph +galumphed +galumphing +galumphs +galvanic +galvanically +galvanise +galvanised +galvanises +galvanising +galvanism +galvanisms +galvanization +galvanizations +galvanize +galvanized +galvanizer +galvanizers +galvanizes +galvanizing +galvanometer +galvanometers +galvanometric +galvanoscope +galvanoscopes +galyac +galyacs +galyak +galyaks +gam +gama +gamas +gamashes +gamay +gamays +gamb +gamba +gambade +gambades +gambado +gambadoes +gambados +gambas +gambe +gambes +gambeson +gambesons +gambia +gambias +gambier +gambiers +gambir +gambirs +gambit +gambits +gamble +gambled +gambler +gamblers +gambles +gambling +gamboge +gamboges +gambol +gamboled +gamboling +gambolled +gambolling +gambols +gambrel +gambrels +gambs +gambusia +gambusias +game +gamecock +gamecocks +gamed +gamekeeper +gamekeepers +gamelan +gamelans +gamelike +gamely +gameness +gamenesses +gamer +gamers +games +gamesman +gamesmanship +gamesmanships +gamesmen +gamesome +gamesomely +gamesomeness +gamesomenesses +gamest +gamester +gamesters +gametangia +gametangium +gamete +gametes +gametic +gametically +gametocyte +gametocytes +gametogeneses +gametogenesis +gametogenic +gametogenous +gametophore +gametophores +gametophyte +gametophytes +gametophytic +gamey +gamic +gamier +gamiest +gamily +gamin +gamine +gamines +gaminess +gaminesses +gaming +gamings +gamins +gamma +gammadia +gammadion +gammas +gammed +gammer +gammers +gammier +gammiest +gamming +gammon +gammoned +gammoner +gammoners +gammoning +gammons +gammy +gamodeme +gamodemes +gamopetalous +gamp +gamps +gams +gamut +gamuts +gamy +gan +ganache +ganaches +gander +gandered +gandering +ganders +gane +ganef +ganefs +ganev +ganevs +gang +gangbang +gangbanger +gangbangers +gangbangs +gangbuster +gangbusters +ganged +ganger +gangers +ganging +gangland +ganglands +ganglia +ganglial +gangliar +ganglier +gangliest +gangling +ganglion +ganglionated +ganglionic +ganglions +ganglioside +gangliosides +gangly +gangplank +gangplanks +gangplow +gangplows +gangrel +gangrels +gangrene +gangrened +gangrenes +gangrening +gangrenous +gangs +gangster +gangsterdom +gangsterdoms +gangsterish +gangsterism +gangsterisms +gangsters +gangue +gangues +gangway +gangways +ganister +ganisters +ganja +ganjah +ganjahs +ganjas +gannet +gannets +gannister +gannisters +ganof +ganofs +ganoid +ganoids +gantelope +gantelopes +gantlet +gantleted +gantleting +gantlets +gantline +gantlines +gantlope +gantlopes +gantries +gantry +ganymede +ganymedes +gaol +gaoled +gaoler +gaolers +gaoling +gaols +gap +gape +gaped +gaper +gapers +gapes +gapeseed +gapeseeds +gapeworm +gapeworms +gaping +gapingly +gaposis +gaposises +gapped +gappier +gappiest +gapping +gappy +gaps +gapy +gar +garage +garaged +garageman +garagemen +garages +garaging +garb +garbage +garbageman +garbagemen +garbages +garbanzo +garbanzos +garbed +garbing +garble +garbled +garbler +garblers +garbles +garbless +garbling +garboard +garboards +garboil +garboils +garbs +garcon +garcons +gardant +garden +gardened +gardener +gardeners +gardenful +gardenfuls +gardenia +gardenias +gardening +gardens +garderobe +garderobes +gardyloo +garfish +garfishes +garganey +garganeys +gargantuan +garget +gargets +gargety +gargle +gargled +gargler +garglers +gargles +gargling +gargoyle +gargoyled +gargoyles +garibaldi +garibaldis +garigue +garigues +garish +garishly +garishness +garishnesses +garland +garlanded +garlanding +garlands +garlic +garlicked +garlicky +garlics +garment +garmented +garmenting +garments +garner +garnered +garnering +garners +garnet +garnetiferous +garnets +garni +garnierite +garnierites +garnish +garnished +garnishee +garnisheed +garnisheeing +garnishees +garnishes +garnishing +garnishment +garnishments +garniture +garnitures +garote +garoted +garotes +garoting +garotte +garotted +garotter +garotters +garottes +garotting +garpike +garpikes +garred +garret +garrets +garring +garrison +garrisoned +garrisoning +garrisons +garron +garrons +garrote +garroted +garroter +garroters +garrotes +garroting +garrotte +garrotted +garrottes +garrotting +garrulities +garrulity +garrulous +garrulously +garrulousness +garrulousnesses +gars +garter +gartered +gartering +garters +garth +garths +garvey +garveys +gas +gasalier +gasaliers +gasbag +gasbags +gascon +gasconade +gasconaded +gasconader +gasconaders +gasconades +gasconading +gascons +gaselier +gaseliers +gaseous +gaseousness +gaseousnesses +gases +gash +gashed +gasher +gashes +gashest +gashing +gasholder +gasholders +gashouse +gashouses +gasification +gasifications +gasified +gasifier +gasifiers +gasifies +gasiform +gasify +gasifying +gasket +gaskets +gaskin +gasking +gaskings +gaskins +gasless +gaslight +gaslights +gaslit +gasman +gasmen +gasogene +gasogenes +gasohol +gasohols +gasolene +gasolenes +gasolier +gasoliers +gasoline +gasolines +gasolinic +gasometer +gasometers +gasp +gasped +gasper +gaspers +gasping +gasps +gassed +gasser +gassers +gasses +gassier +gassiest +gassily +gassiness +gassinesses +gassing +gassings +gassy +gast +gasted +gaster +gasters +gastight +gastightness +gastightnesses +gasting +gastness +gastnesses +gastraea +gastraeas +gastral +gastrea +gastreas +gastrectomies +gastrectomy +gastric +gastrin +gastrins +gastritides +gastritis +gastrocnemii +gastrocnemius +gastroduodenal +gastroenteritides +gastroenteritis +gastroenteritises +gastroenterological +gastroenterologies +gastroenterologist +gastroenterologists +gastroenterology +gastroesophageal +gastrointestinal +gastrolith +gastroliths +gastronome +gastronomes +gastronomic +gastronomical +gastronomically +gastronomies +gastronomist +gastronomists +gastronomy +gastropod +gastropods +gastroscope +gastroscopes +gastroscopic +gastroscopies +gastroscopist +gastroscopists +gastroscopy +gastrotrich +gastrotrichs +gastrovascular +gastrula +gastrulae +gastrular +gastrulas +gastrulate +gastrulated +gastrulates +gastrulating +gastrulation +gastrulations +gasts +gasworks +gat +gate +gateau +gateaux +gated +gatefold +gatefolds +gatehouse +gatehouses +gatekeeper +gatekeepers +gatekeeping +gateless +gatelike +gateman +gatemen +gatepost +gateposts +gates +gateway +gateways +gather +gathered +gatherer +gatherers +gathering +gatherings +gathers +gating +gator +gators +gats +gauche +gauchely +gaucheness +gauchenesses +gaucher +gaucherie +gaucheries +gauchest +gaucho +gauchos +gaud +gauderies +gaudery +gaudier +gaudies +gaudiest +gaudily +gaudiness +gaudinesses +gauds +gaudy +gauffer +gauffered +gauffering +gauffers +gauge +gauged +gauger +gaugers +gauges +gauging +gault +gaults +gaum +gaumed +gauming +gaums +gaun +gaunt +gaunter +gauntest +gauntlet +gauntleted +gauntleting +gauntlets +gauntly +gauntness +gauntnesses +gauntries +gauntry +gaur +gaurs +gauss +gausses +gauze +gauzelike +gauzes +gauzier +gauziest +gauzily +gauzy +gavage +gavages +gave +gavel +gaveled +gaveling +gavelkind +gavelkinds +gavelled +gavelling +gavelock +gavelocks +gavels +gavial +gavials +gavot +gavots +gavotte +gavotted +gavottes +gavotting +gawk +gawked +gawker +gawkers +gawkier +gawkies +gawkiest +gawkily +gawkiness +gawkinesses +gawking +gawkish +gawkishly +gawkishness +gawkishnesses +gawks +gawky +gawp +gawped +gawper +gawpers +gawping +gawps +gawsie +gawsy +gay +gayal +gayals +gayer +gayest +gayeties +gayety +gayly +gayness +gaynesses +gays +gaywings +gazabo +gazaboes +gazabos +gazania +gazanias +gazar +gazars +gaze +gazebo +gazeboes +gazebos +gazed +gazehound +gazehounds +gazelle +gazelles +gazer +gazers +gazes +gazette +gazetted +gazetteer +gazetteers +gazettes +gazetting +gazing +gazogene +gazogenes +gazpacho +gazpachos +gazump +gazumped +gazumper +gazumpers +gazumping +gazumps +geanticline +geanticlines +gear +gearbox +gearboxes +gearcase +gearcases +gearchange +gearchanges +geared +gearing +gearings +gearless +gears +gearshift +gearshifts +gearwheel +gearwheels +geck +gecked +gecking +gecko +geckoes +geckos +gecks +ged +gedankenexperiment +gedankenexperiments +geds +gee +geed +geegaw +geegaws +geeing +geek +geekier +geekiest +geeks +geeky +geepound +geepounds +gees +geese +geest +geests +geez +geezer +geezers +gegenschein +gegenscheins +geisha +geishas +gel +gelable +gelada +geladas +gelandesprung +gelandesprungs +gelant +gelants +gelate +gelated +gelates +gelati +gelatin +gelatine +gelatines +gelating +gelatinization +gelatinizations +gelatinize +gelatinized +gelatinizes +gelatinizing +gelatinous +gelatinously +gelatinousness +gelatinousnesses +gelatins +gelation +gelations +gelato +gelatos +geld +gelded +gelder +gelders +gelding +geldings +gelds +gelee +gelees +gelid +gelidities +gelidity +gelidly +gelignite +gelignites +gellant +gellants +gelled +gelling +gels +gelsemia +gelsemium +gelsemiums +gelt +gelts +gem +gemeinschaft +gemeinschaften +gemeinschafts +geminal +geminally +geminate +geminated +geminates +geminating +gemination +geminations +gemlike +gemma +gemmae +gemmate +gemmated +gemmates +gemmating +gemmation +gemmations +gemmed +gemmier +gemmiest +gemmily +gemming +gemmologies +gemmologist +gemmologists +gemmology +gemmule +gemmules +gemmy +gemological +gemologies +gemologist +gemologists +gemology +gemot +gemote +gemotes +gemots +gems +gemsbok +gemsboks +gemsbuck +gemsbucks +gemstone +gemstones +gemutlich +gemutlichkeit +gemutlichkeits +gen +gendarme +gendarmerie +gendarmeries +gendarmery +gendarmes +gender +gendered +gendering +genders +gene +genealogical +genealogically +genealogies +genealogist +genealogists +genealogy +genera +generable +general +generalisation +generalisations +generalise +generalised +generalises +generalising +generalissimo +generalissimos +generalist +generalists +generalities +generality +generalizabilities +generalizability +generalizable +generalization +generalizations +generalize +generalized +generalizer +generalizers +generalizes +generalizing +generally +generals +generalship +generalships +generate +generated +generates +generating +generation +generational +generationally +generations +generative +generator +generators +generatrices +generatrix +generic +generically +genericness +genericnesses +generics +generosities +generosity +generous +generously +generousness +generousnesses +genes +geneses +genesis +genet +genetic +genetical +genetically +geneticist +geneticists +genetics +genets +genette +genettes +geneva +genevas +genial +genialities +geniality +genially +genic +genically +geniculate +geniculated +genie +genies +genii +genip +genipap +genipaps +genips +genital +genitalia +genitalic +genitally +genitals +genitival +genitivally +genitive +genitives +genitor +genitors +genitourinary +geniture +genitures +genius +geniuses +genoa +genoas +genocidal +genocide +genocides +genoise +genoises +genom +genome +genomes +genomic +genoms +genotype +genotypes +genotypic +genotypical +genotypically +genre +genres +genro +genros +gens +genseng +gensengs +gent +gentamicin +gentamicins +genteel +genteeler +genteelest +genteelism +genteelisms +genteelly +genteelness +genteelnesses +gentes +gentian +gentians +gentil +gentile +gentiles +gentilesse +gentilesses +gentilities +gentility +gentle +gentled +gentlefolk +gentlefolks +gentleman +gentlemanlike +gentlemanlikeness +gentlemanlikenesses +gentlemanliness +gentlemanlinesses +gentlemanly +gentlemen +gentleness +gentlenesses +gentleperson +gentlepersons +gentler +gentles +gentlest +gentlewoman +gentlewomen +gentling +gently +gentoo +gentoos +gentrice +gentrices +gentries +gentrification +gentrifications +gentrified +gentrifier +gentrifiers +gentrifies +gentrify +gentrifying +gentry +gents +genu +genua +genuflect +genuflected +genuflecting +genuflection +genuflections +genuflects +genuine +genuinely +genuineness +genuinenesses +genus +genuses +geobotanic +geobotanical +geobotanies +geobotanist +geobotanists +geobotany +geocentric +geocentrically +geochemical +geochemically +geochemist +geochemistries +geochemistry +geochemists +geochronologic +geochronological +geochronologically +geochronologies +geochronologist +geochronologists +geochronology +geode +geodes +geodesic +geodesics +geodesies +geodesist +geodesists +geodesy +geodetic +geodetical +geodic +geoduck +geoducks +geognosies +geognosy +geographer +geographers +geographic +geographical +geographically +geographies +geography +geohydrologic +geohydrologies +geohydrologist +geohydrologists +geohydrology +geoid +geoidal +geoids +geologer +geologers +geologic +geological +geologically +geologies +geologist +geologists +geologize +geologized +geologizes +geologizing +geology +geomagnetic +geomagnetically +geomagnetism +geomagnetisms +geomancer +geomancers +geomancies +geomancy +geomantic +geometer +geometers +geometric +geometrical +geometrically +geometrician +geometricians +geometrics +geometrid +geometrids +geometries +geometrise +geometrised +geometrises +geometrising +geometrization +geometrizations +geometrize +geometrized +geometrizes +geometrizing +geometry +geomorphic +geomorphological +geomorphologies +geomorphologist +geomorphologists +geomorphology +geophagies +geophagy +geophone +geophones +geophysical +geophysically +geophysicist +geophysicists +geophysics +geophyte +geophytes +geopolitical +geopolitically +geopolitician +geopoliticians +geopolitics +geoponic +geopressured +geoprobe +geoprobes +georgette +georgettes +georgic +georgics +geoscience +geosciences +geoscientist +geoscientists +geostationary +geostrategic +geostrategies +geostrategist +geostrategists +geostrategy +geostrophic +geostrophically +geosynchronous +geosynclinal +geosyncline +geosynclines +geotactic +geotaxes +geotaxis +geotechnical +geotectonic +geotectonically +geothermal +geothermally +geotropic +geotropically +geotropism +geotropisms +gerah +gerahs +geranial +geranials +geraniol +geraniols +geranium +geraniums +gerardia +gerardias +gerbera +gerberas +gerbil +gerbille +gerbilles +gerbils +gerent +gerents +gerenuk +gerenuks +gerfalcon +gerfalcons +geriatric +geriatrician +geriatricians +geriatrics +germ +german +germander +germanders +germane +germanely +germanic +germanium +germaniums +germanization +germanizations +germanize +germanized +germanizes +germanizing +germans +germen +germens +germfree +germicidal +germicide +germicides +germier +germiest +germina +germinabilities +germinability +germinal +germinally +germinate +germinated +germinates +germinating +germination +germinations +germinative +germproof +germs +germy +gerontic +gerontocracies +gerontocracy +gerontocrat +gerontocratic +gerontocrats +gerontologic +gerontological +gerontologies +gerontologist +gerontologists +gerontology +gerontomorphic +gerrymander +gerrymandered +gerrymandering +gerrymanders +gerund +gerundive +gerundives +gerunds +gesellschaft +gesellschaften +gesellschafts +gesneria +gesneriad +gesneriads +gesso +gessoed +gessoes +gest +gestalt +gestalten +gestaltist +gestaltists +gestalts +gestapo +gestapos +gestate +gestated +gestates +gestating +gestation +gestational +gestations +geste +gestes +gestic +gestical +gesticulant +gesticulate +gesticulated +gesticulates +gesticulating +gesticulation +gesticulations +gesticulative +gesticulator +gesticulators +gesticulatory +gests +gestural +gesturally +gesture +gestured +gesturer +gesturers +gestures +gesturing +gesundheit +get +geta +getable +getas +getatable +getaway +getaways +gets +gettable +getter +gettered +gettering +getters +getting +getup +getups +geum +geums +gewgaw +gewgaws +gewurztraminer +gewurztraminers +gey +geyser +geyserite +geyserites +geysers +gharial +gharials +gharri +gharries +gharris +gharry +ghast +ghastful +ghastfully +ghastlier +ghastliest +ghastliness +ghastlinesses +ghastly +ghat +ghats +ghaut +ghauts +ghazi +ghazies +ghazis +ghee +ghees +gherao +gheraoed +gheraoes +gheraoing +gherkin +gherkins +ghetto +ghettoed +ghettoes +ghettoing +ghettoization +ghettoizations +ghettoize +ghettoized +ghettoizes +ghettoizing +ghettos +ghi +ghibli +ghiblis +ghillie +ghillies +ghis +ghost +ghosted +ghostier +ghostiest +ghosting +ghostings +ghostlier +ghostliest +ghostlike +ghostliness +ghostlinesses +ghostly +ghosts +ghostwrite +ghostwriter +ghostwriters +ghostwrites +ghostwriting +ghostwritten +ghostwrote +ghosty +ghoul +ghoulie +ghoulies +ghoulish +ghoulishly +ghoulishness +ghoulishnesses +ghouls +ghyll +ghylls +giant +giantess +giantesses +giantism +giantisms +giantlike +giants +giaour +giaours +giardiases +giardiasis +gib +gibbed +gibber +gibbered +gibberellin +gibberellins +gibbering +gibberish +gibberishes +gibbers +gibbet +gibbeted +gibbeting +gibbets +gibbetted +gibbetting +gibbing +gibbon +gibbons +gibbose +gibbosities +gibbosity +gibbous +gibbsite +gibbsites +gibe +gibed +giber +gibers +gibes +gibing +gibingly +giblet +giblets +gibs +gibson +gibsons +gid +giddap +giddied +giddier +giddies +giddiest +giddily +giddiness +giddinesses +giddy +giddyap +giddying +giddyup +gids +gie +gied +gieing +gien +gies +gift +gifted +giftedly +giftedness +giftednesses +gifting +giftless +gifts +giftware +giftwares +gig +giga +gigabit +gigabits +gigabyte +gigabytes +gigahertz +gigantesque +gigantic +gigantically +gigantism +gigantisms +gigas +gigaton +gigatons +gigawatt +gigawatts +gigged +gigging +giggle +giggled +giggler +gigglers +giggles +gigglier +giggliest +giggling +gigglingly +giggly +gighe +giglet +giglets +giglot +giglots +gigolo +gigolos +gigot +gigots +gigs +gigue +gigues +gilbert +gilberts +gild +gilded +gilder +gilders +gildhall +gildhalls +gilding +gildings +gilds +gill +gilled +giller +gillers +gillie +gillied +gillies +gilling +gillnet +gillnets +gillnetted +gillnetter +gillnetters +gillnetting +gills +gilly +gillyflower +gillyflowers +gillying +gilt +gilthead +giltheads +gilts +gimbal +gimbaled +gimbaling +gimballed +gimballing +gimbals +gimcrack +gimcrackeries +gimcrackery +gimcracks +gimel +gimels +gimlet +gimleted +gimleting +gimlets +gimmal +gimmals +gimme +gimmes +gimmick +gimmicked +gimmicking +gimmickries +gimmickry +gimmicks +gimmicky +gimmie +gimmies +gimp +gimped +gimpier +gimpiest +gimping +gimps +gimpy +gin +gingal +gingall +gingalls +gingals +gingeley +gingeleys +gingeli +gingelies +gingelis +gingelli +gingellies +gingellis +gingelly +gingely +ginger +gingerbread +gingerbreaded +gingerbreads +gingerbready +gingered +gingering +gingerliness +gingerlinesses +gingerly +gingerroot +gingerroots +gingers +gingersnap +gingersnaps +gingery +gingham +ginghams +gingili +gingilis +gingilli +gingillis +gingiva +gingivae +gingival +gingivectomies +gingivectomy +gingivites +gingivitides +gingivitis +gingivitises +gingko +gingkoes +gink +ginkgo +ginkgoes +ginkgos +ginks +ginned +ginner +ginners +ginnier +ginniest +ginning +ginnings +ginny +gins +ginseng +ginsengs +gip +gipon +gipons +gipped +gipper +gippers +gipping +gips +gipsied +gipsies +gipsy +gipsying +giraffe +giraffes +giraffish +girandole +girandoles +girasol +girasole +girasoles +girasols +gird +girded +girder +girders +girding +girdle +girdled +girdler +girdlers +girdles +girdling +girds +girl +girlfriend +girlfriends +girlhood +girlhoods +girlie +girlies +girlish +girlishly +girlishness +girlishnesses +girls +girly +girn +girned +girning +girns +giro +giron +girons +giros +girosol +girosols +girsh +girshes +girt +girted +girth +girthed +girthing +girths +girting +girts +gisarme +gisarmes +gismo +gismos +gist +gists +git +gitano +gitanos +gits +gittern +gitterns +gittin +give +giveable +giveaway +giveaways +giveback +givebacks +given +givens +giver +givers +gives +giving +gizmo +gizmos +gizzard +gizzards +gjetost +gjetosts +glabella +glabellae +glabellar +glabrate +glabrescent +glabrous +glace +glaceed +glaceing +glaces +glacial +glacially +glaciate +glaciated +glaciates +glaciating +glaciation +glaciations +glacier +glaciers +glaciological +glaciologies +glaciologist +glaciologists +glaciology +glacis +glacises +glad +gladded +gladden +gladdened +gladdening +gladdens +gladder +gladdest +gladding +glade +glades +gladiate +gladiator +gladiatorial +gladiators +gladier +gladiest +gladiola +gladiolas +gladioli +gladiolus +gladioluses +gladlier +gladliest +gladly +gladness +gladnesses +glads +gladsome +gladsomely +gladsomeness +gladsomenesses +gladsomer +gladsomest +gladstone +gladstones +glady +glaiket +glaikit +glair +glaire +glaired +glaires +glairier +glairiest +glairing +glairs +glairy +glaive +glaived +glaives +glamor +glamorise +glamorised +glamorises +glamorising +glamorization +glamorizations +glamorize +glamorized +glamorizer +glamorizers +glamorizes +glamorizing +glamorous +glamorously +glamorousness +glamorousnesses +glamors +glamour +glamoured +glamouring +glamourize +glamourized +glamourizes +glamourizing +glamourless +glamourous +glamours +glance +glanced +glancer +glancers +glances +glancing +glancingly +gland +glandered +glanders +glandes +glandless +glands +glandular +glandularly +glandule +glandules +glans +glare +glared +glares +glarier +glariest +glaring +glaringly +glaringness +glaringnesses +glary +glasnost +glasnosts +glass +glassblower +glassblowers +glassblowing +glassblowings +glassed +glasses +glassful +glassfuls +glasshouse +glasshouses +glassie +glassier +glassies +glassiest +glassily +glassine +glassines +glassiness +glassinesses +glassing +glassless +glassmaker +glassmakers +glassmaking +glassmakings +glassman +glassmen +glasspaper +glasspapered +glasspapering +glasspapers +glassware +glasswares +glasswork +glassworker +glassworkers +glassworks +glasswort +glassworts +glassy +glaucoma +glaucomas +glauconite +glauconites +glauconitic +glaucous +glaucousness +glaucousnesses +glaze +glazed +glazer +glazers +glazes +glazier +glazieries +glaziers +glaziery +glaziest +glazing +glazings +glazy +gleam +gleamed +gleamer +gleamers +gleamier +gleamiest +gleaming +gleams +gleamy +glean +gleanable +gleaned +gleaner +gleaners +gleaning +gleanings +gleans +gleba +glebae +glebe +glebes +gled +glede +gledes +gleds +glee +gleed +gleeds +gleeful +gleefully +gleefulness +gleefulnesses +gleek +gleeked +gleeking +gleeks +gleeman +gleemen +glees +gleesome +gleet +gleeted +gleetier +gleetiest +gleeting +gleets +gleety +gleg +glegly +glegness +glegnesses +gleization +gleizations +glen +glengarries +glengarry +glenlike +glenoid +glens +gley +gleyed +gleying +gleyings +gleys +glia +gliadin +gliadine +gliadines +gliadins +glial +glias +glib +glibber +glibbest +glibly +glibness +glibnesses +glide +glided +glider +gliders +glides +gliding +gliff +gliffs +glim +glime +glimed +glimes +gliming +glimmer +glimmered +glimmering +glimmerings +glimmers +glimpse +glimpsed +glimpser +glimpsers +glimpses +glimpsing +glims +glint +glinted +glinting +glints +glioblastoma +glioblastomas +glioblastomata +glioma +gliomas +gliomata +glissade +glissaded +glissader +glissaders +glissades +glissading +glissandi +glissando +glissandos +glisten +glistened +glistening +glistens +glister +glistered +glistering +glisters +glitch +glitches +glitchy +glitter +glitterati +glittered +glittering +glitteringly +glitters +glittery +glitz +glitzes +glitzier +glitziest +glitzy +gloam +gloaming +gloamings +gloams +gloat +gloated +gloater +gloaters +gloating +gloatingly +gloats +glob +global +globalise +globalised +globalises +globalising +globalism +globalisms +globalist +globalists +globalization +globalizations +globalize +globalized +globalizes +globalizing +globally +globate +globated +globbier +globbiest +globby +globe +globed +globefish +globefishes +globeflower +globeflowers +globes +globin +globing +globins +globoid +globoids +globose +globous +globs +globular +globule +globules +globulin +globulins +glochid +glochidia +glochidium +glochids +glockenspiel +glockenspiels +glogg +gloggs +glom +glomera +glomerular +glomerule +glomerules +glomeruli +glomerulonephritides +glomerulonephritis +glomerulus +glommed +glomming +gloms +glomus +glonoin +glonoins +gloom +gloomed +gloomful +gloomier +gloomiest +gloomily +gloominess +gloominesses +glooming +gloomings +glooms +gloomy +glop +glopped +glopping +gloppy +glops +gloria +glorias +gloried +glories +glorification +glorifications +glorified +glorifier +glorifiers +glorifies +glorify +glorifying +gloriole +glorioles +glorious +gloriously +gloriousness +gloriousnesses +glory +glorying +gloss +glossa +glossae +glossal +glossarial +glossaries +glossarist +glossarists +glossary +glossas +glossator +glossators +glossed +glosseme +glossemes +glosser +glossers +glosses +glossier +glossies +glossiest +glossily +glossina +glossinas +glossiness +glossinesses +glossing +glossitis +glossitises +glossographer +glossographers +glossolalia +glossolalias +glossolalist +glossolalists +glossopharyngeal +glossopharyngeals +glossy +glost +glosts +glottal +glottic +glottides +glottis +glottises +glottochronological +glottochronologies +glottochronology +glout +glouted +glouting +glouts +glove +gloved +glover +glovers +gloves +gloving +glow +glowed +glower +glowered +glowering +glowers +glowflies +glowfly +glowing +glowingly +glows +glowworm +glowworms +gloxinia +gloxinias +gloze +glozed +glozes +glozing +glucagon +glucagons +glucan +glucans +glucinic +glucinum +glucinums +glucocorticoid +glucocorticoids +glucokinase +glucokinases +gluconate +gluconates +gluconeogeneses +gluconeogenesis +glucosamine +glucosamines +glucose +glucoses +glucosic +glucosidase +glucosidases +glucoside +glucosides +glucosidic +glucuronidase +glucuronidases +glucuronide +glucuronides +glue +glued +glueing +gluelike +gluepot +gluepots +gluer +gluers +glues +gluey +glug +glugged +glugging +glugs +gluier +gluiest +gluily +gluing +glum +glume +glumes +glumly +glummer +glummest +glumness +glumnesses +glumpier +glumpiest +glumpily +glumpy +glunch +glunched +glunches +glunching +gluon +gluons +glut +glutamate +glutamates +glutaminase +glutaminases +glutamine +glutamines +glutaraldehyde +glutaraldehydes +glutathione +glutathiones +gluteal +glutei +glutelin +glutelins +gluten +glutenous +glutens +glutethimide +glutethimides +gluteus +glutinous +glutinously +gluts +glutted +glutting +glutton +gluttonies +gluttonous +gluttonously +gluttonousness +gluttonousnesses +gluttons +gluttony +glycan +glycans +glyceraldehyde +glyceraldehydes +glyceric +glyceride +glycerides +glyceridic +glycerin +glycerinate +glycerinated +glycerinates +glycerinating +glycerine +glycerines +glycerins +glycerol +glycerols +glyceryl +glyceryls +glycin +glycine +glycines +glycins +glycogen +glycogeneses +glycogenesis +glycogenolyses +glycogenolysis +glycogenolytic +glycogens +glycol +glycolic +glycolipid +glycolipids +glycols +glycolyses +glycolysis +glycolytic +glyconic +glyconics +glycopeptide +glycopeptides +glycoprotein +glycoproteins +glycosaminoglycan +glycosaminoglycans +glycosidase +glycosidases +glycoside +glycosides +glycosidic +glycosidically +glycosuria +glycosurias +glycosyl +glycosylate +glycosylated +glycosylates +glycosylating +glycosylation +glycosylations +glycosyls +glycyl +glycyls +glyph +glyphic +glyphs +glyptic +glyptics +gnar +gnarl +gnarled +gnarlier +gnarliest +gnarling +gnarls +gnarly +gnarr +gnarred +gnarring +gnarrs +gnars +gnash +gnashed +gnashes +gnashing +gnat +gnatcatcher +gnatcatchers +gnathal +gnathic +gnathion +gnathions +gnathite +gnathites +gnatlike +gnats +gnattier +gnattiest +gnatty +gnaw +gnawable +gnawed +gnawer +gnawers +gnawing +gnawings +gnawn +gnaws +gneiss +gneisses +gneissic +gneissoid +gneissose +gnocchi +gnome +gnomelike +gnomes +gnomic +gnomical +gnomish +gnomist +gnomists +gnomon +gnomonic +gnomons +gnoses +gnosis +gnostic +gnosticism +gnosticisms +gnotobiotic +gnotobiotically +gnu +gnus +go +goa +goad +goaded +goading +goadlike +goads +goal +goaled +goalie +goalies +goaling +goalkeeper +goalkeepers +goalless +goalmouth +goalmouths +goalpost +goalposts +goals +goaltender +goaltenders +goaltending +goaltendings +goalward +goanna +goannas +goas +goat +goatee +goateed +goatees +goatfish +goatfishes +goatherd +goatherds +goatish +goatlike +goats +goatskin +goatskins +goatsucker +goatsuckers +gob +goban +gobang +gobangs +gobans +gobbed +gobbet +gobbets +gobbing +gobble +gobbled +gobbledegook +gobbledegooks +gobbledygook +gobbledygooks +gobbler +gobblers +gobbles +gobbling +gobies +gobioid +gobioids +goblet +goblets +goblin +goblins +gobo +goboes +gobonee +gobony +gobos +gobs +goby +god +godchild +godchildren +goddam +goddammed +goddamming +goddamn +goddamned +goddamning +goddamns +goddams +goddaughter +goddaughters +godded +goddess +goddesses +godding +godet +godets +godfather +godfathered +godfathering +godfathers +godforsaken +godhead +godheads +godhood +godhoods +godless +godlessness +godlessnesses +godlier +godliest +godlike +godlikeness +godlikenesses +godlily +godliness +godlinesses +godling +godlings +godly +godmother +godmothers +godown +godowns +godparent +godparents +godroon +godroons +gods +godsend +godsends +godship +godships +godson +godsons +godwit +godwits +goer +goers +goes +goethite +goethites +gofer +gofers +goffer +goffered +goffering +goffers +goggle +goggled +goggler +gogglers +goggles +gogglier +goggliest +goggling +goggly +goglet +goglets +gogo +gogos +going +goings +goiter +goiters +goitre +goitres +goitrogen +goitrogenic +goitrogenicities +goitrogenicity +goitrogens +goitrous +golconda +golcondas +gold +goldarn +goldarns +goldbrick +goldbricked +goldbricking +goldbricks +goldbug +goldbugs +golden +goldener +goldenest +goldeneye +goldeneyes +goldenly +goldenness +goldennesses +goldenrod +goldenrods +goldenseal +goldenseals +golder +goldest +goldeye +goldeyes +goldfield +goldfields +goldfinch +goldfinches +goldfish +goldfishes +golds +goldsmith +goldsmiths +goldstone +goldstones +goldurn +goldurns +golem +golems +golf +golfed +golfer +golfers +golfing +golfings +golfs +golgotha +golgothas +goliard +goliardic +goliards +golliwog +golliwogg +golliwoggs +golliwogs +golly +gollywog +gollywogs +golosh +goloshe +goloshes +gombo +gombos +gombroon +gombroons +gomeral +gomerals +gomerel +gomerels +gomeril +gomerils +gomuti +gomutis +gonad +gonadal +gonadectomies +gonadectomized +gonadectomy +gonadial +gonadic +gonadotrophic +gonadotrophin +gonadotrophins +gonadotropic +gonadotropin +gonadotropins +gonads +gondola +gondolas +gondolier +gondoliers +gone +gonef +gonefs +goneness +gonenesses +goner +goners +gonfalon +gonfalons +gonfanon +gonfanons +gong +gonged +gonging +gonglike +gongoristic +gongs +gonia +gonidia +gonidial +gonidic +gonidium +gonif +goniff +goniffs +gonifs +goniometer +goniometers +goniometric +goniometries +goniometry +gonion +gonium +gonococcal +gonococci +gonococcus +gonocyte +gonocytes +gonof +gonofs +gonoph +gonophore +gonophores +gonophs +gonopore +gonopores +gonorrhea +gonorrheal +gonorrheas +gonzo +goo +goober +goobers +good +goodby +goodbye +goodbyes +goodbys +goodie +goodies +goodish +goodlier +goodliest +goodly +goodman +goodmen +goodness +goodnesses +goods +goodwife +goodwill +goodwilled +goodwills +goodwives +goody +gooey +gooeyness +gooeynesses +goof +goofball +goofballs +goofed +goofier +goofiest +goofily +goofiness +goofinesses +goofing +goofs +goofy +googlies +googly +googol +googolplex +googolplexes +googols +gooier +gooiest +gook +gooks +gooky +goombah +goombahs +goombay +goombays +goon +gooney +gooneys +goonie +goonies +goons +goony +goop +goopier +goopiest +goops +goopy +gooral +goorals +goos +goosander +goosanders +goose +gooseberries +gooseberry +goosed +goosefish +goosefishes +gooseflesh +goosefleshes +goosefoot +goosefoots +goosegrass +goosegrasses +gooseneck +goosenecked +goosenecks +gooses +goosey +goosier +goosiest +goosing +goosy +gopher +gophers +gor +goral +gorals +gorbellies +gorbelly +gorblimy +gorcock +gorcocks +gore +gored +gores +gorge +gorged +gorgedly +gorgeous +gorgeously +gorgeousness +gorgeousnesses +gorger +gorgerin +gorgerins +gorgers +gorges +gorget +gorgeted +gorgets +gorging +gorgon +gorgonian +gorgonians +gorgonize +gorgonized +gorgonizes +gorgonizing +gorgons +gorhen +gorhens +gorier +goriest +gorilla +gorillas +gorily +goriness +gorinesses +goring +gormand +gormandise +gormandised +gormandises +gormandising +gormandize +gormandized +gormandizer +gormandizers +gormandizes +gormandizing +gormands +gormless +gorp +gorps +gorse +gorses +gorsier +gorsiest +gorsy +gory +gosh +goshawk +goshawks +gosling +goslings +gospel +gospeler +gospelers +gospeller +gospellers +gospels +gosport +gosports +gossamer +gossamers +gossamery +gossan +gossans +gossip +gossiped +gossiper +gossipers +gossiping +gossipmonger +gossipmongers +gossipped +gossipping +gossipries +gossipry +gossips +gossipy +gossoon +gossoons +gossypol +gossypols +got +gothic +gothically +gothicize +gothicized +gothicizes +gothicizing +gothics +gothite +gothites +gotten +gouache +gouaches +gouge +gouged +gouger +gougers +gouges +gouging +goulash +goulashes +gourami +gouramies +gouramis +gourd +gourde +gourdes +gourds +gourmand +gourmandise +gourmandises +gourmandism +gourmandisms +gourmandize +gourmandized +gourmandizes +gourmandizing +gourmands +gourmet +gourmets +gout +goutier +goutiest +goutily +gouts +gouty +govern +governable +governance +governances +governed +governess +governesses +governessy +governing +government +governmental +governmentalism +governmentalisms +governmentalist +governmentalists +governmentalize +governmentalized +governmentalizes +governmentalizing +governmentally +governmentese +governmenteses +governments +governor +governorate +governorates +governors +governorship +governorships +governs +gowan +gowaned +gowans +gowany +gowd +gowds +gowk +gowks +gown +gowned +gowning +gowns +gownsman +gownsmen +gox +goxes +goy +goyim +goyish +goys +graal +graals +grab +grabbed +grabber +grabbers +grabbier +grabbiest +grabbing +grabble +grabbled +grabbler +grabblers +grabbles +grabbling +grabby +graben +grabens +grabs +grace +graced +graceful +gracefuller +gracefullest +gracefully +gracefulness +gracefulnesses +graceless +gracelessly +gracelessness +gracelessnesses +graces +gracile +gracileness +gracilenesses +graciles +gracilis +gracilities +gracility +gracing +gracioso +graciosos +gracious +graciously +graciousness +graciousnesses +grackle +grackles +grad +gradable +gradate +gradated +gradates +gradating +gradation +gradational +gradationally +gradations +grade +graded +gradeless +grader +graders +grades +gradient +gradients +gradin +gradine +gradines +grading +gradins +gradiometer +gradiometers +grads +gradual +gradualism +gradualisms +gradualist +gradualists +gradually +gradualness +gradualnesses +graduals +graduand +graduands +graduate +graduated +graduates +graduating +graduation +graduations +graduator +graduators +gradus +graduses +graecize +graecized +graecizes +graecizing +graffiti +graffitist +graffitists +graffito +graft +graftage +graftages +grafted +grafter +grafters +grafting +grafts +graham +grahams +grail +grails +grain +grained +grainer +grainers +grainfield +grainfields +grainier +grainiest +graininess +graininesses +graining +grains +grainy +gram +grama +gramaries +gramary +gramarye +gramaryes +gramas +gramercies +gramercy +gramicidin +gramicidins +gramineous +graminivorous +grammar +grammarian +grammarians +grammars +grammatical +grammaticalities +grammaticality +grammatically +grammaticalness +grammaticalnesses +gramme +grammes +gramophone +gramophones +gramp +gramps +grampus +grampuses +grams +gran +grana +granadilla +granadillas +granaries +granary +grand +grandad +grandaddies +grandaddy +grandads +grandam +grandame +grandames +grandams +grandaunt +grandaunts +grandbabies +grandbaby +grandchild +grandchildren +granddad +granddaddies +granddaddy +granddads +granddam +granddams +granddaughter +granddaughters +grandee +grandees +grander +grandest +grandeur +grandeurs +grandfather +grandfathered +grandfathering +grandfatherly +grandfathers +grandiflora +grandiflorae +grandifloras +grandiloquence +grandiloquences +grandiloquent +grandiloquently +grandiose +grandiosely +grandioseness +grandiosenesses +grandiosities +grandiosity +grandioso +grandkid +grandkids +grandly +grandma +grandmas +grandmaster +grandmasters +grandmother +grandmotherly +grandmothers +grandnephew +grandnephews +grandness +grandnesses +grandniece +grandnieces +grandpa +grandparent +grandparental +grandparenthood +grandparenthoods +grandparents +grandpas +grands +grandsir +grandsire +grandsires +grandsirs +grandson +grandsons +grandstand +grandstanded +grandstander +grandstanders +grandstanding +grandstands +granduncle +granduncles +grange +granger +grangerism +grangerisms +grangers +granges +granita +granitas +granite +granitelike +granites +graniteware +granitewares +granitic +granitoid +granivorous +grannie +grannies +granny +granodiorite +granodiorites +granodioritic +granola +granolas +granolithic +granophyre +granophyres +granophyric +grans +grant +grantable +granted +grantee +grantees +granter +granters +granting +grantor +grantors +grants +grantsman +grantsmanship +grantsmanships +grantsmen +granular +granularities +granularity +granulate +granulated +granulates +granulating +granulation +granulations +granulator +granulators +granule +granules +granulite +granulites +granulitic +granulocyte +granulocytes +granulocytic +granulocytopoieses +granulocytopoiesis +granuloma +granulomas +granulomata +granulomatous +granulose +granuloses +granulosis +granum +grape +grapefruit +grapefruits +grapelike +graperies +grapery +grapes +grapeshot +grapevine +grapevines +grapey +graph +graphed +grapheme +graphemes +graphemic +graphemically +graphemics +graphic +graphical +graphically +graphicness +graphicnesses +graphics +graphing +graphite +graphites +graphitic +graphitizable +graphitization +graphitizations +graphitize +graphitized +graphitizes +graphitizing +grapholect +grapholects +graphological +graphologies +graphologist +graphologists +graphology +graphs +grapier +grapiest +grapiness +grapinesses +graplin +grapline +graplines +graplins +grapnel +grapnels +grappa +grappas +grapple +grappled +grappler +grapplers +grapples +grappling +grapplings +graptolite +graptolites +grapy +grasp +graspable +grasped +grasper +graspers +grasping +graspingly +graspingness +graspingnesses +grasps +grass +grassed +grasses +grasshopper +grasshoppers +grassier +grassiest +grassily +grassing +grassland +grasslands +grassless +grasslike +grassroot +grassroots +grassy +grat +grate +grated +grateful +gratefuller +gratefullest +gratefully +gratefulness +gratefulnesses +grater +graters +grates +graticule +graticules +gratification +gratifications +gratified +gratifies +gratify +gratifying +gratifyingly +gratin +gratine +gratinee +gratineed +gratineeing +gratinees +grating +gratingly +gratings +gratins +gratis +gratitude +gratitudes +gratuities +gratuitous +gratuitously +gratuitousness +gratuitousnesses +gratuity +gratulate +gratulated +gratulates +gratulating +gratulation +gratulations +gratulatory +graupel +graupels +gravamen +gravamens +gravamina +grave +graved +gravel +graveled +graveless +graveling +gravelled +gravelling +gravelly +gravels +gravely +graven +graveness +gravenesses +graver +gravers +graves +graveside +gravesides +gravest +gravestone +gravestones +graveyard +graveyards +gravid +gravida +gravidae +gravidas +gravidities +gravidity +gravidly +gravies +gravimeter +gravimeters +gravimetric +gravimetrically +gravimetries +gravimetry +graving +gravitas +gravitases +gravitate +gravitated +gravitates +gravitating +gravitation +gravitational +gravitationally +gravitations +gravitative +gravities +graviton +gravitons +gravity +gravlaks +gravlax +gravure +gravures +gravy +gray +grayback +graybacks +graybeard +graybeards +grayed +grayer +grayest +grayfish +grayfishes +graying +grayish +graylag +graylags +grayling +graylings +grayly +graymail +graymails +grayness +graynesses +grayout +grayouts +grays +graywacke +graywackes +grazable +graze +grazeable +grazed +grazer +grazers +grazes +grazier +graziers +grazing +grazings +grazioso +grease +greaseball +greaseballs +greased +greaseless +greasepaint +greasepaints +greaseproof +greaseproofs +greaser +greasers +greases +greasewood +greasewoods +greasier +greasiest +greasily +greasiness +greasinesses +greasing +greasy +great +greatcoat +greatcoats +greaten +greatened +greatening +greatens +greater +greatest +greathearted +greatheartedly +greatheartedness +greatheartednesses +greatly +greatness +greatnesses +greats +greave +greaved +greaves +grebe +grebes +grecianize +grecianized +grecianizes +grecianizing +grecize +grecized +grecizes +grecizing +gree +greed +greedier +greediest +greedily +greediness +greedinesses +greeds +greedy +greegree +greegrees +greeing +greek +green +greenback +greenbacker +greenbackers +greenbackism +greenbackisms +greenbacks +greenbelt +greenbelts +greenbrier +greenbriers +greenbug +greenbugs +greened +greener +greeneries +greenery +greenest +greenfinch +greenfinches +greenflies +greenfly +greengage +greengages +greengrocer +greengroceries +greengrocers +greengrocery +greenhead +greenheads +greenheart +greenhearts +greenhorn +greenhorns +greenhouse +greenhouses +greenie +greenier +greenies +greeniest +greening +greenings +greenish +greenishness +greenishnesses +greenkeeper +greenkeepers +greenlet +greenlets +greenling +greenlings +greenly +greenmail +greenmailed +greenmailer +greenmailers +greenmailing +greenmails +greenness +greennesses +greenockite +greenockites +greenroom +greenrooms +greens +greensand +greensands +greenshank +greenshanks +greensick +greensickness +greensicknesses +greenskeeper +greenskeepers +greenstone +greenstones +greenstuff +greenstuffs +greensward +greenswards +greenth +greenths +greenway +greenways +greenwing +greenwings +greenwood +greenwoods +greeny +grees +greet +greeted +greeter +greeters +greeting +greetings +greets +gregarine +gregarines +gregarious +gregariously +gregariousness +gregariousnesses +grego +gregos +greige +greiges +greisen +greisens +gremial +gremials +gremlin +gremlins +gremmie +gremmies +gremmy +grenade +grenades +grenadier +grenadiers +grenadine +grenadines +grew +grewsome +grewsomer +grewsomest +grey +greyed +greyer +greyest +greyhen +greyhens +greyhound +greyhounds +greying +greyish +greylag +greylags +greyly +greyness +greynesses +greys +gribble +gribbles +grid +gridder +gridders +griddle +griddlecake +griddlecakes +griddled +griddles +griddling +gride +grided +grides +griding +gridiron +gridirons +gridlock +gridlocked +gridlocking +gridlocks +grids +grief +griefs +grievance +grievances +grievant +grievants +grieve +grieved +griever +grievers +grieves +grieving +grievous +grievously +grievousness +grievousnesses +griff +griffe +griffes +griffin +griffins +griffon +griffons +griffs +grift +grifted +grifter +grifters +grifting +grifts +grig +grigri +grigris +grigs +grill +grillade +grillades +grillage +grillages +grille +grilled +griller +grillers +grilles +grilling +grillroom +grillrooms +grills +grillwork +grillworks +grilse +grilses +grim +grimace +grimaced +grimacer +grimacers +grimaces +grimacing +grimalkin +grimalkins +grime +grimed +grimes +grimier +grimiest +grimily +griminess +griminesses +griming +grimly +grimmer +grimmest +grimness +grimnesses +grimy +grin +grinch +grinches +grind +grinded +grinder +grinderies +grinders +grindery +grinding +grindingly +grinds +grindstone +grindstones +gringo +gringos +grinned +grinner +grinners +grinning +grinningly +grins +griot +griots +grip +gripe +griped +griper +gripers +gripes +gripey +gripier +gripiest +griping +gripman +gripmen +grippe +gripped +gripper +grippers +grippes +grippier +grippiest +gripping +grippingly +gripple +grippy +grips +gripsack +gripsacks +gript +gripy +grisaille +grisailles +griseofulvin +griseofulvins +griseous +grisette +grisettes +griskin +griskins +grislier +grisliest +grisliness +grislinesses +grisly +grison +grisons +grist +gristle +gristles +gristlier +gristliest +gristliness +gristlinesses +gristly +gristmill +gristmills +grists +grit +grith +griths +grits +gritted +grittier +grittiest +grittily +grittiness +grittinesses +gritting +gritty +grivet +grivets +grizzle +grizzled +grizzler +grizzlers +grizzles +grizzlier +grizzlies +grizzliest +grizzling +grizzly +groan +groaned +groaner +groaners +groaning +groans +groat +groats +grocer +groceries +grocers +grocery +grog +groggeries +groggery +groggier +groggiest +groggily +grogginess +grogginesses +groggy +grogram +grograms +grogs +grogshop +grogshops +groin +groined +groining +groins +grommet +grommets +gromwell +gromwells +groom +groomed +groomer +groomers +grooming +grooms +groomsman +groomsmen +groove +grooved +groover +groovers +grooves +groovier +grooviest +grooving +groovy +grope +groped +groper +gropers +gropes +groping +grosbeak +grosbeaks +groschen +grosgrain +grosgrains +gross +grossed +grosser +grossers +grosses +grossest +grossing +grossly +grossness +grossnesses +grossular +grossularite +grossularites +grossulars +grosz +grosze +groszy +grot +grotesque +grotesquely +grotesqueness +grotesquenesses +grotesquerie +grotesqueries +grotesquery +grotesques +grots +grottier +grottiest +grotto +grottoes +grottos +grotty +grouch +grouched +grouches +grouchier +grouchiest +grouchily +grouchiness +grouchinesses +grouching +grouchy +ground +groundbreaker +groundbreakers +groundbreaking +groundburst +groundbursts +grounded +grounder +grounders +groundfish +groundfishes +groundhog +groundhogs +grounding +groundings +groundless +groundlessly +groundlessness +groundlessnesses +groundling +groundlings +groundmass +groundmasses +groundnut +groundnuts +groundout +groundouts +grounds +groundsel +groundsels +groundsheet +groundsheets +groundskeeper +groundskeepers +groundsman +groundsmen +groundswell +groundswells +groundwater +groundwaters +groundwood +groundwoods +groundwork +groundworks +group +groupable +grouped +grouper +groupers +groupie +groupies +grouping +groupings +groupoid +groupoids +groups +groupthink +groupthinks +groupuscule +groupuscules +grouse +groused +grouser +grousers +grouses +grousing +grout +grouted +grouter +grouters +groutier +groutiest +grouting +grouts +grouty +grove +groved +grovel +groveled +groveler +grovelers +groveling +grovelingly +grovelled +grovelling +grovels +groves +grow +growable +grower +growers +growing +growingly +growl +growled +growler +growlers +growlier +growliest +growliness +growlinesses +growling +growlingly +growls +growly +grown +grownup +grownups +grows +growth +growthier +growthiest +growthiness +growthinesses +growths +growthy +groyne +groynes +grub +grubbed +grubber +grubbers +grubbier +grubbiest +grubbily +grubbiness +grubbinesses +grubbing +grubby +grubs +grubstake +grubstaked +grubstaker +grubstakers +grubstakes +grubstaking +grubworm +grubworms +grudge +grudged +grudger +grudgers +grudges +grudging +grudgingly +grue +gruel +grueled +grueler +gruelers +grueling +gruelingly +gruelings +gruelled +grueller +gruellers +gruelling +gruellings +gruels +grues +gruesome +gruesomely +gruesomeness +gruesomenesses +gruesomer +gruesomest +gruff +gruffed +gruffer +gruffest +gruffier +gruffiest +gruffily +gruffing +gruffish +gruffly +gruffness +gruffnesses +gruffs +gruffy +grugru +grugrus +gruiform +grum +grumble +grumbled +grumbler +grumblers +grumbles +grumbling +grumblingly +grumbly +grume +grumes +grummer +grummest +grummet +grummets +grumose +grumous +grump +grumped +grumphie +grumphies +grumphy +grumpier +grumpiest +grumpily +grumpiness +grumpinesses +grumping +grumpish +grumps +grumpy +grunge +grunges +grungier +grungiest +grungy +grunion +grunions +grunt +grunted +grunter +grunters +grunting +gruntle +gruntled +gruntles +gruntling +grunts +grushie +grutch +grutched +grutches +grutching +grutten +gruyere +gruyeres +gryphon +gryphons +guacamole +guacamoles +guacharo +guacharoes +guacharos +guaco +guacos +guaiac +guaiacol +guaiacols +guaiacs +guaiacum +guaiacums +guaiocum +guaiocums +guan +guanaco +guanacos +guanase +guanases +guanay +guanays +guanethidine +guanethidines +guanidin +guanidine +guanidines +guanidins +guanin +guanine +guanines +guanins +guano +guanos +guanosine +guanosines +guans +guar +guarani +guaranies +guaranis +guarantee +guaranteed +guaranteeing +guarantees +guarantied +guaranties +guarantor +guarantors +guaranty +guarantying +guard +guardant +guardants +guarded +guardedly +guardedness +guardednesses +guarder +guarders +guardhouse +guardhouses +guardian +guardians +guardianship +guardianships +guarding +guardrail +guardrails +guardroom +guardrooms +guards +guardsman +guardsmen +guars +guava +guavas +guayabera +guayaberas +guayule +guayules +gubernatorial +guck +gucks +gude +gudes +gudgeon +gudgeoned +gudgeoning +gudgeons +guenon +guenons +guerdon +guerdoned +guerdoning +guerdons +gueridon +gueridons +guerilla +guerillas +guernsey +guernseys +guerrilla +guerrillas +guess +guessable +guessed +guesser +guessers +guesses +guessing +guesstimate +guesstimated +guesstimates +guesstimating +guesswork +guessworks +guest +guested +guesthouse +guesthouses +guesting +guests +guff +guffaw +guffawed +guffawing +guffaws +guffs +guggle +guggled +guggles +guggling +guglet +guglets +guid +guidable +guidance +guidances +guide +guidebook +guidebooks +guided +guideline +guidelines +guidepost +guideposts +guider +guiders +guides +guideway +guideways +guiding +guidon +guidons +guids +guidwillie +guild +guilder +guilders +guildhall +guildhalls +guilds +guildship +guildships +guildsman +guildsmen +guile +guiled +guileful +guilefully +guilefulness +guilefulnesses +guileless +guilelessly +guilelessness +guilelessnesses +guiles +guiling +guillemet +guillemets +guillemot +guillemots +guilloche +guilloches +guillotine +guillotined +guillotines +guillotining +guilt +guiltier +guiltiest +guiltily +guiltiness +guiltinesses +guiltless +guiltlessly +guiltlessness +guiltlessnesses +guilts +guilty +guimpe +guimpes +guinea +guineas +guipure +guipures +guiro +guiros +guisard +guisards +guise +guised +guises +guising +guitar +guitarfish +guitarfishes +guitarist +guitarists +guitars +guitguit +guitguits +gul +gulag +gulags +gular +gulch +gulches +gulden +guldens +gules +gulf +gulfed +gulfier +gulfiest +gulfing +gulflike +gulfs +gulfweed +gulfweeds +gulfy +gull +gullable +gullably +gulled +gullet +gullets +gulley +gulleys +gullibilities +gullibility +gullible +gullibly +gullied +gullies +gulling +gulls +gully +gullying +gulosities +gulosity +gulp +gulped +gulper +gulpers +gulpier +gulpiest +gulping +gulps +gulpy +guls +gum +gumbo +gumboil +gumboils +gumboot +gumboots +gumbos +gumbotil +gumbotils +gumdrop +gumdrops +gumless +gumlike +gumma +gummas +gummata +gummatous +gummed +gummer +gummers +gummier +gummiest +gumminess +gumminesses +gumming +gummite +gummites +gummose +gummoses +gummosis +gummous +gummy +gumption +gumptions +gums +gumshoe +gumshoed +gumshoeing +gumshoes +gumtree +gumtrees +gumweed +gumweeds +gumwood +gumwoods +gun +gunboat +gunboats +guncotton +guncottons +gundog +gundogs +gunfight +gunfighter +gunfighters +gunfighting +gunfights +gunfire +gunfires +gunflint +gunflints +gunfought +gunite +gunites +gunk +gunkhole +gunkholed +gunkholes +gunkholing +gunks +gunky +gunless +gunlock +gunlocks +gunman +gunmen +gunmetal +gunmetals +gunned +gunnel +gunnels +gunnen +gunner +gunneries +gunners +gunnery +gunnies +gunning +gunnings +gunny +gunnybag +gunnybags +gunnysack +gunnysacks +gunpaper +gunpapers +gunplay +gunplays +gunpoint +gunpoints +gunpowder +gunpowders +gunroom +gunrooms +gunrunner +gunrunners +gunrunning +gunrunnings +guns +gunsel +gunsels +gunship +gunships +gunshot +gunshots +gunslinger +gunslingers +gunslinging +gunslingings +gunsmith +gunsmithing +gunsmithings +gunsmiths +gunstock +gunstocks +gunwale +gunwales +guppies +guppy +gurge +gurged +gurges +gurging +gurgle +gurgled +gurgles +gurglet +gurglets +gurgling +gurnard +gurnards +gurnet +gurnets +gurney +gurneys +gurries +gurry +gursh +gurshes +guru +gurus +guruship +guruships +gush +gushed +gusher +gushers +gushes +gushier +gushiest +gushily +gushiness +gushinesses +gushing +gushingly +gushy +gusset +gusseted +gusseting +gussets +gussie +gussied +gussies +gussy +gussying +gust +gustable +gustables +gustation +gustations +gustatorily +gustatory +gusted +gustier +gustiest +gustily +gustiness +gustinesses +gusting +gustless +gusto +gustoes +gusts +gusty +gut +gutbucket +gutbuckets +gutless +gutlessness +gutlessnesses +gutlike +guts +gutsier +gutsiest +gutsily +gutsiness +gutsinesses +gutsy +gutta +guttae +guttate +guttated +guttation +guttations +gutted +gutter +guttered +guttering +gutterings +gutters +guttersnipe +guttersnipes +guttersnipish +guttery +guttier +guttiest +gutting +guttle +guttled +guttler +guttlers +guttles +guttling +guttural +gutturalism +gutturalisms +gutturals +gutty +guv +guvs +guy +guyed +guying +guyline +guylines +guyot +guyots +guys +guzzle +guzzled +guzzler +guzzlers +guzzles +guzzling +gweduc +gweduck +gweducks +gweducs +gybe +gybed +gybes +gybing +gym +gymkhana +gymkhanas +gymnasia +gymnasium +gymnasiums +gymnast +gymnastic +gymnastically +gymnastics +gymnasts +gymnosophist +gymnosophists +gymnosperm +gymnospermies +gymnospermous +gymnosperms +gymnospermy +gyms +gynaecea +gynaeceum +gynaecia +gynaecium +gynaecologies +gynaecology +gynandries +gynandromorph +gynandromorphic +gynandromorphies +gynandromorphism +gynandromorphisms +gynandromorphs +gynandromorphy +gynandrous +gynandry +gynarchies +gynarchy +gynecia +gynecic +gynecium +gynecocracies +gynecocracy +gynecocratic +gynecoid +gynecologic +gynecological +gynecologies +gynecologist +gynecologists +gynecology +gynecomastia +gynecomastias +gyniatries +gyniatry +gynoecia +gynoecium +gynogeneses +gynogenesis +gynogenetic +gynophore +gynophores +gyp +gyplure +gyplures +gypped +gypper +gyppers +gypping +gyps +gypseian +gypseous +gypsied +gypsies +gypsiferous +gypsophila +gypsophilas +gypster +gypsters +gypsum +gypsums +gypsy +gypsydom +gypsydoms +gypsying +gypsyish +gypsyism +gypsyisms +gyral +gyrally +gyrase +gyrases +gyrate +gyrated +gyrates +gyrating +gyration +gyrational +gyrations +gyrator +gyrators +gyratory +gyre +gyred +gyrene +gyrenes +gyres +gyrfalcon +gyrfalcons +gyri +gyring +gyro +gyrocompass +gyrocompasses +gyrofrequencies +gyrofrequency +gyroidal +gyromagnetic +gyron +gyrons +gyroplane +gyroplanes +gyros +gyroscope +gyroscopes +gyroscopic +gyroscopically +gyrose +gyrostabilizer +gyrostabilizers +gyrostat +gyrostats +gyrus +gyve +gyved +gyves +gyving +ha +haaf +haafs +haar +haars +habanera +habaneras +habdalah +habdalahs +haberdasher +haberdasheries +haberdashers +haberdashery +habergeon +habergeons +habile +habiliment +habiliments +habilitate +habilitated +habilitates +habilitating +habilitation +habilitations +habit +habitabilities +habitability +habitable +habitableness +habitablenesses +habitably +habitan +habitans +habitant +habitants +habitat +habitation +habitations +habitats +habited +habiting +habits +habitual +habitually +habitualness +habitualnesses +habituate +habituated +habituates +habituating +habituation +habituations +habitude +habitudes +habitue +habitues +habitus +haboob +haboobs +habu +habus +hacek +haceks +hacendado +hacendados +hachure +hachured +hachures +hachuring +hacienda +haciendado +haciendados +haciendas +hack +hackamore +hackamores +hackberries +hackberry +hackbut +hackbuts +hacked +hackee +hackees +hacker +hackers +hackie +hackies +hacking +hackle +hackled +hackler +hacklers +hackles +hacklier +hackliest +hackling +hackly +hackman +hackmatack +hackmatacks +hackmen +hackney +hackneyed +hackneying +hackneys +hacks +hacksaw +hacksaws +hackwork +hackworks +had +hadal +hadarim +haddest +haddock +haddocks +hade +haded +hades +hading +hadith +hadiths +hadj +hadjee +hadjees +hadjes +hadji +hadjis +hadron +hadronic +hadrons +hadrosaur +hadrosaurs +hadst +hae +haecceities +haecceity +haed +haeing +haem +haemal +haematal +haematic +haematics +haematin +haematins +haematite +haematites +haemic +haemin +haemins +haemoid +haems +haen +haeredes +haeres +haes +haet +haets +haffet +haffets +haffit +haffits +hafis +hafiz +hafnium +hafniums +haft +haftara +haftarah +haftarahs +haftaras +haftarot +haftaroth +hafted +hafter +hafters +hafting +haftorah +haftorahs +haftorot +haftoroth +hafts +hag +hagadic +hagadist +hagadists +hagberries +hagberry +hagborn +hagbush +hagbushes +hagbut +hagbuts +hagdon +hagdons +hagfish +hagfishes +haggada +haggadah +haggadahs +haggadas +haggadic +haggadist +haggadistic +haggadists +haggadot +haggadoth +haggard +haggardly +haggardness +haggardnesses +haggards +hagged +hagging +haggis +haggises +haggish +haggle +haggled +haggler +hagglers +haggles +haggling +hagiographer +hagiographers +hagiographic +hagiographical +hagiographies +hagiography +hagiologic +hagiological +hagiologies +hagiology +hagioscope +hagioscopes +hagioscopic +hagridden +hagride +hagrides +hagriding +hagrode +hags +hah +haha +hahas +hahnium +hahniums +hahs +haik +haika +haiks +haiku +hail +hailed +hailer +hailers +hailing +hails +hailstone +hailstones +hailstorm +hailstorms +hair +hairball +hairballs +hairband +hairbands +hairbreadth +hairbreadths +hairbrush +hairbrushes +haircap +haircaps +haircloth +haircloths +haircut +haircuts +haircutter +haircutters +haircutting +haircuttings +hairdo +hairdos +hairdresser +hairdressers +hairdressing +hairdressings +haired +hairier +hairiest +hairiness +hairinesses +hairless +hairlessness +hairlessnesses +hairlike +hairline +hairlines +hairlock +hairlocks +hairnet +hairnets +hairpiece +hairpieces +hairpin +hairpins +hairs +hairsbreadth +hairsbreadths +hairsplitter +hairsplitters +hairsplitting +hairsplittings +hairspring +hairsprings +hairstreak +hairstreaks +hairstyle +hairstyles +hairstyling +hairstylings +hairstylist +hairstylists +hairwork +hairworks +hairworm +hairworms +hairy +haj +hajes +haji +hajis +hajj +hajjes +hajji +hajjis +hake +hakeem +hakeems +hakes +hakim +hakims +halacha +halachas +halachot +halachoth +halakah +halakahs +halakha +halakhas +halakhot +halakic +halakist +halakists +halakoth +halala +halalah +halalahs +halalas +halation +halations +halavah +halavahs +halazone +halazones +halberd +halberds +halbert +halberts +halcyon +halcyons +hale +haled +haleness +halenesses +haler +halers +haleru +hales +halest +half +halfback +halfbacks +halfbeak +halfbeaks +halfhearted +halfheartedly +halfheartedness +halfheartednesses +halflife +halflives +halfness +halfnesses +halfpence +halfpennies +halfpenny +halftime +halftimes +halftone +halftones +halfway +halibut +halibuts +halid +halide +halides +halidom +halidome +halidomes +halidoms +halids +haling +halite +halites +halitoses +halitosis +halitus +halituses +hall +hallah +hallahs +hallel +hallels +hallelujah +hallelujahs +halliard +halliards +hallmark +hallmarked +hallmarking +hallmarks +hallo +halloa +halloaed +halloaing +halloas +halloed +halloes +halloing +halloo +hallooed +hallooing +halloos +hallos +hallot +halloth +hallow +hallowed +hallower +hallowers +hallowing +hallows +halls +halluces +hallucinate +hallucinated +hallucinates +hallucinating +hallucination +hallucinations +hallucinator +hallucinators +hallucinatory +hallucinogen +hallucinogenic +hallucinogenics +hallucinogens +hallucinoses +hallucinosis +hallucinosises +hallux +hallway +hallways +halm +halma +halmas +halms +halo +halocarbon +halocarbons +halocline +haloclines +haloed +haloes +halogen +halogenate +halogenated +halogenates +halogenating +halogenation +halogenations +halogenous +halogens +halogeton +halogetons +haloid +haloids +haloing +halolike +halomorphic +haloperidol +haloperidols +halophile +halophiles +halophilic +halophyte +halophytes +halophytic +halos +halothane +halothanes +halt +halted +halter +halterbreak +halterbreaking +halterbreaks +halterbroke +halterbroken +haltere +haltered +halteres +haltering +halters +halting +haltingly +haltless +halts +halutz +halutzim +halva +halvah +halvahs +halvas +halve +halved +halvers +halves +halving +halyard +halyards +ham +hamada +hamadas +hamadryad +hamadryades +hamadryads +hamal +hamals +hamantasch +hamantaschen +hamartia +hamartias +hamate +hamates +hamaul +hamauls +hambone +hamboned +hambones +hamboning +hamburg +hamburger +hamburgers +hamburgs +hame +hames +hamlet +hamlets +hammada +hammadas +hammal +hammals +hammed +hammer +hammered +hammerer +hammerers +hammerhead +hammerheads +hammering +hammerless +hammerlock +hammerlocks +hammers +hammertoe +hammertoes +hammier +hammiest +hammily +hamminess +hamminesses +hamming +hammock +hammocks +hammy +hamper +hampered +hamperer +hamperers +hampering +hampers +hams +hamster +hamsters +hamstring +hamstringing +hamstrings +hamstrung +hamular +hamulate +hamuli +hamulose +hamulous +hamulus +hamza +hamzah +hamzahs +hamzas +hanaper +hanapers +hance +hances +hand +handbag +handbags +handball +handballs +handbarrow +handbarrows +handbasket +handbaskets +handbell +handbells +handbill +handbills +handblown +handbook +handbooks +handbreadth +handbreadths +handcar +handcars +handcart +handcarts +handclasp +handclasps +handcraft +handcrafted +handcrafting +handcrafts +handcraftsman +handcraftsmanship +handcraftsmanships +handcraftsmen +handcuff +handcuffed +handcuffing +handcuffs +handed +handedness +handednesses +handfast +handfasted +handfasting +handfastings +handfasts +handful +handfuls +handgrip +handgrips +handgun +handguns +handheld +handhelds +handhold +handholding +handholdings +handholds +handicap +handicapped +handicapper +handicappers +handicapping +handicaps +handicraft +handicrafter +handicrafters +handicrafts +handicraftsman +handicraftsmen +handier +handiest +handily +handiness +handinesses +handing +handiwork +handiworks +handkerchief +handkerchiefs +handkerchieves +handle +handleable +handlebar +handlebars +handled +handleless +handler +handlers +handles +handless +handlike +handling +handlings +handlist +handlists +handloom +handlooms +handmade +handmaid +handmaiden +handmaidens +handmaids +handoff +handoffs +handout +handouts +handover +handovers +handpick +handpicked +handpicking +handpicks +handpress +handpresses +handprint +handprints +handrail +handrailing +handrailings +handrails +hands +handsaw +handsaws +handsbreadth +handsbreadths +handsel +handseled +handseling +handselled +handselling +handsels +handset +handsets +handsewn +handsful +handshake +handshakes +handsome +handsomely +handsomeness +handsomenesses +handsomer +handsomest +handspike +handspikes +handspring +handsprings +handstand +handstands +handwheel +handwheels +handwork +handworker +handworkers +handworks +handwoven +handwringer +handwringers +handwringing +handwringings +handwrit +handwrite +handwrites +handwriting +handwritings +handwritten +handwrote +handwrought +handy +handyman +handymen +handyperson +handypersons +hang +hangable +hangar +hangared +hangaring +hangars +hangbird +hangbirds +hangdog +hangdogs +hanged +hanger +hangers +hangfire +hangfires +hanging +hangings +hangman +hangmen +hangnail +hangnails +hangnest +hangnests +hangout +hangouts +hangover +hangovers +hangs +hangtag +hangtags +hangul +hangup +hangups +haniwa +hank +hanked +hanker +hankered +hankerer +hankerers +hankering +hankers +hankie +hankies +hanking +hanks +hanky +hansa +hansas +hanse +hansel +hanseled +hanseling +hanselled +hanselling +hansels +hanses +hansom +hansoms +hant +hanted +hanting +hantle +hantles +hants +hanuman +hanumans +hao +haole +haoles +hap +hapax +hapaxes +haphazard +haphazardly +haphazardness +haphazardnesses +haphazardries +haphazardry +haphazards +haphtara +haphtaras +haphtarot +haphtaroth +hapless +haplessly +haplessness +haplessnesses +haplite +haplites +haploid +haploidies +haploids +haploidy +haplologies +haplology +haplont +haplontic +haplonts +haplopia +haplopias +haploses +haplosis +haplotype +haplotypes +haply +happed +happen +happenchance +happenchances +happened +happening +happenings +happens +happenstance +happenstances +happier +happiest +happily +happiness +happinesses +happing +happy +haps +hapten +haptene +haptenes +haptenic +haptens +haptic +haptical +haptoglobin +haptoglobins +harangue +harangued +haranguer +haranguers +harangues +haranguing +harass +harassed +harasser +harassers +harasses +harassing +harassment +harassments +harbinger +harbingered +harbingering +harbingers +harbor +harborage +harborages +harbored +harborer +harborers +harborful +harborfuls +harboring +harborless +harbormaster +harbormasters +harbors +harborside +harbour +harboured +harbouring +harbours +hard +hardback +hardbacks +hardball +hardballs +hardboard +hardboards +hardboot +hardboots +hardbound +hardcase +hardcore +hardcover +hardcovers +hardedge +hardedges +harden +hardened +hardener +hardeners +hardening +hardenings +hardens +harder +hardest +hardfisted +hardhack +hardhacks +hardhanded +hardhandedness +hardhandednesses +hardhat +hardhats +hardhead +hardheaded +hardheadedly +hardheadedness +hardheadednesses +hardheads +hardhearted +hardheartedness +hardheartednesses +hardier +hardies +hardiest +hardihood +hardihoods +hardily +hardiment +hardiments +hardiness +hardinesses +hardinggrass +hardinggrasses +hardline +hardly +hardmouthed +hardness +hardnesses +hardnose +hardnoses +hardpan +hardpans +hards +hardscrabble +hardset +hardship +hardships +hardstand +hardstanding +hardstandings +hardstands +hardtack +hardtacks +hardtop +hardtops +hardware +hardwares +hardwire +hardwired +hardwires +hardwiring +hardwood +hardwoods +hardworking +hardy +hare +harebell +harebells +harebrained +hared +hareem +hareems +harelike +harelip +harelips +harem +harems +hares +hariana +harianas +haricot +haricots +harijan +harijans +haring +hark +harked +harken +harkened +harkener +harkeners +harkening +harkens +harking +harks +harl +harlequin +harlequinade +harlequinades +harlequins +harlot +harlotries +harlotry +harlots +harls +harm +harmattan +harmattans +harmed +harmer +harmers +harmful +harmfully +harmfulness +harmfulnesses +harmin +harmine +harmines +harming +harmins +harmless +harmlessly +harmlessness +harmlessnesses +harmonic +harmonica +harmonically +harmonicas +harmonicist +harmonicists +harmonics +harmonies +harmonious +harmoniously +harmoniousness +harmoniousnesses +harmonise +harmonised +harmonises +harmonising +harmonium +harmoniums +harmonization +harmonizations +harmonize +harmonized +harmonizer +harmonizers +harmonizes +harmonizing +harmony +harms +harness +harnessed +harnesses +harnessing +harp +harped +harper +harpers +harpies +harpin +harping +harpings +harpins +harpist +harpists +harpoon +harpooned +harpooner +harpooners +harpooning +harpoons +harps +harpsichord +harpsichordist +harpsichordists +harpsichords +harpy +harquebus +harquebuses +harquebusier +harquebusiers +harridan +harridans +harried +harrier +harriers +harries +harrow +harrowed +harrower +harrowers +harrowing +harrows +harrumph +harrumphed +harrumphing +harrumphs +harry +harrying +harsh +harshen +harshened +harshening +harshens +harsher +harshest +harshly +harshness +harshnesses +harslet +harslets +hart +hartal +hartals +hartebeest +hartebeests +harts +hartshorn +hartshorns +harumph +harumphed +harumphing +harumphs +haruspex +haruspication +haruspications +haruspices +harvest +harvestable +harvested +harvester +harvesters +harvesting +harvestman +harvestmen +harvests +harvesttime +harvesttimes +has +hasenpfeffer +hasenpfeffers +hash +hashed +hasheesh +hasheeshes +hashes +hashhead +hashheads +hashing +hashish +hashishes +haslet +haslets +hasp +hasped +hasping +hasps +hassel +hassels +hassle +hassled +hassles +hassling +hassock +hassocks +hast +hastate +haste +hasted +hasteful +hasten +hastened +hastener +hasteners +hastening +hastens +hastes +hastier +hastiest +hastily +hastiness +hastinesses +hasting +hasty +hat +hatable +hatband +hatbands +hatbox +hatboxes +hatch +hatchabilities +hatchability +hatchable +hatchback +hatchbacks +hatcheck +hatched +hatchel +hatcheled +hatcheling +hatchelled +hatchelling +hatchels +hatcher +hatcheries +hatchers +hatchery +hatches +hatchet +hatchets +hatching +hatchings +hatchling +hatchlings +hatchment +hatchments +hatchway +hatchways +hate +hateable +hated +hateful +hatefully +hatefulness +hatefulnesses +hatemonger +hatemongers +hater +haters +hates +hatful +hatfuls +hath +hating +hatless +hatlike +hatmaker +hatmakers +hatpin +hatpins +hatrack +hatracks +hatred +hatreds +hats +hatsful +hatted +hatter +hatteria +hatterias +hatters +hatting +hauberk +hauberks +haugh +haughs +haughtier +haughtiest +haughtily +haughtiness +haughtinesses +haughty +haul +haulage +haulages +hauled +hauler +haulers +haulier +hauliers +hauling +haulm +haulmier +haulmiest +haulms +haulmy +hauls +haulyard +haulyards +haunch +haunched +haunches +haunt +haunted +haunter +haunters +haunting +hauntingly +haunts +hausen +hausens +hausfrau +hausfrauen +hausfraus +haustella +haustellum +haustoria +haustorial +haustorium +haut +hautbois +hautboy +hautboys +haute +hauteur +hauteurs +havarti +havartis +havdalah +havdalahs +have +havelock +havelocks +haven +havened +havening +havens +haver +havered +haverel +haverels +havering +havers +haversack +haversacks +haves +having +havior +haviors +haviour +haviours +havoc +havocked +havocker +havockers +havocking +havocs +haw +hawed +hawfinch +hawfinches +hawing +hawk +hawkbill +hawkbills +hawked +hawker +hawkers +hawkey +hawkeyed +hawkeys +hawkie +hawkies +hawking +hawkings +hawkish +hawkishly +hawkishness +hawkishnesses +hawklike +hawkmoth +hawkmoths +hawknose +hawknoses +hawks +hawksbill +hawksbills +hawkshaw +hawkshaws +hawkweed +hawkweeds +haws +hawse +hawsehole +hawseholes +hawser +hawsers +hawses +hawthorn +hawthorns +hay +haycock +haycocks +hayed +hayer +hayers +hayfield +hayfields +hayfork +hayforks +haying +hayings +haylage +haylages +hayloft +haylofts +haymaker +haymakers +haymow +haymows +hayrack +hayracks +hayrick +hayricks +hayride +hayrides +hays +hayseed +hayseeds +haystack +haystacks +hayward +haywards +haywire +haywires +hazan +hazanim +hazans +hazard +hazarded +hazarding +hazardous +hazardously +hazardousness +hazardousnesses +hazards +haze +hazed +hazel +hazelhen +hazelhens +hazelly +hazelnut +hazelnuts +hazels +hazer +hazers +hazes +hazier +haziest +hazily +haziness +hazinesses +hazing +hazings +hazy +hazzan +hazzanim +hazzans +he +head +headache +headaches +headachier +headachiest +headachy +headband +headbands +headboard +headboards +headcheese +headcheeses +headdress +headdresses +headed +header +headers +headfirst +headfish +headfishes +headforemost +headgate +headgates +headgear +headgears +headhunt +headhunted +headhunter +headhunters +headhunting +headhunts +headier +headiest +headily +headiness +headinesses +heading +headings +headlamp +headlamps +headland +headlands +headless +headlessness +headlessnesses +headlight +headlights +headline +headlined +headliner +headliners +headlines +headlining +headlock +headlocks +headlong +headman +headmaster +headmasters +headmastership +headmasterships +headmen +headmistress +headmistresses +headmost +headnote +headnotes +headphone +headphones +headpiece +headpieces +headpin +headpins +headquarter +headquartered +headquartering +headquarters +headrace +headraces +headrest +headrests +headroom +headrooms +heads +headsail +headsails +headset +headsets +headship +headships +headshrinker +headshrinkers +headsman +headsmen +headspace +headspaces +headspring +headsprings +headstall +headstalls +headstand +headstands +headstay +headstays +headstock +headstocks +headstone +headstones +headstream +headstreams +headstrong +headwaiter +headwaiters +headwater +headwaters +headway +headways +headwind +headwinds +headword +headwords +headwork +headworks +heady +heal +healable +healed +healer +healers +healing +heals +health +healthful +healthfully +healthfulness +healthfulnesses +healthier +healthiest +healthily +healthiness +healthinesses +healths +healthy +heap +heaped +heaping +heaps +hear +hearable +heard +hearer +hearers +hearing +hearings +hearken +hearkened +hearkening +hearkens +hears +hearsay +hearsays +hearse +hearsed +hearses +hearsing +heart +heartache +heartaches +heartbeat +heartbeats +heartbreak +heartbreaker +heartbreakers +heartbreaking +heartbreakingly +heartbreaks +heartbroken +heartburn +heartburning +heartburnings +heartburns +hearted +hearten +heartened +heartening +hearteningly +heartens +heartfelt +hearth +hearths +hearthstone +hearthstones +heartier +hearties +heartiest +heartily +heartiness +heartinesses +hearting +heartland +heartlands +heartless +heartlessly +heartlessness +heartlessnesses +heartrending +heartrendingly +hearts +heartsease +heartseases +heartsick +heartsickness +heartsicknesses +heartsome +heartsomely +heartsore +heartstring +heartstrings +heartthrob +heartthrobs +heartwarming +heartwood +heartwoods +heartworm +heartworms +hearty +heat +heatable +heated +heatedly +heater +heaters +heath +heathen +heathendom +heathendoms +heathenish +heathenishly +heathenism +heathenisms +heathenize +heathenized +heathenizes +heathenizing +heathens +heather +heathers +heathery +heathier +heathiest +heathland +heathlands +heathless +heathlike +heaths +heathy +heating +heatless +heatproof +heats +heatstroke +heatstrokes +heaume +heaumes +heave +heaved +heaven +heavenlier +heavenliest +heavenliness +heavenlinesses +heavenly +heavens +heavenward +heavenwards +heaver +heavers +heaves +heavier +heavies +heaviest +heavily +heaviness +heavinesses +heaving +heavy +heavyhearted +heavyheartedly +heavyheartedness +heavyheartednesses +heavyset +heavyweight +heavyweights +hebdomad +hebdomadal +hebdomadally +hebdomads +hebe +hebephrenia +hebephrenias +hebephrenic +hebephrenics +hebes +hebetate +hebetated +hebetates +hebetating +hebetation +hebetations +hebetic +hebetude +hebetudes +hebetudinous +hebraization +hebraizations +hebraize +hebraized +hebraizes +hebraizing +hecatomb +hecatombs +heck +heckle +heckled +heckler +hecklers +heckles +heckling +hecks +hectare +hectares +hectic +hectical +hectically +hecticly +hectogram +hectograms +hectograph +hectographed +hectographing +hectographs +hectoliter +hectoliters +hectometer +hectometers +hector +hectored +hectoring +hectoringly +hectors +heddle +heddles +heder +heders +hedge +hedged +hedgehog +hedgehogs +hedgehop +hedgehopped +hedgehopper +hedgehoppers +hedgehopping +hedgehops +hedgepig +hedgepigs +hedger +hedgerow +hedgerows +hedgers +hedges +hedgier +hedgiest +hedging +hedgingly +hedgy +hedonic +hedonically +hedonics +hedonism +hedonisms +hedonist +hedonistic +hedonistically +hedonists +heed +heeded +heeder +heeders +heedful +heedfully +heedfulness +heedfulnesses +heeding +heedless +heedlessly +heedlessness +heedlessnesses +heeds +heehaw +heehawed +heehawing +heehaws +heel +heelball +heelballs +heeled +heeler +heelers +heeling +heelings +heelless +heelpiece +heelpieces +heelpost +heelposts +heels +heeltap +heeltaps +heeze +heezed +heezes +heezing +heft +hefted +hefter +hefters +heftier +heftiest +heftily +heftiness +heftinesses +hefting +hefts +hefty +hegari +hegaris +hegemonic +hegemonies +hegemony +hegira +hegiras +hegumen +hegumene +hegumenes +hegumenies +hegumens +hegumeny +heh +hehs +heifer +heifers +heigh +height +heighten +heightened +heightening +heightens +heighth +heighths +heights +heil +heiled +heiling +heils +heimish +heinie +heinies +heinous +heinously +heinousness +heinousnesses +heir +heirdom +heirdoms +heired +heiress +heiresses +heiring +heirless +heirloom +heirlooms +heirs +heirship +heirships +heishi +heist +heisted +heister +heisters +heisting +heists +hejira +hejiras +hektare +hektares +held +heldentenor +heldentenors +heliac +heliacal +heliacally +heliast +heliasts +helical +helically +helices +helicities +helicity +helicoid +helicoidal +helicoids +helicon +helicons +helicopt +helicopted +helicopter +helicoptered +helicoptering +helicopters +helicopting +helicopts +helilift +helilifted +helilifting +helilifts +helio +heliocentric +heliograph +heliographed +heliographic +heliographing +heliographs +heliolatries +heliolatrous +heliolatry +heliometer +heliometers +heliometric +heliometrically +helios +heliostat +heliostats +heliotrope +heliotropes +heliotropic +heliotropism +heliotropisms +heliozoan +heliozoans +helipad +helipads +heliport +heliports +helistop +helistops +helium +heliums +helix +helixes +hell +hellacious +hellaciously +hellbender +hellbenders +hellbent +hellbox +hellboxes +hellbroth +hellbroths +hellcat +hellcats +hellebore +hellebores +helled +hellenization +hellenizations +hellenize +hellenized +hellenizes +hellenizing +heller +helleri +helleries +hellers +hellery +hellfire +hellfires +hellgrammite +hellgrammites +hellhole +hellholes +hellhound +hellhounds +helling +hellion +hellions +hellish +hellishly +hellishness +hellishnesses +hellkite +hellkites +hello +helloed +helloes +helloing +hellos +hells +helluva +helm +helmed +helmet +helmeted +helmeting +helmetlike +helmets +helming +helminth +helminthiases +helminthiasis +helminthic +helminthologies +helminthology +helminths +helmless +helms +helmsman +helmsmanship +helmsmanships +helmsmen +helo +helos +helot +helotage +helotages +helotism +helotisms +helotries +helotry +helots +help +helpable +helped +helper +helpers +helpful +helpfully +helpfulness +helpfulnesses +helping +helpings +helpless +helplessly +helplessness +helplessnesses +helpmate +helpmates +helpmeet +helpmeets +helps +helve +helved +helves +helving +hem +hemacytometer +hemacytometers +hemagglutinate +hemagglutinated +hemagglutinates +hemagglutinating +hemagglutination +hemagglutinations +hemagglutinin +hemagglutinins +hemagog +hemagogs +hemal +hemangioma +hemangiomas +hemangiomata +hematal +hematein +hemateins +hematic +hematics +hematin +hematine +hematines +hematinic +hematinics +hematins +hematite +hematites +hematitic +hematocrit +hematocrits +hematogenous +hematoid +hematologic +hematological +hematologies +hematologist +hematologists +hematology +hematoma +hematomas +hematomata +hematophagous +hematopoieses +hematopoiesis +hematopoietic +hematoporphyrin +hematoporphyrins +hematoxylin +hematoxylins +hematuria +hematurias +heme +hemelytra +hemelytron +hemerocallis +hemerocallises +hemerythrin +hemerythrins +hemes +hemiacetal +hemiacetals +hemic +hemicellulose +hemicelluloses +hemichordate +hemichordates +hemicycle +hemicycles +hemidemisemiquaver +hemidemisemiquavers +hemihedral +hemihydrate +hemihydrated +hemihydrates +hemimetabolous +hemimorphic +hemimorphism +hemimorphisms +hemin +hemins +hemiola +hemiolas +hemiolia +hemiolias +hemiplegia +hemiplegias +hemiplegic +hemiplegics +hemipter +hemipteran +hemipterans +hemipterous +hemipters +hemisphere +hemispheres +hemispheric +hemispherical +hemistich +hemistichs +hemizygous +hemline +hemlines +hemlock +hemlocks +hemmed +hemmer +hemmers +hemming +hemochromatoses +hemochromatosis +hemochromatosises +hemocoel +hemocoels +hemocyanin +hemocyanins +hemocyte +hemocytes +hemocytometer +hemocytometers +hemodialyses +hemodialysis +hemodilution +hemodilutions +hemodynamic +hemodynamically +hemodynamics +hemoflagellate +hemoflagellates +hemoglobin +hemoglobinopathies +hemoglobinopathy +hemoglobins +hemoglobinuria +hemoglobinurias +hemoglobinuric +hemoid +hemolymph +hemolymphs +hemolyses +hemolysin +hemolysins +hemolysis +hemolytic +hemolyze +hemolyzed +hemolyzes +hemolyzing +hemophilia +hemophiliac +hemophiliacs +hemophilias +hemophilic +hemophilics +hemopoieses +hemopoiesis +hemopoietic +hemoprotein +hemoproteins +hemoptyses +hemoptysis +hemorrhage +hemorrhaged +hemorrhages +hemorrhagic +hemorrhaging +hemorrhoid +hemorrhoidal +hemorrhoidals +hemorrhoids +hemosiderin +hemosiderins +hemostases +hemostasis +hemostat +hemostatic +hemostatics +hemostats +hemp +hempen +hempie +hempier +hempiest +hemplike +hemps +hempseed +hempseeds +hempweed +hempweeds +hempy +hems +hemstitch +hemstitched +hemstitcher +hemstitchers +hemstitches +hemstitching +hen +henbane +henbanes +henbit +henbits +hence +henceforth +henceforward +henchman +henchmen +hencoop +hencoops +hendecasyllabic +hendecasyllabics +hendecasyllable +hendecasyllables +hendiadys +hendiadyses +henequen +henequens +henequin +henequins +henhouse +henhouses +heniquen +heniquens +henlike +henna +hennaed +hennaing +hennas +henneries +hennery +henotheism +henotheisms +henotheist +henotheistic +henotheists +henpeck +henpecked +henpecking +henpecks +henries +henry +henrys +hens +hent +hented +henting +hents +hep +heparin +heparinized +heparins +hepatectomies +hepatectomized +hepatectomy +hepatic +hepatica +hepaticae +hepaticas +hepatics +hepatitides +hepatitis +hepatize +hepatized +hepatizes +hepatizing +hepatocellular +hepatocyte +hepatocytes +hepatoma +hepatomas +hepatomata +hepatomegalies +hepatomegaly +hepatopancreas +hepatopancreases +hepatotoxic +hepatotoxicities +hepatotoxicity +hepcat +hepcats +heptachlor +heptachlors +heptad +heptads +heptagon +heptagonal +heptagons +heptameter +heptameters +heptane +heptanes +heptarch +heptarchies +heptarchs +heptarchy +heptose +heptoses +her +herald +heralded +heraldic +heraldically +heralding +heraldries +heraldry +heralds +herb +herbaceous +herbage +herbages +herbal +herbalist +herbalists +herbals +herbaria +herbarium +herbariums +herbed +herbicidal +herbicidally +herbicide +herbicides +herbier +herbiest +herbivore +herbivores +herbivories +herbivorous +herbivory +herbless +herblike +herbs +herby +herculean +hercules +herculeses +herd +herded +herder +herders +herdic +herdics +herding +herdlike +herdman +herdmen +herds +herdsman +herdsmen +here +hereabout +hereabouts +hereafter +hereafters +hereat +hereaway +hereaways +hereby +heredes +hereditament +hereditaments +hereditarian +hereditarians +hereditarily +hereditary +heredities +heredity +herein +hereinabove +hereinafter +hereinbefore +hereinbelow +hereinto +hereof +hereon +heres +heresiarch +heresiarchs +heresies +heresy +heretic +heretical +heretically +heretics +hereto +heretofore +heretrices +heretrix +heretrixes +hereunder +hereunto +hereupon +herewith +heriot +heriots +heritabilities +heritability +heritable +heritage +heritages +heritor +heritors +heritrices +heritrix +heritrixes +herl +herls +herm +herma +hermae +hermaean +hermai +hermaphrodite +hermaphrodites +hermaphroditic +hermaphroditism +hermaphroditisms +hermatypic +hermeneutic +hermeneutical +hermeneutically +hermeneutics +hermetic +hermetical +hermetically +hermeticism +hermeticisms +hermetism +hermetisms +hermetist +hermetists +hermit +hermitage +hermitages +hermitic +hermitism +hermitisms +hermitries +hermitry +hermits +herms +hern +hernia +herniae +hernial +hernias +herniate +herniated +herniates +herniating +herniation +herniations +herns +hero +heroes +heroic +heroical +heroically +heroicomic +heroicomical +heroics +heroin +heroine +heroines +heroinism +heroinisms +heroins +heroism +heroisms +heroize +heroized +heroizes +heroizing +heron +heronries +heronry +herons +heros +herpes +herpesvirus +herpesviruses +herpetic +herpetological +herpetologies +herpetologist +herpetologists +herpetology +herrenvolk +herrenvolks +herried +herries +herring +herringbone +herringboned +herringbones +herringboning +herrings +herry +herrying +hers +herself +herstories +herstory +hertz +hertzes +hes +hesitance +hesitances +hesitancies +hesitancy +hesitant +hesitantly +hesitate +hesitated +hesitater +hesitaters +hesitates +hesitating +hesitatingly +hesitation +hesitations +hesperidia +hesperidin +hesperidins +hesperidium +hessian +hessians +hessite +hessites +hessonite +hessonites +hest +hests +het +hetaera +hetaerae +hetaeras +hetaeric +hetaira +hetairai +hetairas +hetero +heteroatom +heteroatoms +heteroauxin +heteroauxins +heterocercal +heterochromatic +heterochromatin +heterochromatins +heteroclite +heteroclites +heterocycle +heterocycles +heterocyclic +heterocyclics +heterocyst +heterocystous +heterocysts +heterodox +heterodoxies +heterodoxy +heteroduplex +heteroduplexes +heterodyne +heterodyned +heterodynes +heterodyning +heteroecious +heteroecism +heteroecisms +heterogamete +heterogametes +heterogametic +heterogameties +heterogamety +heterogamies +heterogamous +heterogamy +heterogeneities +heterogeneity +heterogeneous +heterogeneously +heterogeneousness +heterogeneousnesses +heterogenies +heterogenous +heterogeny +heterogonic +heterogonies +heterogony +heterograft +heterografts +heterokaryon +heterokaryons +heterokaryoses +heterokaryosis +heterokaryosises +heterokaryotic +heterologous +heterologously +heterolyses +heterolysis +heterolytic +heteromorphic +heteromorphism +heteromorphisms +heteronomies +heteronomous +heteronomy +heteronym +heteronyms +heterophil +heterophile +heterophonies +heterophony +heterophyllies +heterophyllous +heterophylly +heteroploid +heteroploidies +heteroploids +heteroploidy +heteropterous +heteros +heteroses +heterosexual +heterosexualities +heterosexuality +heterosexually +heterosexuals +heterosis +heterospories +heterosporous +heterospory +heterothallic +heterothallism +heterothallisms +heterotic +heterotopic +heterotroph +heterotrophic +heterotrophically +heterotrophies +heterotrophs +heterotrophy +heterotypic +heterozygoses +heterozygosis +heterozygosities +heterozygosity +heterozygote +heterozygotes +heterozygous +heth +heths +hetman +hetmans +hets +heuch +heuchs +heugh +heughs +heulandite +heulandites +heuristic +heuristically +heuristics +hew +hewable +hewed +hewer +hewers +hewing +hewn +hews +hex +hexachlorethane +hexachlorethanes +hexachloroethane +hexachloroethanes +hexachlorophene +hexachlorophenes +hexachord +hexachords +hexad +hexade +hexadecimal +hexadecimals +hexades +hexadic +hexads +hexagon +hexagonal +hexagonally +hexagons +hexagram +hexagrams +hexahedra +hexahedron +hexahedrons +hexahydrate +hexahydrates +hexameter +hexameters +hexamethonium +hexamethoniums +hexamethylenetetramine +hexamethylenetetramines +hexamine +hexamines +hexane +hexanes +hexapla +hexaplar +hexaplas +hexaploid +hexaploidies +hexaploids +hexaploidy +hexapod +hexapodies +hexapods +hexapody +hexarchies +hexarchy +hexed +hexer +hexerei +hexereis +hexers +hexes +hexing +hexobarbital +hexobarbitals +hexokinase +hexokinases +hexone +hexones +hexosaminidase +hexosaminidases +hexosan +hexosans +hexose +hexoses +hexyl +hexylresorcinol +hexylresorcinols +hexyls +hey +heyday +heydays +heydey +heydeys +hi +hiatal +hiatus +hiatuses +hibachi +hibachis +hibakusha +hibernacula +hibernaculum +hibernal +hibernate +hibernated +hibernates +hibernating +hibernation +hibernations +hibernator +hibernators +hibiscus +hibiscuses +hic +hiccough +hiccoughed +hiccoughing +hiccoughs +hiccup +hiccuped +hiccuping +hiccupped +hiccupping +hiccups +hick +hickey +hickeys +hickies +hickish +hickories +hickory +hicks +hid +hidable +hidalgo +hidalgos +hidden +hiddenite +hiddenites +hiddenly +hiddenness +hiddennesses +hide +hideaway +hideaways +hidebound +hided +hideless +hideosities +hideosity +hideous +hideously +hideousness +hideousnesses +hideout +hideouts +hider +hiders +hides +hiding +hidings +hidroses +hidrosis +hidrotic +hidrotics +hie +hied +hieing +hiemal +hierarch +hierarchal +hierarchic +hierarchical +hierarchically +hierarchies +hierarchize +hierarchized +hierarchizes +hierarchizing +hierarchs +hierarchy +hieratic +hieratically +hierodule +hierodules +hieroglyph +hieroglyphic +hieroglyphical +hieroglyphically +hieroglyphics +hieroglyphs +hierophant +hierophantic +hierophants +hies +hifalutin +higgle +higgled +higgler +higglers +higgles +higgling +high +highball +highballed +highballing +highballs +highbinder +highbinders +highborn +highboy +highboys +highbred +highbrow +highbrowed +highbrowism +highbrowisms +highbrows +highbush +highchair +highchairs +higher +highest +highfalutin +highflier +highfliers +highflyer +highflyers +highhanded +highhandedly +highhandedness +highhandednesses +highjack +highjacked +highjacking +highjacks +highland +highlander +highlanders +highlands +highlife +highlifes +highlight +highlighted +highlighter +highlighters +highlighting +highlights +highly +highness +highnesses +highroad +highroads +highs +highspot +highspots +hight +hightail +hightailed +hightailing +hightails +highted +highth +highths +highting +hights +highway +highwayman +highwaymen +highways +hijack +hijacked +hijacker +hijackers +hijacking +hijackings +hijacks +hijinks +hike +hiked +hiker +hikers +hikes +hiking +hila +hilar +hilarious +hilariously +hilariousness +hilariousnesses +hilarities +hilarity +hilding +hildings +hili +hill +hillbillies +hillbilly +hillcrest +hillcrests +hilled +hiller +hillers +hillier +hilliest +hilling +hillo +hilloa +hilloaed +hilloaing +hilloas +hillock +hillocks +hillocky +hilloed +hilloes +hilloing +hillos +hills +hillside +hillsides +hilltop +hilltops +hilly +hilt +hilted +hilting +hiltless +hilts +hilum +hilus +him +himatia +himation +himations +himself +hin +hind +hindbrain +hindbrains +hinder +hindered +hinderer +hinderers +hindering +hinders +hindgut +hindguts +hindmost +hindquarter +hindquarters +hindrance +hindrances +hinds +hindsight +hindsights +hinge +hinged +hinger +hingers +hinges +hinging +hinnied +hinnies +hinny +hinnying +hins +hint +hinted +hinter +hinterland +hinterlands +hinters +hinting +hints +hip +hipbone +hipbones +hipless +hiplike +hipline +hiplines +hipness +hipnesses +hipparch +hipparchs +hipped +hipper +hippest +hippie +hippiedom +hippiedoms +hippieness +hippienesses +hippier +hippies +hippiest +hippiness +hippinesses +hipping +hippish +hippo +hippocampal +hippocampi +hippocampus +hippocras +hippocrases +hippodrome +hippodromes +hippogriff +hippogriffs +hippopotami +hippopotamus +hippopotamuses +hippos +hippy +hips +hipshot +hipster +hipsterism +hipsterisms +hipsters +hirable +hiragana +hiraganas +hircine +hire +hireable +hired +hireling +hirelings +hirer +hirers +hires +hiring +hirple +hirpled +hirples +hirpling +hirsel +hirseled +hirseling +hirselled +hirselling +hirsels +hirsle +hirsled +hirsles +hirsling +hirsute +hirsuteness +hirsutenesses +hirsutism +hirsutisms +hirudin +hirudins +his +hisn +hispanidad +hispanidads +hispanism +hispanisms +hispid +hiss +hissed +hisself +hisser +hissers +hisses +hissies +hissing +hissings +hissy +hist +histamin +histaminase +histaminases +histamine +histaminergic +histamines +histamins +histed +histidin +histidine +histidines +histidins +histing +histiocyte +histiocytes +histiocytic +histochemical +histochemically +histochemistries +histochemistry +histocompatibilities +histocompatibility +histogen +histogeneses +histogenesis +histogenetic +histogens +histogram +histograms +histoid +histologic +histological +histologically +histologies +histologist +histologists +histology +histolyses +histolysis +histone +histones +histopathologic +histopathological +histopathologically +histopathologies +histopathologist +histopathologists +histopathology +histophysiologic +histophysiological +histophysiologies +histophysiology +histoplasmoses +histoplasmosis +histoplasmosises +historian +historians +historic +historical +historically +historicalness +historicalnesses +historicism +historicisms +historicist +historicists +historicities +historicity +historicize +historicized +historicizes +historicizing +histories +historiographer +historiographers +historiographic +historiographical +historiographically +historiographies +historiography +history +histrionic +histrionically +histrionics +hists +hit +hitch +hitched +hitcher +hitchers +hitches +hitchhike +hitchhiked +hitchhiker +hitchhikers +hitchhikes +hitchhiking +hitching +hither +hithermost +hitherto +hitherward +hitless +hits +hitter +hitters +hitting +hive +hived +hiveless +hives +hiving +hizzoner +hizzoners +hm +hmm +ho +hoactzin +hoactzines +hoactzins +hoagie +hoagies +hoagy +hoar +hoard +hoarded +hoarder +hoarders +hoarding +hoardings +hoards +hoarfrost +hoarfrosts +hoarier +hoariest +hoarily +hoariness +hoarinesses +hoars +hoarse +hoarsely +hoarsen +hoarsened +hoarseness +hoarsenesses +hoarsening +hoarsens +hoarser +hoarsest +hoary +hoatzin +hoatzines +hoatzins +hoax +hoaxed +hoaxer +hoaxers +hoaxes +hoaxing +hob +hobbed +hobbies +hobbing +hobbit +hobbits +hobble +hobblebush +hobblebushes +hobbled +hobbledehoy +hobbledehoys +hobbler +hobblers +hobbles +hobbling +hobby +hobbyhorse +hobbyhorses +hobbyist +hobbyists +hobgoblin +hobgoblins +hoblike +hobnail +hobnailed +hobnailing +hobnails +hobnob +hobnobbed +hobnobber +hobnobbers +hobnobbing +hobnobs +hobo +hoboed +hoboes +hoboing +hoboism +hoboisms +hobos +hobs +hock +hocked +hocker +hockers +hockey +hockeys +hocking +hocks +hockshop +hockshops +hocus +hocused +hocuses +hocusing +hocussed +hocusses +hocussing +hod +hodad +hodaddies +hodaddy +hodads +hodden +hoddens +hoddin +hoddins +hodgepodge +hodgepodges +hodoscope +hodoscopes +hods +hoe +hoecake +hoecakes +hoed +hoedown +hoedowns +hoeing +hoelike +hoer +hoers +hoes +hog +hogan +hogans +hogback +hogbacks +hogfish +hogfishes +hogg +hogged +hogger +hoggers +hogget +hoggets +hogging +hoggish +hoggishly +hoggishness +hoggishnesses +hoggs +hoglike +hogmanay +hogmanays +hogmane +hogmanes +hogmenay +hogmenays +hognose +hognoses +hognut +hognuts +hogs +hogshead +hogsheads +hogtie +hogtied +hogtieing +hogties +hogtying +hogwash +hogwashes +hogweed +hogweeds +hoick +hoicked +hoicking +hoicks +hoiden +hoidened +hoidening +hoidens +hoise +hoised +hoises +hoising +hoist +hoisted +hoister +hoisters +hoisting +hoists +hoke +hoked +hokes +hokey +hokeyness +hokeynesses +hokeypokey +hokeypokeys +hokier +hokiest +hokily +hokiness +hokinesses +hoking +hokku +hokum +hokums +hokypokies +hokypoky +holandric +holard +holards +hold +holdable +holdall +holdalls +holdback +holdbacks +holden +holder +holders +holdfast +holdfasts +holding +holdings +holdout +holdouts +holdover +holdovers +holds +holdup +holdups +hole +holed +holeless +holes +holey +holibut +holibuts +holiday +holidayed +holidayer +holidayers +holidaying +holidaymaker +holidaymakers +holidays +holier +holies +holiest +holily +holiness +holinesses +holing +holism +holisms +holist +holistic +holistically +holists +holk +holked +holking +holks +holla +hollaed +hollaing +holland +hollandaise +hollandaises +hollands +hollas +holler +hollered +hollering +hollers +hollies +hollo +holloa +holloaed +holloaing +holloas +holloed +holloes +holloing +holloo +hollooed +hollooing +holloos +hollos +hollow +holloware +hollowares +hollowed +hollower +hollowest +hollowing +hollowly +hollowness +hollownesses +hollows +hollowware +hollowwares +holly +hollyhock +hollyhocks +holm +holmic +holmium +holmiums +holms +holoblastic +holocaust +holocausts +holocrine +holoenzyme +holoenzymes +hologamies +hologamy +hologram +holograms +holograph +holographed +holographer +holographers +holographic +holographically +holographies +holographing +holographs +holography +hologynies +hologyny +holohedral +holometabolism +holometabolisms +holometabolous +holophrastic +holophytic +holothurian +holothurians +holotype +holotypes +holotypic +holozoic +holp +holpen +hols +holstein +holsteins +holster +holstered +holstering +holsters +holt +holts +holy +holyday +holydays +holystone +holystoned +holystones +holystoning +holytide +holytides +homage +homaged +homager +homagers +homages +homaging +hombre +hombres +homburg +homburgs +home +homebodies +homebody +homebound +homeboy +homeboys +homebred +homebreds +homebuilt +homecoming +homecomings +homed +homegrown +homeland +homelands +homeless +homelessness +homelessnesses +homelier +homeliest +homelike +homeliness +homelinesses +homely +homemade +homemaker +homemakers +homemaking +homemakings +homeobox +homeoboxes +homeomorphic +homeomorphism +homeomorphisms +homeopath +homeopathic +homeopathically +homeopathies +homeopaths +homeopathy +homeostases +homeostasis +homeostatic +homeotherm +homeothermic +homeothermies +homeotherms +homeothermy +homeotic +homeowner +homeowners +homeport +homeported +homeporting +homeports +homer +homered +homering +homeroom +homerooms +homers +homes +homeschool +homeschooled +homeschooler +homeschoolers +homeschooling +homeschools +homesick +homesickness +homesicknesses +homesite +homesites +homespun +homespuns +homestay +homestays +homestead +homesteaded +homesteader +homesteaders +homesteading +homesteads +homestretch +homestretches +hometown +hometowns +homeward +homewards +homework +homeworks +homey +homeyness +homeynesses +homicidal +homicidally +homicide +homicides +homier +homiest +homiletic +homiletical +homiletics +homilies +homilist +homilists +homily +homines +hominess +hominesses +homing +hominian +hominians +hominid +hominids +hominies +hominine +hominization +hominizations +hominize +hominized +hominizes +hominizing +hominoid +hominoids +hominy +hommock +hommocks +hommos +hommoses +homo +homocercal +homoerotic +homoeroticism +homoeroticisms +homogametic +homogamies +homogamous +homogamy +homogenate +homogenates +homogeneities +homogeneity +homogeneous +homogeneously +homogeneousness +homogeneousnesses +homogenies +homogenisation +homogenisations +homogenise +homogenised +homogenises +homogenising +homogenization +homogenizations +homogenize +homogenized +homogenizer +homogenizers +homogenizes +homogenizing +homogenous +homogeny +homogonies +homogony +homograft +homografts +homograph +homographic +homographs +homoiotherm +homoiothermic +homoiotherms +homoiousian +homoiousians +homolog +homologate +homologated +homologates +homologating +homologation +homologations +homological +homologically +homologies +homologize +homologized +homologizer +homologizers +homologizes +homologizing +homologous +homologs +homologue +homologues +homology +homolyses +homolysis +homolytic +homomorphic +homomorphism +homomorphisms +homonuclear +homonym +homonymic +homonymies +homonymous +homonymously +homonyms +homonymy +homoousian +homoousians +homophile +homophobe +homophobes +homophobia +homophobias +homophobic +homophone +homophones +homophonic +homophonies +homophonous +homophony +homoplasies +homoplastic +homoplasy +homopolar +homopolymer +homopolymeric +homopolymers +homopteran +homopterans +homopterous +homos +homoscedastic +homoscedasticities +homoscedasticity +homosex +homosexes +homosexual +homosexualities +homosexuality +homosexually +homosexuals +homospories +homosporous +homospory +homothallic +homothallism +homothallisms +homotransplant +homotransplantation +homotransplantations +homotransplants +homozygoses +homozygosis +homozygosities +homozygosity +homozygote +homozygotes +homozygous +homozygously +homunculi +homunculus +homy +hon +honan +honans +honcho +honchoed +honchoing +honchos +honda +hondas +hondle +hondled +hondles +hondling +hone +honed +honer +honers +hones +honest +honester +honestest +honesties +honestly +honesty +honewort +honeworts +honey +honeybee +honeybees +honeybun +honeybunch +honeybunches +honeybuns +honeycomb +honeycombed +honeycombing +honeycombs +honeycreeper +honeycreepers +honeydew +honeydews +honeyeater +honeyeaters +honeyed +honeyful +honeyguide +honeyguides +honeying +honeymoon +honeymooned +honeymooner +honeymooners +honeymooning +honeymoons +honeys +honeysuckle +honeysuckles +hong +hongs +honied +honing +honk +honked +honker +honkers +honkey +honkeys +honkie +honkies +honking +honks +honky +honor +honorabilities +honorability +honorable +honorableness +honorablenesses +honorably +honorand +honorands +honoraria +honoraries +honorarily +honorarium +honorariums +honorary +honored +honoree +honorees +honorer +honorers +honorific +honorifically +honorifics +honoring +honors +honour +honourable +honoured +honourer +honourers +honouring +honours +hons +hooch +hooches +hood +hooded +hoodedness +hoodednesses +hoodie +hoodier +hoodies +hoodiest +hooding +hoodless +hoodlike +hoodlum +hoodlumish +hoodlumism +hoodlumisms +hoodlums +hoodoo +hoodooed +hoodooing +hoodooism +hoodooisms +hoodoos +hoods +hoodwink +hoodwinked +hoodwinker +hoodwinkers +hoodwinking +hoodwinks +hoody +hooey +hooeys +hoof +hoofbeat +hoofbeats +hoofed +hoofer +hoofers +hoofing +hoofless +hooflike +hoofprint +hoofprints +hoofs +hook +hooka +hookah +hookahs +hookas +hooked +hooker +hookers +hookey +hookeys +hookier +hookies +hookiest +hooking +hookless +hooklet +hooklets +hooklike +hooknose +hooknoses +hooks +hookup +hookups +hookworm +hookworms +hooky +hoolie +hooligan +hooliganism +hooliganisms +hooligans +hooly +hoop +hooped +hooper +hoopers +hooping +hoopla +hooplas +hoopless +hooplike +hoopoe +hoopoes +hoopoo +hoopoos +hoops +hoopskirt +hoopskirts +hoopster +hoopsters +hoorah +hoorahed +hoorahing +hoorahs +hooray +hoorayed +hooraying +hoorays +hoosegow +hoosegows +hoosgow +hoosgows +hoot +hootch +hootches +hooted +hootenannies +hootenanny +hooter +hooters +hootier +hootiest +hooting +hoots +hooty +hooved +hooves +hop +hope +hoped +hopeful +hopefully +hopefulness +hopefulnesses +hopefuls +hopeless +hopelessly +hopelessness +hopelessnesses +hoper +hopers +hopes +hophead +hopheads +hoping +hoplite +hoplites +hoplitic +hopped +hopper +hoppers +hoppier +hoppiest +hopping +hoppings +hopple +hoppled +hopples +hoppling +hoppy +hops +hopsack +hopsacking +hopsackings +hopsacks +hopscotch +hopscotched +hopscotches +hopscotching +hoptoad +hoptoads +hora +horah +horahs +horal +horary +horas +horde +horded +hordein +hordeins +hordes +hording +horehound +horehounds +horizon +horizonal +horizonless +horizons +horizontal +horizontalities +horizontality +horizontally +horizontals +hormogonia +hormogonium +hormonal +hormonally +hormone +hormonelike +hormones +hormonic +horn +hornbeam +hornbeams +hornbill +hornbills +hornblende +hornblendes +hornblendic +hornbook +hornbooks +horned +hornedness +hornednesses +hornet +hornets +hornfels +hornier +horniest +hornily +horniness +horninesses +horning +hornist +hornists +hornito +hornitos +hornless +hornlessness +hornlessnesses +hornlike +hornpipe +hornpipes +hornpout +hornpouts +horns +hornstone +hornstones +hornswoggle +hornswoggled +hornswoggles +hornswoggling +horntail +horntails +hornworm +hornworms +hornwort +hornworts +horny +horologe +horologes +horological +horologies +horologist +horologists +horology +horoscope +horoscopes +horrendous +horrendously +horrent +horrible +horribleness +horriblenesses +horribles +horribly +horrid +horridly +horridness +horridnesses +horrific +horrifically +horrified +horrifies +horrify +horrifying +horrifyingly +horror +horrors +horse +horseback +horsebacks +horsebean +horsebeans +horsecar +horsecars +horsed +horsefeathers +horseflesh +horsefleshes +horseflies +horsefly +horsehair +horsehairs +horsehide +horsehides +horselaugh +horselaughs +horseless +horselike +horseman +horsemanship +horsemanships +horsemen +horsemint +horsemints +horseplay +horseplayer +horseplayers +horseplays +horsepower +horsepowers +horsepox +horsepoxes +horseradish +horseradishes +horses +horseshit +horseshits +horseshod +horseshoe +horseshoed +horseshoeing +horseshoer +horseshoers +horseshoes +horsetail +horsetails +horseweed +horseweeds +horsewhip +horsewhipped +horsewhipper +horsewhippers +horsewhipping +horsewhips +horsewoman +horsewomen +horsey +horsier +horsiest +horsily +horsiness +horsinesses +horsing +horst +horste +horstes +horsts +horsy +hortative +hortatively +hortatory +horticultural +horticulturally +horticulture +horticultures +horticulturist +horticulturists +hosanna +hosannaed +hosannah +hosannahs +hosannaing +hosannas +hose +hosed +hosel +hosels +hosen +hosepipe +hosepipes +hoses +hosier +hosieries +hosiers +hosiery +hosing +hospice +hospices +hospitable +hospitably +hospital +hospitalise +hospitalised +hospitalises +hospitalising +hospitalities +hospitality +hospitalization +hospitalizations +hospitalize +hospitalized +hospitalizes +hospitalizing +hospitals +hospitia +hospitium +hospodar +hospodars +host +hosta +hostage +hostages +hostas +hosted +hostel +hosteled +hosteler +hostelers +hosteling +hostelled +hosteller +hostellers +hostelling +hostelries +hostelry +hostels +hostess +hostessed +hostesses +hostessing +hostile +hostilely +hostiles +hostilities +hostility +hosting +hostler +hostlers +hostly +hosts +hot +hotbed +hotbeds +hotblood +hotbloods +hotbox +hotboxes +hotcake +hotcakes +hotch +hotched +hotches +hotching +hotchpot +hotchpotch +hotchpotches +hotchpots +hotdog +hotdogged +hotdogger +hotdoggers +hotdogging +hotdogs +hotel +hoteldom +hoteldoms +hotelier +hoteliers +hotelman +hotelmen +hotels +hotfoot +hotfooted +hotfooting +hotfoots +hothead +hotheaded +hotheadedly +hotheadedness +hotheadednesses +hotheads +hothouse +hothouses +hotline +hotlines +hotly +hotness +hotnesses +hotpress +hotpressed +hotpresses +hotpressing +hotrod +hotrods +hots +hotshot +hotshots +hotspur +hotspurs +hotted +hotter +hottest +hotting +hottish +houdah +houdahs +hound +hounded +hounder +hounders +hounding +hounds +hour +hourglass +hourglasses +houri +houris +hourly +hours +house +houseboat +houseboater +houseboaters +houseboats +housebound +houseboy +houseboys +housebreak +housebreaker +housebreakers +housebreaking +housebreakings +housebreaks +housebroke +housebroken +housecarl +housecarls +houseclean +housecleaned +housecleaning +housecleanings +housecleans +housecoat +housecoats +housed +housedress +housedresses +housefather +housefathers +houseflies +housefly +housefront +housefronts +houseful +housefuls +houseguest +houseguests +household +householder +householders +households +househusband +househusbands +housekeep +housekeeper +housekeepers +housekeeping +housekeepings +housekeeps +housekept +housel +houseled +houseleek +houseleeks +houseless +houselessness +houselessnesses +houselights +houseling +houselled +houselling +housels +housemaid +housemaids +houseman +housemaster +housemasters +housemate +housemates +housemen +housemother +housemothers +housepainter +housepainters +houseparent +houseparents +houseperson +housepersons +houseplant +houseplants +houser +houseroom +houserooms +housers +houses +housesat +housesit +housesits +housesitting +housetop +housetops +housewares +housewarming +housewarmings +housewife +housewifeliness +housewifelinesses +housewifely +housewiferies +housewifery +housewifey +housewives +housework +houseworks +housing +housings +hove +hovel +hoveled +hoveling +hovelled +hovelling +hovels +hover +hovercraft +hovercrafts +hovered +hoverer +hoverers +hovering +hovers +how +howbeit +howdah +howdahs +howdie +howdied +howdies +howdy +howdying +howe +howes +however +howf +howff +howffs +howfs +howitzer +howitzers +howk +howked +howking +howks +howl +howled +howler +howlers +howlet +howlets +howling +howlingly +howls +hows +howsoever +hoy +hoya +hoyas +hoyden +hoydened +hoydening +hoydenish +hoydens +hoyle +hoyles +hoys +huarache +huaraches +huaracho +huarachos +hub +hubbies +hubbly +hubbub +hubbubs +hubby +hubcap +hubcaps +hubris +hubrises +hubristic +hubs +huck +huckaback +huckabacks +huckle +huckleberries +huckleberry +huckles +hucks +huckster +huckstered +huckstering +hucksterism +hucksterisms +hucksters +huddle +huddled +huddler +huddlers +huddles +huddling +hue +hued +hueless +hues +huff +huffed +huffier +huffiest +huffily +huffiness +huffinesses +huffing +huffish +huffs +huffy +hug +huge +hugely +hugeness +hugenesses +hugeous +hugeously +huger +hugest +huggable +hugged +hugger +huggers +hugging +hugs +huh +huic +huipil +huipiles +huipils +huisache +huisaches +hula +hulas +hulk +hulked +hulkier +hulkiest +hulking +hulks +hulky +hull +hullabaloo +hullabaloos +hulled +huller +hullers +hulling +hullo +hulloa +hulloaed +hulloaing +hulloas +hulloed +hulloes +hulloing +hullos +hulls +hum +human +humane +humanely +humaneness +humanenesses +humaner +humanest +humanise +humanised +humanises +humanising +humanism +humanisms +humanist +humanistic +humanistically +humanists +humanitarian +humanitarianism +humanitarianisms +humanitarians +humanities +humanity +humanization +humanizations +humanize +humanized +humanizer +humanizers +humanizes +humanizing +humankind +humanlike +humanly +humanness +humannesses +humanoid +humanoids +humans +humate +humates +humble +humbled +humbleness +humblenesses +humbler +humblers +humbles +humblest +humbling +humblingly +humbly +humbug +humbugged +humbuggeries +humbuggery +humbugging +humbugs +humdinger +humdingers +humdrum +humdrums +humectant +humectants +humeral +humerals +humeri +humerus +humic +humid +humidification +humidifications +humidified +humidifier +humidifiers +humidifies +humidify +humidifying +humidistat +humidistats +humidities +humidity +humidly +humidor +humidors +humification +humifications +humified +humiliate +humiliated +humiliates +humiliating +humiliatingly +humiliation +humiliations +humilities +humility +hummable +hummed +hummer +hummers +humming +hummingbird +hummingbirds +hummock +hummocked +hummocking +hummocks +hummocky +hummus +hummuses +humongous +humor +humoral +humored +humoresque +humoresques +humorful +humoring +humorist +humoristic +humorists +humorless +humorlessly +humorlessness +humorlessnesses +humorous +humorously +humorousness +humorousnesses +humors +humour +humoured +humouring +humours +hump +humpback +humpbacked +humpbacks +humped +humph +humphed +humphing +humphs +humpier +humpiest +humping +humpless +humps +humpy +hums +humungous +humus +humuses +humvee +humvees +hun +hunch +hunchback +hunchbacked +hunchbacks +hunched +hunches +hunching +hundred +hundredfold +hundreds +hundredth +hundredths +hundredweight +hundredweights +hung +hunger +hungered +hungering +hungers +hungover +hungrier +hungriest +hungrily +hungriness +hungrinesses +hungry +hunh +hunk +hunker +hunkered +hunkering +hunkers +hunkier +hunkies +hunkiest +hunks +hunky +hunnish +huns +hunt +huntable +hunted +huntedly +hunter +hunters +hunting +huntings +huntress +huntresses +hunts +huntsman +huntsmen +hup +hurdies +hurdle +hurdled +hurdler +hurdlers +hurdles +hurdling +hurds +hurl +hurled +hurler +hurlers +hurley +hurleys +hurlies +hurling +hurlings +hurls +hurly +hurrah +hurrahed +hurrahing +hurrahs +hurray +hurrayed +hurraying +hurrays +hurricane +hurricanes +hurried +hurriedly +hurriedness +hurriednesses +hurrier +hurriers +hurries +hurry +hurrying +hurst +hursts +hurt +hurter +hurters +hurtful +hurtfully +hurtfulness +hurtfulnesses +hurting +hurtle +hurtled +hurtles +hurtless +hurtling +hurts +husband +husbanded +husbander +husbanders +husbanding +husbandly +husbandman +husbandmen +husbandries +husbandry +husbands +hush +hushaby +hushed +hushedly +hushes +hushful +hushing +husk +husked +husker +huskers +huskier +huskies +huskiest +huskily +huskiness +huskinesses +husking +huskings +husklike +husks +husky +hussar +hussars +hussies +hussy +hustings +hustle +hustled +hustler +hustlers +hustles +hustling +huswife +huswifes +huswives +hut +hutch +hutched +hutches +hutching +hutlike +hutment +hutments +huts +hutted +hutting +hutzpa +hutzpah +hutzpahs +hutzpas +huzza +huzzaed +huzzah +huzzahed +huzzahing +huzzahs +huzzaing +huzzas +hwan +hyacinth +hyacinthine +hyacinths +hyaena +hyaenas +hyaenic +hyalin +hyaline +hyalines +hyalins +hyalite +hyalites +hyalogen +hyalogens +hyaloid +hyaloids +hyaloplasm +hyaloplasms +hyaluronidase +hyaluronidases +hybrid +hybridism +hybridisms +hybridities +hybridity +hybridization +hybridizations +hybridize +hybridized +hybridizer +hybridizers +hybridizes +hybridizing +hybridoma +hybridomas +hybrids +hybris +hybrises +hydathode +hydathodes +hydatid +hydatids +hydra +hydracid +hydracids +hydrae +hydragog +hydragogs +hydralazine +hydralazines +hydrangea +hydrangeas +hydrant +hydranth +hydranths +hydrants +hydras +hydrase +hydrases +hydrate +hydrated +hydrates +hydrating +hydration +hydrations +hydrator +hydrators +hydraulic +hydraulically +hydraulics +hydrazide +hydrazides +hydrazine +hydrazines +hydria +hydriae +hydric +hydrid +hydride +hydrides +hydrids +hydro +hydrobiological +hydrobiologies +hydrobiologist +hydrobiologists +hydrobiology +hydrocarbon +hydrocarbons +hydrocele +hydroceles +hydrocephalic +hydrocephalics +hydrocephalies +hydrocephalus +hydrocephaluses +hydrocephaly +hydrochloride +hydrochlorides +hydrochlorothiazide +hydrochlorothiazides +hydrocolloid +hydrocolloidal +hydrocolloids +hydrocortisone +hydrocortisones +hydrocrack +hydrocracked +hydrocracker +hydrocrackers +hydrocracking +hydrocrackings +hydrocracks +hydrodynamic +hydrodynamical +hydrodynamically +hydrodynamicist +hydrodynamicists +hydrodynamics +hydroelectric +hydroelectrically +hydroelectricities +hydroelectricity +hydrofoil +hydrofoils +hydrogel +hydrogels +hydrogen +hydrogenase +hydrogenases +hydrogenate +hydrogenated +hydrogenates +hydrogenating +hydrogenation +hydrogenations +hydrogenous +hydrogens +hydrographer +hydrographers +hydrographic +hydrographies +hydrography +hydroid +hydroids +hydrokinetic +hydrolase +hydrolases +hydrologic +hydrological +hydrologically +hydrologies +hydrologist +hydrologists +hydrology +hydrolysate +hydrolysates +hydrolyses +hydrolysis +hydrolytic +hydrolytically +hydrolyzable +hydrolyzate +hydrolyzates +hydrolyze +hydrolyzed +hydrolyzes +hydrolyzing +hydromagnetic +hydromancies +hydromancy +hydromechanical +hydromechanics +hydromedusa +hydromedusae +hydromel +hydromels +hydrometallurgical +hydrometallurgies +hydrometallurgist +hydrometallurgists +hydrometallurgy +hydrometeor +hydrometeorological +hydrometeorologies +hydrometeorologist +hydrometeorologists +hydrometeorology +hydrometeors +hydrometer +hydrometers +hydrometric +hydromorphic +hydronic +hydronically +hydronium +hydroniums +hydropathic +hydropathies +hydropathy +hydroperoxide +hydroperoxides +hydrophane +hydrophanes +hydrophilic +hydrophilicities +hydrophilicity +hydrophobia +hydrophobias +hydrophobic +hydrophobicities +hydrophobicity +hydrophone +hydrophones +hydrophyte +hydrophytes +hydrophytic +hydropic +hydroplane +hydroplaned +hydroplanes +hydroplaning +hydroponic +hydroponically +hydroponics +hydropower +hydropowers +hydrops +hydropses +hydropsies +hydropsy +hydroquinone +hydroquinones +hydros +hydrosere +hydroseres +hydroski +hydroskis +hydrosol +hydrosolic +hydrosols +hydrospace +hydrospaces +hydrosphere +hydrospheres +hydrospheric +hydrostatic +hydrostatically +hydrostatics +hydrotherapies +hydrotherapy +hydrothermal +hydrothermally +hydrothoraces +hydrothorax +hydrothoraxes +hydrotropic +hydrotropism +hydrotropisms +hydrous +hydroxide +hydroxides +hydroxy +hydroxyapatite +hydroxyapatites +hydroxyl +hydroxylamine +hydroxylamines +hydroxylapatite +hydroxylapatites +hydroxylase +hydroxylases +hydroxylate +hydroxylated +hydroxylates +hydroxylating +hydroxylation +hydroxylations +hydroxylic +hydroxyls +hydroxyproline +hydroxyprolines +hydroxytryptamine +hydroxytryptamines +hydroxyurea +hydroxyureas +hydroxyzine +hydroxyzines +hydrozoan +hydrozoans +hyena +hyenas +hyenic +hyenine +hyenoid +hyetal +hygeist +hygeists +hygieist +hygieists +hygiene +hygienes +hygienic +hygienically +hygienics +hygienist +hygienists +hygrograph +hygrographs +hygrometer +hygrometers +hygrometric +hygrophilous +hygrophyte +hygrophytes +hygrophytic +hygroscopic +hygroscopicities +hygroscopicity +hying +hyla +hylas +hylozoic +hylozoism +hylozoisms +hylozoist +hylozoistic +hylozoists +hymen +hymenal +hymeneal +hymeneally +hymeneals +hymenia +hymenial +hymenium +hymeniums +hymenoptera +hymenopteran +hymenopterans +hymenopteron +hymenopterons +hymenopterous +hymens +hymn +hymnal +hymnals +hymnaries +hymnary +hymnbook +hymnbooks +hymned +hymning +hymnist +hymnists +hymnless +hymnlike +hymnodies +hymnody +hymnologies +hymnology +hymns +hyoid +hyoidal +hyoidean +hyoids +hyoscine +hyoscines +hyoscyamine +hyoscyamines +hyp +hypabyssal +hypabyssally +hypaethral +hypallage +hypallages +hypanthia +hypanthium +hype +hyped +hyper +hyperacid +hyperacidities +hyperacidity +hyperactive +hyperactives +hyperactivities +hyperactivity +hyperacuities +hyperacuity +hyperacute +hyperaesthesia +hyperaesthesias +hyperaesthetic +hyperaggressive +hyperalert +hyperalimentation +hyperalimentations +hyperarid +hyperarousal +hyperarousals +hyperaware +hyperawareness +hyperawarenesses +hyperbaric +hyperbarically +hyperbola +hyperbolae +hyperbolas +hyperbole +hyperboles +hyperbolic +hyperbolical +hyperbolically +hyperbolist +hyperbolists +hyperbolize +hyperbolized +hyperbolizes +hyperbolizing +hyperboloid +hyperboloidal +hyperboloids +hyperborean +hyperboreans +hypercalcemia +hypercalcemias +hypercalcemic +hypercapnia +hypercapnias +hypercapnic +hypercatabolism +hypercatabolisms +hypercatalectic +hypercatalexes +hypercatalexis +hypercautious +hypercharge +hypercharged +hypercharges +hypercholesterolemia +hypercholesterolemias +hypercholesterolemic +hypercivilized +hypercoagulabilities +hypercoagulability +hypercoagulable +hypercompetitive +hypercomplex +hyperconcentration +hyperconcentrations +hyperconscious +hyperconsciousness +hyperconsciousnesses +hypercorrect +hypercorrection +hypercorrections +hypercorrectly +hypercorrectness +hypercorrectnesses +hypercritic +hypercritical +hypercritically +hypercriticism +hypercriticisms +hypercritics +hypercube +hypercubes +hyperdevelopment +hyperdevelopments +hyperefficient +hyperemia +hyperemias +hyperemic +hyperemotional +hyperemotionalities +hyperemotionality +hyperendemic +hyperenergetic +hyperesthesia +hyperesthesias +hyperesthetic +hypereutectic +hypereutectoid +hyperexcitabilities +hyperexcitability +hyperexcitable +hyperexcited +hyperexcitement +hyperexcitements +hyperexcretion +hyperexcretions +hyperextend +hyperextended +hyperextending +hyperextends +hyperextension +hyperextensions +hyperfastidious +hyperfine +hyperfunction +hyperfunctional +hyperfunctioning +hyperfunctions +hypergamies +hypergamy +hyperglycemia +hyperglycemias +hyperglycemic +hypergol +hypergolic +hypergolically +hypergols +hyperhidroses +hyperhidrosis +hyperimmune +hyperimmunization +hyperimmunizations +hyperimmunize +hyperimmunized +hyperimmunizes +hyperimmunizing +hyperinflated +hyperinflation +hyperinflationary +hyperinflations +hyperinnervation +hyperinnervations +hyperinsulinism +hyperinsulinisms +hyperintellectual +hyperintelligent +hyperintense +hyperinvolution +hyperinvolutions +hyperirritabilities +hyperirritability +hyperirritable +hyperkeratoses +hyperkeratosis +hyperkeratotic +hyperkineses +hyperkinesia +hyperkinesias +hyperkinesis +hyperkinetic +hyperlipemia +hyperlipemias +hyperlipemic +hyperlipidemia +hyperlipidemias +hypermania +hypermanias +hypermanic +hypermarket +hypermarkets +hypermasculine +hypermedia +hypermetabolic +hypermetabolism +hypermetabolisms +hypermeter +hypermeters +hypermetric +hypermetrical +hypermetropia +hypermetropias +hypermetropic +hypermnesia +hypermnesias +hypermnesic +hypermobilities +hypermobility +hypermodern +hypermodernist +hypermodernists +hypermutabilities +hypermutability +hypermutable +hypernationalistic +hyperon +hyperons +hyperope +hyperopes +hyperopia +hyperopias +hyperopic +hyperostoses +hyperostosis +hyperostotic +hyperparasite +hyperparasites +hyperparasitic +hyperparasitism +hyperparasitisms +hyperparathyroidism +hyperparathyroidisms +hyperphagia +hyperphagias +hyperphagic +hyperphysical +hyperpigmentation +hyperpigmentations +hyperpigmented +hyperpituitarism +hyperpituitarisms +hyperpituitary +hyperplane +hyperplanes +hyperplasia +hyperplasias +hyperplastic +hyperploid +hyperploidies +hyperploids +hyperploidy +hyperpnea +hyperpneas +hyperpneic +hyperpolarization +hyperpolarizations +hyperpolarize +hyperpolarized +hyperpolarizes +hyperpolarizing +hyperproducer +hyperproducers +hyperproduction +hyperproductions +hyperpure +hyperpyrexia +hyperpyrexias +hyperrational +hyperrationalities +hyperrationality +hyperreactive +hyperreactivities +hyperreactivity +hyperreactor +hyperreactors +hyperrealism +hyperrealisms +hyperrealist +hyperrealistic +hyperresponsive +hyperromantic +hypersaline +hypersalinities +hypersalinity +hypersalivation +hypersalivations +hypersecretion +hypersecretions +hypersensitive +hypersensitiveness +hypersensitivenesses +hypersensitivities +hypersensitivity +hypersensitization +hypersensitizations +hypersensitize +hypersensitized +hypersensitizes +hypersensitizing +hypersexual +hypersexualities +hypersexuality +hypersomnolence +hypersomnolences +hypersonic +hypersonically +hyperspace +hyperspaces +hyperstatic +hypersthene +hypersthenes +hypersthenic +hyperstimulate +hyperstimulated +hyperstimulates +hyperstimulating +hyperstimulation +hyperstimulations +hypersurface +hypersurfaces +hypersusceptibilities +hypersusceptibility +hypersusceptible +hypertense +hypertension +hypertensions +hypertensive +hypertensives +hypertext +hypertexts +hyperthermia +hyperthermias +hyperthermic +hyperthyroid +hyperthyroidism +hyperthyroidisms +hypertonia +hypertonias +hypertonic +hypertonicities +hypertonicity +hypertrophic +hypertrophied +hypertrophies +hypertrophy +hypertrophying +hypertypical +hyperurbanism +hyperurbanisms +hyperuricemia +hyperuricemias +hypervelocities +hypervelocity +hyperventilate +hyperventilated +hyperventilates +hyperventilating +hyperventilation +hyperventilations +hypervigilance +hypervigilances +hypervigilant +hypervirulent +hyperviscosities +hyperviscosity +hypervitaminoses +hypervitaminosis +hypes +hypha +hyphae +hyphal +hyphemia +hyphemias +hyphen +hyphenate +hyphenated +hyphenates +hyphenating +hyphenation +hyphenations +hyphened +hyphening +hyphenless +hyphens +hyping +hypnagogic +hypnic +hypnogogic +hypnoid +hypnoidal +hypnopompic +hypnoses +hypnosis +hypnotherapies +hypnotherapist +hypnotherapists +hypnotherapy +hypnotic +hypnotically +hypnotics +hypnotism +hypnotisms +hypnotist +hypnotists +hypnotizabilities +hypnotizability +hypnotizable +hypnotize +hypnotized +hypnotizes +hypnotizing +hypo +hypoacid +hypoallergenic +hypoblast +hypoblasts +hypocalcemia +hypocalcemias +hypocalcemic +hypocaust +hypocausts +hypocenter +hypocenters +hypocentral +hypochlorite +hypochlorites +hypochondria +hypochondriac +hypochondriacal +hypochondriacally +hypochondriacs +hypochondrias +hypochondriases +hypochondriasis +hypocorism +hypocorisms +hypocoristic +hypocoristical +hypocoristically +hypocotyl +hypocotyls +hypocrisies +hypocrisy +hypocrite +hypocrites +hypocritical +hypocritically +hypocycloid +hypocycloids +hypoderm +hypodermal +hypodermic +hypodermically +hypodermics +hypodermis +hypodermises +hypoderms +hypodiploid +hypodiploidies +hypodiploidy +hypoed +hypoeutectoid +hypogastric +hypogea +hypogeal +hypogean +hypogene +hypogeous +hypogeum +hypoglossal +hypoglossals +hypoglycemia +hypoglycemias +hypoglycemic +hypoglycemics +hypogynies +hypogynous +hypogyny +hypoing +hypokalemia +hypokalemias +hypokalemic +hypolimnia +hypolimnion +hypolimnions +hypomagnesemia +hypomagnesemias +hypomania +hypomanias +hypomanic +hypomorph +hypomorphic +hypomorphs +hyponea +hyponeas +hyponoia +hyponoias +hypoparathyroidism +hypoparathyroidisms +hypopharynges +hypopharynx +hypopharynxes +hypophyseal +hypophysectomies +hypophysectomize +hypophysectomized +hypophysectomizes +hypophysectomizing +hypophysectomy +hypophyses +hypophysial +hypophysis +hypopituitarism +hypopituitarisms +hypopituitary +hypoplasia +hypoplasias +hypoplastic +hypoploid +hypoploids +hypopnea +hypopneas +hypopyon +hypopyons +hypos +hyposensitization +hyposensitizations +hyposensitize +hyposensitized +hyposensitizes +hyposensitizing +hypospadias +hypospadiases +hypostases +hypostasis +hypostatic +hypostatically +hypostatization +hypostatizations +hypostatize +hypostatized +hypostatizes +hypostatizing +hypostome +hypostomes +hypostyle +hypostyles +hypotactic +hypotaxes +hypotaxis +hypotension +hypotensions +hypotensive +hypotensives +hypotenuse +hypotenuses +hypothalami +hypothalamic +hypothalamus +hypothec +hypothecate +hypothecated +hypothecates +hypothecating +hypothecation +hypothecations +hypothecator +hypothecators +hypothecs +hypothenuse +hypothenuses +hypothermal +hypothermia +hypothermias +hypothermic +hypotheses +hypothesis +hypothesize +hypothesized +hypothesizes +hypothesizing +hypothetical +hypothetically +hypothyroid +hypothyroidism +hypothyroidisms +hypotonia +hypotonias +hypotonic +hypotonicities +hypotonicity +hypoxanthine +hypoxanthines +hypoxemia +hypoxemias +hypoxemic +hypoxia +hypoxias +hypoxic +hyps +hypsometer +hypsometers +hypsometric +hyraces +hyracoid +hyracoids +hyrax +hyraxes +hyson +hysons +hyssop +hyssops +hysterectomies +hysterectomized +hysterectomy +hystereses +hysteresis +hysteretic +hysteria +hysterias +hysteric +hysterical +hysterically +hysterics +hysteroid +hysterotomies +hysterotomy +hyte +iamb +iambi +iambic +iambics +iambs +iambus +iambuses +iatric +iatrical +iatrogenic +iatrogenically +ibex +ibexes +ibices +ibidem +ibis +ibises +ibogaine +ibogaines +ibuprofen +ibuprofens +ice +iceberg +icebergs +iceblink +iceblinks +iceboat +iceboater +iceboaters +iceboating +iceboatings +iceboats +icebound +icebox +iceboxes +icebreaker +icebreakers +icecap +icecaps +iced +icefall +icefalls +icehouse +icehouses +icekhana +icekhanas +iceless +icelike +iceman +icemen +ices +ich +ichneumon +ichneumons +ichnite +ichnites +ichor +ichorous +ichors +ichs +ichthyic +ichthyofauna +ichthyofaunae +ichthyofaunal +ichthyofaunas +ichthyological +ichthyologically +ichthyologies +ichthyologist +ichthyologists +ichthyology +ichthyophagous +ichthyosaur +ichthyosaurian +ichthyosaurians +ichthyosaurs +icicle +icicled +icicles +icier +iciest +icily +iciness +icinesses +icing +icings +ick +icker +ickers +ickier +ickiest +ickily +ickiness +ickinesses +icky +icon +icones +iconic +iconical +iconically +iconicities +iconicity +iconoclasm +iconoclasms +iconoclast +iconoclastic +iconoclastically +iconoclasts +iconographer +iconographers +iconographic +iconographical +iconographically +iconographies +iconography +iconolatries +iconolatry +iconological +iconologies +iconology +iconoscope +iconoscopes +iconostases +iconostasis +icons +icosahedra +icosahedral +icosahedron +icosahedrons +icteric +icterics +icterus +icteruses +ictic +ictus +ictuses +icy +id +idea +ideal +idealess +idealise +idealised +idealises +idealising +idealism +idealisms +idealist +idealistic +idealistically +idealists +idealities +ideality +idealization +idealizations +idealize +idealized +idealizer +idealizers +idealizes +idealizing +idealless +ideally +idealogies +idealogue +idealogues +idealogy +ideals +ideas +ideate +ideated +ideates +ideating +ideation +ideational +ideationally +ideations +ideative +idem +idempotent +idempotents +identic +identical +identically +identicalness +identicalnesses +identifiable +identifiably +identification +identifications +identified +identifier +identifiers +identifies +identify +identifying +identities +identity +ideogram +ideogramic +ideogrammatic +ideogrammic +ideograms +ideograph +ideographic +ideographically +ideographies +ideographs +ideography +ideologic +ideological +ideologically +ideologies +ideologist +ideologists +ideologize +ideologized +ideologizes +ideologizing +ideologue +ideologues +ideology +ideomotor +ides +idioblast +idioblastic +idioblasts +idiocies +idiocy +idiographic +idiolect +idiolectal +idiolects +idiom +idiomatic +idiomatically +idiomaticness +idiomaticnesses +idiomorphic +idioms +idiopathic +idiopathically +idiosyncrasies +idiosyncrasy +idiosyncratic +idiosyncratically +idiot +idiotic +idiotical +idiotically +idiotism +idiotisms +idiots +idle +idled +idleness +idlenesses +idler +idlers +idles +idlesse +idlesses +idlest +idling +idly +idocrase +idocrases +idol +idolater +idolaters +idolator +idolators +idolatries +idolatrous +idolatrously +idolatrousness +idolatrousnesses +idolatry +idolise +idolised +idoliser +idolisers +idolises +idolising +idolism +idolisms +idolization +idolizations +idolize +idolized +idolizer +idolizers +idolizes +idolizing +idols +idoneities +idoneity +idoneous +ids +idyl +idylist +idylists +idyll +idyllic +idyllically +idyllist +idyllists +idylls +idyls +if +iff +iffier +iffiest +iffiness +iffinesses +iffy +ifs +igloo +igloos +iglu +iglus +ignatia +ignatias +igneous +ignescent +ignified +ignifies +ignify +ignifying +ignimbrite +ignimbrites +ignitabilities +ignitability +ignitable +ignite +ignited +igniter +igniters +ignites +ignitible +igniting +ignition +ignitions +ignitor +ignitors +ignitron +ignitrons +ignobilities +ignobility +ignoble +ignobleness +ignoblenesses +ignobly +ignominies +ignominious +ignominiously +ignominiousness +ignominiousnesses +ignominy +ignorable +ignorami +ignoramus +ignoramuses +ignorance +ignorances +ignorant +ignorantly +ignorantness +ignorantnesses +ignore +ignored +ignorer +ignorers +ignores +ignoring +iguana +iguanas +iguanian +iguanians +iguanodon +iguanodons +ihram +ihrams +ikat +ikats +ikebana +ikebanas +ikon +ikons +ilea +ileac +ileal +ileitides +ileitis +ileum +ileus +ileuses +ilex +ilexes +ilia +iliac +iliad +iliads +ilial +ilium +ilk +ilka +ilks +ill +illation +illations +illative +illatively +illatives +illaudable +illaudably +illegal +illegalities +illegality +illegalization +illegalizations +illegalize +illegalized +illegalizes +illegalizing +illegally +illegals +illegibilities +illegibility +illegible +illegibly +illegitimacies +illegitimacy +illegitimate +illegitimately +iller +illest +illiberal +illiberalism +illiberalisms +illiberalities +illiberality +illiberally +illiberalness +illiberalnesses +illicit +illicitly +illimitabilities +illimitability +illimitable +illimitableness +illimitablenesses +illimitably +illinium +illiniums +illiquid +illiquidities +illiquidity +illite +illiteracies +illiteracy +illiterate +illiterately +illiterateness +illiteratenesses +illiterates +illites +illitic +illness +illnesses +illocutionary +illogic +illogical +illogicalities +illogicality +illogically +illogicalness +illogicalnesses +illogics +ills +illume +illumed +illumes +illuminable +illuminance +illuminances +illuminant +illuminants +illuminate +illuminated +illuminates +illuminati +illuminating +illuminatingly +illumination +illuminations +illuminative +illuminator +illuminators +illumine +illumined +illumines +illuming +illumining +illuminism +illuminisms +illuminist +illuminists +illusion +illusional +illusionary +illusionism +illusionisms +illusionist +illusionistic +illusionistically +illusionists +illusions +illusive +illusively +illusiveness +illusivenesses +illusorily +illusoriness +illusorinesses +illusory +illustrate +illustrated +illustrates +illustrating +illustration +illustrational +illustrations +illustrative +illustratively +illustrator +illustrators +illustrious +illustriously +illustriousness +illustriousnesses +illuvia +illuvial +illuviated +illuviation +illuviations +illuvium +illuviums +illy +ilmenite +ilmenites +image +imaged +imager +imageries +imagers +imagery +images +imaginable +imaginableness +imaginablenesses +imaginably +imaginal +imaginaries +imaginarily +imaginariness +imaginarinesses +imaginary +imagination +imaginations +imaginative +imaginatively +imaginativeness +imaginativenesses +imagine +imagined +imaginer +imaginers +imagines +imaging +imagings +imagining +imagism +imagisms +imagist +imagistic +imagistically +imagists +imago +imagoes +imagos +imam +imamate +imamates +imams +imaret +imarets +imaum +imaums +imbalance +imbalanced +imbalances +imbalm +imbalmed +imbalmer +imbalmers +imbalming +imbalms +imbark +imbarked +imbarking +imbarks +imbecile +imbeciles +imbecilic +imbecilities +imbecility +imbed +imbedded +imbedding +imbeds +imbibe +imbibed +imbiber +imbibers +imbibes +imbibing +imbibition +imbibitional +imbibitions +imbitter +imbittered +imbittering +imbitters +imblaze +imblazed +imblazes +imblazing +imbodied +imbodies +imbody +imbodying +imbolden +imboldened +imboldening +imboldens +imbosom +imbosomed +imbosoming +imbosoms +imbower +imbowered +imbowering +imbowers +imbricate +imbricated +imbricates +imbricating +imbrication +imbrications +imbroglio +imbroglios +imbrown +imbrowned +imbrowning +imbrowns +imbrue +imbrued +imbrues +imbruing +imbrute +imbruted +imbrutes +imbruting +imbue +imbued +imbues +imbuing +imid +imidazole +imidazoles +imide +imides +imidic +imido +imids +imine +imines +imino +imipramine +imipramines +imitable +imitate +imitated +imitates +imitating +imitation +imitations +imitative +imitatively +imitativeness +imitativenesses +imitator +imitators +immaculacies +immaculacy +immaculate +immaculately +immane +immanence +immanences +immanencies +immanency +immanent +immanentism +immanentisms +immanentist +immanentistic +immanentists +immanently +immaterial +immaterialism +immaterialisms +immaterialist +immaterialists +immaterialities +immateriality +immaterialize +immaterialized +immaterializes +immaterializing +immature +immaturely +immatures +immaturities +immaturity +immeasurable +immeasurableness +immeasurablenesses +immeasurably +immediacies +immediacy +immediate +immediately +immediateness +immediatenesses +immedicable +immedicably +immemorial +immemorially +immense +immensely +immenseness +immensenesses +immenser +immensest +immensities +immensity +immensurable +immerge +immerged +immerges +immerging +immerse +immersed +immerses +immersible +immersing +immersion +immersions +immesh +immeshed +immeshes +immeshing +immethodical +immethodically +immies +immigrant +immigrants +immigrate +immigrated +immigrates +immigrating +immigration +immigrational +immigrations +imminence +imminences +imminencies +imminency +imminent +imminently +immingle +immingled +immingles +immingling +immiscibilities +immiscibility +immiscible +immitigable +immitigably +immittance +immittances +immix +immixed +immixes +immixing +immixture +immixtures +immobile +immobilism +immobilisms +immobilities +immobility +immobilization +immobilizations +immobilize +immobilized +immobilizer +immobilizers +immobilizes +immobilizing +immoderacies +immoderacy +immoderate +immoderately +immoderateness +immoderatenesses +immoderation +immoderations +immodest +immodesties +immodestly +immodesty +immolate +immolated +immolates +immolating +immolation +immolations +immolator +immolators +immoral +immoralism +immoralisms +immoralist +immoralists +immoralities +immorality +immorally +immortal +immortalise +immortalised +immortalises +immortalising +immortalities +immortality +immortalization +immortalizations +immortalize +immortalized +immortalizer +immortalizers +immortalizes +immortalizing +immortally +immortals +immortelle +immortelles +immotile +immovabilities +immovability +immovable +immovableness +immovablenesses +immovables +immovably +immune +immunes +immunise +immunised +immunises +immunising +immunities +immunity +immunization +immunizations +immunize +immunized +immunizes +immunizing +immunoassay +immunoassayable +immunoassays +immunoblot +immunoblots +immunoblotting +immunoblottings +immunochemical +immunochemically +immunochemist +immunochemistries +immunochemistry +immunochemists +immunocompetence +immunocompetences +immunocompetent +immunocompromised +immunocytochemical +immunocytochemically +immunocytochemistries +immunocytochemistry +immunodeficiencies +immunodeficiency +immunodeficient +immunodiagnoses +immunodiagnosis +immunodiagnostic +immunodiffusion +immunodiffusions +immunoelectrophoreses +immunoelectrophoresis +immunoelectrophoretic +immunoelectrophoretically +immunofluorescence +immunofluorescences +immunofluorescent +immunogen +immunogeneses +immunogenesis +immunogenetic +immunogenetically +immunogeneticist +immunogeneticists +immunogenetics +immunogenic +immunogenicities +immunogenicity +immunogens +immunoglobulin +immunoglobulins +immunohematologic +immunohematological +immunohematologies +immunohematologist +immunohematologists +immunohematology +immunohistochemical +immunohistochemistries +immunohistochemistry +immunologic +immunological +immunologically +immunologies +immunologist +immunologists +immunology +immunomodulator +immunomodulators +immunomodulatory +immunopathologic +immunopathological +immunopathologies +immunopathologist +immunopathologists +immunopathology +immunoprecipitate +immunoprecipitated +immunoprecipitates +immunoprecipitating +immunoprecipitation +immunoprecipitations +immunoreactive +immunoreactivities +immunoreactivity +immunoregulation +immunoregulations +immunoregulatory +immunosorbent +immunosorbents +immunosuppress +immunosuppressant +immunosuppressants +immunosuppressed +immunosuppresses +immunosuppressing +immunosuppression +immunosuppressions +immunosuppressive +immunotherapeutic +immunotherapies +immunotherapy +immure +immured +immurement +immurements +immures +immuring +immutabilities +immutability +immutable +immutableness +immutablenesses +immutably +immy +imp +impact +impacted +impacter +impacters +impacting +impaction +impactions +impactive +impactor +impactors +impacts +impaint +impainted +impainting +impaints +impair +impaired +impairer +impairers +impairing +impairment +impairments +impairs +impala +impalas +impale +impaled +impalement +impalements +impaler +impalers +impales +impaling +impalpabilities +impalpability +impalpable +impalpably +impanel +impaneled +impaneling +impanelled +impanelling +impanels +imparadise +imparadised +imparadises +imparadising +imparities +imparity +impark +imparked +imparking +imparks +impart +impartation +impartations +imparted +imparter +imparters +impartial +impartialities +impartiality +impartially +impartible +impartibly +imparting +impartment +impartments +imparts +impassabilities +impassability +impassable +impassableness +impassablenesses +impassably +impasse +impasses +impassibilities +impassibility +impassible +impassibly +impassion +impassioned +impassioning +impassions +impassive +impassively +impassiveness +impassivenesses +impassivities +impassivity +impaste +impasted +impastes +impasting +impasto +impastoed +impastos +impatience +impatiences +impatiens +impatient +impatiently +impavid +impawn +impawned +impawning +impawns +impeach +impeachable +impeached +impeaches +impeaching +impeachment +impeachments +impearl +impearled +impearling +impearls +impeccabilities +impeccability +impeccable +impeccably +impecuniosities +impecuniosity +impecunious +impecuniously +impecuniousness +impecuniousnesses +imped +impedance +impedances +impede +impeded +impeder +impeders +impedes +impediment +impedimenta +impediments +impeding +impel +impelled +impeller +impellers +impelling +impellor +impellors +impels +impend +impended +impendent +impending +impends +impenetrabilities +impenetrability +impenetrable +impenetrably +impenitence +impenitences +impenitent +impenitently +imperative +imperatively +imperativeness +imperativenesses +imperatives +imperator +imperatorial +imperators +imperceivable +imperceptible +imperceptibly +imperceptive +imperceptiveness +imperceptivenesses +impercipience +impercipiences +impercipient +imperfect +imperfection +imperfections +imperfective +imperfectives +imperfectly +imperfectness +imperfectnesses +imperfects +imperforate +imperia +imperial +imperialism +imperialisms +imperialist +imperialistic +imperialistically +imperialists +imperially +imperials +imperil +imperiled +imperiling +imperilled +imperilling +imperilment +imperilments +imperils +imperious +imperiously +imperiousness +imperiousnesses +imperishabilities +imperishability +imperishable +imperishableness +imperishablenesses +imperishables +imperishably +imperium +imperiums +impermanence +impermanences +impermanencies +impermanency +impermanent +impermanently +impermeabilities +impermeability +impermeable +impermissibilities +impermissibility +impermissible +impermissibly +impersonal +impersonalities +impersonality +impersonalization +impersonalizations +impersonalize +impersonalized +impersonalizes +impersonalizing +impersonally +impersonate +impersonated +impersonates +impersonating +impersonation +impersonations +impersonator +impersonators +impertinence +impertinences +impertinencies +impertinency +impertinent +impertinently +imperturbabilities +imperturbability +imperturbable +imperturbably +impervious +imperviously +imperviousness +imperviousnesses +impetiginous +impetigo +impetigos +impetrate +impetrated +impetrates +impetrating +impetration +impetrations +impetuosities +impetuosity +impetuous +impetuously +impetuousness +impetuousnesses +impetus +impetuses +imphee +imphees +impi +impieties +impiety +imping +impinge +impinged +impingement +impingements +impinger +impingers +impinges +impinging +impings +impious +impiously +impis +impish +impishly +impishness +impishnesses +implacabilities +implacability +implacable +implacably +implant +implantable +implantation +implantations +implanted +implanter +implanters +implanting +implants +implausibilities +implausibility +implausible +implausibly +implead +impleaded +impleading +impleads +impledge +impledged +impledges +impledging +implement +implementation +implementations +implemented +implementer +implementers +implementing +implementor +implementors +implements +implicate +implicated +implicates +implicating +implication +implications +implicative +implicatively +implicativeness +implicativenesses +implicit +implicitly +implicitness +implicitnesses +implied +implies +implode +imploded +implodes +imploding +implore +implored +implorer +implorers +implores +imploring +imploringly +implosion +implosions +implosive +implosives +imply +implying +impolicies +impolicy +impolite +impolitely +impoliteness +impolitenesses +impolitic +impolitical +impolitically +impoliticly +imponderabilities +imponderability +imponderable +imponderables +imponderably +impone +imponed +impones +imponing +imporous +import +importable +importance +importances +importancies +importancy +important +importantly +importation +importations +imported +importer +importers +importing +imports +importunate +importunately +importunateness +importunatenesses +importune +importuned +importunely +importuner +importuners +importunes +importuning +importunities +importunity +impose +imposed +imposer +imposers +imposes +imposing +imposingly +imposition +impositions +impossibilities +impossibility +impossible +impossibleness +impossiblenesses +impossibly +impost +imposted +imposter +imposters +imposthume +imposthumes +imposting +impostor +impostors +imposts +impostume +impostumes +imposture +impostures +impotence +impotences +impotencies +impotency +impotent +impotently +impotents +impound +impounded +impounding +impoundment +impoundments +impounds +impoverish +impoverished +impoverisher +impoverishers +impoverishes +impoverishing +impoverishment +impoverishments +impower +impowered +impowering +impowers +impracticabilities +impracticability +impracticable +impracticably +impractical +impracticalities +impracticality +impractically +imprecate +imprecated +imprecates +imprecating +imprecation +imprecations +imprecatory +imprecise +imprecisely +impreciseness +imprecisenesses +imprecision +imprecisions +impregn +impregnabilities +impregnability +impregnable +impregnableness +impregnablenesses +impregnably +impregnant +impregnants +impregnate +impregnated +impregnates +impregnating +impregnation +impregnations +impregnator +impregnators +impregned +impregning +impregns +impresa +impresario +impresarios +impresas +imprese +impreses +impress +impressed +impresses +impressibilities +impressibility +impressible +impressing +impression +impressionabilities +impressionability +impressionable +impressionism +impressionisms +impressionist +impressionistic +impressionistically +impressionists +impressions +impressive +impressively +impressiveness +impressivenesses +impressment +impressments +impressure +impressures +imprest +imprests +imprimatur +imprimaturs +imprimis +imprint +imprinted +imprinter +imprinters +imprinting +imprintings +imprints +imprison +imprisoned +imprisoning +imprisonment +imprisonments +imprisons +improbabilities +improbability +improbable +improbably +impromptu +impromptus +improper +improperly +improperness +impropernesses +improprieties +impropriety +improv +improvabilities +improvability +improvable +improve +improved +improvement +improvements +improver +improvers +improves +improvidence +improvidences +improvident +improvidently +improving +improvisation +improvisational +improvisationally +improvisations +improvisator +improvisatore +improvisatores +improvisatori +improvisatorial +improvisators +improvisatory +improvise +improvised +improviser +improvisers +improvises +improvising +improvisor +improvisors +improvs +imprudence +imprudences +imprudent +imprudently +imps +impudence +impudences +impudent +impudently +impudicities +impudicity +impugn +impugnable +impugned +impugner +impugners +impugning +impugns +impuissance +impuissances +impuissant +impulse +impulsed +impulses +impulsing +impulsion +impulsions +impulsive +impulsively +impulsiveness +impulsivenesses +impulsivities +impulsivity +impunities +impunity +impure +impurely +impureness +impurenesses +impurities +impurity +imputabilities +imputability +imputable +imputation +imputations +imputative +imputatively +impute +imputed +imputer +imputers +imputes +imputing +in +inabilities +inability +inaccessibilities +inaccessibility +inaccessible +inaccessibly +inaccuracies +inaccuracy +inaccurate +inaccurately +inaction +inactions +inactivate +inactivated +inactivates +inactivating +inactivation +inactivations +inactive +inactively +inactivities +inactivity +inadequacies +inadequacy +inadequate +inadequately +inadequateness +inadequatenesses +inadmissibilities +inadmissibility +inadmissible +inadmissibly +inadvertence +inadvertences +inadvertencies +inadvertency +inadvertent +inadvertently +inadvisabilities +inadvisability +inadvisable +inalienabilities +inalienability +inalienable +inalienably +inalterabilities +inalterability +inalterable +inalterableness +inalterablenesses +inalterably +inamorata +inamoratas +inane +inanely +inaneness +inanenesses +inaner +inanes +inanest +inanimate +inanimately +inanimateness +inanimatenesses +inanities +inanition +inanitions +inanity +inapparent +inapparently +inappeasable +inappetence +inappetences +inapplicabilities +inapplicability +inapplicable +inapplicably +inapposite +inappositely +inappositeness +inappositenesses +inappreciable +inappreciably +inappreciative +inappreciatively +inappreciativeness +inappreciativenesses +inapproachable +inappropriate +inappropriately +inappropriateness +inappropriatenesses +inapt +inaptitude +inaptitudes +inaptly +inaptness +inaptnesses +inarable +inarch +inarched +inarches +inarching +inarguable +inarguably +inarm +inarmed +inarming +inarms +inarticulacies +inarticulacy +inarticulate +inarticulately +inarticulateness +inarticulatenesses +inarticulates +inartistic +inartistically +inattention +inattentions +inattentive +inattentively +inattentiveness +inattentivenesses +inaudibilities +inaudibility +inaudible +inaudibly +inaugural +inaugurals +inaugurate +inaugurated +inaugurates +inaugurating +inauguration +inaugurations +inaugurator +inaugurators +inauspicious +inauspiciously +inauspiciousness +inauspiciousnesses +inauthentic +inauthenticities +inauthenticity +inbeing +inbeings +inboard +inboards +inborn +inbound +inbounded +inbounding +inbounds +inbreathe +inbreathed +inbreathes +inbreathing +inbred +inbreds +inbreed +inbreeding +inbreedings +inbreeds +inbuilt +inburst +inbursts +inby +inbye +incage +incaged +incages +incaging +incalculabilities +incalculability +incalculable +incalculably +incalescence +incalescences +incalescent +incandesce +incandesced +incandescence +incandescences +incandescent +incandescently +incandescents +incandesces +incandescing +incant +incantation +incantational +incantations +incantatory +incanted +incanting +incants +incapabilities +incapability +incapable +incapableness +incapablenesses +incapably +incapacitate +incapacitated +incapacitates +incapacitating +incapacitation +incapacitations +incapacities +incapacity +incarcerate +incarcerated +incarcerates +incarcerating +incarceration +incarcerations +incardination +incardinations +incarnadine +incarnadined +incarnadines +incarnadining +incarnate +incarnated +incarnates +incarnating +incarnation +incarnations +incase +incased +incases +incasing +incaution +incautions +incautious +incautiously +incautiousness +incautiousnesses +incendiaries +incendiarism +incendiarisms +incendiary +incense +incensed +incenses +incensing +incenter +incenters +incentive +incentives +incept +incepted +incepting +inception +inceptions +inceptive +inceptively +inceptives +inceptor +inceptors +incepts +incertitude +incertitudes +incessancies +incessancy +incessant +incessantly +incest +incests +incestuous +incestuously +incestuousness +incestuousnesses +inch +inched +inches +inching +inchmeal +inchoate +inchoately +inchoateness +inchoatenesses +inchoative +inchoatively +inchoatives +inchworm +inchworms +incidence +incidences +incident +incidental +incidentally +incidentals +incidents +incinerate +incinerated +incinerates +incinerating +incineration +incinerations +incinerator +incinerators +incipience +incipiences +incipiencies +incipiency +incipient +incipiently +incipit +incipits +incisal +incise +incised +incises +incising +incision +incisions +incisive +incisively +incisiveness +incisivenesses +incisor +incisors +incisory +incisure +incisures +incitant +incitants +incitation +incitations +incite +incited +incitement +incitements +inciter +inciters +incites +inciting +incivil +incivilities +incivility +inclasp +inclasped +inclasping +inclasps +inclemencies +inclemency +inclement +inclemently +inclinable +inclination +inclinational +inclinations +incline +inclined +incliner +incliners +inclines +inclining +inclinings +inclinometer +inclinometers +inclip +inclipped +inclipping +inclips +inclose +inclosed +incloser +inclosers +incloses +inclosing +inclosure +inclosures +includable +include +included +includes +includible +including +inclusion +inclusions +inclusive +inclusively +inclusiveness +inclusivenesses +incoercible +incog +incogitant +incognita +incognitas +incognito +incognitos +incognizance +incognizances +incognizant +incogs +incoherence +incoherences +incoherent +incoherently +incombustibilities +incombustibility +incombustible +incombustibles +income +incomer +incomers +incomes +incoming +incomings +incommensurabilities +incommensurability +incommensurable +incommensurables +incommensurably +incommensurate +incommode +incommoded +incommodes +incommoding +incommodious +incommodiously +incommodiousness +incommodiousnesses +incommodities +incommodity +incommunicabilities +incommunicability +incommunicable +incommunicably +incommunicado +incommunicative +incommutable +incommutably +incomparabilities +incomparability +incomparable +incomparably +incompatibilities +incompatibility +incompatible +incompatibles +incompatibly +incompetence +incompetences +incompetencies +incompetency +incompetent +incompetently +incompetents +incomplete +incompletely +incompleteness +incompletenesses +incompliant +incomprehensibilities +incomprehensibility +incomprehensible +incomprehensibleness +incomprehensiblenesses +incomprehensibly +incomprehension +incomprehensions +incompressible +incomputable +incomputably +inconceivabilities +inconceivability +inconceivable +inconceivableness +inconceivablenesses +inconceivably +inconcinnities +inconcinnity +inconclusive +inconclusively +inconclusiveness +inconclusivenesses +incondite +inconformities +inconformity +incongruence +incongruences +incongruent +incongruently +incongruities +incongruity +incongruous +incongruously +incongruousness +incongruousnesses +inconnu +inconnus +inconscient +inconsecutive +inconsequence +inconsequences +inconsequent +inconsequential +inconsequentialities +inconsequentiality +inconsequentially +inconsequently +inconsiderable +inconsiderableness +inconsiderablenesses +inconsiderably +inconsiderate +inconsiderately +inconsiderateness +inconsideratenesses +inconsideration +inconsiderations +inconsistence +inconsistences +inconsistencies +inconsistency +inconsistent +inconsistently +inconsolable +inconsolableness +inconsolablenesses +inconsolably +inconsonance +inconsonances +inconsonant +inconspicuous +inconspicuously +inconspicuousness +inconspicuousnesses +inconstancies +inconstancy +inconstant +inconstantly +inconsumable +inconsumably +incontestabilities +incontestability +incontestable +incontestably +incontinence +incontinences +incontinencies +incontinency +incontinent +incontinently +incontrollable +incontrovertible +incontrovertibly +inconvenience +inconvenienced +inconveniences +inconveniencies +inconveniencing +inconveniency +inconvenient +inconveniently +inconvertibilities +inconvertibility +inconvertible +inconvertibly +inconvincible +incony +incoordination +incoordinations +incorporable +incorporate +incorporated +incorporates +incorporating +incorporation +incorporations +incorporative +incorporator +incorporators +incorporeal +incorporeally +incorporeities +incorporeity +incorpse +incorpsed +incorpses +incorpsing +incorrect +incorrectly +incorrectness +incorrectnesses +incorrigibilities +incorrigibility +incorrigible +incorrigibleness +incorrigiblenesses +incorrigibles +incorrigibly +incorrupt +incorrupted +incorruptibilities +incorruptibility +incorruptible +incorruptibles +incorruptibly +incorruption +incorruptions +incorruptly +incorruptness +incorruptnesses +increasable +increase +increased +increaser +increasers +increases +increasing +increasingly +increate +incredibilities +incredibility +incredible +incredibleness +incrediblenesses +incredibly +incredulities +incredulity +incredulous +incredulously +increment +incremental +incrementalism +incrementalisms +incrementalist +incrementalists +incrementally +incremented +incrementing +increments +increscent +incriminate +incriminated +incriminates +incriminating +incrimination +incriminations +incriminatory +incross +incrossed +incrosses +incrossing +incrust +incrustation +incrustations +incrusted +incrusting +incrusts +incubate +incubated +incubates +incubating +incubation +incubations +incubative +incubator +incubators +incubatory +incubi +incubus +incubuses +incudal +incudate +incudes +inculcate +inculcated +inculcates +inculcating +inculcation +inculcations +inculcator +inculcators +inculpable +inculpate +inculpated +inculpates +inculpating +inculpation +inculpations +inculpatory +incult +incumbencies +incumbency +incumbent +incumbents +incumber +incumbered +incumbering +incumbers +incunable +incunables +incunabula +incunabulum +incur +incurable +incurables +incurably +incuriosities +incuriosity +incurious +incuriously +incuriousness +incuriousnesses +incurred +incurrence +incurrences +incurrent +incurring +incurs +incursion +incursions +incurvate +incurvated +incurvates +incurvating +incurvation +incurvations +incurvature +incurvatures +incurve +incurved +incurves +incurving +incus +incuse +incused +incuses +incusing +indaba +indabas +indagate +indagated +indagates +indagating +indagation +indagations +indagator +indagators +indamin +indamine +indamines +indamins +indebted +indebtedness +indebtednesses +indecencies +indecency +indecent +indecenter +indecentest +indecently +indecipherable +indecision +indecisions +indecisive +indecisively +indecisiveness +indecisivenesses +indeclinable +indecomposable +indecorous +indecorously +indecorousness +indecorousnesses +indecorum +indecorums +indeed +indefatigabilities +indefatigability +indefatigable +indefatigableness +indefatigablenesses +indefatigably +indefeasibilities +indefeasibility +indefeasible +indefeasibly +indefectibilities +indefectibility +indefectible +indefectibly +indefensibilities +indefensibility +indefensible +indefensibly +indefinabilities +indefinability +indefinable +indefinableness +indefinablenesses +indefinables +indefinably +indefinite +indefinitely +indefiniteness +indefinitenesses +indefinites +indehiscence +indehiscences +indehiscent +indelibilities +indelibility +indelible +indelibly +indelicacies +indelicacy +indelicate +indelicately +indelicateness +indelicatenesses +indemnification +indemnifications +indemnified +indemnifier +indemnifiers +indemnifies +indemnify +indemnifying +indemnities +indemnity +indemonstrable +indemonstrably +indene +indenes +indent +indentation +indentations +indented +indenter +indenters +indenting +indention +indentions +indentor +indentors +indents +indenture +indentured +indentures +indenturing +independence +independences +independencies +independency +independent +independently +independents +indescribable +indescribableness +indescribablenesses +indescribably +indestructibilities +indestructibility +indestructible +indestructibleness +indestructiblenesses +indestructibly +indeterminable +indeterminably +indeterminacies +indeterminacy +indeterminate +indeterminately +indeterminateness +indeterminatenesses +indetermination +indeterminations +indeterminism +indeterminisms +indeterminist +indeterministic +indeterminists +indevout +index +indexation +indexations +indexed +indexer +indexers +indexes +indexical +indexicals +indexing +indexings +indican +indicans +indicant +indicants +indicate +indicated +indicates +indicating +indication +indicational +indications +indicative +indicatively +indicatives +indicator +indicators +indicatory +indices +indicia +indicias +indicium +indiciums +indict +indictable +indicted +indictee +indictees +indicter +indicters +indicting +indiction +indictions +indictment +indictments +indictor +indictors +indicts +indie +indies +indifference +indifferences +indifferencies +indifferency +indifferent +indifferentism +indifferentisms +indifferentist +indifferentists +indifferently +indigen +indigence +indigences +indigene +indigenes +indigenization +indigenizations +indigenize +indigenized +indigenizes +indigenizing +indigenous +indigenously +indigenousness +indigenousnesses +indigens +indigent +indigents +indigested +indigestibilities +indigestibility +indigestible +indigestibles +indigestion +indigestions +indign +indignant +indignantly +indignation +indignations +indignities +indignity +indignly +indigo +indigoes +indigoid +indigoids +indigos +indigotin +indigotins +indirect +indirection +indirections +indirectly +indirectness +indirectnesses +indiscernible +indisciplinable +indiscipline +indisciplined +indisciplines +indiscoverable +indiscreet +indiscreetly +indiscreetness +indiscreetnesses +indiscretion +indiscretions +indiscriminate +indiscriminately +indiscriminateness +indiscriminatenesses +indiscriminating +indiscriminatingly +indiscrimination +indiscriminations +indispensabilities +indispensability +indispensable +indispensableness +indispensablenesses +indispensables +indispensably +indispose +indisposed +indisposes +indisposing +indisposition +indispositions +indisputable +indisputableness +indisputablenesses +indisputably +indissociable +indissociably +indissolubilities +indissolubility +indissoluble +indissolubleness +indissolublenesses +indissolubly +indistinct +indistinctive +indistinctly +indistinctness +indistinctnesses +indistinguishabilities +indistinguishability +indistinguishable +indistinguishableness +indistinguishablenesses +indistinguishably +indite +indited +inditer +inditers +indites +inditing +indium +indiums +individual +individualise +individualised +individualises +individualising +individualism +individualisms +individualist +individualistic +individualistically +individualists +individualities +individuality +individualization +individualizations +individualize +individualized +individualizes +individualizing +individually +individuals +individuate +individuated +individuates +individuating +individuation +individuations +indivisibilities +indivisibility +indivisible +indivisibles +indivisibly +indocile +indocilities +indocility +indoctrinate +indoctrinated +indoctrinates +indoctrinating +indoctrination +indoctrinations +indoctrinator +indoctrinators +indol +indole +indolence +indolences +indolent +indolently +indoles +indols +indomethacin +indomethacins +indomitabilities +indomitability +indomitable +indomitableness +indomitablenesses +indomitably +indoor +indoors +indophenol +indophenols +indorse +indorsed +indorsee +indorsees +indorsement +indorsements +indorser +indorsers +indorses +indorsing +indorsor +indorsors +indow +indowed +indowing +indows +indoxyl +indoxyls +indraft +indrafts +indrawn +indri +indris +indubitabilities +indubitability +indubitable +indubitableness +indubitablenesses +indubitably +induce +induced +inducement +inducements +inducer +inducers +induces +inducibilities +inducibility +inducible +inducing +induct +inductance +inductances +inducted +inductee +inductees +inducting +induction +inductions +inductive +inductively +inductor +inductors +inducts +indue +indued +indues +induing +indulge +indulged +indulgence +indulgences +indulgent +indulgently +indulger +indulgers +indulges +indulging +indulin +induline +indulines +indulins +indult +indults +indurate +indurated +indurates +indurating +induration +indurations +indurative +indusia +indusial +indusium +industrial +industrialise +industrialised +industrialises +industrialising +industrialism +industrialisms +industrialist +industrialists +industrialization +industrializations +industrialize +industrialized +industrializes +industrializing +industrially +industrials +industries +industrious +industriously +industriousness +industriousnesses +industry +indwell +indweller +indwellers +indwelling +indwells +indwelt +inearth +inearthed +inearthing +inearths +inebriant +inebriants +inebriate +inebriated +inebriates +inebriating +inebriation +inebriations +inebrieties +inebriety +inedible +inedita +inedited +ineducabilities +ineducability +ineducable +ineffabilities +ineffability +ineffable +ineffableness +ineffablenesses +ineffably +ineffaceabilities +ineffaceability +ineffaceable +ineffaceably +ineffective +ineffectively +ineffectiveness +ineffectivenesses +ineffectual +ineffectualities +ineffectuality +ineffectually +ineffectualness +ineffectualnesses +inefficacies +inefficacious +inefficaciously +inefficaciousness +inefficaciousnesses +inefficacy +inefficiencies +inefficiency +inefficient +inefficiently +inefficients +inegalitarian +inelastic +inelasticities +inelasticity +inelegance +inelegances +inelegant +inelegantly +ineligibilities +ineligibility +ineligible +ineligibles +ineloquent +ineloquently +ineluctabilities +ineluctability +ineluctable +ineluctably +ineludible +inenarrable +inept +ineptitude +ineptitudes +ineptly +ineptness +ineptnesses +inequalities +inequality +inequitable +inequitably +inequities +inequity +inequivalve +inequivalved +ineradicabilities +ineradicability +ineradicable +ineradicably +inerrancies +inerrancy +inerrant +inert +inertia +inertiae +inertial +inertially +inertias +inertly +inertness +inertnesses +inerts +inescapable +inescapably +inessential +inessentials +inestimable +inestimably +inevitabilities +inevitability +inevitable +inevitableness +inevitablenesses +inevitably +inexact +inexactitude +inexactitudes +inexactly +inexactness +inexactnesses +inexcusable +inexcusableness +inexcusablenesses +inexcusably +inexhaustibilities +inexhaustibility +inexhaustible +inexhaustibleness +inexhaustiblenesses +inexhaustibly +inexistence +inexistences +inexistent +inexorabilities +inexorability +inexorable +inexorableness +inexorablenesses +inexorably +inexpedience +inexpediences +inexpediencies +inexpediency +inexpedient +inexpediently +inexpensive +inexpensively +inexpensiveness +inexpensivenesses +inexperience +inexperienced +inexperiences +inexpert +inexpertly +inexpertness +inexpertnesses +inexperts +inexpiable +inexpiably +inexplainable +inexplicabilities +inexplicability +inexplicable +inexplicableness +inexplicablenesses +inexplicably +inexplicit +inexpressibilities +inexpressibility +inexpressible +inexpressibleness +inexpressiblenesses +inexpressibly +inexpressive +inexpressively +inexpressiveness +inexpressivenesses +inexpugnable +inexpugnableness +inexpugnablenesses +inexpugnably +inexpungible +inextinguishable +inextinguishably +inextricabilities +inextricability +inextricable +inextricably +infall +infallibilities +infallibility +infallible +infallibly +infalling +infalls +infamies +infamous +infamously +infamy +infancies +infancy +infant +infanta +infantas +infante +infantes +infanticidal +infanticide +infanticides +infantile +infantilism +infantilisms +infantilities +infantility +infantilization +infantilizations +infantilize +infantilized +infantilizes +infantilizing +infantine +infantries +infantry +infantryman +infantrymen +infants +infarct +infarcted +infarction +infarctions +infarcts +infare +infares +infatuate +infatuated +infatuates +infatuating +infatuation +infatuations +infauna +infaunae +infaunal +infaunas +infeasibilities +infeasibility +infeasible +infect +infected +infecter +infecters +infecting +infection +infections +infectious +infectiously +infectiousness +infectiousnesses +infective +infectivities +infectivity +infector +infectors +infects +infecund +infelicities +infelicitous +infelicitously +infelicity +infeoff +infeoffed +infeoffing +infeoffs +infer +inferable +inference +inferences +inferential +inferentially +inferior +inferiorities +inferiority +inferiorly +inferiors +infernal +infernally +inferno +infernos +inferred +inferrer +inferrers +inferrible +inferring +infers +infertile +infertilities +infertility +infest +infestant +infestants +infestation +infestations +infested +infester +infesters +infesting +infests +infibulate +infibulated +infibulates +infibulating +infibulation +infibulations +infidel +infidelities +infidelity +infidels +infield +infielder +infielders +infields +infight +infighter +infighters +infighting +infightings +infights +infiltrate +infiltrated +infiltrates +infiltrating +infiltration +infiltrations +infiltrative +infiltrator +infiltrators +infinite +infinitely +infiniteness +infinitenesses +infinites +infinitesimal +infinitesimally +infinitesimals +infinities +infinitival +infinitive +infinitively +infinitives +infinitude +infinitudes +infinity +infirm +infirmaries +infirmary +infirmed +infirming +infirmities +infirmity +infirmly +infirms +infix +infixation +infixations +infixed +infixes +infixing +infixion +infixions +inflame +inflamed +inflamer +inflamers +inflames +inflaming +inflammabilities +inflammability +inflammable +inflammableness +inflammablenesses +inflammables +inflammably +inflammation +inflammations +inflammatorily +inflammatory +inflatable +inflatables +inflate +inflated +inflater +inflaters +inflates +inflating +inflation +inflationary +inflationism +inflationisms +inflationist +inflationists +inflations +inflator +inflators +inflect +inflectable +inflected +inflecting +inflection +inflectional +inflectionally +inflections +inflective +inflects +inflexed +inflexibilities +inflexibility +inflexible +inflexibleness +inflexiblenesses +inflexibly +inflexion +inflexions +inflict +inflicted +inflicter +inflicters +inflicting +infliction +inflictions +inflictive +inflictor +inflictors +inflicts +inflight +inflorescence +inflorescences +inflow +inflows +influence +influenceable +influenced +influences +influencing +influent +influential +influentially +influentials +influents +influenza +influenzal +influenzas +influx +influxes +info +infold +infolded +infolder +infolders +infolding +infolds +infomercial +infomercials +inform +informal +informalities +informality +informally +informant +informants +informatics +information +informational +informationally +informations +informative +informatively +informativeness +informativenesses +informatorily +informatory +informed +informedly +informer +informers +informing +informs +infos +infotainment +infotainments +infought +infra +infract +infracted +infracting +infraction +infractions +infracts +infrahuman +infrahumans +infrangibilities +infrangibility +infrangible +infrangibly +infrared +infrareds +infrasonic +infraspecific +infrastructure +infrastructures +infrequence +infrequences +infrequencies +infrequency +infrequent +infrequently +infringe +infringed +infringement +infringements +infringer +infringers +infringes +infringing +infrugal +infundibula +infundibular +infundibuliform +infundibulum +infuriate +infuriated +infuriates +infuriating +infuriatingly +infuriation +infuriations +infuse +infused +infuser +infusers +infuses +infusibilities +infusibility +infusible +infusibleness +infusiblenesses +infusing +infusion +infusions +infusive +infusorian +infusorians +ingate +ingates +ingather +ingathered +ingathering +ingatherings +ingathers +ingenious +ingeniously +ingeniousness +ingeniousnesses +ingenue +ingenues +ingenuities +ingenuity +ingenuous +ingenuously +ingenuousness +ingenuousnesses +ingest +ingesta +ingested +ingestible +ingesting +ingestion +ingestions +ingestive +ingests +ingle +inglenook +inglenooks +ingles +inglorious +ingloriously +ingloriousness +ingloriousnesses +ingoing +ingot +ingoted +ingoting +ingots +ingraft +ingrafted +ingrafting +ingrafts +ingrain +ingrained +ingrainedly +ingraining +ingrains +ingrate +ingrates +ingratiate +ingratiated +ingratiates +ingratiating +ingratiatingly +ingratiation +ingratiations +ingratiatory +ingratitude +ingratitudes +ingredient +ingredients +ingress +ingresses +ingression +ingressions +ingressive +ingressiveness +ingressivenesses +ingressives +ingroup +ingroups +ingrowing +ingrown +ingrownness +ingrownnesses +ingrowth +ingrowths +inguinal +ingulf +ingulfed +ingulfing +ingulfs +ingurgitate +ingurgitated +ingurgitates +ingurgitating +ingurgitation +ingurgitations +inhabit +inhabitable +inhabitancies +inhabitancy +inhabitant +inhabitants +inhabitation +inhabitations +inhabited +inhabiter +inhabiters +inhabiting +inhabits +inhalant +inhalants +inhalation +inhalational +inhalations +inhalator +inhalators +inhale +inhaled +inhaler +inhalers +inhales +inhaling +inharmonic +inharmonies +inharmonious +inharmoniously +inharmoniousness +inharmoniousnesses +inharmony +inhaul +inhauler +inhaulers +inhauls +inhere +inhered +inherence +inherences +inherent +inherently +inheres +inhering +inherit +inheritabilities +inheritability +inheritable +inheritableness +inheritablenesses +inheritance +inheritances +inherited +inheriting +inheritor +inheritors +inheritress +inheritresses +inheritrices +inheritrix +inheritrixes +inherits +inhesion +inhesions +inhibin +inhibins +inhibit +inhibited +inhibiting +inhibition +inhibitions +inhibitive +inhibitor +inhibitors +inhibitory +inhibits +inholding +inholdings +inhomogeneities +inhomogeneity +inhomogeneous +inhospitable +inhospitableness +inhospitablenesses +inhospitably +inhospitalities +inhospitality +inhuman +inhumane +inhumanely +inhumanities +inhumanity +inhumanly +inhumanness +inhumannesses +inhumation +inhumations +inhume +inhumed +inhumer +inhumers +inhumes +inhuming +inia +inimical +inimically +inimitable +inimitableness +inimitablenesses +inimitably +inion +iniquities +iniquitous +iniquitously +iniquitousness +iniquitousnesses +iniquity +initial +initialed +initialing +initialism +initialisms +initialization +initializations +initialize +initialized +initializes +initializing +initialled +initialling +initially +initialness +initialnesses +initials +initiate +initiated +initiates +initiating +initiation +initiations +initiative +initiatives +initiator +initiators +initiatory +inject +injectable +injectables +injectant +injectants +injected +injecting +injection +injections +injective +injector +injectors +injects +injudicious +injudiciously +injudiciousness +injudiciousnesses +injunction +injunctions +injunctive +injure +injured +injurer +injurers +injures +injuries +injuring +injurious +injuriously +injuriousness +injuriousnesses +injury +injustice +injustices +ink +inkberries +inkberry +inkblot +inkblots +inked +inker +inkers +inkhorn +inkhorns +inkier +inkiest +inkiness +inkinesses +inking +inkjet +inkle +inkles +inkless +inklike +inkling +inklings +inkpot +inkpots +inks +inkstand +inkstands +inkstone +inkstones +inkwell +inkwells +inkwood +inkwoods +inky +inlace +inlaced +inlaces +inlacing +inlaid +inland +inlander +inlanders +inlands +inlay +inlayer +inlayers +inlaying +inlays +inlet +inlets +inletting +inlier +inliers +inly +inmate +inmates +inmesh +inmeshed +inmeshes +inmeshing +inmost +inn +innards +innate +innately +innateness +innatenesses +inned +inner +innerly +innermost +innermosts +inners +innersole +innersoles +innerspring +innervate +innervated +innervates +innervating +innervation +innervations +innerve +innerved +innerves +innerving +inning +innings +innkeeper +innkeepers +innless +innocence +innocences +innocencies +innocency +innocent +innocenter +innocentest +innocently +innocents +innocuous +innocuously +innocuousness +innocuousnesses +innominate +innovate +innovated +innovates +innovating +innovation +innovational +innovations +innovative +innovatively +innovativeness +innovativenesses +innovator +innovators +innovatory +inns +innuendo +innuendoed +innuendoes +innuendoing +innuendos +innumerable +innumerably +innumeracies +innumeracy +innumerate +innumerates +innumerous +inobservance +inobservances +inobservant +inocula +inoculant +inoculants +inoculate +inoculated +inoculates +inoculating +inoculation +inoculations +inoculative +inoculator +inoculators +inoculum +inoculums +inoffensive +inoffensively +inoffensiveness +inoffensivenesses +inoperable +inoperative +inoperativeness +inoperativenesses +inoperculate +inoperculates +inopportune +inopportunely +inopportuneness +inopportunenesses +inordinate +inordinately +inordinateness +inordinatenesses +inorganic +inorganically +inosculate +inosculated +inosculates +inosculating +inosculation +inosculations +inosite +inosites +inositol +inositols +inotropic +inpatient +inpatients +inphase +inpour +inpoured +inpouring +inpourings +inpours +input +inputs +inputted +inputting +inquest +inquests +inquiet +inquieted +inquieting +inquiets +inquietude +inquietudes +inquiline +inquilines +inquire +inquired +inquirer +inquirers +inquires +inquiries +inquiring +inquiringly +inquiry +inquisition +inquisitional +inquisitions +inquisitive +inquisitively +inquisitiveness +inquisitivenesses +inquisitor +inquisitorial +inquisitorially +inquisitors +inro +inroad +inroads +inrush +inrushes +ins +insalubrious +insalubrities +insalubrity +insane +insanely +insaneness +insanenesses +insaner +insanest +insanitary +insanitation +insanitations +insanities +insanity +insatiabilities +insatiability +insatiable +insatiableness +insatiablenesses +insatiably +insatiate +insatiately +insatiateness +insatiatenesses +inscape +inscapes +inscribe +inscribed +inscriber +inscribers +inscribes +inscribing +inscription +inscriptional +inscriptions +inscriptive +inscriptively +inscroll +inscrolled +inscrolling +inscrolls +inscrutabilities +inscrutability +inscrutable +inscrutableness +inscrutablenesses +inscrutably +insculp +insculped +insculping +insculps +inseam +inseams +insect +insectan +insectaries +insectary +insecticidal +insecticidally +insecticide +insecticides +insectile +insectivore +insectivores +insectivorous +insects +insecure +insecurely +insecureness +insecurenesses +insecurities +insecurity +inselberg +inselberge +inselbergs +inseminate +inseminated +inseminates +inseminating +insemination +inseminations +inseminator +inseminators +insensate +insensately +insensibilities +insensibility +insensible +insensibleness +insensiblenesses +insensibly +insensitive +insensitively +insensitiveness +insensitivenesses +insensitivities +insensitivity +insentience +insentiences +insentient +inseparabilities +inseparability +inseparable +inseparableness +inseparablenesses +inseparables +inseparably +insert +inserted +inserter +inserters +inserting +insertion +insertional +insertions +inserts +inset +insets +insetted +insetter +insetters +insetting +insheath +insheathed +insheathing +insheaths +inshore +inshrine +inshrined +inshrines +inshrining +inside +insider +insiders +insides +insidious +insidiously +insidiousness +insidiousnesses +insight +insightful +insightfully +insights +insigne +insignia +insignias +insignificance +insignificances +insignificancies +insignificancy +insignificant +insignificantly +insincere +insincerely +insincerities +insincerity +insinuate +insinuated +insinuates +insinuating +insinuatingly +insinuation +insinuations +insinuative +insinuator +insinuators +insipid +insipidities +insipidity +insipidly +insist +insisted +insistence +insistences +insistencies +insistency +insistent +insistently +insister +insisters +insisting +insists +insnare +insnared +insnarer +insnarers +insnares +insnaring +insobrieties +insobriety +insociabilities +insociability +insociable +insociably +insofar +insolate +insolated +insolates +insolating +insolation +insolations +insole +insolence +insolences +insolent +insolently +insolents +insoles +insolubilities +insolubility +insolubilization +insolubilizations +insolubilize +insolubilized +insolubilizes +insolubilizing +insoluble +insolubleness +insolublenesses +insolubles +insolubly +insolvable +insolvably +insolvencies +insolvency +insolvent +insolvents +insomnia +insomniac +insomniacs +insomnias +insomuch +insouciance +insouciances +insouciant +insouciantly +insoul +insouled +insouling +insouls +inspan +inspanned +inspanning +inspans +inspect +inspected +inspecting +inspection +inspections +inspective +inspector +inspectorate +inspectorates +inspectors +inspectorship +inspectorships +inspects +insphere +insphered +inspheres +insphering +inspiration +inspirational +inspirationally +inspirations +inspirator +inspirators +inspiratory +inspire +inspired +inspirer +inspirers +inspires +inspiring +inspiringly +inspirit +inspirited +inspiriting +inspiritingly +inspirits +inspissate +inspissated +inspissates +inspissating +inspissation +inspissations +inspissator +inspissators +instabilities +instability +instable +instal +install +installation +installations +installed +installer +installers +installing +installment +installments +installs +instalment +instalments +instals +instance +instanced +instances +instancies +instancing +instancy +instant +instantaneities +instantaneity +instantaneous +instantaneously +instantaneousness +instantaneousnesses +instanter +instantiate +instantiated +instantiates +instantiating +instantiation +instantiations +instantly +instantness +instantnesses +instants +instar +instarred +instarring +instars +instate +instated +instates +instating +instauration +instaurations +instead +instep +insteps +instigate +instigated +instigates +instigating +instigation +instigations +instigative +instigator +instigators +instil +instill +instillation +instillations +instilled +instiller +instillers +instilling +instillment +instillments +instills +instils +instinct +instinctive +instinctively +instincts +instinctual +instinctually +institute +instituted +instituter +instituters +institutes +instituting +institution +institutional +institutionalise +institutionalised +institutionalises +institutionalising +institutionalism +institutionalisms +institutionalist +institutionalists +institutionalization +institutionalizations +institutionalize +institutionalized +institutionalizes +institutionalizing +institutionally +institutions +institutor +institutors +instroke +instrokes +instruct +instructed +instructing +instruction +instructional +instructions +instructive +instructively +instructiveness +instructivenesses +instructor +instructors +instructorship +instructorships +instructress +instructresses +instructs +instrument +instrumental +instrumentalism +instrumentalisms +instrumentalist +instrumentalists +instrumentalities +instrumentality +instrumentally +instrumentals +instrumentation +instrumentations +instrumented +instrumenting +instruments +insubordinate +insubordinately +insubordinates +insubordination +insubordinations +insubstantial +insubstantialities +insubstantiality +insufferable +insufferableness +insufferablenesses +insufferably +insufficiencies +insufficiency +insufficient +insufficiently +insufflate +insufflated +insufflates +insufflating +insufflation +insufflations +insufflator +insufflators +insulant +insulants +insular +insularism +insularisms +insularities +insularity +insularly +insulars +insulate +insulated +insulates +insulating +insulation +insulations +insulator +insulators +insulin +insulins +insult +insulted +insulter +insulters +insulting +insultingly +insults +insuperable +insuperably +insupportable +insupportably +insuppressible +insurabilities +insurability +insurable +insurance +insurances +insurant +insurants +insure +insured +insureds +insurer +insurers +insures +insurgence +insurgences +insurgencies +insurgency +insurgent +insurgently +insurgents +insuring +insurmountable +insurmountably +insurrection +insurrectional +insurrectionaries +insurrectionary +insurrectionist +insurrectionists +insurrections +insusceptibilities +insusceptibility +insusceptible +insusceptibly +inswathe +inswathed +inswathes +inswathing +inswept +intact +intactness +intactnesses +intagli +intaglio +intaglioed +intaglioing +intaglios +intake +intakes +intangibilities +intangibility +intangible +intangibleness +intangiblenesses +intangibles +intangibly +intarsia +intarsias +integer +integers +integrabilities +integrability +integrable +integral +integralities +integrality +integrally +integrals +integrand +integrands +integrate +integrated +integrates +integrating +integration +integrationist +integrationists +integrations +integrative +integrator +integrators +integrities +integrity +integument +integumentary +integuments +intellect +intellection +intellections +intellective +intellectively +intellects +intellectual +intellectualism +intellectualisms +intellectualist +intellectualistic +intellectualists +intellectualities +intellectuality +intellectualization +intellectualizations +intellectualize +intellectualized +intellectualizer +intellectualizers +intellectualizes +intellectualizing +intellectually +intellectualness +intellectualnesses +intellectuals +intelligence +intelligencer +intelligencers +intelligences +intelligent +intelligential +intelligently +intelligentsia +intelligentsias +intelligibilities +intelligibility +intelligible +intelligibleness +intelligiblenesses +intelligibly +intemperance +intemperances +intemperate +intemperately +intemperateness +intemperatenesses +intend +intendance +intendances +intendant +intendants +intended +intendedly +intendeds +intender +intenders +intending +intendment +intendments +intends +intenerate +intenerated +intenerates +intenerating +inteneration +intenerations +intense +intensely +intenseness +intensenesses +intenser +intensest +intensification +intensifications +intensified +intensifier +intensifiers +intensifies +intensify +intensifying +intension +intensional +intensionalities +intensionality +intensionally +intensions +intensities +intensity +intensive +intensively +intensiveness +intensivenesses +intensives +intent +intention +intentional +intentionalities +intentionality +intentionally +intentions +intently +intentness +intentnesses +intents +inter +interabang +interabangs +interact +interactant +interactants +interacted +interacting +interaction +interactional +interactions +interactive +interactively +interacts +interage +interagency +interallelic +interallied +interanimation +interanimations +interannual +interassociation +interassociations +interatomic +interavailabilities +interavailability +interbank +interbasin +interbed +interbedded +interbedding +interbeds +interbehavior +interbehavioral +interbehaviors +interborough +interboroughs +interbranch +interbred +interbreed +interbreeding +interbreeds +intercalary +intercalate +intercalated +intercalates +intercalating +intercalation +intercalations +intercalibration +intercalibrations +intercampus +intercaste +intercede +interceded +interceder +interceders +intercedes +interceding +intercell +intercellular +intercensal +intercept +intercepted +intercepter +intercepters +intercepting +interception +interceptions +interceptor +interceptors +intercepts +intercession +intercessional +intercessions +intercessor +intercessors +intercessory +interchain +interchained +interchaining +interchains +interchange +interchangeabilities +interchangeability +interchangeable +interchangeableness +interchangeablenesses +interchangeably +interchanged +interchanger +interchangers +interchanges +interchanging +interchannel +interchromosomal +interchurch +intercity +interclan +interclass +interclub +intercluster +intercoastal +intercollegiate +intercolonial +intercolumniation +intercolumniations +intercom +intercommunal +intercommunicate +intercommunicated +intercommunicates +intercommunicating +intercommunication +intercommunications +intercommunion +intercommunions +intercommunities +intercommunity +intercompany +intercompare +intercompared +intercompares +intercomparing +intercomparison +intercomparisons +intercomprehensibilities +intercomprehensibility +intercoms +interconnect +interconnected +interconnectedness +interconnectednesses +interconnecting +interconnection +interconnections +interconnects +intercontinental +interconversion +interconversions +interconvert +interconverted +interconvertibilities +interconvertibility +interconvertible +interconverting +interconverts +intercooler +intercoolers +intercorporate +intercorrelate +intercorrelated +intercorrelates +intercorrelating +intercorrelation +intercorrelations +intercortical +intercostal +intercostals +intercountry +intercounty +intercouple +intercourse +intercourses +intercrater +intercrop +intercropped +intercropping +intercrops +intercross +intercrossed +intercrosses +intercrossing +intercrystalline +intercultural +interculturally +interculture +intercultures +intercurrent +intercut +intercuts +intercutting +interdealer +interdealers +interdenominational +interdental +interdentally +interdepartmental +interdepartmentally +interdepend +interdepended +interdependence +interdependences +interdependencies +interdependency +interdependent +interdependently +interdepending +interdepends +interdialectal +interdict +interdicted +interdicting +interdiction +interdictions +interdictive +interdictor +interdictors +interdictory +interdicts +interdiffuse +interdiffused +interdiffuses +interdiffusing +interdiffusion +interdiffusions +interdigitate +interdigitated +interdigitates +interdigitating +interdigitation +interdigitations +interdisciplinary +interdistrict +interdivisional +interdominion +interelectrode +interelectrodes +interelectron +interelectronic +interepidemic +interest +interested +interestedly +interesting +interestingly +interestingness +interestingnesses +interests +interethnic +interface +interfaced +interfaces +interfacial +interfacing +interfacings +interfaculties +interfaculty +interfaith +interfamilial +interfamily +interfere +interfered +interference +interferences +interferential +interferer +interferers +interferes +interfering +interferogram +interferograms +interferometer +interferometers +interferometric +interferometrically +interferometries +interferometry +interferon +interferons +interfertile +interfertilities +interfertility +interfiber +interfile +interfiled +interfiles +interfiling +interfirm +interflow +interfluve +interfluves +interfluvial +interfold +interfolded +interfolding +interfolds +interfraternity +interfuse +interfused +interfuses +interfusing +interfusion +interfusions +intergalactic +intergang +intergeneration +intergenerational +intergenerations +intergeneric +interglacial +interglacials +intergovernmental +intergradation +intergradational +intergradations +intergrade +intergraded +intergrades +intergrading +intergraft +intergrafted +intergrafting +intergrafts +intergranular +intergroup +intergrowth +intergrowths +interhemispheric +interim +interims +interindividual +interindustry +interinfluence +interinfluenced +interinfluences +interinfluencing +interinstitutional +interinvolve +interinvolved +interinvolves +interinvolving +interionic +interior +interiorise +interiorised +interiorises +interiorising +interiorities +interiority +interiorization +interiorizations +interiorize +interiorized +interiorizes +interiorizing +interiorly +interiors +interisland +interject +interjected +interjecting +interjection +interjectional +interjectionally +interjections +interjector +interjectors +interjectory +interjects +interjurisdictional +interknit +interknits +interknitted +interknitting +interlace +interlaced +interlacement +interlacements +interlaces +interlacing +interlacustrine +interlaid +interlaminar +interlap +interlapped +interlapping +interlaps +interlard +interlarded +interlarding +interlards +interlay +interlayer +interlayered +interlayering +interlayers +interlaying +interlays +interleave +interleaved +interleaves +interleaving +interlend +interlending +interlends +interlent +interleukin +interleukins +interlibrary +interline +interlinear +interlinearly +interlinears +interlineation +interlineations +interlined +interliner +interliners +interlines +interlining +interlinings +interlink +interlinked +interlinking +interlinks +interlobular +interlocal +interlock +interlocked +interlocking +interlocks +interlocutor +interlocutors +interlocutory +interlope +interloped +interloper +interlopers +interlopes +interloping +interlude +interludes +interlunar +interlunary +intermale +intermarginal +intermarriage +intermarriages +intermarried +intermarries +intermarry +intermarrying +intermeddle +intermeddled +intermeddler +intermeddlers +intermeddles +intermeddling +intermediacies +intermediacy +intermediaries +intermediary +intermediate +intermediated +intermediately +intermediateness +intermediatenesses +intermediates +intermediating +intermediation +intermediations +intermedin +intermedins +intermembrane +intermenstrual +interment +interments +intermesh +intermeshed +intermeshes +intermeshing +intermetallic +intermetallics +intermezzi +intermezzo +intermezzos +interminable +interminableness +interminablenesses +interminably +intermingle +intermingled +intermingles +intermingling +interministerial +intermission +intermissionless +intermissions +intermit +intermitotic +intermits +intermitted +intermittence +intermittences +intermittencies +intermittency +intermittent +intermittently +intermitter +intermitters +intermitting +intermix +intermixed +intermixes +intermixing +intermixture +intermixtures +intermodal +intermodulation +intermodulations +intermolecular +intermolecularly +intermont +intermontane +intermountain +intermural +intern +internal +internalise +internalised +internalises +internalising +internalities +internality +internalization +internalizations +internalize +internalized +internalizes +internalizing +internally +internals +international +internationalise +internationalised +internationalises +internationalising +internationalism +internationalisms +internationalist +internationalists +internationalities +internationality +internationalization +internationalizations +internationalize +internationalized +internationalizes +internationalizing +internationally +internationals +interne +internecine +interned +internee +internees +internes +interneuron +interneuronal +interneurons +interning +internist +internists +internment +internments +internodal +internode +internodes +interns +internship +internships +internuclear +internucleon +internucleonic +internucleotide +internuncial +internuncio +internuncios +interobserver +interobservers +interocean +interoceanic +interoceptive +interoceptor +interoceptors +interoffice +interoperabilities +interoperability +interoperable +interoperative +interoperatives +interorbital +interorgan +interorganizational +interpandemic +interparish +interparochial +interparoxysmal +interparticle +interparty +interpellate +interpellated +interpellates +interpellating +interpellation +interpellations +interpellator +interpellators +interpenetrate +interpenetrated +interpenetrates +interpenetrating +interpenetration +interpenetrations +interperceptual +interpermeate +interpermeated +interpermeates +interpermeating +interpersonal +interpersonally +interphalangeal +interphase +interphases +interplanetary +interplant +interplanted +interplanting +interplants +interplay +interplayed +interplaying +interplays +interplead +interpleaded +interpleader +interpleaders +interpleading +interpleads +interpled +interpluvial +interpoint +interpoints +interpolate +interpolated +interpolates +interpolating +interpolation +interpolations +interpolative +interpolator +interpolators +interpopulation +interpopulational +interpose +interposed +interposer +interposers +interposes +interposing +interposition +interpositions +interpret +interpretabilities +interpretability +interpretable +interpretation +interpretational +interpretations +interpretative +interpretatively +interpreted +interpreter +interpreters +interpreting +interpretive +interpretively +interprets +interprofessional +interprovincial +interproximal +interpsychic +interpupillary +interracial +interracially +interred +interreges +interregional +interregna +interregnum +interregnums +interrelate +interrelated +interrelatedly +interrelatedness +interrelatednesses +interrelates +interrelating +interrelation +interrelations +interrelationship +interrelationships +interreligious +interrenal +interrex +interring +interrobang +interrobangs +interrogate +interrogated +interrogatee +interrogatees +interrogates +interrogating +interrogation +interrogational +interrogations +interrogative +interrogatively +interrogatives +interrogator +interrogatories +interrogators +interrogatory +interrogee +interrogees +interrow +interrupt +interrupted +interrupter +interrupters +interruptible +interrupting +interruption +interruptions +interruptive +interruptor +interruptors +interrupts +inters +interscholastic +interschool +interschools +intersect +intersected +intersecting +intersection +intersectional +intersections +intersects +intersegment +intersegmental +intersegments +intersensory +interservice +intersession +intersessions +intersex +intersexes +intersexual +intersexualities +intersexuality +intersexually +intersocietal +intersociety +interspace +interspaced +interspaces +interspacing +interspecies +interspecific +intersperse +interspersed +intersperses +interspersing +interspersion +interspersions +interstadial +interstadials +interstage +interstate +interstates +interstation +interstellar +intersterile +intersterilities +intersterility +interstice +interstices +interstimulation +interstimulations +interstimuli +interstimulus +interstitial +interstitially +interstrain +interstrains +interstrand +interstrands +interstratification +interstratifications +interstratified +interstratifies +interstratify +interstratifying +intersubjective +intersubjectively +intersubjectivities +intersubjectivity +intersubstitutabilities +intersubstitutability +intersubstitutable +intersystem +interterm +interterminal +interterritorial +intertestamental +intertidal +intertidally +intertie +interties +intertill +intertillage +intertillages +intertilled +intertilling +intertills +intertranslatable +intertrial +intertribal +intertroop +intertropical +intertwine +intertwined +intertwinement +intertwinements +intertwines +intertwining +intertwist +intertwisted +intertwisting +intertwists +interunion +interunions +interunit +interuniversity +interurban +interurbans +interval +intervale +intervales +intervalley +intervalleys +intervallic +intervalometer +intervalometers +intervals +intervene +intervened +intervener +interveners +intervenes +intervening +intervenor +intervenors +intervention +interventionism +interventionisms +interventionist +interventionists +interventions +interventricular +intervertebral +interview +interviewed +interviewee +interviewees +interviewer +interviewers +interviewing +interviews +intervillage +intervisibilities +intervisibility +intervisible +intervisitation +intervisitations +intervocalic +intervocalically +interwar +interweave +interweaved +interweaves +interweaving +interwork +interworked +interworking +interworkings +interworks +interwove +interwoven +interwrought +interzonal +interzone +intestacies +intestacy +intestate +intestates +intestinal +intestinally +intestine +intestines +inthral +inthrall +inthralled +inthralling +inthralls +inthrals +inthrone +inthroned +inthrones +inthroning +inti +intima +intimacies +intimacy +intimae +intimal +intimas +intimate +intimated +intimately +intimateness +intimatenesses +intimater +intimaters +intimates +intimating +intimation +intimations +intime +intimidate +intimidated +intimidates +intimidating +intimidatingly +intimidation +intimidations +intimidator +intimidators +intimidatory +intimist +intimists +intinction +intinctions +intine +intines +intis +intitle +intitled +intitles +intitling +intitule +intituled +intitules +intituling +into +intolerabilities +intolerability +intolerable +intolerableness +intolerablenesses +intolerably +intolerance +intolerances +intolerant +intolerantly +intolerantness +intolerantnesses +intomb +intombed +intombing +intombs +intonate +intonated +intonates +intonating +intonation +intonational +intonations +intone +intoned +intoner +intoners +intones +intoning +intort +intorted +intorting +intorts +intown +intoxicant +intoxicants +intoxicate +intoxicated +intoxicatedly +intoxicates +intoxicating +intoxication +intoxications +intracardiac +intracardial +intracardially +intracellular +intracellularly +intracerebral +intracerebrally +intracompany +intracranial +intracranially +intractabilities +intractability +intractable +intractably +intracutaneous +intracutaneously +intraday +intradermal +intradermally +intrados +intradoses +intragalactic +intragenic +intramolecular +intramolecularly +intramural +intramurally +intramuscular +intramuscularly +intranasal +intranasally +intransigeance +intransigeances +intransigeant +intransigeantly +intransigeants +intransigence +intransigences +intransigent +intransigently +intransigents +intransitive +intransitively +intransitiveness +intransitivenesses +intransitivities +intransitivity +intrant +intrants +intraocular +intraocularly +intraperitoneal +intraperitoneally +intrapersonal +intraplate +intrapopulation +intrapreneur +intrapreneurial +intrapreneurs +intrapsychic +intrapsychically +intraspecies +intraspecific +intrastate +intrathecal +intrathecally +intrathoracic +intrathoracically +intrauterine +intravascular +intravascularly +intravenous +intravenouses +intravenously +intraventricular +intraventricularly +intravital +intravitally +intravitam +intrazonal +intreat +intreated +intreating +intreats +intrench +intrenched +intrenches +intrenching +intrepid +intrepidities +intrepidity +intrepidly +intrepidness +intrepidnesses +intricacies +intricacy +intricate +intricately +intricateness +intricatenesses +intrigant +intrigants +intriguant +intriguants +intrigue +intrigued +intriguer +intriguers +intrigues +intriguing +intriguingly +intrinsic +intrinsical +intrinsically +intro +introduce +introduced +introducer +introducers +introduces +introducing +introduction +introductions +introductorily +introductory +introfied +introfies +introfy +introfying +introgressant +introgressants +introgression +introgressions +introgressive +introit +introits +introject +introjected +introjecting +introjection +introjections +introjects +intromission +intromissions +intromit +intromits +intromitted +intromittent +intromitter +intromitters +intromitting +intron +introns +introrse +intros +introspect +introspected +introspecting +introspection +introspectional +introspectionism +introspectionisms +introspectionist +introspectionistic +introspectionists +introspections +introspective +introspectively +introspectiveness +introspectivenesses +introspects +introversion +introversions +introversive +introversively +introvert +introverted +introverting +introverts +intrude +intruded +intruder +intruders +intrudes +intruding +intrusion +intrusions +intrusive +intrusively +intrusiveness +intrusivenesses +intrusives +intrust +intrusted +intrusting +intrusts +intubate +intubated +intubates +intubating +intubation +intubations +intuit +intuitable +intuited +intuiting +intuition +intuitional +intuitionism +intuitionisms +intuitionist +intuitionists +intuitions +intuitive +intuitively +intuitiveness +intuitivenesses +intuits +intumescence +intumescences +intumescent +inturn +inturned +inturns +intussuscept +intussuscepted +intussuscepting +intussusception +intussusceptions +intussusceptive +intussuscepts +intwine +intwined +intwines +intwining +intwist +intwisted +intwisting +intwists +inulase +inulases +inulin +inulins +inunction +inunctions +inundant +inundate +inundated +inundates +inundating +inundation +inundations +inundator +inundators +inundatory +inurbane +inure +inured +inurement +inurements +inures +inuring +inurn +inurned +inurning +inurns +inutile +inutilities +inutility +invade +invaded +invader +invaders +invades +invading +invaginate +invaginated +invaginates +invaginating +invagination +invaginations +invalid +invalidate +invalidated +invalidates +invalidating +invalidation +invalidations +invalidator +invalidators +invalided +invaliding +invalidism +invalidisms +invalidities +invalidity +invalidly +invalids +invaluable +invaluableness +invaluablenesses +invaluably +invar +invariabilities +invariability +invariable +invariables +invariably +invariance +invariances +invariant +invariants +invars +invasion +invasions +invasive +invasively +invasiveness +invasivenesses +invected +invective +invectively +invectiveness +invectivenesses +invectives +inveigh +inveighed +inveigher +inveighers +inveighing +inveighs +inveigle +inveigled +inveiglement +inveiglements +inveigler +inveiglers +inveigles +inveigling +invent +invented +inventer +inventers +inventing +invention +inventions +inventive +inventively +inventiveness +inventivenesses +inventor +inventorial +inventorially +inventoried +inventories +inventors +inventory +inventorying +inventress +inventresses +invents +inverities +inverity +inverness +invernesses +inverse +inversely +inverses +inversion +inversions +inversive +invert +invertase +invertases +invertebrate +invertebrates +inverted +inverter +inverters +invertible +inverting +invertor +invertors +inverts +invest +investable +invested +investigate +investigated +investigates +investigating +investigation +investigational +investigations +investigative +investigator +investigators +investigatory +investing +investiture +investitures +investment +investments +investor +investors +invests +inveteracies +inveteracy +inveterate +inveterately +inviabilities +inviability +inviable +inviably +invidious +invidiously +invidiousness +invidiousnesses +invigilate +invigilated +invigilates +invigilating +invigilation +invigilations +invigilator +invigilators +invigorate +invigorated +invigorates +invigorating +invigoratingly +invigoration +invigorations +invigorator +invigorators +invincibilities +invincibility +invincible +invincibleness +invinciblenesses +invincibly +inviolabilities +inviolability +inviolable +inviolableness +inviolablenesses +inviolably +inviolacies +inviolacy +inviolate +inviolately +inviolateness +inviolatenesses +invirile +inviscid +invisibilities +invisibility +invisible +invisibleness +invisiblenesses +invisibles +invisibly +invital +invitation +invitational +invitationals +invitations +invitatories +invitatory +invite +invited +invitee +invitees +inviter +inviters +invites +inviting +invitingly +invocate +invocated +invocates +invocating +invocation +invocational +invocations +invocatory +invoice +invoiced +invoices +invoicing +invoke +invoked +invoker +invokers +invokes +invoking +involucra +involucral +involucrate +involucre +involucres +involucrum +involuntarily +involuntariness +involuntarinesses +involuntary +involute +involuted +involutes +involuting +involution +involutional +involutions +involve +involved +involvedly +involvement +involvements +involver +involvers +involves +involving +invulnerabilities +invulnerability +invulnerable +invulnerableness +invulnerablenesses +invulnerably +inwall +inwalled +inwalling +inwalls +inward +inwardly +inwardness +inwardnesses +inwards +inweave +inweaved +inweaves +inweaving +inwind +inwinding +inwinds +inwound +inwove +inwoven +inwrap +inwrapped +inwrapping +inwraps +iodate +iodated +iodates +iodating +iodation +iodations +iodic +iodid +iodide +iodides +iodids +iodin +iodinate +iodinated +iodinates +iodinating +iodination +iodinations +iodine +iodines +iodins +iodise +iodised +iodises +iodising +iodism +iodisms +iodize +iodized +iodizer +iodizers +iodizes +iodizing +iodoform +iodoforms +iodophor +iodophors +iodopsin +iodopsins +iodous +iolite +iolites +ion +ionic +ionicities +ionicity +ionics +ionise +ionised +ionises +ionising +ionium +ioniums +ionizable +ionization +ionizations +ionize +ionized +ionizer +ionizers +ionizes +ionizing +ionogen +ionogens +ionomer +ionomers +ionone +ionones +ionophore +ionophores +ionosphere +ionospheres +ionospheric +ionospherically +ions +iontophoreses +iontophoresis +iontophoretic +iontophoretically +iota +iotacism +iotacisms +iotas +ipecac +ipecacs +ipecacuanha +ipecacuanhas +ipomoea +ipomoeas +iproniazid +iproniazids +ipsilateral +ipsilaterally +iracund +irade +irades +irascibilities +irascibility +irascible +irascibleness +irasciblenesses +irascibly +irate +irately +irateness +iratenesses +irater +iratest +ire +ired +ireful +irefully +ireless +irenic +irenical +irenically +irenics +ires +irid +irides +iridescence +iridescences +iridescent +iridescently +iridic +iridium +iridiums +iridologies +iridologist +iridologists +iridology +iridosmine +iridosmines +irids +iring +iris +irised +irises +irising +iritic +iritis +iritises +irk +irked +irking +irks +irksome +irksomely +irksomeness +irksomenesses +iroko +irokos +iron +ironbark +ironbarks +ironbound +ironclad +ironclads +irone +ironed +ironer +ironers +irones +ironfisted +ironhanded +ironhearted +ironic +ironical +ironically +ironicalness +ironicalnesses +ironies +ironing +ironings +ironist +ironists +ironize +ironized +ironizes +ironizing +ironlike +ironmaster +ironmasters +ironmonger +ironmongeries +ironmongers +ironmongery +ironness +ironnesses +irons +ironside +ironsides +ironstone +ironstones +ironware +ironwares +ironweed +ironweeds +ironwood +ironwoods +ironwork +ironworker +ironworkers +ironworks +irony +irradiance +irradiances +irradiate +irradiated +irradiates +irradiating +irradiation +irradiations +irradiative +irradiator +irradiators +irradicable +irradicably +irrational +irrationalism +irrationalisms +irrationalist +irrationalistic +irrationalists +irrationalities +irrationality +irrationally +irrationals +irreal +irrealities +irreality +irreclaimable +irreclaimably +irreconcilabilities +irreconcilability +irreconcilable +irreconcilableness +irreconcilablenesses +irreconcilables +irreconcilably +irrecoverable +irrecoverableness +irrecoverablenesses +irrecoverably +irrecusable +irrecusably +irredeemable +irredeemably +irredenta +irredentas +irredentism +irredentisms +irredentist +irredentists +irreducibilities +irreducibility +irreducible +irreducibly +irreflexive +irreformabilities +irreformability +irreformable +irrefragabilities +irrefragability +irrefragable +irrefragably +irrefutabilities +irrefutability +irrefutable +irrefutably +irregardless +irregular +irregularities +irregularity +irregularly +irregulars +irrelative +irrelatively +irrelevance +irrelevances +irrelevancies +irrelevancy +irrelevant +irrelevantly +irreligion +irreligionist +irreligionists +irreligions +irreligious +irreligiously +irremeable +irremediable +irremediableness +irremediablenesses +irremediably +irremovabilities +irremovability +irremovable +irremovably +irreparable +irreparableness +irreparablenesses +irreparably +irrepealabilities +irrepealability +irrepealable +irreplaceabilities +irreplaceability +irreplaceable +irreplaceableness +irreplaceablenesses +irreplaceably +irrepressibilities +irrepressibility +irrepressible +irrepressibly +irreproachabilities +irreproachability +irreproachable +irreproachableness +irreproachablenesses +irreproachably +irreproducibilities +irreproducibility +irreproducible +irresistibilities +irresistibility +irresistible +irresistibleness +irresistiblenesses +irresistibly +irresoluble +irresolute +irresolutely +irresoluteness +irresolutenesses +irresolution +irresolutions +irresolvable +irrespective +irresponsibilities +irresponsibility +irresponsible +irresponsibleness +irresponsiblenesses +irresponsibles +irresponsibly +irresponsive +irresponsiveness +irresponsivenesses +irretrievabilities +irretrievability +irretrievable +irretrievably +irreverence +irreverences +irreverent +irreverently +irreversibilities +irreversibility +irreversible +irreversibly +irrevocabilities +irrevocability +irrevocable +irrevocableness +irrevocablenesses +irrevocably +irridenta +irridentas +irrigate +irrigated +irrigates +irrigating +irrigation +irrigations +irrigator +irrigators +irritabilities +irritability +irritable +irritableness +irritablenesses +irritably +irritant +irritants +irritate +irritated +irritates +irritating +irritatingly +irritation +irritations +irritative +irrotational +irrupt +irrupted +irrupting +irruption +irruptions +irruptive +irruptively +irrupts +is +isagoge +isagoges +isagogic +isagogics +isallobar +isallobaric +isallobars +isarithm +isarithms +isatin +isatine +isatines +isatinic +isatins +isba +isbas +ischaemia +ischaemias +ischemia +ischemias +ischemic +ischia +ischial +ischium +isentropic +isentropically +isinglass +isinglasses +island +islanded +islander +islanders +islanding +islands +isle +isled +isleless +isles +islet +islets +isling +ism +isms +isoagglutinin +isoagglutinins +isoalloxazine +isoalloxazines +isoantibodies +isoantibody +isoantigen +isoantigenic +isoantigens +isobar +isobare +isobares +isobaric +isobars +isobath +isobaths +isobutane +isobutanes +isobutylene +isobutylenes +isocaloric +isocarboxazid +isocarboxazids +isocheim +isocheims +isochime +isochimes +isochor +isochore +isochores +isochors +isochromosome +isochromosomes +isochron +isochronal +isochronally +isochrone +isochrones +isochronism +isochronisms +isochronous +isochronously +isochrons +isocline +isoclines +isocracies +isocracy +isocyanate +isocyanates +isocyclic +isodiametric +isodose +isoelectric +isoelectronic +isoelectronically +isoenzymatic +isoenzyme +isoenzymes +isoenzymic +isogamete +isogametes +isogametic +isogamies +isogamous +isogamy +isogeneic +isogenic +isogenies +isogeny +isogloss +isoglossal +isoglosses +isoglossic +isogon +isogonal +isogonals +isogone +isogones +isogonic +isogonics +isogonies +isogons +isogony +isograft +isografted +isografting +isografts +isogram +isograms +isograph +isographs +isogriv +isogrivs +isohel +isohels +isohyet +isohyetal +isohyets +isolable +isolatable +isolate +isolated +isolates +isolating +isolation +isolationism +isolationisms +isolationist +isolationists +isolations +isolator +isolators +isolead +isoleads +isoleucine +isoleucines +isoline +isolines +isolog +isologs +isologue +isologues +isomer +isomerase +isomerases +isomeric +isomerism +isomerisms +isomerization +isomerizations +isomerize +isomerized +isomerizes +isomerizing +isomers +isometric +isometrically +isometrics +isometries +isometry +isomorph +isomorphic +isomorphically +isomorphism +isomorphisms +isomorphous +isomorphs +isoniazid +isoniazids +isonomic +isonomies +isonomy +isooctane +isooctanes +isopach +isopachs +isophotal +isophote +isophotes +isopiestic +isopleth +isoplethic +isopleths +isopod +isopodan +isopodans +isopods +isoprenaline +isoprenalines +isoprene +isoprenes +isoprenoid +isopropyl +isopropyls +isoproterenol +isoproterenols +isopycnic +isosceles +isosmotic +isosmotically +isospin +isospins +isospories +isospory +isostasies +isostasy +isostatic +isostatically +isotach +isotachs +isotactic +isothere +isotheres +isotherm +isothermal +isothermally +isotherms +isotone +isotones +isotonic +isotonically +isotonicities +isotonicity +isotope +isotopes +isotopic +isotopically +isotopies +isotopy +isotropic +isotropies +isotropy +isotype +isotypes +isotypic +isozyme +isozymes +isozymic +issei +isseis +issuable +issuably +issuance +issuances +issuant +issue +issued +issueless +issuer +issuers +issues +issuing +isthmi +isthmian +isthmians +isthmic +isthmoid +isthmus +isthmuses +istle +istles +it +italianate +italianated +italianates +italianating +italianise +italianised +italianises +italianising +italianize +italianized +italianizes +italianizing +italic +italicise +italicised +italicises +italicising +italicization +italicizations +italicize +italicized +italicizes +italicizing +italics +itch +itched +itches +itchier +itchiest +itchily +itchiness +itchinesses +itching +itchings +itchy +item +itemed +iteming +itemise +itemised +itemises +itemising +itemization +itemizations +itemize +itemized +itemizer +itemizers +itemizes +itemizing +items +iterance +iterances +iterant +iterate +iterated +iterates +iterating +iteration +iterations +iterative +iteratively +iterum +ither +ithyphallic +itinerancies +itinerancy +itinerant +itinerantly +itinerants +itineraries +itinerary +itinerate +itinerated +itinerates +itinerating +itineration +itinerations +its +itself +ivermectin +ivermectins +ivied +ivies +ivories +ivory +ivorybill +ivorybills +ivy +ivylike +iwis +ixia +ixias +ixodid +ixodids +ixora +ixoras +ixtle +ixtles +izar +izars +izzard +izzards +jab +jabbed +jabber +jabbered +jabberer +jabberers +jabbering +jabbers +jabberwockies +jabberwocky +jabbing +jabiru +jabirus +jaborandi +jaborandis +jabot +jaboticaba +jaboticabas +jabots +jabs +jacal +jacales +jacals +jacamar +jacamars +jacana +jacanas +jacaranda +jacarandas +jacinth +jacinthe +jacinthes +jacinths +jack +jackal +jackals +jackanapes +jackanapeses +jackaroo +jackaroos +jackass +jackasseries +jackassery +jackasses +jackboot +jackbooted +jackboots +jackdaw +jackdaws +jacked +jacker +jackeroo +jackeroos +jackers +jacket +jacketed +jacketing +jacketless +jackets +jackfish +jackfishes +jackfruit +jackfruits +jackhammer +jackhammered +jackhammering +jackhammers +jackies +jacking +jackknife +jackknifed +jackknifes +jackknifing +jackknives +jackleg +jacklegs +jacklight +jacklights +jackpot +jackpots +jackrabbit +jackrabbits +jackroll +jackrolled +jackrolling +jackrolls +jacks +jackscrew +jackscrews +jacksmelt +jacksmelts +jackstay +jackstays +jackstraw +jackstraws +jacky +jacobin +jacobins +jacobus +jacobuses +jaconet +jaconets +jacquard +jacquards +jacquerie +jacqueries +jactitation +jactitations +jaculate +jaculated +jaculates +jaculating +jade +jaded +jadedly +jadedness +jadednesses +jadeite +jadeites +jades +jading +jadish +jadishly +jaditic +jaeger +jaegers +jag +jager +jagers +jagg +jaggaries +jaggary +jagged +jaggeder +jaggedest +jaggedly +jaggedness +jaggednesses +jagger +jaggeries +jaggers +jaggery +jaggheries +jagghery +jaggier +jaggiest +jagging +jaggs +jaggy +jagless +jagra +jagras +jags +jaguar +jaguarondi +jaguarondis +jaguars +jaguarundi +jaguarundis +jail +jailbait +jailbird +jailbirds +jailbreak +jailbreaks +jailed +jailer +jailers +jailhouse +jailhouses +jailing +jailor +jailors +jails +jake +jakes +jalap +jalapeno +jalapenos +jalapic +jalapin +jalapins +jalaps +jalop +jalopies +jaloppies +jaloppy +jalops +jalopy +jalousie +jalousies +jam +jamb +jambalaya +jambalayas +jambe +jambeau +jambeaux +jambed +jambes +jambing +jamboree +jamborees +jambs +jammed +jammer +jammers +jammier +jammies +jammiest +jamming +jammy +jams +jane +janes +jangle +jangled +jangler +janglers +jangles +janglier +jangliest +jangling +jangly +janiform +janisaries +janisary +janissaries +janissary +janitor +janitorial +janitors +janizaries +janizary +janty +japan +japanize +japanized +japanizes +japanizing +japanned +japanner +japanners +japanning +japans +jape +japed +japer +japeries +japers +japery +japes +japing +japingly +japonaiserie +japonaiseries +japonica +japonicas +jar +jardiniere +jardinieres +jarful +jarfuls +jargon +jargoned +jargonel +jargonels +jargoning +jargonish +jargonistic +jargonize +jargonized +jargonizes +jargonizing +jargons +jargoon +jargoons +jarhead +jarheads +jarina +jarinas +jarl +jarldom +jarldoms +jarls +jarosite +jarosites +jarovize +jarovized +jarovizes +jarovizing +jarrah +jarrahs +jarred +jarring +jarringly +jars +jarsful +jarvey +jarveys +jasmin +jasmine +jasmines +jasmins +jasper +jaspers +jasperware +jasperwares +jaspery +jassid +jassids +jato +jatos +jauk +jauked +jauking +jauks +jaunce +jaunced +jaunces +jauncing +jaundice +jaundiced +jaundices +jaundicing +jaunt +jaunted +jauntier +jauntiest +jauntily +jauntiness +jauntinesses +jaunting +jaunts +jaunty +jaup +jauped +jauping +jaups +java +javas +javelin +javelina +javelinas +javelined +javelining +javelins +jaw +jawan +jawans +jawbone +jawboned +jawboner +jawboners +jawbones +jawboning +jawbonings +jawbreaker +jawbreakers +jawed +jawing +jawlike +jawline +jawlines +jaws +jay +jaybird +jaybirds +jaygee +jaygees +jayhawker +jayhawkers +jays +jayvee +jayvees +jaywalk +jaywalked +jaywalker +jaywalkers +jaywalking +jaywalks +jazz +jazzed +jazzer +jazzers +jazzes +jazzier +jazziest +jazzily +jazziness +jazzinesses +jazzing +jazzlike +jazzman +jazzmen +jazzy +jealous +jealousies +jealously +jealousness +jealousnesses +jealousy +jean +jeans +jebel +jebels +jee +jeed +jeeing +jeep +jeeped +jeepers +jeeping +jeepney +jeepneys +jeeps +jeer +jeered +jeerer +jeerers +jeering +jeeringly +jeers +jees +jeez +jefe +jefes +jehad +jehads +jehu +jehus +jejuna +jejunal +jejune +jejunely +jejuneness +jejunenesses +jejunities +jejunity +jejunum +jell +jellaba +jellabas +jelled +jellied +jellies +jellified +jellifies +jellify +jellifying +jelling +jells +jelly +jellybean +jellybeans +jellyfish +jellyfishes +jellying +jellylike +jelutong +jelutongs +jemadar +jemadars +jemidar +jemidars +jemmied +jemmies +jemmy +jemmying +jennet +jennets +jennies +jenny +jeon +jeopard +jeoparded +jeopardies +jeoparding +jeopardise +jeopardised +jeopardises +jeopardising +jeopardize +jeopardized +jeopardizes +jeopardizing +jeopards +jeopardy +jerboa +jerboas +jereed +jereeds +jeremiad +jeremiads +jerid +jerids +jerk +jerked +jerker +jerkers +jerkier +jerkies +jerkiest +jerkily +jerkin +jerkiness +jerkinesses +jerking +jerkins +jerks +jerkwater +jerky +jeroboam +jeroboams +jerreed +jerreeds +jerrican +jerricans +jerrid +jerrids +jerries +jerry +jerrycan +jerrycans +jersey +jerseyed +jerseys +jess +jessamine +jessamines +jessant +jesse +jessed +jesses +jessing +jest +jested +jester +jesters +jestful +jesting +jestings +jests +jesuit +jesuitic +jesuitical +jesuitically +jesuitism +jesuitisms +jesuitries +jesuitry +jesuits +jet +jetbead +jetbeads +jete +jetes +jetlike +jetliner +jetliners +jeton +jetons +jetport +jetports +jets +jetsam +jetsams +jetsom +jetsoms +jetted +jettied +jettier +jetties +jettiest +jetting +jettison +jettisonable +jettisoned +jettisoning +jettisons +jetton +jettons +jetty +jettying +jeu +jeux +jew +jewed +jewel +jeweled +jeweler +jewelers +jeweling +jewelled +jeweller +jewelleries +jewellers +jewellery +jewellike +jewelling +jewelries +jewelry +jewels +jewelweed +jewelweeds +jewfish +jewfishes +jewing +jews +jezail +jezails +jezebel +jezebels +jiao +jib +jibb +jibbed +jibber +jibbers +jibbing +jibboom +jibbooms +jibbs +jibe +jibed +jiber +jibers +jibes +jibing +jibingly +jibs +jicama +jicamas +jiff +jiffies +jiffs +jiffy +jig +jigaboo +jigaboos +jigged +jigger +jiggered +jiggering +jiggers +jigging +jiggle +jiggled +jiggles +jigglier +jiggliest +jiggling +jiggly +jigs +jigsaw +jigsawed +jigsawing +jigsawn +jigsaws +jihad +jihads +jill +jillion +jillions +jills +jilt +jilted +jilter +jilters +jilting +jilts +jiminy +jimjams +jimmied +jimmies +jimminy +jimmy +jimmying +jimp +jimper +jimpest +jimply +jimpy +jimsonweed +jimsonweeds +jin +jingal +jingall +jingalls +jingals +jingko +jingkoes +jingle +jingled +jingler +jinglers +jingles +jinglier +jingliest +jingling +jingly +jingo +jingoes +jingoish +jingoism +jingoisms +jingoist +jingoistic +jingoistically +jingoists +jink +jinked +jinker +jinkers +jinking +jinks +jinn +jinnee +jinni +jinns +jinricksha +jinrickshas +jinrikisha +jinrikishas +jins +jinx +jinxed +jinxes +jinxing +jipijapa +jipijapas +jism +jisms +jitney +jitneys +jitter +jitterbug +jitterbugged +jitterbugging +jitterbugs +jittered +jitterier +jitteriest +jitteriness +jitterinesses +jittering +jitters +jittery +jiujitsu +jiujitsus +jiujutsu +jiujutsus +jive +jiveass +jived +jiver +jivers +jives +jivey +jivier +jiviest +jiving +jnana +jnanas +jo +joannes +job +jobbed +jobber +jobberies +jobbers +jobbery +jobbing +jobholder +jobholders +jobless +joblessness +joblessnesses +jobname +jobnames +jobs +jock +jockette +jockettes +jockey +jockeyed +jockeying +jockeys +jocko +jockos +jocks +jockstrap +jockstraps +jocose +jocosely +jocoseness +jocosenesses +jocosities +jocosity +jocular +jocularities +jocularity +jocularly +jocund +jocundities +jocundity +jocundly +jodhpur +jodhpurs +joe +joes +joey +joeys +jog +jogged +jogger +joggers +jogging +joggings +joggle +joggled +joggler +jogglers +joggles +joggling +jogs +johannes +john +johnboat +johnboats +johnnies +johnny +johnnycake +johnnycakes +johns +johnsongrass +johnsongrasses +join +joinable +joinder +joinders +joined +joiner +joineries +joiners +joinery +joining +joinings +joins +joint +jointed +jointedly +jointedness +jointednesses +jointer +jointers +jointing +jointly +jointress +jointresses +joints +jointure +jointured +jointures +jointuring +jointworm +jointworms +joist +joisted +joisting +joists +jojoba +jojobas +joke +joked +joker +jokers +jokes +jokester +jokesters +jokey +jokier +jokiest +jokily +jokiness +jokinesses +joking +jokingly +joky +jole +joles +jollied +jollier +jollies +jolliest +jollification +jollifications +jollified +jollifies +jollify +jollifying +jollily +jollities +jollity +jolly +jollying +jolt +jolted +jolter +jolters +joltier +joltiest +joltily +jolting +jolts +jolty +jones +joneses +jongleur +jongleurs +jonquil +jonquils +joram +jorams +jordan +jordans +jorum +jorums +joseph +josephs +josh +joshed +josher +joshers +joshes +joshing +joss +josses +jostle +jostled +jostler +jostlers +jostles +jostling +jot +jota +jotas +jots +jotted +jotter +jotters +jotting +jottings +jotty +joual +jouals +jouk +jouked +jouking +jouks +joule +joules +jounce +jounced +jounces +jouncier +jounciest +jouncing +jouncy +journal +journalese +journaleses +journalism +journalisms +journalist +journalistic +journalistically +journalists +journalize +journalized +journalizer +journalizers +journalizes +journalizing +journals +journey +journeyed +journeyer +journeyers +journeying +journeyman +journeymen +journeys +journeywork +journeyworks +joust +jousted +jouster +jousters +jousting +jousts +jovial +jovialities +joviality +jovially +jovialties +jovialty +jow +jowar +jowars +jowed +jowing +jowl +jowled +jowlier +jowliest +jowls +jowly +jows +joy +joyance +joyances +joyed +joyful +joyfuller +joyfullest +joyfully +joyfulness +joyfulnesses +joying +joyless +joylessly +joylessness +joylessnesses +joyous +joyously +joyousness +joyousnesses +joypop +joypopped +joypopper +joypoppers +joypopping +joypops +joyridden +joyride +joyrider +joyriders +joyrides +joyriding +joyridings +joyrode +joys +joystick +joysticks +juba +jubas +jubbah +jubbahs +jube +jubes +jubhah +jubhahs +jubilance +jubilances +jubilant +jubilantly +jubilarian +jubilarians +jubilate +jubilated +jubilates +jubilating +jubilation +jubilations +jubile +jubilee +jubilees +jubiles +judas +judases +judder +juddered +juddering +judders +judge +judged +judgement +judgements +judger +judgers +judges +judgeship +judgeships +judging +judgmatic +judgmatical +judgmatically +judgment +judgmental +judgmentally +judgments +judicatories +judicatory +judicature +judicatures +judicial +judicially +judiciaries +judiciary +judicious +judiciously +judiciousness +judiciousnesses +judo +judoist +judoists +judoka +judokas +judos +jug +juga +jugal +jugate +jugful +jugfuls +jugged +juggernaut +juggernauts +jugging +juggle +juggled +juggler +juggleries +jugglers +jugglery +juggles +juggling +jugglings +jughead +jugheads +jugs +jugsful +jugula +jugular +jugulars +jugulate +jugulated +jugulates +jugulating +jugulum +jugum +jugums +juice +juiced +juicehead +juiceheads +juiceless +juicer +juicers +juices +juicier +juiciest +juicily +juiciness +juicinesses +juicing +juicy +jujitsu +jujitsus +juju +jujube +jujubes +jujuism +jujuisms +jujuist +jujuists +jujus +jujutsu +jujutsus +juke +jukebox +jukeboxes +juked +jukes +juking +julep +juleps +julienne +julienned +juliennes +julienning +jumbal +jumbals +jumble +jumbled +jumbler +jumblers +jumbles +jumbling +jumbo +jumbos +jumbuck +jumbucks +jump +jumped +jumper +jumpers +jumpier +jumpiest +jumpily +jumpiness +jumpinesses +jumping +jumpoff +jumpoffs +jumps +jumpsuit +jumpsuits +jumpy +jun +junco +juncoes +juncos +junction +junctional +junctions +junctural +juncture +junctures +jungle +jungled +junglelike +jungles +junglier +jungliest +jungly +junior +juniorate +juniorates +juniors +juniper +junipers +junk +junked +junker +junkers +junket +junketed +junketeer +junketeers +junketer +junketers +junketing +junkets +junkie +junkier +junkies +junkiest +junking +junkman +junkmen +junks +junky +junkyard +junkyards +junta +juntas +junto +juntos +jupe +jupes +jupon +jupons +jura +jural +jurally +jurant +jurants +jurat +juratory +jurats +jurel +jurels +juridic +juridical +juridically +juried +juries +jurisconsult +jurisconsults +jurisdiction +jurisdictional +jurisdictionally +jurisdictions +jurisprudence +jurisprudences +jurisprudent +jurisprudential +jurisprudentially +jurisprudents +jurist +juristic +juristically +jurists +juror +jurors +jury +jurying +juryman +jurymen +jus +jussive +jussives +just +justed +juster +justers +justest +justice +justices +justiciabilities +justiciability +justiciable +justiciar +justiciars +justifiabilities +justifiability +justifiable +justifiably +justification +justifications +justificative +justificatory +justified +justifier +justifiers +justifies +justify +justifying +justing +justle +justled +justles +justling +justly +justness +justnesses +justs +jut +jute +jutes +juts +jutted +juttied +jutties +jutting +jutty +juttying +juvenal +juvenals +juvenescence +juvenescences +juvenescent +juvenile +juveniles +juvenilia +juvenilities +juvenility +juxtapose +juxtaposed +juxtaposes +juxtaposing +juxtaposition +juxtapositional +juxtapositions +ka +kaas +kab +kabab +kababs +kabaka +kabakas +kabala +kabalas +kabar +kabars +kabaya +kabayas +kabbala +kabbalah +kabbalahs +kabbalas +kabeljou +kabeljous +kabiki +kabikis +kabob +kabobs +kabs +kabuki +kabukis +kachina +kachinas +kaddish +kaddishim +kadi +kadis +kae +kaes +kaf +kaffeeklatsch +kaffeeklatsches +kaffir +kaffirs +kaffiyeh +kaffiyehs +kafir +kafirs +kafs +kaftan +kaftans +kagu +kagus +kahuna +kahunas +kaiak +kaiaks +kaif +kaifs +kail +kails +kailyard +kailyards +kain +kainit +kainite +kainites +kainits +kains +kaiser +kaiserdom +kaiserdoms +kaiserin +kaiserins +kaiserism +kaiserisms +kaisers +kajeput +kajeputs +kaka +kakapo +kakapos +kakas +kakemono +kakemonos +kaki +kakiemon +kakiemons +kakis +kalam +kalams +kalanchoe +kalanchoes +kale +kaleidoscope +kaleidoscopes +kaleidoscopic +kaleidoscopically +kalends +kales +kalewife +kalewives +kaleyard +kaleyards +kalian +kalians +kalif +kalifate +kalifates +kalifs +kalimba +kalimbas +kaliph +kaliphs +kalium +kaliums +kallidin +kallidins +kallikrein +kallikreins +kalmia +kalmias +kalong +kalongs +kalpa +kalpak +kalpaks +kalpas +kalyptra +kalyptras +kamaaina +kamaainas +kamacite +kamacites +kamala +kamalas +kame +kames +kami +kamik +kamikaze +kamikazes +kamiks +kampong +kampongs +kamseen +kamseens +kamsin +kamsins +kana +kanamycin +kanamycins +kanas +kanban +kanbans +kane +kanes +kangaroo +kangaroos +kanji +kanjis +kantar +kantars +kantele +kanteles +kaoliang +kaoliangs +kaolin +kaoline +kaolines +kaolinic +kaolinite +kaolinites +kaolinitic +kaolins +kaon +kaons +kapa +kapas +kapellmeister +kapellmeisters +kaph +kaphs +kapok +kapoks +kappa +kappas +kaput +kaputt +karabiner +karabiners +karakul +karakuls +karaoke +karaokes +karat +karate +karateist +karateists +karates +karats +karma +karmas +karmic +karn +karns +karoo +karoos +kaross +karosses +karroo +karroos +karst +karstic +karsts +kart +karting +kartings +karts +karyogamies +karyogamy +karyokineses +karyokinesis +karyokinetic +karyologic +karyological +karyologies +karyology +karyolymph +karyolymphs +karyosome +karyosomes +karyotin +karyotins +karyotype +karyotyped +karyotypes +karyotypic +karyotypically +karyotyping +kas +kasbah +kasbahs +kasha +kashas +kasher +kashered +kashering +kashers +kashmir +kashmirs +kashrut +kashruth +kashruths +kashruts +kat +kata +katabatic +katakana +katakanas +katas +katchina +katchinas +katcina +katcinas +katharses +katharsis +kathodal +kathode +kathodes +kathodic +kation +kations +kats +katydid +katydids +katzenjammer +katzenjammers +kauri +kauries +kauris +kaury +kava +kavakava +kavakavas +kavas +kavass +kavasses +kay +kayak +kayaked +kayaker +kayakers +kayaking +kayakings +kayaks +kayles +kayo +kayoed +kayoes +kayoing +kayos +kays +kazachki +kazachok +kazatski +kazatskies +kazatsky +kazoo +kazoos +kbar +kbars +kea +keas +kebab +kebabs +kebar +kebars +kebbie +kebbies +kebbock +kebbocks +kebbuck +kebbucks +keblah +keblahs +kebob +kebobs +keck +kecked +kecking +keckle +keckled +keckles +keckling +kecks +keddah +keddahs +kedge +kedged +kedgeree +kedgerees +kedges +kedging +keef +keefs +keek +keeked +keeking +keeks +keel +keelage +keelages +keelboat +keelboats +keeled +keelhale +keelhaled +keelhales +keelhaling +keelhaul +keelhauled +keelhauling +keelhauls +keeling +keelless +keels +keelson +keelsons +keen +keened +keener +keeners +keenest +keening +keenly +keenness +keennesses +keens +keep +keepable +keeper +keepers +keeping +keepings +keeps +keepsake +keepsakes +keeshond +keeshonden +keeshonds +keester +keesters +keet +keets +keeve +keeves +kef +keffiyeh +keffiyehs +kefir +kefirs +kefs +keg +kegeler +kegelers +kegler +keglers +kegling +keglings +kegs +keir +keirs +keister +keisters +keitloa +keitloas +kelep +keleps +kelim +kelims +kellies +kelly +keloid +keloidal +keloids +kelp +kelped +kelpie +kelpies +kelping +kelps +kelpy +kelson +kelsons +kelter +kelters +kelvin +kelvins +kemp +kemps +kempt +ken +kenaf +kenafs +kench +kenches +kendo +kendos +kenned +kennel +kenneled +kenneling +kennelled +kennelling +kennels +kenning +kennings +keno +kenos +kenosis +kenosises +kenotic +kenotron +kenotrons +kens +kenspeckle +kent +kentledge +kentledges +kep +kephalin +kephalins +kepi +kepis +kepped +keppen +kepping +keps +kept +keramic +keramics +keratin +keratinization +keratinizations +keratinize +keratinized +keratinizes +keratinizing +keratinophilic +keratinous +keratins +keratitides +keratitis +keratoconjunctivites +keratoconjunctivitides +keratoconjunctivitis +keratoconjunctivitises +keratoid +keratoma +keratomas +keratomata +keratoplasties +keratoplasty +keratose +keratoses +keratosis +keratotic +keratotomies +keratotomy +kerb +kerbed +kerbing +kerbs +kerchief +kerchiefed +kerchiefs +kerchieves +kerchoo +kerf +kerfed +kerfing +kerfs +kerfuffle +kerfuffles +kermes +kermess +kermesse +kermesses +kermis +kermises +kern +kerne +kerned +kernel +kerneled +kerneling +kernelled +kernelling +kernels +kernes +kerning +kernite +kernites +kerns +kerogen +kerogens +kerosene +kerosenes +kerosine +kerosines +kerplunk +kerplunked +kerplunking +kerplunks +kerria +kerrias +kerries +kerry +kersey +kerseymere +kerseymeres +kerseys +kerygma +kerygmata +kerygmatic +kestrel +kestrels +ketch +ketches +ketchup +ketchups +ketene +ketenes +keto +ketogeneses +ketogenesis +ketogenic +ketol +ketols +ketone +ketones +ketonic +ketose +ketoses +ketosis +ketosteroid +ketosteroids +ketotic +kettle +kettledrum +kettledrums +kettles +kevel +kevels +kevil +kevils +kex +kexes +key +keyboard +keyboarded +keyboarder +keyboarders +keyboarding +keyboardist +keyboardists +keyboards +keybutton +keybuttons +keycard +keycards +keyed +keyhole +keyholes +keying +keyless +keynote +keynoted +keynoter +keynoters +keynotes +keynoting +keypad +keypads +keypunch +keypunched +keypuncher +keypunchers +keypunches +keypunching +keys +keyset +keysets +keyster +keysters +keystone +keystones +keystroke +keystroked +keystrokes +keystroking +keyway +keyways +keyword +keywords +khaddar +khaddars +khadi +khadis +khaf +khafs +khaki +khakis +khalif +khalifa +khalifas +khalifs +khamseen +khamseens +khamsin +khamsins +khan +khanate +khanates +khans +khaph +khaphs +khat +khats +khazen +khazenim +khazens +kheda +khedah +khedahs +khedas +khedival +khedive +khedives +khedivial +khet +kheth +kheths +khets +khi +khirkah +khirkahs +khis +khoum +khoums +kiang +kiangs +kiaugh +kiaughs +kibbe +kibbeh +kibbehs +kibbes +kibbi +kibbis +kibbitz +kibbitzed +kibbitzer +kibbitzers +kibbitzes +kibbitzing +kibble +kibbled +kibbles +kibbling +kibbutz +kibbutzim +kibbutznik +kibbutzniks +kibe +kibei +kibeis +kibes +kibitz +kibitzed +kibitzer +kibitzers +kibitzes +kibitzing +kibla +kiblah +kiblahs +kiblas +kibosh +kiboshed +kiboshes +kiboshing +kick +kickable +kickback +kickbacks +kickball +kickballs +kickboard +kickboards +kickboxer +kickboxers +kickboxing +kickboxings +kicked +kicker +kickers +kickier +kickiest +kicking +kickoff +kickoffs +kicks +kickshaw +kickshaws +kickstand +kickstands +kickup +kickups +kicky +kid +kidded +kidder +kidders +kiddie +kiddies +kidding +kiddingly +kiddish +kiddo +kiddoes +kiddos +kiddush +kiddushes +kiddy +kidlike +kidnap +kidnaped +kidnapee +kidnapees +kidnaper +kidnapers +kidnaping +kidnapped +kidnappee +kidnappees +kidnapper +kidnappers +kidnapping +kidnaps +kidney +kidneys +kids +kidskin +kidskins +kidvid +kidvids +kief +kiefs +kielbasa +kielbasas +kielbasi +kielbasy +kier +kiers +kieselguhr +kieselguhrs +kieserite +kieserites +kiester +kiesters +kif +kifs +kike +kikes +kilderkin +kilderkins +kilim +kilims +kill +killdee +killdeer +killdeers +killdees +killed +killer +killers +killick +killicks +killie +killies +killifish +killifishes +killing +killingly +killings +killjoy +killjoys +killock +killocks +kills +kiln +kilned +kilning +kilns +kilo +kilobar +kilobars +kilobase +kilobases +kilobaud +kilobauds +kilobit +kilobits +kilobyte +kilobytes +kilocalorie +kilocalories +kilocycle +kilocycles +kilogauss +kilogausses +kilogram +kilograms +kilohertz +kilojoule +kilojoules +kiloliter +kiloliters +kilometer +kilometers +kilomole +kilomoles +kiloparsec +kiloparsecs +kilopascal +kilopascals +kilorad +kilorads +kilos +kiloton +kilotons +kilovolt +kilovolts +kilowatt +kilowatts +kilt +kilted +kilter +kilters +kiltie +kilties +kilting +kiltings +kilts +kilty +kimberlite +kimberlites +kimchee +kimchees +kimchi +kimchis +kimono +kimonoed +kimonos +kin +kina +kinas +kinase +kinases +kind +kinder +kindergarten +kindergartener +kindergarteners +kindergartens +kindergartner +kindergartners +kindest +kindhearted +kindheartedly +kindheartedness +kindheartednesses +kindle +kindled +kindler +kindlers +kindles +kindless +kindlessly +kindlier +kindliest +kindliness +kindlinesses +kindling +kindlings +kindly +kindness +kindnesses +kindred +kindreds +kinds +kine +kinema +kinemas +kinematic +kinematical +kinematically +kinematics +kines +kinescope +kinescoped +kinescopes +kinescoping +kineses +kinesic +kinesics +kinesiologies +kinesiology +kinesis +kinestheses +kinesthesia +kinesthesias +kinesthesis +kinesthetic +kinesthetically +kinetic +kinetically +kineticist +kineticists +kinetics +kinetin +kinetins +kinetochore +kinetochores +kinetoplast +kinetoplasts +kinetoscope +kinetoscopes +kinetosome +kinetosomes +kinfolk +kinfolks +king +kingbird +kingbirds +kingbolt +kingbolts +kingcraft +kingcrafts +kingcup +kingcups +kingdom +kingdoms +kinged +kingfish +kingfisher +kingfishers +kingfishes +kinghood +kinghoods +kinging +kingless +kinglet +kinglets +kinglier +kingliest +kinglike +kingliness +kinglinesses +kingly +kingmaker +kingmakers +kingpin +kingpins +kingpost +kingposts +kings +kingship +kingships +kingside +kingsides +kingwood +kingwoods +kinin +kinins +kink +kinkajou +kinkajous +kinked +kinkier +kinkiest +kinkily +kinkiness +kinkinesses +kinking +kinks +kinky +kinnikinnick +kinnikinnicks +kino +kinos +kins +kinsfolk +kinship +kinships +kinsman +kinsmen +kinswoman +kinswomen +kiosk +kiosks +kip +kipped +kippen +kipper +kippered +kipperer +kipperers +kippering +kippers +kipping +kips +kipskin +kipskins +kir +kirigami +kirigamis +kirk +kirkman +kirkmen +kirks +kirmess +kirmesses +kirn +kirned +kirning +kirns +kirs +kirsch +kirsches +kirtle +kirtled +kirtles +kishka +kishkas +kishke +kishkes +kismat +kismats +kismet +kismetic +kismets +kiss +kissable +kissably +kissed +kisser +kissers +kisses +kissing +kissy +kist +kistful +kistfuls +kists +kit +kitchen +kitchenette +kitchenettes +kitchens +kitchenware +kitchenwares +kite +kited +kitelike +kiter +kiters +kites +kith +kithara +kitharas +kithe +kithed +kithes +kithing +kiths +kiting +kitling +kitlings +kits +kitsch +kitsches +kitschy +kitted +kittel +kitten +kittened +kittening +kittenish +kittenishly +kittenishness +kittenishnesses +kittens +kitties +kitting +kittiwake +kittiwakes +kittle +kittled +kittler +kittles +kittlest +kittling +kitty +kiva +kivas +kiwi +kiwifruit +kiwifruits +kiwis +klatch +klatches +klatsch +klatsches +klavern +klaverns +klaxon +klaxons +kleagle +kleagles +klebsiella +klebsiellas +klepht +klephtic +klephts +kleptomania +kleptomaniac +kleptomaniacs +kleptomanias +klezmer +klezmorim +klister +klisters +klong +klongs +kloof +kloofs +kludge +kludges +kluge +kluges +klutz +klutzes +klutzier +klutziest +klutziness +klutzinesses +klutzy +klystron +klystrons +knack +knacked +knacker +knackered +knackeries +knackers +knackery +knacking +knacks +knackwurst +knackwursts +knap +knapped +knapper +knappers +knapping +knaps +knapsack +knapsacked +knapsacks +knapweed +knapweeds +knar +knarred +knarry +knars +knaur +knaurs +knave +knaveries +knavery +knaves +knavish +knavishly +knawel +knawels +knead +kneadable +kneaded +kneader +kneaders +kneading +kneads +knee +kneecap +kneecapped +kneecapping +kneecappings +kneecaps +kneed +kneehole +kneeholes +kneeing +kneel +kneeled +kneeler +kneelers +kneeling +kneels +kneepad +kneepads +kneepan +kneepans +knees +kneesock +kneesocks +knell +knelled +knelling +knells +knelt +knesset +knessets +knew +knickerbocker +knickerbockers +knickers +knickknacks +knife +knifed +knifelike +knifepoint +knifepoints +knifer +knifers +knifes +knifing +knight +knighted +knighthood +knighthoods +knighting +knightliness +knightlinesses +knightly +knights +knish +knishes +knit +knits +knitted +knitter +knitters +knitting +knittings +knitwear +knives +knob +knobbed +knobbier +knobbiest +knobblier +knobbliest +knobbly +knobby +knobkerrie +knobkerries +knoblike +knobs +knock +knockabout +knockabouts +knockdown +knockdowns +knocked +knocker +knockers +knocking +knockoff +knockoffs +knockout +knockouts +knocks +knockwurst +knockwursts +knoll +knolled +knoller +knollers +knolling +knolls +knolly +knop +knopped +knops +knosp +knosps +knot +knotgrass +knotgrasses +knothole +knotholes +knotless +knotlike +knots +knotted +knotter +knotters +knottier +knottiest +knottily +knottiness +knottinesses +knotting +knottings +knotty +knotweed +knotweeds +knout +knouted +knouting +knouts +know +knowable +knower +knowers +knowing +knowinger +knowingest +knowingly +knowingness +knowingnesses +knowings +knowledge +knowledgeabilities +knowledgeability +knowledgeable +knowledgeableness +knowledgeablenesses +knowledgeably +knowledges +known +knowns +knows +knubbier +knubbiest +knubby +knuckle +knuckleball +knuckleballer +knuckleballers +knuckleballs +knucklebone +knucklebones +knuckled +knucklehead +knuckleheaded +knuckleheads +knuckler +knucklers +knuckles +knucklier +knuckliest +knuckling +knuckly +knur +knurl +knurled +knurlier +knurliest +knurling +knurls +knurly +knurs +koa +koala +koalas +koan +koans +koas +kob +kobo +kobold +kobolds +kobs +koel +koels +kohl +kohlrabi +kohlrabies +kohls +koi +koine +koines +kokanee +kokanees +kola +kolacky +kolas +kolbasi +kolbasis +kolbassi +kolbassis +kolhoz +kolhozes +kolhozy +kolinski +kolinskies +kolinsky +kolkhos +kolkhoses +kolkhosy +kolkhoz +kolkhozes +kolkhoznik +kolkhozniki +kolkhozniks +kolkhozy +kolkoz +kolkozes +kolkozy +kolo +kolos +komatik +komatiks +komondor +komondorock +komondorok +komondors +konk +konked +konking +konks +koodoo +koodoos +kook +kookaburra +kookaburras +kookie +kookier +kookiest +kookiness +kookinesses +kooks +kooky +kop +kopeck +kopecks +kopek +kopeks +koph +kophs +kopje +kopjes +koppa +koppas +koppie +koppies +kops +kor +korai +korat +korats +kore +kors +korun +koruna +korunas +koruny +kos +kosher +koshered +koshering +koshers +koss +koto +kotos +kotow +kotowed +kotower +kotowers +kotowing +kotows +koumis +koumises +koumiss +koumisses +koumys +koumyses +koumyss +koumysses +kouprey +koupreys +kouroi +kouros +kousso +koussos +kowtow +kowtowed +kowtower +kowtowers +kowtowing +kowtows +kraal +kraaled +kraaling +kraals +kraft +krafts +krait +kraits +kraken +krakens +krater +kraters +kraut +krauts +kreep +kreeps +kremlin +kremlinologies +kremlinologist +kremlinologists +kremlinology +kremlins +kreplach +kreutzer +kreutzers +kreuzer +kreuzers +krill +krills +krimmer +krimmers +kris +krises +krona +krone +kronen +kroner +kronor +kronur +kroon +krooni +kroons +krubi +krubis +krubut +krubuts +kruller +krullers +krumhorn +krumhorns +krummholz +krummhorn +krummhorns +kryolite +kryolites +kryolith +kryoliths +krypton +kryptons +kuchen +kudo +kudos +kudu +kudus +kudzu +kudzus +kue +kues +kugel +kugels +kukri +kukris +kulak +kulaki +kulaks +kultur +kulturs +kumiss +kumisses +kummel +kummels +kumquat +kumquats +kumys +kumyses +kundalini +kundalinis +kunzite +kunzites +kurbash +kurbashed +kurbashes +kurbashing +kurgan +kurgans +kurrajong +kurrajongs +kurta +kurtas +kurtosis +kurtosises +kuru +kurus +kusso +kussos +kuvasz +kuvaszok +kvas +kvases +kvass +kvasses +kvetch +kvetched +kvetches +kvetchier +kvetchiest +kvetching +kvetchy +kwacha +kwanza +kwanzas +kwashiorkor +kwashiorkors +kyack +kyacks +kyak +kyaks +kyanise +kyanised +kyanises +kyanising +kyanite +kyanites +kyanize +kyanized +kyanizes +kyanizing +kyar +kyars +kyat +kyats +kybosh +kyboshed +kyboshes +kyboshing +kylikes +kylix +kymogram +kymograms +kymograph +kymographic +kymographies +kymographs +kymography +kyphoses +kyphosis +kyphotic +kyrie +kyries +kyte +kytes +kythe +kythed +kythes +kything +la +laager +laagered +laagering +laagers +laari +lab +labanotation +labanotations +labara +labarum +labarums +labdanum +labdanums +label +labelable +labeled +labeler +labelers +labeling +labella +labelled +labeller +labellers +labelling +labellum +labels +labia +labial +labialization +labializations +labialize +labialized +labializes +labializing +labially +labials +labiate +labiated +labiates +labile +labilities +lability +labiodental +labiodentals +labiovelar +labiovelars +labium +labor +laboratories +laboratory +labored +laborer +laborers +laboring +laborious +laboriously +laboriousness +laboriousnesses +laborite +laborites +labors +laborsaving +labour +laboured +labourer +labourers +labouring +labours +labra +labrador +labradorite +labradorites +labradors +labret +labrets +labroid +labroids +labrum +labrums +labrusca +labs +laburnum +laburnums +labyrinth +labyrinthian +labyrinthine +labyrinthodont +labyrinthodonts +labyrinths +lac +laccolith +laccolithic +laccoliths +lace +laced +laceless +lacelike +lacer +lacerate +lacerated +lacerates +lacerating +laceration +lacerations +lacerative +lacers +lacertid +lacertids +laces +lacewing +lacewings +lacewood +lacewoods +lacework +laceworks +lacey +laches +lachrymal +lachrymator +lachrymators +lachrymose +lachrymosely +lachrymosities +lachrymosity +lacier +laciest +lacily +laciness +lacinesses +lacing +lacings +laciniate +laciniation +laciniations +lack +lackadaisical +lackadaisically +lackaday +lacked +lacker +lackered +lackering +lackers +lackey +lackeyed +lackeying +lackeys +lacking +lackluster +lacklusters +lacks +laconic +laconically +laconism +laconisms +lacquer +lacquered +lacquerer +lacquerers +lacquering +lacquers +lacquerware +lacquerwares +lacquerwork +lacquerworks +lacquey +lacqueyed +lacqueying +lacqueys +lacrimal +lacrimals +lacrimation +lacrimations +lacrimator +lacrimators +lacrosse +lacrosses +lacs +lactalbumin +lactalbumins +lactam +lactams +lactary +lactase +lactases +lactate +lactated +lactates +lactating +lactation +lactational +lactations +lacteal +lacteals +lactean +lacteous +lactic +lactiferous +lactobacilli +lactobacillus +lactogenic +lactoglobulin +lactoglobulins +lactone +lactones +lactonic +lactose +lactoses +lacuna +lacunae +lacunal +lacunar +lacunaria +lacunars +lacunary +lacunas +lacunate +lacune +lacunes +lacunose +lacustrine +lacy +lad +ladanum +ladanums +ladder +laddered +laddering +ladderlike +ladders +laddie +laddies +lade +laded +laden +ladened +ladening +ladens +lader +laders +lades +ladies +lading +ladings +ladino +ladinos +ladle +ladled +ladleful +ladlefuls +ladler +ladlers +ladles +ladling +ladron +ladrone +ladrones +ladrons +lads +lady +ladybird +ladybirds +ladybug +ladybugs +ladyfinger +ladyfingers +ladyfish +ladyfishes +ladyhood +ladyhoods +ladyish +ladykin +ladykins +ladylike +ladylove +ladyloves +ladypalm +ladypalms +ladyship +ladyships +laetrile +laetriles +laevo +lag +lagan +lagans +lagend +lagends +lager +lagered +lagering +lagers +laggard +laggardly +laggardness +laggardnesses +laggards +lagged +lagger +laggers +lagging +laggings +lagnappe +lagnappes +lagniappe +lagniappes +lagomorph +lagomorphs +lagoon +lagoonal +lagoons +lags +laguna +lagunas +lagune +lagunes +lahar +lahars +laic +laical +laically +laich +laichs +laicise +laicised +laicises +laicising +laicism +laicisms +laicization +laicizations +laicize +laicized +laicizes +laicizing +laics +laid +laigh +laighs +lain +lair +laird +lairdly +lairds +laired +lairing +lairs +laitance +laitances +laith +laithly +laities +laity +lake +laked +lakefront +lakefronts +lakelike +lakeport +lakeports +laker +lakers +lakes +lakeshore +lakeshores +lakeside +lakesides +lakh +lakhs +lakier +lakiest +laking +lakings +laky +lall +lallan +lalland +lallands +lallans +lalled +lalling +lalls +lallygag +lallygagged +lallygagging +lallygags +lam +lama +lamas +lamaseries +lamasery +lamb +lambast +lambaste +lambasted +lambastes +lambasting +lambasts +lambda +lambdas +lambdoid +lambed +lambencies +lambency +lambent +lambently +lamber +lambers +lambert +lamberts +lambie +lambier +lambies +lambiest +lambing +lambkill +lambkills +lambkin +lambkins +lamblike +lambrequin +lambrequins +lambs +lambskin +lambskins +lamby +lame +lamebrain +lamebrained +lamebrains +lamed +lamedh +lamedhs +lameds +lamella +lamellae +lamellar +lamellas +lamellate +lamellately +lamellibranch +lamellibranchs +lamellicorn +lamellicorns +lamelliform +lamely +lameness +lamenesses +lament +lamentable +lamentableness +lamentablenesses +lamentably +lamentation +lamentations +lamented +lamentedly +lamenter +lamenters +lamenting +laments +lamer +lames +lamest +lamia +lamiae +lamias +lamina +laminae +laminal +laminar +laminaria +laminarian +laminarians +laminarias +laminarin +laminarins +laminary +laminas +laminate +laminated +laminates +laminating +lamination +laminations +laminator +laminators +laming +laminitis +laminitises +laminose +laminous +lamister +lamisters +lammed +lammergeier +lammergeiers +lammergeyer +lammergeyers +lamming +lamp +lampad +lampads +lampas +lampases +lampblack +lampblacks +lamped +lampers +lamperses +lamping +lampion +lampions +lamplight +lamplighter +lamplighters +lamplights +lampoon +lampooned +lampooner +lampooneries +lampooners +lampoonery +lampooning +lampoons +lamppost +lampposts +lamprey +lampreys +lamps +lampshell +lampshells +lampyrid +lampyrids +lams +lamster +lamsters +lanai +lanais +lanate +lanated +lance +lanced +lancelet +lancelets +lanceolate +lancer +lancers +lances +lancet +lanceted +lancets +lancewood +lancewoods +lanciers +lancinating +lancing +land +landau +landaulet +landaulets +landaus +landed +lander +landers +landfall +landfalls +landfill +landfills +landform +landforms +landgrab +landgrabs +landholder +landholders +landholding +landholdings +landing +landings +landladies +landlady +landler +landlers +landless +landlessness +landlessnesses +landline +landlines +landlocked +landlord +landlordism +landlordisms +landlords +landlubber +landlubberliness +landlubberlinesses +landlubberly +landlubbers +landlubbing +landman +landmark +landmarks +landmass +landmasses +landmen +landowner +landowners +landownership +landownerships +landowning +landownings +lands +landscape +landscaped +landscaper +landscapers +landscapes +landscaping +landscapist +landscapists +landside +landsides +landskip +landskips +landsleit +landslid +landslide +landslides +landsliding +landslip +landslips +landsman +landsmen +landward +lane +lanely +lanes +laneway +laneways +lang +langbeinite +langbeinites +langlauf +langlaufer +langlaufers +langlaufs +langley +langleys +langostino +langostinos +langouste +langoustes +langoustine +langoustines +langrage +langrages +langrel +langrels +langshan +langshans +langsyne +langsynes +language +languages +langue +langues +languet +languets +languid +languidly +languidness +languidnesses +languish +languished +languisher +languishers +languishes +languishing +languishingly +languishment +languishments +languor +languorous +languorously +languors +langur +langurs +laniard +laniards +laniaries +laniary +lanital +lanitals +lank +lanker +lankest +lankier +lankiest +lankily +lankiness +lankinesses +lankly +lankness +lanknesses +lanky +lanner +lanneret +lannerets +lanners +lanolin +lanoline +lanolines +lanolins +lanose +lanosities +lanosity +lantana +lantanas +lantern +lanterns +lanthanide +lanthanides +lanthanum +lanthanums +lanthorn +lanthorns +lanuginous +lanugo +lanugos +lanyard +lanyards +lap +laparoscope +laparoscopes +laparoscopic +laparoscopies +laparoscopist +laparoscopists +laparoscopy +laparotomies +laparotomy +lapboard +lapboards +lapdog +lapdogs +lapel +lapeled +lapelled +lapels +lapful +lapfuls +lapidarian +lapidaries +lapidary +lapidate +lapidated +lapidates +lapidating +lapides +lapidified +lapidifies +lapidify +lapidifying +lapidist +lapidists +lapilli +lapillus +lapin +lapins +lapis +lapises +lapped +lapper +lappered +lappering +lappers +lappet +lappeted +lappets +lapping +laps +lapsable +lapse +lapsed +lapser +lapsers +lapses +lapsible +lapsing +lapstrake +lapsus +laptop +laptops +lapwing +lapwings +lar +larboard +larboards +larcener +larceners +larcenies +larcenist +larcenists +larcenous +larcenously +larceny +larch +larches +lard +larded +larder +larders +lardier +lardiest +larding +lardlike +lardon +lardons +lardoon +lardoons +lards +lardy +laree +larees +lares +largando +large +largehearted +largeheartedness +largeheartednesses +largely +largemouth +largemouths +largeness +largenesses +larger +larges +largess +largesse +largesses +largest +larghetto +larghettos +largish +largo +largos +lari +lariat +lariated +lariating +lariats +larine +laris +lark +larked +larker +larkers +larkier +larkiest +larkiness +larkinesses +larking +larkish +larks +larksome +larkspur +larkspurs +larky +larrigan +larrigans +larrikin +larrikins +larrup +larruped +larruper +larrupers +larruping +larrups +lars +larum +larums +larva +larvae +larval +larvas +larvicidal +larvicide +larvicides +laryngal +laryngals +laryngeal +laryngeals +laryngectomee +laryngectomees +laryngectomies +laryngectomized +laryngectomy +larynges +laryngites +laryngitic +laryngitides +laryngitis +laryngitises +laryngologies +laryngology +laryngoscope +laryngoscopes +laryngoscopies +laryngoscopy +larynx +larynxes +las +lasagna +lasagnas +lasagne +lasagnes +lascar +lascars +lascivious +lasciviously +lasciviousness +lasciviousnesses +lase +lased +laser +lasers +lases +lash +lashed +lasher +lashers +lashes +lashing +lashings +lashins +lashkar +lashkars +lasing +lass +lasses +lassie +lassies +lassitude +lassitudes +lasso +lassoed +lassoer +lassoers +lassoes +lassoing +lassos +last +lasted +laster +lasters +lasting +lastingly +lastingness +lastingnesses +lastings +lastly +lasts +lat +latakia +latakias +latch +latched +latches +latchet +latchets +latching +latchkey +latchkeys +latchstring +latchstrings +late +latecomer +latecomers +lated +lateen +lateener +lateeners +lateens +lately +laten +latencies +latency +latened +lateness +latenesses +latening +latens +latensification +latensifications +latent +latently +latents +later +laterad +lateral +lateraled +lateraling +lateralization +lateralizations +lateralize +lateralized +lateralizes +lateralizing +laterally +laterals +laterite +laterites +lateritic +laterization +laterizations +laterize +laterized +laterizes +laterizing +latest +latests +latewood +latewoods +latex +latexes +lath +lathe +lathed +lather +lathered +latherer +latherers +lathering +lathers +lathery +lathes +lathi +lathier +lathiest +lathing +lathings +lathis +laths +lathwork +lathworks +lathy +lathyrism +lathyrisms +lathyritic +lati +latices +laticifer +laticifers +latifundia +latifundio +latifundios +latifundium +latigo +latigoes +latigos +latinities +latinity +latinization +latinizations +latinize +latinized +latinizes +latinizing +latino +latinos +latish +latitude +latitudes +latitudinal +latitudinally +latitudinarian +latitudinarianism +latitudinarianisms +latitudinarians +latke +latkes +latosol +latosolic +latosols +latria +latrias +latrine +latrines +lats +latte +latten +lattens +latter +latterly +lattes +lattice +latticed +lattices +latticework +latticeworks +latticing +lattin +lattins +lauan +lauans +laud +laudable +laudableness +laudablenesses +laudably +laudanum +laudanums +laudation +laudations +laudative +laudator +laudators +laudatory +lauded +lauder +lauders +lauding +lauds +laugh +laughable +laughableness +laughablenesses +laughably +laughed +laugher +laughers +laughing +laughingly +laughings +laughingstock +laughingstocks +laughs +laughter +laughters +launce +launces +launch +launched +launcher +launchers +launches +launching +launchpad +launchpads +launder +laundered +launderer +launderers +launderette +launderettes +laundering +launders +laundress +laundresses +laundrette +laundrettes +laundries +laundry +laundryman +laundrymen +laura +laurae +lauras +laureate +laureated +laureates +laureateship +laureateships +laureating +laureation +laureations +laurel +laureled +laureling +laurelled +laurelling +laurels +lauwine +lauwines +lav +lava +lavabo +lavaboes +lavabos +lavage +lavages +lavalava +lavalavas +lavalier +lavaliere +lavalieres +lavaliers +lavalike +lavalliere +lavallieres +lavas +lavation +lavations +lavatories +lavatory +lave +laved +laveer +laveered +laveering +laveers +lavender +lavendered +lavendering +lavenders +laver +laverock +laverocks +lavers +laves +laving +lavish +lavished +lavisher +lavishers +lavishes +lavishest +lavishing +lavishly +lavishness +lavishnesses +lavrock +lavrocks +lavs +law +lawbook +lawbooks +lawbreaker +lawbreakers +lawbreaking +lawbreakings +lawed +lawful +lawfully +lawfulness +lawfulnesses +lawgiver +lawgivers +lawine +lawines +lawing +lawings +lawless +lawlessly +lawlessness +lawlessnesses +lawlike +lawmaker +lawmakers +lawmaking +lawmakings +lawman +lawmen +lawn +lawnmower +lawnmowers +lawns +lawny +lawrencium +lawrenciums +laws +lawsuit +lawsuits +lawyer +lawyered +lawyering +lawyerings +lawyerlike +lawyerly +lawyers +lax +laxation +laxations +laxative +laxatives +laxer +laxest +laxities +laxity +laxly +laxness +laxnesses +lay +layabout +layabouts +layaway +layaways +layed +layer +layerage +layerages +layered +layering +layerings +layers +layette +layettes +laying +layman +laymen +layoff +layoffs +layout +layouts +layover +layovers +laypeople +layperson +laypersons +lays +layup +layups +laywoman +laywomen +lazar +lazaret +lazarets +lazarette +lazarettes +lazaretto +lazarettos +lazars +laze +lazed +lazes +lazied +lazier +lazies +laziest +lazily +laziness +lazinesses +lazing +lazuli +lazulis +lazulite +lazulites +lazurite +lazurites +lazy +lazybones +lazying +lazyish +lea +leach +leachabilities +leachability +leachable +leachate +leachates +leached +leacher +leachers +leaches +leachier +leachiest +leaching +leachy +lead +leaded +leaden +leadenly +leadenness +leadennesses +leader +leaderless +leaders +leadership +leaderships +leadier +leadiest +leading +leadings +leadless +leadman +leadmen +leadoff +leadoffs +leadplant +leadplants +leads +leadscrew +leadscrews +leadsman +leadsmen +leadwork +leadworks +leadwort +leadworts +leady +leaf +leafage +leafages +leafed +leafhopper +leafhoppers +leafier +leafiest +leafing +leafless +leaflet +leafleted +leafleteer +leafleteers +leafleting +leaflets +leafletted +leafletting +leaflike +leafs +leafstalk +leafstalks +leafworm +leafworms +leafy +league +leagued +leaguer +leaguered +leaguering +leaguers +leagues +leaguing +leak +leakage +leakages +leaked +leaker +leakers +leakier +leakiest +leakily +leakiness +leakinesses +leaking +leakless +leakproof +leaks +leaky +leal +leally +lealties +lealty +lean +leaned +leaner +leaners +leanest +leaning +leanings +leanly +leanness +leannesses +leans +leant +leap +leaped +leaper +leapers +leapfrog +leapfrogged +leapfrogging +leapfrogs +leaping +leaps +leapt +lear +learier +leariest +learn +learnable +learned +learnedly +learnedness +learnednesses +learner +learners +learning +learnings +learns +learnt +lears +leary +leas +leasable +lease +leaseback +leasebacks +leased +leasehold +leaseholder +leaseholders +leaseholds +leaser +leasers +leases +leash +leashed +leashes +leashing +leasing +leasings +least +leasts +leastways +leastwise +leather +leatherback +leatherbacks +leathered +leatherette +leatherettes +leathering +leatherleaf +leatherleaves +leatherlike +leathern +leatherneck +leathernecks +leathers +leatherwood +leatherwoods +leathery +leave +leaved +leaven +leavened +leavening +leavenings +leavens +leaver +leavers +leaves +leavier +leaviest +leaving +leavings +leavy +leben +lebens +lebensraum +lebensraums +lech +lechayim +lechayims +leched +lecher +lechered +lecheries +lechering +lecherous +lecherously +lecherousness +lecherousnesses +lechers +lechery +leches +leching +lechwe +lechwes +lecithin +lecithinase +lecithinases +lecithins +lectern +lecterns +lectin +lectins +lection +lectionaries +lectionary +lections +lector +lectors +lectotype +lectotypes +lecture +lectured +lecturer +lecturers +lectures +lectureship +lectureships +lecturing +lecythi +lecythis +lecythus +led +lederhosen +ledge +ledger +ledgers +ledges +ledgier +ledgiest +ledgy +lee +leeboard +leeboards +leech +leeched +leeches +leeching +leechlike +leek +leeks +leer +leered +leerier +leeriest +leerily +leering +leeringly +leers +leery +lees +leet +leets +leeward +leewards +leeway +leeways +left +lefter +leftest +lefties +leftish +leftism +leftisms +leftist +leftists +leftover +leftovers +lefts +leftward +leftwing +lefty +leg +legacies +legacy +legal +legalese +legaleses +legalise +legalised +legalises +legalising +legalism +legalisms +legalist +legalistic +legalistically +legalists +legalities +legality +legalization +legalizations +legalize +legalized +legalizer +legalizers +legalizes +legalizing +legally +legals +legate +legated +legatee +legatees +legates +legateship +legateships +legatine +legating +legation +legations +legato +legator +legators +legatos +legend +legendarily +legendary +legendries +legendry +legends +leger +legerdemain +legerdemains +legerities +legerity +legers +leges +legged +leggier +leggiero +leggiest +leggin +legginess +legginesses +legging +leggings +leggins +leggy +leghorn +leghorns +legibilities +legibility +legible +legibly +legion +legionaries +legionary +legionnaire +legionnaires +legions +legislate +legislated +legislates +legislating +legislation +legislations +legislative +legislatively +legislatives +legislator +legislatorial +legislators +legislatorship +legislatorships +legislature +legislatures +legist +legists +legit +legitimacies +legitimacy +legitimate +legitimated +legitimately +legitimates +legitimating +legitimation +legitimations +legitimatize +legitimatized +legitimatizes +legitimatizing +legitimator +legitimators +legitimise +legitimised +legitimises +legitimising +legitimism +legitimisms +legitimist +legitimists +legitimization +legitimizations +legitimize +legitimized +legitimizer +legitimizers +legitimizes +legitimizing +legits +legless +leglike +legman +legmen +legong +legongs +legroom +legrooms +legs +legume +legumes +legumin +leguminous +legumins +legwork +legworks +lehayim +lehayims +lehr +lehrs +lehua +lehuas +lei +leis +leishmania +leishmanial +leishmanias +leishmaniases +leishmaniasis +leister +leistered +leistering +leisters +leisure +leisured +leisureliness +leisurelinesses +leisurely +leisures +leitmotif +leitmotifs +leitmotiv +leitmotivs +lek +leke +leks +leku +lekvar +lekvars +lekythi +lekythoi +lekythos +lekythus +leman +lemans +lemma +lemmas +lemmata +lemming +lemminglike +lemmings +lemniscal +lemniscate +lemniscates +lemnisci +lemniscus +lemon +lemonade +lemonades +lemongrass +lemongrasses +lemonish +lemons +lemony +lempira +lempiras +lemur +lemures +lemurine +lemuroid +lemuroids +lemurs +lend +lendable +lender +lenders +lending +lends +lenes +length +lengthen +lengthened +lengthener +lengtheners +lengthening +lengthens +lengthier +lengthiest +lengthily +lengthiness +lengthinesses +lengths +lengthways +lengthwise +lengthy +lenience +leniences +leniencies +leniency +lenient +leniently +lenis +lenities +lenition +lenitions +lenitive +lenitively +lenitives +lenity +leno +lenos +lens +lense +lensed +lenses +lensing +lensless +lensman +lensmen +lent +lentamente +lentando +lenten +lentic +lenticel +lenticels +lenticular +lenticule +lenticules +lentigines +lentigo +lentil +lentils +lentisk +lentisks +lentissimo +lentivirus +lentiviruses +lento +lentoid +lentos +leone +leones +leonine +leopard +leopardess +leopardesses +leopards +leotard +leotarded +leotards +leper +lepers +lepidolite +lepidolites +lepidoptera +lepidopteran +lepidopterans +lepidopterist +lepidopterists +lepidopterological +lepidopterologies +lepidopterologist +lepidopterologists +lepidopterology +lepidopterous +lepidote +lepidotes +leporid +leporidae +leporids +leporine +leprechaun +leprechaunish +leprechauns +lepromatous +leprosaria +leprosarium +leprosariums +leprose +leprosies +leprosy +leprotic +leprous +leprously +lept +lepta +leptocephali +leptocephalus +lepton +leptonic +leptons +leptosome +leptosomes +leptospiral +leptospire +leptospires +leptospiroses +leptospirosis +leptotene +leptotenes +lesbian +lesbianism +lesbianisms +lesbians +lesion +lesioned +lesions +lespedeza +lespedezas +less +lessee +lessees +lessen +lessened +lessening +lessens +lesser +lesson +lessoned +lessoning +lessons +lessor +lessors +lest +let +letch +letched +letches +letching +letdown +letdowns +lethal +lethalities +lethality +lethally +lethals +lethargic +lethargically +lethargies +lethargy +lethe +lethean +lethes +lets +letted +letter +letterboxed +letterboxing +letterboxings +lettered +letterer +letterers +letterform +letterforms +letterhead +letterheads +lettering +letterings +letterman +lettermen +letterpress +letterpresses +letters +letterspace +letterspaces +letterspacing +letterspacings +letting +lettuce +lettuces +letup +letups +leu +leucemia +leucemias +leucemic +leucin +leucine +leucines +leucins +leucite +leucites +leucitic +leucocidin +leucocidins +leucoma +leucomas +leucoplast +leucoplasts +leud +leudes +leuds +leukaemia +leukaemias +leukaemogeneses +leukaemogenesis +leukemia +leukemias +leukemic +leukemics +leukemogeneses +leukemogenesis +leukemogenic +leukemoid +leukocyte +leukocytes +leukocytic +leukocytoses +leukocytosis +leukocytosises +leukodystrophies +leukodystrophy +leukoma +leukomas +leukon +leukons +leukopenia +leukopenias +leukopenic +leukoplakia +leukoplakias +leukoplakic +leukopoieses +leukopoiesis +leukopoietic +leukorrhea +leukorrheal +leukorrheas +leukoses +leukosis +leukotic +leukotomies +leukotomy +leukotriene +leukotrienes +lev +leva +levant +levanted +levanter +levanters +levanting +levants +levator +levatores +levators +levee +leveed +leveeing +levees +level +leveled +leveler +levelers +levelheaded +levelheadedness +levelheadednesses +leveling +levelled +leveller +levellers +levelling +levelly +levelness +levelnesses +levels +lever +leverage +leveraged +leverages +leveraging +levered +leveret +leverets +levering +levers +leviable +leviathan +leviathans +levied +levier +leviers +levies +levigate +levigated +levigates +levigating +levigation +levigations +levin +levins +levirate +levirates +leviratic +levitate +levitated +levitates +levitating +levitation +levitational +levitations +levities +levity +levo +levodopa +levodopas +levogyre +levorotary +levorotatory +levulin +levulins +levulose +levuloses +levy +levying +lewd +lewder +lewdest +lewdly +lewdness +lewdnesses +lewis +lewises +lewisite +lewisites +lewisson +lewissons +lex +lexeme +lexemes +lexemic +lexes +lexica +lexical +lexicalisation +lexicalisations +lexicalities +lexicality +lexicalization +lexicalizations +lexicalize +lexicalized +lexicalizes +lexicalizing +lexically +lexicographer +lexicographers +lexicographic +lexicographical +lexicographically +lexicographies +lexicography +lexicologies +lexicologist +lexicologists +lexicology +lexicon +lexicons +lexis +ley +leys +lez +lezzes +lezzie +lezzies +lezzy +li +liabilities +liability +liable +liaise +liaised +liaises +liaising +liaison +liaisons +liana +lianas +liane +lianes +liang +liangs +lianoid +liar +liard +liards +liars +lib +libation +libationary +libations +libber +libbers +libecchio +libecchios +libeccio +libeccios +libel +libelant +libelants +libeled +libelee +libelees +libeler +libelers +libeling +libelist +libelists +libellant +libellants +libelled +libellee +libellees +libeller +libellers +libelling +libellous +libelous +libels +liber +liberal +liberalise +liberalised +liberalises +liberalising +liberalism +liberalisms +liberalist +liberalistic +liberalists +liberalities +liberality +liberalization +liberalizations +liberalize +liberalized +liberalizer +liberalizers +liberalizes +liberalizing +liberally +liberalness +liberalnesses +liberals +liberate +liberated +liberates +liberating +liberation +liberationist +liberationists +liberations +liberator +liberators +libers +libertarian +libertarianism +libertarianisms +libertarians +liberties +libertinage +libertinages +libertine +libertines +libertinism +libertinisms +liberty +libidinal +libidinally +libidinous +libidinously +libidinousness +libidinousnesses +libido +libidos +liblab +liblabs +libra +librae +librarian +librarians +librarianship +librarianships +libraries +library +libras +librate +librated +librates +librating +libration +librational +librations +libratory +libretti +librettist +librettists +libretto +librettos +libri +libriform +libs +lice +licence +licenced +licencee +licencees +licencer +licencers +licences +licencing +licensable +license +licensed +licensee +licensees +licenser +licensers +licenses +licensing +licensor +licensors +licensure +licensures +licente +licentiate +licentiates +licentious +licentiously +licentiousness +licentiousnesses +lich +lichee +lichees +lichen +lichened +lichenin +lichening +lichenins +lichenological +lichenologies +lichenologist +lichenologists +lichenology +lichenous +lichens +liches +lichi +lichis +licht +lichted +lichting +lichtly +lichts +licit +licitly +lick +licked +licker +lickerish +lickerishly +lickerishness +lickerishnesses +lickers +licking +lickings +licks +lickspit +lickspits +lickspittle +lickspittles +licorice +licorices +lictor +lictors +lid +lidar +lidars +lidded +lidding +lidless +lido +lidocaine +lidocaines +lidos +lids +lie +liebfraumilch +liebfraumilchs +lied +lieder +lief +liefer +liefest +liefly +liege +liegeman +liegemen +lieges +lien +lienable +lienal +liens +lienteries +lientery +lier +lierne +liernes +liers +lies +lieu +lieus +lieutenancies +lieutenancy +lieutenant +lieutenants +lieve +liever +lievest +life +lifeblood +lifebloods +lifeboat +lifeboats +lifeful +lifeguard +lifeguarded +lifeguarding +lifeguards +lifeless +lifelessly +lifelessness +lifelessnesses +lifelike +lifelikeness +lifelikenesses +lifeline +lifelines +lifelong +lifemanship +lifemanships +lifer +lifers +lifesaver +lifesavers +lifesaving +lifesavings +lifestyle +lifestyles +lifetime +lifetimes +lifeway +lifeways +lifework +lifeworks +lift +liftable +lifted +lifter +lifters +liftgate +liftgates +lifting +liftman +liftmen +liftoff +liftoffs +lifts +ligament +ligamentous +ligaments +ligan +ligand +ligands +ligans +ligase +ligases +ligate +ligated +ligates +ligating +ligation +ligations +ligative +ligature +ligatured +ligatures +ligaturing +liger +ligers +light +lightbulb +lightbulbs +lighted +lighten +lightened +lightener +lighteners +lightening +lightens +lighter +lighterage +lighterages +lightered +lightering +lighters +lightest +lightface +lightfaced +lightfaces +lightfast +lightfastness +lightfastnesses +lightful +lightheaded +lighthearted +lightheartedly +lightheartedness +lightheartednesses +lighthouse +lighthouses +lighting +lightings +lightish +lightless +lightly +lightness +lightnesses +lightning +lightninged +lightnings +lightplane +lightplanes +lightproof +lights +lightship +lightships +lightsome +lightsomely +lightsomeness +lightsomenesses +lighttight +lightweight +lightweights +lightwood +lightwoods +ligneous +lignification +lignifications +lignified +lignifies +lignify +lignifying +lignin +lignins +lignite +lignites +lignitic +lignocellulose +lignocelluloses +lignocellulosic +lignosulfonate +lignosulfonates +ligroin +ligroine +ligroines +ligroins +ligula +ligulae +ligular +ligulas +ligulate +ligule +ligules +liguloid +ligure +ligures +likabilities +likability +likable +likableness +likablenesses +like +likeable +liked +likelier +likeliest +likelihood +likelihoods +likely +liken +likened +likeness +likenesses +likening +likens +liker +likers +likes +likest +likewise +liking +likings +likuta +lilac +lilacs +lilangeni +lilied +lilies +lilliput +lilliputian +lilliputians +lilliputs +lilt +lilted +lilting +liltingly +liltingness +liltingnesses +lilts +lily +lilylike +lima +limacine +limacon +limacons +liman +limans +limas +limb +limba +limbas +limbate +limbeck +limbecks +limbed +limber +limbered +limberer +limberest +limbering +limberly +limberness +limbernesses +limbers +limbi +limbic +limbier +limbiest +limbing +limbless +limbo +limbos +limbs +limbus +limbuses +limby +lime +limeade +limeades +limed +limekiln +limekilns +limeless +limelight +limelighted +limelighting +limelights +limen +limens +limerick +limericks +limes +limestone +limestones +limewater +limewaters +limey +limeys +limier +limiest +limina +liminal +liminess +liminesses +liming +limit +limitable +limitary +limitation +limitational +limitations +limitative +limited +limitedly +limitedness +limitednesses +limiteds +limiter +limiters +limites +limiting +limitingly +limitless +limitlessly +limitlessness +limitlessnesses +limitrophe +limits +limmer +limmers +limn +limned +limner +limners +limnetic +limnic +limning +limnologic +limnological +limnologies +limnologist +limnologists +limnology +limns +limo +limonene +limonenes +limonite +limonites +limonitic +limos +limousine +limousines +limp +limpa +limpas +limped +limper +limpers +limpest +limpet +limpets +limpid +limpidities +limpidity +limpidly +limpidness +limpidnesses +limping +limpkin +limpkins +limply +limpness +limpnesses +limps +limpsey +limpsier +limpsiest +limpsy +limuli +limuloid +limuloids +limulus +limy +lin +linable +linac +linacs +linage +linages +linalol +linalols +linalool +linalools +linchpin +linchpins +lincomycin +lincomycins +lindane +lindanes +linden +lindens +lindies +lindy +line +lineable +lineage +lineages +lineal +linealities +lineality +lineally +lineament +lineamental +lineaments +linear +linearise +linearised +linearises +linearising +linearities +linearity +linearization +linearizations +linearize +linearized +linearizes +linearizing +linearly +lineate +lineated +lineation +lineations +linebacker +linebackers +linebacking +linebackings +linebred +linebreeding +linebreedings +linecaster +linecasters +linecasting +linecastings +linecut +linecuts +lined +lineless +linelike +lineman +linemen +linen +linens +lineny +liner +linerboard +linerboards +linerless +liners +lines +linesman +linesmen +lineup +lineups +liney +ling +linga +lingam +lingams +lingas +lingcod +lingcods +linger +lingered +lingerer +lingerers +lingerie +lingeries +lingering +lingeringly +lingers +lingier +lingiest +lingo +lingoes +lingonberries +lingonberry +lings +lingua +linguae +lingual +lingually +linguals +linguine +linguines +linguini +linguinis +linguist +linguistic +linguistical +linguistically +linguistician +linguisticians +linguistics +linguists +lingy +linier +liniest +liniment +liniments +linin +lining +linings +linins +link +linkable +linkage +linkages +linkboy +linkboys +linked +linker +linkers +linking +linkman +linkmen +links +linksman +linksmen +linkup +linkups +linkwork +linkworks +linky +linn +linnet +linnets +linns +lino +linocut +linocuts +linoleate +linoleates +linoleum +linoleums +linos +lins +linsang +linsangs +linseed +linseeds +linsey +linseys +linstock +linstocks +lint +lintel +lintels +linter +linters +lintier +lintiest +lintless +lintol +lintols +lints +lintwhite +lintwhites +linty +linum +linums +linuron +linurons +liny +lion +lioness +lionesses +lionfish +lionfishes +lionhearted +lionise +lionised +lioniser +lionisers +lionises +lionising +lionization +lionizations +lionize +lionized +lionizer +lionizers +lionizes +lionizing +lionlike +lions +lip +lipase +lipases +lipid +lipide +lipides +lipidic +lipids +lipin +lipins +lipless +liplike +lipocyte +lipocytes +lipogeneses +lipogenesis +lipoid +lipoidal +lipoids +lipolyses +lipolysis +lipolytic +lipoma +lipomas +lipomata +lipomatous +lipophilic +lipopolysaccharide +lipopolysaccharides +lipoprotein +lipoproteins +liposomal +liposome +liposomes +liposuction +liposuctions +lipotropic +lipotropin +lipotropins +lipped +lippen +lippened +lippening +lippens +lipper +lippered +lippering +lippers +lippier +lippiest +lipping +lippings +lippy +lipreading +lipreadings +lips +lipstick +lipsticked +lipsticks +liquate +liquated +liquates +liquating +liquation +liquations +liquefaction +liquefactions +liquefied +liquefier +liquefiers +liquefies +liquefy +liquefying +liquescent +liqueur +liqueurs +liquid +liquidambar +liquidambars +liquidate +liquidated +liquidates +liquidating +liquidation +liquidations +liquidator +liquidators +liquidities +liquidity +liquidize +liquidized +liquidizes +liquidizing +liquidly +liquidness +liquidnesses +liquids +liquified +liquifies +liquify +liquifying +liquor +liquored +liquorice +liquorices +liquoring +liquors +lira +liras +lire +liri +liripipe +liripipes +lirot +liroth +lis +lisente +lisle +lisles +lisp +lisped +lisper +lispers +lisping +lisps +lissom +lissome +lissomely +lissomeness +lissomenesses +lissomly +list +listable +listed +listee +listees +listel +listels +listen +listenable +listened +listener +listeners +listenership +listenerships +listening +listens +lister +listerioses +listeriosis +listers +listing +listings +listless +listlessly +listlessness +listlessnesses +lists +lit +litai +litanies +litany +litas +litchi +litchis +lite +liter +literacies +literacy +literal +literalism +literalisms +literalist +literalistic +literalists +literalities +literality +literalization +literalizations +literalize +literalized +literalizes +literalizing +literally +literalness +literalnesses +literals +literarily +literariness +literarinesses +literary +literate +literately +literateness +literatenesses +literates +literati +literatim +literation +literations +literator +literators +literature +literatures +literatus +liters +litharge +litharges +lithe +lithely +lithemia +lithemias +lithemic +litheness +lithenesses +lither +lithesome +lithest +lithia +lithias +lithiases +lithiasis +lithic +lithification +lithifications +lithified +lithifies +lithify +lithifying +lithium +lithiums +litho +lithoed +lithograph +lithographed +lithographer +lithographers +lithographic +lithographically +lithographies +lithographing +lithographs +lithography +lithoid +lithoing +lithologic +lithological +lithologically +lithologies +lithology +lithophane +lithophanes +lithophyte +lithophytes +lithopone +lithopones +lithos +lithosol +lithosols +lithosphere +lithospheres +lithospheric +lithotomies +lithotomy +lithotripsies +lithotripsy +lithotripter +lithotripters +lithotriptor +lithotriptors +litigable +litigant +litigants +litigate +litigated +litigates +litigating +litigation +litigations +litigator +litigators +litigious +litigiously +litigiousness +litigiousnesses +litmus +litmuses +litoral +litotes +litotic +litre +litres +lits +litten +litter +litterateur +litterateurs +litterbag +litterbags +litterbug +litterbugs +littered +litterer +litterers +littering +littermate +littermates +litters +littery +little +littleneck +littlenecks +littleness +littlenesses +littler +littles +littlest +littlish +littoral +littorals +litu +liturgic +liturgical +liturgically +liturgics +liturgies +liturgiologies +liturgiologist +liturgiologists +liturgiology +liturgist +liturgists +liturgy +livabilities +livability +livable +livableness +livablenesses +live +liveabilities +liveability +liveable +lived +livelier +liveliest +livelihood +livelihoods +livelily +liveliness +livelinesses +livelong +lively +liven +livened +livener +liveners +liveness +livenesses +livening +livens +liver +liveried +liveries +liverish +liverishness +liverishnesses +livers +liverwort +liverworts +liverwurst +liverwursts +livery +liveryman +liverymen +lives +livest +livestock +livestocks +livetrap +livetrapped +livetrapping +livetraps +livid +lividities +lividity +lividly +lividness +lividnesses +livier +liviers +living +livingly +livingness +livingnesses +livings +livre +livres +livyer +livyers +lixivia +lixivial +lixiviate +lixiviated +lixiviates +lixiviating +lixiviation +lixiviations +lixivium +lixiviums +lizard +lizards +llama +llamas +llano +llanos +lo +loach +loaches +load +loaded +loader +loaders +loading +loadings +loadmaster +loadmasters +loads +loadstar +loadstars +loadstone +loadstones +loaf +loafed +loafer +loafers +loafing +loafs +loam +loamed +loamier +loamiest +loaming +loamless +loams +loamy +loan +loanable +loaned +loaner +loaners +loaning +loanings +loans +loanword +loanwords +loath +loathe +loathed +loather +loathers +loathes +loathful +loathing +loathings +loathly +loathness +loathnesses +loathsome +loathsomely +loathsomeness +loathsomenesses +loaves +lob +lobar +lobate +lobated +lobately +lobation +lobations +lobbed +lobber +lobbers +lobbied +lobbies +lobbing +lobby +lobbyer +lobbyers +lobbygow +lobbygows +lobbying +lobbyism +lobbyisms +lobbyist +lobbyists +lobe +lobectomies +lobectomy +lobed +lobefin +lobefins +lobelia +lobelias +lobeline +lobelines +lobes +loblollies +loblolly +lobo +lobos +lobotomies +lobotomise +lobotomised +lobotomises +lobotomising +lobotomize +lobotomized +lobotomizes +lobotomizing +lobotomy +lobs +lobscouse +lobscouses +lobster +lobstered +lobstering +lobsterings +lobsterlike +lobsterman +lobstermen +lobsters +lobstick +lobsticks +lobular +lobulate +lobulated +lobulation +lobulations +lobule +lobules +lobulose +lobworm +lobworms +loca +local +locale +locales +localise +localised +localises +localising +localism +localisms +localist +localists +localite +localites +localities +locality +localizabilities +localizability +localizable +localization +localizations +localize +localized +localizes +localizing +locally +locals +locatable +locate +located +locater +locaters +locates +locating +location +locational +locationally +locations +locative +locatives +locator +locators +loch +lochan +lochans +lochia +lochial +lochs +loci +lock +lockable +lockage +lockages +lockbox +lockboxes +lockdown +lockdowns +locked +locker +lockers +locket +lockets +locking +lockjaw +lockjaws +lockkeeper +lockkeepers +locknut +locknuts +lockout +lockouts +lockram +lockrams +locks +locksmith +locksmithing +locksmithings +locksmiths +lockstep +locksteps +lockstitch +lockstitched +lockstitches +lockstitching +lockup +lockups +loco +locoed +locoes +locofoco +locofocos +locoing +locoism +locoisms +locomote +locomoted +locomotes +locomoting +locomotion +locomotions +locomotive +locomotives +locomotor +locomotory +locos +locoweed +locoweeds +locular +loculate +locule +loculed +locules +loculi +loculicidal +loculus +locum +locums +locus +locust +locusta +locustae +locustal +locusts +locution +locutions +locutories +locutory +lode +loden +lodens +lodes +lodestar +lodestars +lodestone +lodestones +lodge +lodged +lodgement +lodgements +lodger +lodgers +lodges +lodging +lodgings +lodgment +lodgments +lodicule +lodicules +loess +loessal +loesses +loessial +loft +lofted +lofter +lofters +loftier +loftiest +loftily +loftiness +loftinesses +lofting +loftless +loftlike +lofts +lofty +log +logan +loganberries +loganberry +logania +logans +logaoedic +logaoedics +logarithm +logarithmic +logarithmically +logarithms +logbook +logbooks +loge +loges +loggats +logged +logger +loggerhead +loggerheads +loggers +loggets +loggia +loggias +loggie +loggier +loggiest +logging +loggings +loggy +logia +logic +logical +logicalities +logicality +logically +logicalness +logicalnesses +logician +logicians +logicise +logicised +logicises +logicising +logicize +logicized +logicizes +logicizing +logics +logier +logiest +logily +loginess +loginesses +logion +logions +logistic +logistical +logistically +logistician +logisticians +logistics +logjam +logjams +lognormal +lognormalities +lognormality +lognormally +logo +logogram +logogrammatic +logograms +logograph +logographic +logographically +logographs +logogriph +logogriphs +logoi +logomach +logomachies +logomachs +logomachy +logorrhea +logorrheas +logorrheic +logos +logotype +logotypes +logotypies +logotypy +logroll +logrolled +logroller +logrollers +logrolling +logrollings +logrolls +logs +logway +logways +logwood +logwoods +logy +loin +loincloth +loincloths +loins +loiter +loitered +loiterer +loiterers +loitering +loiters +loll +lollapalooza +lollapaloozas +lolled +loller +lollers +lollies +lolling +lollipop +lollipops +lollop +lolloped +lolloping +lollops +lolls +lolly +lollygag +lollygagged +lollygagging +lollygags +lollypop +lollypops +lomein +lomeins +loment +lomenta +loments +lomentum +lomentums +lone +lonelier +loneliest +lonelily +loneliness +lonelinesses +lonely +loneness +lonenesses +loner +loners +lonesome +lonesomely +lonesomeness +lonesomenesses +lonesomes +long +longan +longanimities +longanimity +longans +longboat +longboats +longbow +longbowman +longbowmen +longbows +longe +longed +longeing +longer +longeron +longerons +longers +longes +longest +longevities +longevity +longevous +longhair +longhaired +longhairs +longhand +longhands +longhead +longheaded +longheadedness +longheadednesses +longheads +longhorn +longhorns +longhouse +longhouses +longicorn +longicorns +longies +longing +longingly +longings +longish +longitude +longitudes +longitudinal +longitudinally +longleaf +longleaves +longline +longlines +longly +longness +longnesses +longs +longship +longships +longshoreman +longshoremen +longshoring +longshorings +longsighted +longsightedness +longsightednesses +longsome +longsomely +longsomeness +longsomenesses +longspur +longspurs +longtime +longueur +longueurs +longways +longwise +loo +loobies +looby +looed +looey +looeys +loof +loofa +loofah +loofahs +loofas +loofs +looie +looies +looing +look +lookalike +lookalikes +lookdown +lookdowns +looked +looker +lookers +looking +lookout +lookouts +looks +lookup +lookups +loom +loomed +looming +looms +loon +looney +looneys +loonier +loonies +looniest +looniness +looninesses +loons +loony +loop +looped +looper +loopers +loophole +loopholed +loopholes +loopholing +loopier +loopiest +looping +loops +loopy +loos +loose +loosed +loosely +loosen +loosened +loosener +looseners +looseness +loosenesses +loosening +loosens +looser +looses +loosest +loosestrife +loosestrifes +loosing +loot +looted +looter +looters +looting +loots +lop +lope +loped +loper +lopers +lopes +lophophore +lophophores +loping +lopped +lopper +loppered +loppering +loppers +loppier +loppiest +lopping +loppy +lops +lopsided +lopsidedly +lopsidedness +lopsidednesses +lopstick +lopsticks +loquacious +loquaciously +loquaciousness +loquaciousnesses +loquacities +loquacity +loquat +loquats +loral +loran +lorans +lord +lorded +lording +lordings +lordless +lordlier +lordliest +lordlike +lordliness +lordlinesses +lordling +lordlings +lordly +lordoma +lordomas +lordoses +lordosis +lordotic +lords +lordship +lordships +lore +loreal +lores +lorgnette +lorgnettes +lorgnon +lorgnons +lorica +loricae +loricate +loricates +lories +lorikeet +lorikeets +lorimer +lorimers +loriner +loriners +loris +lorises +lorn +lornness +lornnesses +lorries +lorry +lory +losable +losableness +losablenesses +lose +losel +losels +loser +losers +loses +losing +losingly +losings +loss +losses +lossy +lost +lostness +lostnesses +lot +lota +lotah +lotahs +lotas +loth +lothario +lotharios +lothsome +loti +lotic +lotion +lotions +lotos +lotoses +lots +lotte +lotted +lotteries +lottery +lottes +lotting +lotto +lottos +lotus +lotuses +lotusland +lotuslands +louche +loud +louden +loudened +loudening +loudens +louder +loudest +loudish +loudlier +loudliest +loudly +loudmouth +loudmouthed +loudmouths +loudness +loudnesses +loudspeaker +loudspeakers +lough +loughs +louie +louies +louis +lounge +lounged +lounger +loungers +lounges +loungewear +lounging +loungy +loup +loupe +louped +loupen +loupes +louping +loups +lour +loured +louring +lours +loury +louse +loused +louses +lousewort +louseworts +lousier +lousiest +lousily +lousiness +lousinesses +lousing +lousy +lout +louted +louting +loutish +loutishly +loutishness +loutishnesses +louts +louver +louvered +louvers +louvre +louvred +louvres +lovabilities +lovability +lovable +lovableness +lovablenesses +lovably +lovage +lovages +lovastatin +lovastatins +lovat +lovats +love +loveable +loveably +lovebird +lovebirds +lovebug +lovebugs +loved +loveless +lovelessly +lovelessness +lovelessnesses +lovelier +lovelies +loveliest +lovelily +loveliness +lovelinesses +lovelock +lovelocks +lovelorn +lovelornness +lovelornnesses +lovely +lovemaking +lovemakings +lover +loverly +lovers +loves +lovesick +lovesickness +lovesicknesses +lovesome +lovevine +lovevines +loving +lovingly +lovingness +lovingnesses +low +lowball +lowballed +lowballing +lowballs +lowborn +lowboy +lowboys +lowbred +lowbrow +lowbrows +lowdown +lowdowns +lowe +lowed +lower +lowercase +lowercased +lowercases +lowercasing +lowerclassman +lowerclassmen +lowered +lowering +lowermost +lowers +lowery +lowes +lowest +lowing +lowings +lowish +lowland +lowlander +lowlanders +lowlands +lowlier +lowliest +lowlife +lowlifer +lowlifers +lowlifes +lowlight +lowlights +lowlihead +lowliheads +lowliness +lowlinesses +lowlives +lowly +lown +lowness +lownesses +lowrider +lowriders +lows +lowse +lox +loxed +loxes +loxing +loxodrome +loxodromes +loyal +loyaler +loyalest +loyalism +loyalisms +loyalist +loyalists +loyally +loyalties +loyalty +lozenge +lozenges +luau +luaus +lubber +lubberliness +lubberlinesses +lubberly +lubbers +lube +lubes +lubric +lubrical +lubricant +lubricants +lubricate +lubricated +lubricates +lubricating +lubrication +lubrications +lubricative +lubricator +lubricators +lubricious +lubriciously +lubricities +lubricity +lubricous +lucarne +lucarnes +luce +lucence +lucences +lucencies +lucency +lucent +lucently +lucern +lucerne +lucernes +lucerns +luces +lucid +lucidities +lucidity +lucidly +lucidness +lucidnesses +lucifer +luciferase +luciferases +luciferin +luciferins +luciferous +lucifers +luck +lucked +luckie +luckier +luckies +luckiest +luckily +luckiness +luckinesses +lucking +luckless +lucks +lucky +lucrative +lucratively +lucrativeness +lucrativenesses +lucre +lucres +lucubration +lucubrations +luculent +luculently +lude +ludes +ludic +ludicrous +ludicrously +ludicrousness +ludicrousnesses +lues +luetic +luetics +luff +luffa +luffas +luffed +luffing +luffs +luftmensch +luftmenschen +lug +luge +luged +lugeing +luger +lugers +luges +luggage +luggages +lugged +lugger +luggers +luggie +luggies +lugging +lugs +lugsail +lugsails +lugubrious +lugubriously +lugubriousness +lugubriousnesses +lugworm +lugworms +lukewarm +lukewarmly +lukewarmness +lukewarmnesses +lull +lullabied +lullabies +lullaby +lullabying +lulled +lulling +lulls +lulu +lulus +lum +lumbago +lumbagos +lumbar +lumbars +lumber +lumbered +lumberer +lumberers +lumbering +lumberjack +lumberjacks +lumberman +lumbermen +lumbers +lumberyard +lumberyards +lumbosacral +lumen +lumenal +lumens +lumina +luminaire +luminaires +luminal +luminance +luminances +luminaria +luminarias +luminaries +luminary +luminesce +luminesced +luminescence +luminescences +luminescent +luminesces +luminescing +luminiferous +luminism +luminisms +luminist +luminists +luminosities +luminosity +luminous +luminously +luminousness +luminousnesses +lummox +lummoxes +lump +lumpectomies +lumpectomy +lumped +lumpen +lumpenproletariat +lumpenproletariats +lumpens +lumper +lumpers +lumpfish +lumpfishes +lumpier +lumpiest +lumpily +lumpiness +lumpinesses +lumping +lumpish +lumpishly +lumpishness +lumpishnesses +lumps +lumpy +lums +luna +lunacies +lunacy +lunar +lunarian +lunarians +lunars +lunas +lunate +lunated +lunately +lunatic +lunatics +lunation +lunations +lunch +lunched +luncheon +luncheonette +luncheonettes +luncheons +luncher +lunchers +lunches +lunching +lunchmeat +lunchmeats +lunchroom +lunchrooms +lunchtime +lunchtimes +lune +lunes +lunet +lunets +lunette +lunettes +lung +lungan +lungans +lunge +lunged +lungee +lungees +lunger +lungers +lunges +lungfish +lungfishes +lungful +lungfuls +lungi +lunging +lungis +lungs +lungworm +lungworms +lungwort +lungworts +lungyi +lungyis +lunier +lunies +luniest +lunisolar +lunk +lunker +lunkers +lunkhead +lunkheaded +lunkheads +lunks +lunt +lunted +lunting +lunts +lunula +lunulae +lunular +lunulate +lunule +lunules +luny +lupanar +lupanars +lupin +lupine +lupines +lupins +lupous +lupulin +lupulins +lupus +lupuses +lurch +lurched +lurcher +lurchers +lurches +lurching +lurdan +lurdane +lurdanes +lurdans +lure +lured +lurer +lurers +lures +lurid +luridly +luridness +luridnesses +luring +lurk +lurked +lurker +lurkers +lurking +lurks +luscious +lusciously +lusciousness +lusciousnesses +lush +lushed +lusher +lushes +lushest +lushing +lushly +lushness +lushnesses +lust +lusted +luster +lustered +lustering +lusterless +lusters +lusterware +lusterwares +lustful +lustfully +lustfulness +lustfulnesses +lustier +lustiest +lustihood +lustihoods +lustily +lustiness +lustinesses +lusting +lustra +lustral +lustrate +lustrated +lustrates +lustrating +lustration +lustrations +lustre +lustred +lustres +lustring +lustrings +lustrous +lustrously +lustrousness +lustrousnesses +lustrum +lustrums +lusts +lusty +lusus +lususes +lutanist +lutanists +lute +lutea +luteal +lutecium +luteciums +luted +lutefisk +lutefisks +lutein +luteinization +luteinizations +luteinize +luteinized +luteinizes +luteinizing +luteins +lutenist +lutenists +luteolin +luteolins +luteotrophic +luteotrophin +luteotrophins +luteotropic +luteotropin +luteotropins +luteous +lutes +lutestring +lutestrings +lutetium +lutetiums +luteum +luthern +lutherns +luthier +luthiers +luting +lutings +lutist +lutists +lutz +lutzes +luv +luvs +lux +luxate +luxated +luxates +luxating +luxation +luxations +luxe +luxes +luxuriance +luxuriances +luxuriant +luxuriantly +luxuriate +luxuriated +luxuriates +luxuriating +luxuries +luxurious +luxuriously +luxuriousness +luxuriousnesses +luxury +lwei +lweis +lyard +lyart +lyase +lyases +lycanthrope +lycanthropes +lycanthropic +lycanthropies +lycanthropy +lycea +lycee +lycees +lyceum +lyceums +lychee +lychees +lychnis +lychnises +lycopene +lycopenes +lycopod +lycopodium +lycopodiums +lycopods +lyddite +lyddites +lye +lyes +lying +lyingly +lyings +lymph +lymphadenitis +lymphadenitises +lymphadenopathies +lymphadenopathy +lymphangiogram +lymphangiograms +lymphangiographic +lymphangiographies +lymphangiography +lymphatic +lymphatically +lymphatics +lymphoblast +lymphoblastic +lymphoblasts +lymphocyte +lymphocytes +lymphocytic +lymphocytoses +lymphocytosis +lymphocytosises +lymphogram +lymphograms +lymphogranuloma +lymphogranulomas +lymphogranulomata +lymphogranulomatoses +lymphogranulomatosis +lymphographic +lymphographies +lymphography +lymphoid +lymphokine +lymphokines +lymphoma +lymphomas +lymphomata +lymphomatoses +lymphomatosis +lymphomatous +lymphosarcoma +lymphosarcomas +lymphosarcomata +lymphs +lyncean +lynch +lynched +lyncher +lynchers +lynches +lynching +lynchings +lynchpin +lynchpins +lynx +lynxes +lyonnaise +lyophile +lyophiled +lyophilic +lyophilise +lyophilised +lyophilises +lyophilising +lyophilization +lyophilizations +lyophilize +lyophilized +lyophilizer +lyophilizers +lyophilizes +lyophilizing +lyophobic +lyrate +lyrated +lyrately +lyre +lyrebird +lyrebirds +lyres +lyric +lyrical +lyrically +lyricalness +lyricalnesses +lyricise +lyricised +lyricises +lyricising +lyricism +lyricisms +lyricist +lyricists +lyricize +lyricized +lyricizes +lyricizing +lyrics +lyriform +lyrism +lyrisms +lyrist +lyrists +lysate +lysates +lyse +lysed +lyses +lysimeter +lysimeters +lysimetric +lysin +lysine +lysines +lysing +lysins +lysis +lysogen +lysogenic +lysogenicities +lysogenicity +lysogenies +lysogenise +lysogenised +lysogenises +lysogenising +lysogenization +lysogenizations +lysogenize +lysogenized +lysogenizes +lysogenizing +lysogens +lysogeny +lysolecithin +lysolecithins +lysosomal +lysosome +lysosomes +lysozyme +lysozymes +lyssa +lyssas +lytic +lytically +lytta +lyttae +lyttas +ma +maar +maars +mabe +mabes +mac +macaber +macabre +macaco +macacos +macadam +macadamia +macadamias +macadamize +macadamized +macadamizes +macadamizing +macadams +macaque +macaques +macaroni +macaronic +macaronics +macaronies +macaronis +macaroon +macaroons +macaw +macaws +maccabaw +maccabaws +maccaboy +maccaboys +macchia +macchie +maccoboy +maccoboys +mace +maced +macedoine +macedoines +macer +macerate +macerated +macerates +macerating +maceration +macerations +macerator +macerators +macers +maces +mach +mache +maches +machete +machetes +machicolated +machicolation +machicolations +machinabilities +machinability +machinable +machinate +machinated +machinates +machinating +machination +machinations +machinator +machinators +machine +machineabilities +machineability +machineable +machined +machinelike +machineries +machinery +machines +machining +machinist +machinists +machismo +machismos +macho +machos +machree +machrees +machs +machzor +machzorim +machzors +macing +macintosh +macintoshes +mack +mackerel +mackerels +mackinaw +mackinaws +mackintosh +mackintoshes +mackle +mackled +mackles +mackling +macks +macle +macled +macles +macon +macons +macrame +macrames +macro +macroaggregate +macroaggregated +macroaggregates +macrobiotic +macrocosm +macrocosmic +macrocosmically +macrocosms +macrocyclic +macrocyte +macrocytes +macrocytic +macrocytoses +macrocytosis +macroeconomic +macroeconomics +macroevolution +macroevolutionary +macroevolutions +macrofossil +macrofossils +macrogamete +macrogametes +macroglobulin +macroglobulinemia +macroglobulinemias +macroglobulinemic +macroglobulins +macroinstruction +macroinstructions +macrolepidoptera +macromere +macromeres +macromolecular +macromolecule +macromolecules +macron +macrons +macronuclear +macronuclei +macronucleus +macronucleuses +macronutrient +macronutrients +macrophage +macrophages +macrophagic +macrophotograph +macrophotographies +macrophotographs +macrophotography +macrophyte +macrophytes +macrophytic +macropterous +macros +macroscale +macroscales +macroscopic +macroscopically +macrostructural +macrostructure +macrostructures +macrural +macruran +macrurans +macs +macula +maculae +macular +maculas +maculate +maculated +maculates +maculating +maculation +maculations +macule +maculed +macules +maculing +macumba +macumbas +mad +madam +madame +madames +madams +madcap +madcaps +madded +madden +maddened +maddening +maddeningly +maddens +madder +madders +maddest +madding +maddish +made +madeira +madeiras +madeleine +madeleines +mademoiselle +mademoiselles +madhouse +madhouses +madly +madman +madmen +madness +madnesses +madonna +madonnas +madras +madrases +madre +madrepore +madrepores +madreporian +madreporians +madreporic +madreporite +madreporites +madres +madrigal +madrigalian +madrigalist +madrigalists +madrigals +madrilene +madrilenes +madrona +madronas +madrone +madrones +madrono +madronos +mads +maduro +maduros +madwoman +madwomen +madwort +madworts +madzoon +madzoons +mae +maelstrom +maelstroms +maenad +maenades +maenadic +maenads +maes +maestoso +maestosos +maestri +maestro +maestros +maffia +maffias +maffick +mafficked +mafficking +mafficks +mafia +mafias +mafic +mafiosi +mafioso +maftir +maftirs +mag +magazine +magazines +magazinist +magazinists +magdalen +magdalene +magdalenes +magdalens +mage +magenta +magentas +mages +maggot +maggots +maggoty +magi +magian +magians +magic +magical +magically +magician +magicians +magicked +magicking +magics +magilp +magilps +magister +magisterial +magisterially +magisterium +magisteriums +magisters +magistracies +magistracy +magistral +magistrally +magistrate +magistrates +magistratical +magistratically +magistrature +magistratures +maglev +maglevs +magma +magmas +magmata +magmatic +magnanimities +magnanimity +magnanimous +magnanimously +magnanimousness +magnanimousnesses +magnate +magnates +magnesia +magnesian +magnesias +magnesic +magnesite +magnesites +magnesium +magnesiums +magnet +magnetic +magnetically +magnetics +magnetise +magnetised +magnetises +magnetising +magnetism +magnetisms +magnetite +magnetites +magnetizable +magnetization +magnetizations +magnetize +magnetized +magnetizer +magnetizers +magnetizes +magnetizing +magneto +magnetoelectric +magnetofluiddynamics +magnetograph +magnetographs +magnetohydrodynamic +magnetohydrodynamics +magnetometer +magnetometers +magnetometric +magnetometries +magnetometry +magneton +magnetons +magnetopause +magnetopauses +magnetoresistance +magnetoresistances +magnetos +magnetosphere +magnetospheres +magnetospheric +magnetostatic +magnetostriction +magnetostrictions +magnetostrictive +magnetostrictively +magnetron +magnetrons +magnets +magnific +magnifical +magnifically +magnificat +magnification +magnifications +magnificats +magnificence +magnificences +magnificent +magnificently +magnifico +magnificoes +magnificos +magnified +magnifier +magnifiers +magnifies +magnify +magnifying +magniloquence +magniloquences +magniloquent +magniloquently +magnitude +magnitudes +magnolia +magnolias +magnum +magnums +magot +magots +magpie +magpies +mags +maguey +magueys +magus +maharaja +maharajah +maharajahs +maharajas +maharanee +maharanees +maharani +maharanis +maharishi +maharishis +mahatma +mahatmas +mahimahi +mahjong +mahjongg +mahjonggs +mahjongs +mahlstick +mahlsticks +mahoe +mahoes +mahoganies +mahogany +mahonia +mahonias +mahout +mahouts +mahuang +mahuangs +mahzor +mahzorim +mahzors +maid +maiden +maidenhair +maidenhairs +maidenhead +maidenheads +maidenhood +maidenhoods +maidenliness +maidenlinesses +maidenly +maidens +maidhood +maidhoods +maidish +maids +maidservant +maidservants +maieutic +maigre +maihem +maihems +mail +mailabilities +mailability +mailable +mailbag +mailbags +mailbox +mailboxes +maile +mailed +mailer +mailers +mailes +mailing +mailings +maill +mailless +maillot +maillots +maills +mailman +mailmen +mails +maim +maimed +maimer +maimers +maiming +maims +main +mainframe +mainframes +mainland +mainlander +mainlanders +mainlands +mainline +mainlined +mainlines +mainlining +mainly +mainmast +mainmasts +mains +mainsail +mainsails +mainsheet +mainsheets +mainspring +mainsprings +mainstay +mainstays +mainstream +mainstreamed +mainstreaming +mainstreams +maintain +maintainabilities +maintainability +maintainable +maintained +maintainer +maintainers +maintaining +maintains +maintenance +maintenances +maintop +maintops +maiolica +maiolicas +mair +mairs +maisonette +maisonettes +maist +maists +maize +maizes +majagua +majaguas +majestic +majestically +majesties +majesty +majolica +majolicas +major +majordomo +majordomos +majored +majorette +majorettes +majoring +majoritarian +majoritarianism +majoritarianisms +majoritarians +majorities +majority +majorly +majors +majuscular +majuscule +majuscules +makable +makar +makars +make +makeable +makebate +makebates +makefast +makefasts +makeover +makeovers +maker +makereadies +makeready +makers +makes +makeshift +makeshifts +makeup +makeups +makeweight +makeweights +makimono +makimonos +making +makings +mako +makos +makuta +malabsorption +malabsorptions +malacca +malaccas +malachite +malachites +malacological +malacologies +malacologist +malacologists +malacology +malacostracan +malacostracans +maladaptation +maladaptations +maladapted +maladaptive +maladies +maladjusted +maladjustive +maladjustment +maladjustments +maladminister +maladministered +maladministering +maladministers +maladministration +maladministrations +maladroit +maladroitly +maladroitness +maladroitnesses +malady +malaguena +malaguenas +malaise +malaises +malamute +malamutes +malanga +malangas +malapert +malapertly +malapertness +malapertnesses +malaperts +malapportioned +malapportionment +malapportionments +malaprop +malapropian +malapropism +malapropisms +malapropist +malapropists +malapropos +malaprops +malar +malaria +malarial +malarian +malarias +malariologies +malariologist +malariologists +malariology +malarious +malarkey +malarkeys +malarkies +malarky +malaroma +malaromas +malars +malate +malates +malathion +malathions +malcontent +malcontented +malcontentedly +malcontentedness +malcontentednesses +malcontents +maldistribution +maldistributions +male +maleate +maleates +maledict +maledicted +maledicting +malediction +maledictions +maledictory +maledicts +malefaction +malefactions +malefactor +malefactors +malefic +maleficence +maleficences +maleficent +malemiut +malemiuts +malemute +malemutes +maleness +malenesses +males +malevolence +malevolences +malevolent +malevolently +malfeasance +malfeasances +malfed +malformation +malformations +malformed +malfunction +malfunctioned +malfunctioning +malfunctions +malgre +malic +malice +malices +malicious +maliciously +maliciousness +maliciousnesses +malign +malignance +malignances +malignancies +malignancy +malignant +malignantly +maligned +maligner +maligners +maligning +malignities +malignity +malignly +maligns +malihini +malihinis +maline +malines +malinger +malingered +malingerer +malingerers +malingering +malingers +malison +malisons +malkin +malkins +mall +mallard +mallards +malleabilities +malleability +malleable +malled +mallee +mallees +mallei +malleoli +malleolus +mallet +mallets +malleus +malling +mallow +mallows +malls +malm +malmier +malmiest +malms +malmsey +malmseys +malmy +malnourished +malnutrition +malnutritions +malocclusion +malocclusions +malodor +malodorous +malodorously +malodorousness +malodorousnesses +malodors +malolactic +maloti +malposed +malposition +malpositions +malpractice +malpractices +malpractitioner +malpractitioners +malt +maltase +maltases +malted +malteds +maltha +malthas +maltier +maltiest +malting +maltol +maltols +maltose +maltoses +maltreat +maltreated +maltreater +maltreaters +maltreating +maltreatment +maltreatments +maltreats +malts +maltster +maltsters +malty +malvasia +malvasias +malversation +malversations +mama +mamaliga +mamaligas +mamas +mamba +mambas +mambo +mamboed +mamboes +mamboing +mambos +mameluke +mamelukes +mamey +mameyes +mameys +mamie +mamies +mamluk +mamluks +mamma +mammae +mammal +mammalian +mammalians +mammalogies +mammalogist +mammalogists +mammalogy +mammals +mammary +mammas +mammate +mammati +mammatus +mammee +mammees +mammer +mammered +mammering +mammers +mammet +mammets +mammey +mammeys +mammie +mammies +mammilla +mammillae +mammillary +mammillated +mammitides +mammitis +mammock +mammocked +mammocking +mammocks +mammogram +mammograms +mammographic +mammographies +mammography +mammon +mammonism +mammonisms +mammonist +mammonists +mammons +mammoth +mammoths +mammy +man +mana +manacle +manacled +manacles +manacling +manage +manageabilities +manageability +manageable +manageableness +manageablenesses +manageably +managed +management +managemental +managements +manager +manageress +manageresses +managerial +managerially +managers +managership +managerships +manages +managing +manakin +manakins +manana +mananas +manas +manatee +manatees +manatoid +manche +manches +manchet +manchets +manchineel +manchineels +manciple +manciples +mandala +mandalas +mandalic +mandamus +mandamused +mandamuses +mandamusing +mandarin +mandarinate +mandarinates +mandarinic +mandarinism +mandarinisms +mandarins +mandataries +mandatary +mandate +mandated +mandates +mandating +mandator +mandatories +mandatorily +mandators +mandatory +mandible +mandibles +mandibular +mandibulate +mandioca +mandiocas +mandola +mandolas +mandolin +mandoline +mandolines +mandolinist +mandolinists +mandolins +mandragora +mandragoras +mandrake +mandrakes +mandrel +mandrels +mandril +mandrill +mandrills +mandrils +mane +maned +manege +maneges +maneless +manes +maneuver +maneuverabilities +maneuverability +maneuverable +maneuvered +maneuverer +maneuverers +maneuvering +maneuvers +manful +manfully +manfulness +manfulnesses +mangabey +mangabeys +mangabies +mangaby +manganate +manganates +manganese +manganeses +manganesian +manganic +manganite +manganites +manganous +mange +mangel +mangels +manger +mangers +manges +mangey +mangier +mangiest +mangily +manginess +manginesses +mangle +mangled +mangler +manglers +mangles +mangling +mango +mangoes +mangold +mangolds +mangonel +mangonels +mangos +mangosteen +mangosteens +mangrove +mangroves +mangy +manhandle +manhandled +manhandles +manhandling +manhattan +manhattans +manhole +manholes +manhood +manhoods +manhunt +manhunts +mania +maniac +maniacal +maniacally +maniacs +manias +manic +manically +manicotti +manics +manicure +manicured +manicures +manicuring +manicurist +manicurists +manifest +manifestant +manifestants +manifestation +manifestations +manifested +manifester +manifesters +manifesting +manifestly +manifesto +manifestoed +manifestoes +manifestoing +manifestos +manifests +manifold +manifolded +manifolding +manifoldly +manifoldness +manifoldnesses +manifolds +manihot +manihots +manikin +manikins +manila +manilas +manilla +manillas +manille +manilles +manioc +manioca +maniocas +maniocs +maniple +maniples +manipulabilities +manipulability +manipulable +manipular +manipulatable +manipulate +manipulated +manipulates +manipulating +manipulation +manipulations +manipulative +manipulatively +manipulativeness +manipulativenesses +manipulator +manipulators +manipulatory +manito +manitos +manitou +manitous +manitu +manitus +mankind +manless +manlier +manliest +manlike +manlily +manliness +manlinesses +manly +manmade +manna +mannan +mannans +mannas +manned +mannequin +mannequins +manner +mannered +mannerism +mannerisms +mannerist +manneristic +mannerists +mannerless +mannerliness +mannerlinesses +mannerly +manners +mannikin +mannikins +manning +mannish +mannishly +mannishness +mannishnesses +mannite +mannites +mannitic +mannitol +mannitols +mannose +mannoses +mano +manoeuvre +manoeuvred +manoeuvres +manoeuvring +manometer +manometers +manometric +manometrically +manometries +manometry +manor +manorial +manorialism +manorialisms +manors +manos +manpack +manpower +manpowers +manque +manrope +manropes +mans +mansard +mansarded +mansards +manse +manservant +manses +mansion +mansions +manslaughter +manslaughters +manslayer +manslayers +mansuetude +mansuetudes +manta +mantas +manteau +manteaus +manteaux +mantel +mantelet +mantelets +mantelpiece +mantelpieces +mantels +mantelshelf +mantelshelves +mantes +mantic +manticore +manticores +mantid +mantids +mantilla +mantillas +mantis +mantises +mantissa +mantissas +mantle +mantled +mantles +mantlet +mantlets +mantling +mantlings +mantra +mantrap +mantraps +mantras +mantric +mantua +mantuas +manual +manually +manuals +manuary +manubria +manubrium +manubriums +manufactories +manufactory +manufacture +manufactured +manufacturer +manufacturers +manufactures +manufacturing +manufacturings +manumission +manumissions +manumit +manumits +manumitted +manumitting +manure +manured +manurer +manurers +manures +manurial +manuring +manus +manuscript +manuscripts +manward +manwards +manwise +many +manyfold +manzanita +manzanitas +map +maple +maples +maplike +mapmaker +mapmakers +mapmaking +mapmakings +mappable +mapped +mapper +mappers +mapping +mappings +maps +maquette +maquettes +maqui +maquiladora +maquiladoras +maquillage +maquillages +maquis +mar +marabou +marabous +marabout +marabouts +maraca +maracas +maranta +marantas +marasca +marascas +maraschino +maraschinos +marasmic +marasmus +marasmuses +marathon +marathoner +marathoners +marathoning +marathonings +marathons +maraud +marauded +marauder +marauders +marauding +marauds +maravedi +maravedis +marble +marbled +marbleise +marbleised +marbleises +marbleising +marbleize +marbleized +marbleizes +marbleizing +marbler +marblers +marbles +marblier +marbliest +marbling +marblings +marbly +marc +marcasite +marcasites +marcato +marcel +marcelled +marcelling +marcels +march +marched +marchen +marcher +marchers +marches +marchesa +marchese +marchesi +marching +marchioness +marchionesses +marchlike +marchpane +marchpanes +marcs +mare +maremma +maremme +marengo +mares +margaric +margarin +margarine +margarines +margarins +margarita +margaritas +margarite +margarites +margay +margays +marge +margent +margented +margenting +margents +marges +margin +marginal +marginalia +marginalities +marginality +marginalization +marginalizations +marginalize +marginalized +marginalizes +marginalizing +marginally +marginate +marginated +marginates +marginating +margination +marginations +margined +margining +margins +margravate +margravates +margrave +margraves +margravial +margraviate +margraviates +margravine +margravines +marguerite +marguerites +maria +mariachi +mariachis +mariculture +maricultures +mariculturist +mariculturists +marigold +marigolds +marihuana +marihuanas +marijuana +marijuanas +marimba +marimbas +marimbist +marimbists +marina +marinade +marinaded +marinades +marinading +marinara +marinaras +marinas +marinate +marinated +marinates +marinating +marination +marinations +marine +mariner +mariners +marines +marionette +marionettes +mariposa +mariposas +marish +marishes +marital +maritally +maritime +marjoram +marjorams +mark +markdown +markdowns +marked +markedly +markedness +markednesses +marker +markers +market +marketabilities +marketability +marketable +marketed +marketeer +marketeers +marketer +marketers +marketing +marketings +marketplace +marketplaces +markets +markhoor +markhoors +markhor +markhors +marking +markings +markka +markkaa +markkas +marks +marksman +marksmanship +marksmanships +marksmen +markswoman +markswomen +markup +markups +marl +marled +marlier +marliest +marlin +marline +marlines +marlinespike +marlinespikes +marling +marlings +marlins +marlinspike +marlinspikes +marlite +marlites +marlitic +marls +marlstone +marlstones +marly +marmalade +marmalades +marmite +marmites +marmoreal +marmoreally +marmorean +marmoset +marmosets +marmot +marmots +marocain +marocains +maroon +marooned +marooning +maroons +marplot +marplots +marque +marquee +marquees +marques +marquess +marquessate +marquessates +marquesses +marqueterie +marqueteries +marquetries +marquetry +marquis +marquisate +marquisates +marquise +marquises +marquisette +marquisettes +marram +marrams +marrano +marranos +marred +marrer +marrers +marriage +marriageabilities +marriageability +marriageable +marriages +married +marrieds +marrier +marriers +marries +marring +marron +marrons +marrow +marrowbone +marrowbones +marrowed +marrowfat +marrowfats +marrowing +marrows +marrowy +marry +marrying +mars +marsala +marsalas +marse +marses +marsh +marshal +marshalcies +marshalcy +marshaled +marshaling +marshall +marshalled +marshalling +marshalls +marshals +marshalship +marshalships +marshes +marshier +marshiest +marshiness +marshinesses +marshland +marshlands +marshmallow +marshmallows +marshmallowy +marshy +marsupia +marsupial +marsupials +marsupium +mart +martagon +martagons +marted +martello +martellos +marten +martens +martensite +martensites +martensitic +martensitically +martial +martially +martian +martians +martin +martinet +martinets +marting +martingale +martingales +martini +martinis +martins +martlet +martlets +marts +martyr +martyrdom +martyrdoms +martyred +martyries +martyring +martyrization +martyrizations +martyrize +martyrized +martyrizes +martyrizing +martyrly +martyrologies +martyrologist +martyrologists +martyrology +martyrs +martyry +marvel +marveled +marveling +marvelled +marvelling +marvellous +marvelous +marvelously +marvelousness +marvelousnesses +marvels +marvy +maryjane +maryjanes +marzipan +marzipans +mas +mascara +mascaraed +mascaraing +mascaras +mascarpone +mascarpones +mascon +mascons +mascot +mascots +masculine +masculinely +masculines +masculinise +masculinised +masculinises +masculinising +masculinities +masculinity +masculinization +masculinizations +masculinize +masculinized +masculinizes +masculinizing +maser +masers +mash +mashed +masher +mashers +mashes +mashie +mashies +mashing +mashy +masjid +masjids +mask +maskable +masked +maskeg +maskegs +masker +maskers +masking +maskings +masklike +masks +masochism +masochisms +masochist +masochistic +masochistically +masochists +mason +masoned +masonic +masoning +masonries +masonry +masons +masque +masquer +masquerade +masqueraded +masquerader +masqueraders +masquerades +masquerading +masquers +masques +mass +massa +massacre +massacred +massacrer +massacrers +massacres +massacring +massage +massaged +massager +massagers +massages +massaging +massas +massasauga +massasaugas +masscult +masscults +masse +massed +massedly +masses +masseter +masseteric +masseters +masseur +masseurs +masseuse +masseuses +massicot +massicots +massier +massiest +massif +massifs +massing +massive +massively +massiveness +massivenesses +massless +massy +mast +mastaba +mastabah +mastabahs +mastabas +mastectomies +mastectomy +masted +master +mastered +masterful +masterfully +masterfulness +masterfulnesses +masteries +mastering +masterliness +masterlinesses +masterly +mastermind +masterminded +masterminding +masterminds +masterpiece +masterpieces +masters +mastership +masterships +mastersinger +mastersingers +masterstroke +masterstrokes +masterwork +masterworks +mastery +masthead +mastheaded +mastheading +mastheads +mastic +masticate +masticated +masticates +masticating +mastication +mastications +masticator +masticatories +masticators +masticatory +mastiche +mastiches +mastics +mastiff +mastiffs +mastigophoran +mastigophorans +masting +mastitic +mastitides +mastitis +mastix +mastixes +mastless +mastlike +mastodon +mastodonic +mastodons +mastodont +mastodonts +mastoid +mastoidectomies +mastoidectomy +mastoidites +mastoiditides +mastoiditis +mastoiditises +mastoids +masts +masturbate +masturbated +masturbates +masturbating +masturbation +masturbations +masturbator +masturbators +masturbatory +masurium +masuriums +mat +matador +matadors +matambala +match +matchable +matchboard +matchboards +matchbook +matchbooks +matchbox +matchboxes +matched +matcher +matchers +matches +matching +matchless +matchlessly +matchlock +matchlocks +matchmaker +matchmakers +matchmaking +matchmakings +matchstick +matchsticks +matchup +matchups +matchwood +matchwoods +mate +mated +mateless +matelot +matelote +matelotes +matelots +mater +materfamilias +materfamiliases +material +materialise +materialised +materialises +materialising +materialism +materialisms +materialist +materialistic +materialistically +materialists +materialities +materiality +materialization +materializations +materialize +materialized +materializer +materializers +materializes +materializing +materially +materialness +materialnesses +materials +materiel +materiels +maternal +maternalism +maternalisms +maternally +maternities +maternity +maters +mates +mateship +mateships +matey +mateyness +mateynesses +mateys +math +mathematic +mathematical +mathematically +mathematician +mathematicians +mathematics +mathematization +mathematizations +mathematize +mathematized +mathematizes +mathematizing +maths +matilda +matildas +matin +matinal +matinee +matinees +matiness +matinesses +mating +matings +matins +matless +matrass +matrasses +matres +matriarch +matriarchal +matriarchate +matriarchates +matriarchies +matriarchs +matriarchy +matrices +matricidal +matricide +matricides +matriculant +matriculants +matriculate +matriculated +matriculates +matriculating +matriculation +matriculations +matrilineal +matrilineally +matrimonial +matrimonially +matrimonies +matrimony +matrix +matrixes +matron +matronal +matronly +matrons +matronymic +matronymics +mats +matsah +matsahs +matt +matte +matted +mattedly +matter +mattered +mattering +matters +mattery +mattes +mattin +matting +mattings +mattins +mattock +mattocks +mattoid +mattoids +mattrass +mattrasses +mattress +mattresses +matts +maturate +maturated +maturates +maturating +maturation +maturational +maturations +mature +matured +maturely +maturer +matures +maturest +maturing +maturities +maturity +matutinal +matutinally +matza +matzah +matzahs +matzas +matzo +matzoh +matzohs +matzoon +matzoons +matzos +matzot +matzoth +maud +maudlin +mauds +mauger +maugre +maul +mauled +mauler +maulers +mauling +mauls +maulstick +maulsticks +maumet +maumetries +maumetry +maumets +maun +maund +maunder +maundered +maunderer +maunderers +maundering +maunders +maundies +maunds +maundy +mausolea +mausoleum +mausoleums +maut +mauts +mauve +mauves +maven +mavens +maverick +mavericks +mavie +mavies +mavin +mavins +mavis +mavises +mavourneen +mavourneens +maw +mawed +mawing +mawkish +mawkishly +mawkishness +mawkishnesses +mawn +maws +max +maxes +maxi +maxicoat +maxicoats +maxilla +maxillae +maxillaries +maxillary +maxillas +maxilliped +maxillipeds +maxillofacial +maxim +maxima +maximal +maximalist +maximalists +maximally +maximals +maximin +maximins +maximise +maximised +maximises +maximising +maximite +maximites +maximization +maximizations +maximize +maximized +maximizer +maximizers +maximizes +maximizing +maxims +maximum +maximums +maxis +maxixe +maxixes +maxwell +maxwells +may +maya +mayan +mayapple +mayapples +mayas +maybe +maybes +maybush +maybushes +mayday +maydays +mayed +mayest +mayflies +mayflower +mayflowers +mayfly +mayhap +mayhem +mayhems +maying +mayings +mayo +mayonnaise +mayonnaises +mayor +mayoral +mayoralties +mayoralty +mayoress +mayoresses +mayors +mayos +maypole +maypoles +maypop +maypops +mays +mayst +mayvin +mayvins +mayweed +mayweeds +mazaedia +mazaedium +mazard +mazards +maze +mazed +mazedly +mazelike +mazer +mazers +mazes +mazier +maziest +mazily +maziness +mazinesses +mazing +mazourka +mazourkas +mazuma +mazumas +mazurka +mazurkas +mazy +mazzard +mazzards +mbira +mbiras +me +mead +meadow +meadowland +meadowlands +meadowlark +meadowlarks +meadows +meadowsweet +meadowsweets +meadowy +meads +meager +meagerly +meagerness +meagernesses +meagre +meagrely +meal +mealie +mealier +mealies +mealiest +mealless +meals +mealtime +mealtimes +mealworm +mealworms +mealy +mealybug +mealybugs +mealymouthed +mean +meander +meandered +meandering +meanders +meandrous +meaner +meaners +meanest +meanie +meanies +meaning +meaningful +meaningfully +meaningfulness +meaningfulnesses +meaningless +meaninglessly +meaninglessness +meaninglessnesses +meaningly +meanings +meanly +meanness +meannesses +means +meant +meantime +meantimes +meanwhile +meanwhiles +meany +measle +measled +measles +measlier +measliest +measly +measurabilities +measurability +measurable +measurably +measure +measured +measuredly +measureless +measurement +measurements +measurer +measurers +measures +measuring +meat +meatal +meatball +meatballs +meated +meathead +meatheads +meatier +meatiest +meatily +meatiness +meatinesses +meatless +meatloaf +meatloaves +meatman +meatmen +meatpacking +meatpackings +meats +meatus +meatuses +meaty +mecamylamine +mecamylamines +mecca +meccas +mechanic +mechanical +mechanically +mechanicals +mechanician +mechanicians +mechanics +mechanism +mechanisms +mechanist +mechanistic +mechanistically +mechanists +mechanizable +mechanization +mechanizations +mechanize +mechanized +mechanizer +mechanizers +mechanizes +mechanizing +mechanochemical +mechanochemistries +mechanochemistry +mechanoreception +mechanoreceptions +mechanoreceptive +mechanoreceptor +mechanoreceptors +meclizine +meclizines +meconium +meconiums +med +medaillon +medaillons +medaka +medakas +medal +medaled +medaling +medalist +medalists +medalled +medallic +medalling +medallion +medallions +medallist +medallists +medals +meddle +meddled +meddler +meddlers +meddles +meddlesome +meddlesomeness +meddlesomenesses +meddling +medevac +medevacked +medevacking +medevacs +medflies +medfly +media +mediacies +mediacy +mediad +mediae +mediaeval +mediaevals +mediagenic +medial +medially +medials +median +medianly +medians +mediant +mediants +medias +mediastina +mediastinal +mediastinum +mediate +mediated +mediately +mediates +mediating +mediation +mediational +mediations +mediative +mediator +mediators +mediatory +mediatrices +mediatrix +mediatrixes +medic +medicable +medicaid +medicaids +medical +medically +medicals +medicament +medicamentous +medicaments +medicare +medicares +medicate +medicated +medicates +medicating +medication +medications +medicinable +medicinal +medicinally +medicinals +medicine +medicined +medicines +medicining +medick +medicks +medico +medicolegal +medicos +medics +medieval +medievalism +medievalisms +medievalist +medievalists +medievally +medievals +medii +medina +medinas +mediocre +mediocrities +mediocrity +meditate +meditated +meditates +meditating +meditation +meditations +meditative +meditatively +meditativeness +meditativenesses +meditator +meditators +mediterranean +medium +mediumistic +mediums +mediumship +mediumships +medius +medlar +medlars +medley +medleys +medulla +medullae +medullar +medullary +medullas +medullated +medulloblastoma +medulloblastomas +medulloblastomata +medusa +medusae +medusal +medusan +medusans +medusas +medusoid +medusoids +meed +meeds +meek +meeker +meekest +meekly +meekness +meeknesses +meerkat +meerkats +meerschaum +meerschaums +meet +meeter +meeters +meeting +meetinghouse +meetinghouses +meetings +meetly +meetness +meetnesses +meets +megabar +megabars +megabit +megabits +megabuck +megabucks +megabyte +megabytes +megacities +megacity +megacorporation +megacorporations +megacycle +megacycles +megadeal +megadeals +megadeath +megadeaths +megadose +megadoses +megadyne +megadynes +megafauna +megafaunae +megafaunal +megafaunas +megagamete +megagametes +megagametophyte +megagametophytes +megahertz +megahit +megahits +megakaryocyte +megakaryocytes +megakaryocytic +megalith +megalithic +megaliths +megaloblast +megaloblastic +megaloblasts +megalomania +megalomaniac +megalomaniacal +megalomaniacally +megalomaniacs +megalomanias +megalomanic +megalopolis +megalopolises +megalopolitan +megalopolitans +megalops +megalopses +megaparsec +megaparsecs +megaphone +megaphoned +megaphones +megaphonic +megaphoning +megapod +megapode +megapodes +megapods +megaproject +megaprojects +megascopic +megascopically +megasporangia +megasporangium +megaspore +megaspores +megasporic +megasporogeneses +megasporogenesis +megasporophyll +megasporophylls +megass +megasse +megasses +megastar +megastars +megaton +megatonnage +megatonnages +megatons +megavitamin +megavitamins +megavolt +megavolts +megawatt +megawatts +megillah +megillahs +megilp +megilph +megilphs +megilps +megohm +megohms +megrim +megrims +meikle +meinie +meinies +meiny +meioses +meiosis +meiotic +meiotically +mel +melamdim +melamed +melamine +melamines +melancholia +melancholiac +melancholiacs +melancholias +melancholic +melancholics +melancholies +melancholy +melange +melanges +melanian +melanic +melanics +melanin +melanins +melanism +melanisms +melanist +melanistic +melanists +melanite +melanites +melanitic +melanization +melanizations +melanize +melanized +melanizes +melanizing +melanoblast +melanoblasts +melanocyte +melanocytes +melanogeneses +melanogenesis +melanoid +melanoids +melanoma +melanomas +melanomata +melanophore +melanophores +melanosome +melanosomes +melanotic +melanous +melatonin +melatonins +meld +melded +melder +melders +melding +melds +melee +melees +melic +melilite +melilites +melilot +melilots +melinite +melinites +meliorate +meliorated +meliorates +meliorating +melioration +meliorations +meliorative +meliorator +meliorators +meliorism +meliorisms +meliorist +melioristic +meliorists +melisma +melismas +melismata +melismatic +mell +melled +mellific +mellifluent +mellifluently +mellifluous +mellifluously +mellifluousness +mellifluousnesses +melling +mellophone +mellophones +mellotron +mellotrons +mellow +mellowed +mellower +mellowest +mellowing +mellowly +mellowness +mellownesses +mellows +mells +melodeon +melodeons +melodia +melodias +melodic +melodica +melodically +melodicas +melodies +melodious +melodiously +melodiousness +melodiousnesses +melodise +melodised +melodises +melodising +melodist +melodists +melodize +melodized +melodizer +melodizers +melodizes +melodizing +melodrama +melodramas +melodramatic +melodramatically +melodramatics +melodramatise +melodramatised +melodramatises +melodramatising +melodramatist +melodramatists +melodramatization +melodramatizations +melodramatize +melodramatized +melodramatizes +melodramatizing +melody +meloid +meloids +melon +melons +melphalan +melphalans +mels +melt +meltabilities +meltability +meltable +meltage +meltages +meltdown +meltdowns +melted +melter +melters +melting +meltingly +melton +meltons +melts +meltwater +meltwaters +mem +member +membered +members +membership +memberships +membrane +membraned +membranes +membranous +membranously +memento +mementoes +mementos +memo +memoir +memoirist +memoirists +memoirs +memorabilia +memorabilities +memorability +memorable +memorableness +memorablenesses +memorably +memoranda +memorandum +memorandums +memorial +memorialise +memorialised +memorialises +memorialising +memorialist +memorialists +memorialize +memorialized +memorializes +memorializing +memorially +memorials +memories +memorise +memorised +memorises +memorising +memoriter +memorizable +memorization +memorizations +memorize +memorized +memorizer +memorizers +memorizes +memorizing +memory +memos +mems +memsahib +memsahibs +men +menace +menaced +menacer +menacers +menaces +menacing +menacingly +menad +menadione +menadiones +menads +menage +menagerie +menageries +menages +menarche +menarcheal +menarches +menazon +menazons +mend +mendable +mendacious +mendaciously +mendaciousness +mendaciousnesses +mendacities +mendacity +mended +mendelevium +mendeleviums +mender +menders +mendicancies +mendicancy +mendicant +mendicants +mendicities +mendicity +mendigo +mendigos +mending +mendings +mends +menfolk +menfolks +menhaden +menhadens +menhir +menhirs +menial +menially +menials +meningeal +meninges +meningioma +meningiomas +meningiomata +meningitic +meningitides +meningitis +meningococcal +meningococci +meningococcic +meningococcus +meningoencephalitic +meningoencephalitides +meningoencephalitis +meninx +meniscal +menisci +meniscus +meniscuses +meno +menologies +menology +menopausal +menopause +menopauses +menorah +menorahs +menorrhagia +menorrhagias +mensa +mensae +mensal +mensas +mensch +menschen +mensches +mense +mensed +menseful +menseless +menservants +menses +mensing +menstrua +menstrual +menstruate +menstruated +menstruates +menstruating +menstruation +menstruations +menstruum +menstruums +mensurabilities +mensurability +mensurable +mensural +mensuration +mensurations +menswear +menta +mental +mentalism +mentalisms +mentalist +mentalistic +mentalists +mentalities +mentality +mentally +mentation +mentations +menthene +menthenes +menthol +mentholated +menthols +mention +mentionable +mentioned +mentioner +mentioners +mentioning +mentions +mentor +mentored +mentoring +mentors +mentorship +mentorships +mentum +menu +menus +meou +meoued +meouing +meous +meow +meowed +meowing +meows +meperidine +meperidines +mephitic +mephitis +mephitises +meprobamate +meprobamates +merbromin +merbromins +mercantile +mercantilism +mercantilisms +mercantilist +mercantilistic +mercantilists +mercaptan +mercaptans +mercapto +mercaptopurine +mercaptopurines +mercenaries +mercenarily +mercenariness +mercenarinesses +mercenary +mercer +merceries +mercerise +mercerised +mercerises +mercerising +mercerization +mercerizations +mercerize +mercerized +mercerizes +mercerizing +mercers +mercery +merchandise +merchandised +merchandiser +merchandisers +merchandises +merchandising +merchandisings +merchandize +merchandized +merchandizes +merchandizing +merchandizings +merchant +merchantabilities +merchantability +merchantable +merchanted +merchanting +merchantman +merchantmen +merchants +mercies +merciful +mercifully +mercifulness +mercifulnesses +merciless +mercilessly +mercilessness +mercilessnesses +mercurate +mercurated +mercurates +mercurating +mercuration +mercurations +mercurial +mercurially +mercurialness +mercurialnesses +mercurials +mercuric +mercuries +mercurous +mercury +mercy +merde +merdes +mere +merely +merengue +merengues +merer +meres +merest +meretricious +meretriciously +meretriciousness +meretriciousnesses +merganser +mergansers +merge +merged +mergence +mergences +merger +mergers +merges +merging +meridian +meridians +meridional +meridionally +meridionals +meringue +meringues +merino +merinos +merises +merisis +meristem +meristematic +meristematically +meristems +meristic +meristically +merit +merited +meriting +meritocracies +meritocracy +meritocrat +meritocratic +meritocrats +meritorious +meritoriously +meritoriousness +meritoriousnesses +merits +merk +merks +merl +merle +merles +merlin +merlins +merlon +merlons +merlot +merlots +merls +mermaid +mermaids +merman +mermen +meroblastic +meroblastically +merocrine +meromorphic +meromyosin +meromyosins +meropia +meropias +meropic +merozoite +merozoites +merrier +merriest +merrily +merriment +merriments +merriness +merrinesses +merry +merrymaker +merrymakers +merrymaking +merrymakings +merrythought +merrythoughts +mesa +mesalliance +mesalliances +mesally +mesarch +mesas +mescal +mescaline +mescalines +mescals +mesdames +mesdemoiselles +meseemed +meseemeth +meseems +mesembryanthemum +mesembryanthemums +mesencephala +mesencephalic +mesencephalon +mesenchymal +mesenchyme +mesenchymes +mesentera +mesenteric +mesenteries +mesenteron +mesentery +mesh +meshed +meshes +meshier +meshiest +meshing +meshuga +meshugah +meshugga +meshuggah +meshugge +meshuggener +meshuggeners +meshwork +meshworks +meshy +mesial +mesially +mesian +mesic +mesmeric +mesmerically +mesmerise +mesmerised +mesmerises +mesmerising +mesmerism +mesmerisms +mesmerist +mesmerists +mesmerize +mesmerized +mesmerizer +mesmerizers +mesmerizes +mesmerizing +mesnalties +mesnalty +mesne +mesnes +mesocarp +mesocarps +mesocyclone +mesocyclones +mesoderm +mesodermal +mesoderms +mesoglea +mesogleas +mesogloea +mesogloeas +mesomere +mesomeres +mesomorph +mesomorphic +mesomorphies +mesomorphs +mesomorphy +meson +mesonephric +mesonephroi +mesonephros +mesonic +mesons +mesopause +mesopauses +mesopelagic +mesophyl +mesophyll +mesophyllic +mesophyllous +mesophylls +mesophyls +mesophyte +mesophytes +mesophytic +mesoscale +mesosome +mesosomes +mesosphere +mesospheres +mesospheric +mesothelia +mesothelial +mesothelioma +mesotheliomas +mesotheliomata +mesothelium +mesothoraces +mesothoracic +mesothorax +mesothoraxes +mesotron +mesotrons +mesotrophic +mesquit +mesquite +mesquites +mesquits +mess +message +messaged +messages +messaging +messaline +messalines +messan +messans +messed +messeigneurs +messenger +messengers +messes +messiah +messiahs +messiahship +messiahships +messianic +messianism +messianisms +messier +messiest +messieurs +messily +messiness +messinesses +messing +messman +messmate +messmates +messmen +messuage +messuages +messy +mestee +mestees +mesteso +mestesoes +mestesos +mestino +mestinoes +mestinos +mestiza +mestizas +mestizo +mestizoes +mestizos +mestranol +mestranols +met +meta +metabolic +metabolically +metabolism +metabolisms +metabolite +metabolites +metabolizable +metabolize +metabolized +metabolizes +metabolizing +metacarpal +metacarpals +metacarpi +metacarpus +metacenter +metacenters +metacentric +metacentrics +metacercaria +metacercariae +metacercarial +metachromatic +metaethical +metaethics +metafiction +metafictional +metafictionist +metafictionists +metafictions +metagalactic +metagalaxies +metagalaxy +metage +metageneses +metagenesis +metagenetic +metages +metal +metalanguage +metalanguages +metaled +metaling +metalinguistic +metalinguistics +metalise +metalised +metalises +metalising +metalist +metalists +metalize +metalized +metalizes +metalizing +metalled +metallic +metallically +metallics +metalliferous +metalling +metallization +metallizations +metallize +metallized +metallizes +metallizing +metallographer +metallographers +metallographic +metallographically +metallographies +metallography +metalloid +metalloidal +metalloids +metallophone +metallophones +metallurgical +metallurgically +metallurgies +metallurgist +metallurgists +metallurgy +metalmark +metalmarks +metals +metalsmith +metalsmiths +metalware +metalwares +metalwork +metalworker +metalworkers +metalworking +metalworkings +metalworks +metamathematical +metamathematics +metamer +metamere +metameres +metameric +metamerically +metamerism +metamerisms +metamers +metamorphic +metamorphically +metamorphism +metamorphisms +metamorphose +metamorphosed +metamorphoses +metamorphosing +metamorphosis +metanalyses +metanalysis +metanephric +metanephroi +metanephros +metaphase +metaphases +metaphor +metaphoric +metaphorical +metaphorically +metaphors +metaphosphate +metaphosphates +metaphrase +metaphrases +metaphysic +metaphysical +metaphysically +metaphysician +metaphysicians +metaphysics +metaplasia +metaplasias +metaplastic +metapsychological +metapsychologies +metapsychology +metasequoia +metasequoias +metasomatic +metasomatism +metasomatisms +metastabilities +metastability +metastable +metastably +metastases +metastasis +metastasize +metastasized +metastasizes +metastasizing +metastatic +metastatically +metatarsal +metatarsals +metatarsi +metatarsus +metate +metates +metatheses +metathesis +metathetic +metathetical +metathetically +metathoraces +metathoracic +metathorax +metathoraxes +metaxylem +metaxylems +metazoa +metazoal +metazoan +metazoans +metazoic +metazoon +mete +meted +metempsychoses +metempsychosis +metencephala +metencephalic +metencephalon +meteor +meteoric +meteorically +meteorite +meteorites +meteoritic +meteoritical +meteoriticist +meteoriticists +meteoritics +meteoroid +meteoroidal +meteoroids +meteorologic +meteorological +meteorologically +meteorologies +meteorologist +meteorologists +meteorology +meteors +metepa +metepas +meter +meterage +meterages +metered +metering +meters +meterstick +metersticks +metes +metestrus +metestruses +meth +methacrylate +methacrylates +methadon +methadone +methadones +methadons +methamphetamine +methamphetamines +methanation +methanations +methane +methanes +methanol +methanols +methaqualone +methaqualones +methedrine +methedrines +metheglin +metheglins +methemoglobin +methemoglobinemia +methemoglobinemias +methemoglobins +methenamine +methenamines +methicillin +methicillins +methinks +methionine +methionines +method +methodic +methodical +methodically +methodicalness +methodicalnesses +methodise +methodised +methodises +methodising +methodism +methodisms +methodist +methodistic +methodists +methodize +methodized +methodizes +methodizing +methodological +methodologically +methodologies +methodologist +methodologists +methodology +methods +methotrexate +methotrexates +methought +methoxy +methoxychlor +methoxychlors +methoxyflurane +methoxyfluranes +methoxyl +meths +methyl +methylal +methylals +methylamine +methylamines +methylase +methylases +methylate +methylated +methylates +methylating +methylation +methylations +methylator +methylators +methylcellulose +methylcelluloses +methylcholanthrene +methylcholanthrenes +methyldopa +methyldopas +methylene +methylenes +methylic +methylmercuries +methylmercury +methylnaphthalene +methylnaphthalenes +methylphenidate +methylphenidates +methylprednisolone +methylprednisolones +methyls +methylxanthine +methylxanthines +methysergide +methysergides +meticais +metical +meticals +meticulosities +meticulosity +meticulous +meticulously +meticulousness +meticulousnesses +metier +metiers +meting +metis +metisse +metisses +metonym +metonymic +metonymical +metonymies +metonyms +metonymy +metopae +metope +metopes +metopic +metopon +metopons +metre +metred +metres +metric +metrical +metrically +metrication +metrications +metricize +metricized +metricizes +metricizing +metrics +metrified +metrifies +metrify +metrifying +metring +metrist +metrists +metritis +metritises +metro +metrological +metrologies +metrologist +metrologists +metrology +metronidazole +metronidazoles +metronome +metronomes +metronomic +metronomical +metronomically +metropolis +metropolises +metropolitan +metropolitans +metrorrhagia +metrorrhagias +metros +mettle +mettled +mettles +mettlesome +metump +metumps +meuniere +mew +mewed +mewing +mewl +mewled +mewler +mewlers +mewling +mewls +mews +mezcal +mezcals +meze +mezereon +mezereons +mezereum +mezereums +mezes +mezquit +mezquite +mezquites +mezquits +mezuza +mezuzah +mezuzahs +mezuzas +mezuzot +mezuzoth +mezzanine +mezzanines +mezzo +mezzos +mezzotint +mezzotints +mho +mhos +mi +miaou +miaoued +miaouing +miaous +miaow +miaowed +miaowing +miaows +miasm +miasma +miasmal +miasmas +miasmata +miasmatic +miasmic +miasmically +miasms +miaul +miauled +miauling +miauls +mib +mibs +mica +micaceous +micas +micawber +micawbers +mice +micell +micella +micellae +micellar +micelle +micelles +micells +miche +miched +miches +miching +mick +mickey +mickeys +mickle +mickler +mickles +micklest +micks +micra +micrified +micrifies +micrify +micrifying +micro +microampere +microamperes +microanalyses +microanalysis +microanalyst +microanalysts +microanalytic +microanalytical +microanatomical +microanatomies +microanatomy +microbalance +microbalances +microbar +microbarograph +microbarographs +microbars +microbe +microbeam +microbeams +microbes +microbial +microbic +microbiologic +microbiological +microbiologically +microbiologies +microbiologist +microbiologists +microbiology +microbrew +microbrewer +microbreweries +microbrewers +microbrewery +microbrewing +microbrewings +microbrews +microburst +microbursts +microbus +microbuses +microbusses +microcalorimeter +microcalorimeters +microcalorimetric +microcalorimetries +microcalorimetry +microcapsule +microcapsules +microcassette +microcassettes +microcephalic +microcephalics +microcephalies +microcephaly +microchip +microchips +microcircuit +microcircuitries +microcircuitry +microcircuits +microcirculation +microcirculations +microcirculatory +microclimate +microclimates +microclimatic +microcline +microclines +micrococcal +micrococci +micrococcus +microcode +microcodes +microcomputer +microcomputers +microcopies +microcopy +microcosm +microcosmic +microcosmically +microcosmos +microcosmoses +microcosms +microcrystal +microcrystalline +microcrystallinities +microcrystallinity +microcrystals +microcultural +microculture +microcultures +microcurie +microcuries +microcyte +microcytes +microcytic +microdensitometer +microdensitometers +microdensitometric +microdensitometries +microdensitometry +microdissection +microdissections +microdot +microdots +microearthquake +microearthquakes +microeconomic +microeconomics +microelectrode +microelectrodes +microelectronic +microelectronically +microelectronics +microelectrophoreses +microelectrophoresis +microelectrophoretic +microelectrophoretically +microelement +microelements +microencapsulate +microencapsulated +microencapsulates +microencapsulating +microencapsulation +microencapsulations +microenvironment +microenvironmental +microenvironments +microevolution +microevolutionary +microevolutions +microfarad +microfarads +microfauna +microfaunae +microfaunal +microfaunas +microfibril +microfibrillar +microfibrils +microfiche +microfiches +microfilament +microfilaments +microfilaria +microfilariae +microfilarial +microfilm +microfilmable +microfilmed +microfilmer +microfilmers +microfilming +microfilms +microflora +microflorae +microfloral +microfloras +microform +microforms +microfossil +microfossils +microfungi +microfungus +microfunguses +microgamete +microgametes +microgametocyte +microgametocytes +microgram +micrograms +micrograph +micrographed +micrographic +micrographically +micrographics +micrographing +micrographs +microgravities +microgravity +microgroove +microgrooves +microhabitat +microhabitats +microhm +microhms +microimage +microimages +microinch +microinches +microinject +microinjected +microinjecting +microinjection +microinjections +microinjects +microinstruction +microinstructions +microlepidoptera +microlepidopterous +microliter +microliters +microlith +microlithic +microliths +microluces +microlux +microluxes +micromanage +micromanaged +micromanagement +micromanagements +micromanager +micromanagers +micromanages +micromanaging +micromanipulation +micromanipulations +micromanipulator +micromanipulators +micromere +micromeres +micrometeorite +micrometeorites +micrometeoritic +micrometeoroid +micrometeoroids +micrometeorological +micrometeorologies +micrometeorologist +micrometeorologists +micrometeorology +micrometer +micrometers +micromethod +micromethods +micromho +micromhos +micromini +microminiature +microminiaturization +microminiaturizations +microminiaturized +microminis +micromolar +micromole +micromoles +micromorphological +micromorphologies +micromorphology +micron +micronize +micronized +micronizes +micronizing +microns +micronuclei +micronucleus +micronucleuses +micronutrient +micronutrients +microorganism +microorganisms +micropaleontologic +micropaleontological +micropaleontologies +micropaleontologist +micropaleontologists +micropaleontology +microparticle +microparticles +microphage +microphages +microphone +microphones +microphonic +microphonics +microphotograph +microphotographer +microphotographers +microphotographic +microphotographies +microphotographs +microphotography +microphotometer +microphotometers +microphotometric +microphotometrically +microphotometries +microphotometry +microphyll +microphyllous +microphylls +microphysical +microphysically +microphysics +micropipet +micropipets +micropipette +micropipettes +microplankton +microplanktons +micropore +micropores +microporosities +microporosity +microporous +microprism +microprisms +microprobe +microprobes +microprocessor +microprocessors +microprogram +microprogramming +microprogrammings +microprograms +microprojection +microprojections +microprojector +microprojectors +micropublisher +micropublishers +micropublishing +micropublishings +micropulsation +micropulsations +micropuncture +micropunctures +micropylar +micropyle +micropyles +microquake +microquakes +microradiograph +microradiographic +microradiographies +microradiographs +microradiography +microreader +microreaders +microreproduction +microreproductions +micros +microscale +microscales +microscope +microscopes +microscopic +microscopical +microscopically +microscopies +microscopist +microscopists +microscopy +microsecond +microseconds +microseism +microseismic +microseismicities +microseismicity +microseisms +microsomal +microsome +microsomes +microspectrophotometer +microspectrophotometers +microspectrophotometric +microspectrophotometries +microspectrophotometry +microsphere +microspheres +microspherical +microsporangia +microsporangiate +microsporangium +microspore +microspores +microsporocyte +microsporocytes +microsporogeneses +microsporogenesis +microsporophyll +microsporophylls +microsporous +microstate +microstates +microstructural +microstructure +microstructures +microsurgeries +microsurgery +microsurgical +microswitch +microswitches +microtechnic +microtechnics +microtechnique +microtechniques +microtome +microtomes +microtonal +microtonalities +microtonality +microtonally +microtone +microtones +microtubular +microtubule +microtubules +microvascular +microvasculature +microvasculatures +microvillar +microvilli +microvillous +microvillus +microvolt +microvolts +microwatt +microwatts +microwavable +microwave +microwaveable +microwaved +microwaves +microwaving +microworld +microworlds +micrurgies +micrurgy +micturate +micturated +micturates +micturating +micturition +micturitions +mid +midair +midairs +midbrain +midbrains +midcourse +midcult +midcults +midday +middays +midden +middens +middies +middle +middlebrow +middlebrows +middled +middleman +middlemen +middler +middlers +middles +middleweight +middleweights +middling +middlingly +middlings +middorsal +middy +midfield +midfielder +midfielders +midfields +midge +midges +midget +midgets +midgut +midguts +midi +midiron +midirons +midis +midland +midlands +midlatitude +midlatitudes +midleg +midlegs +midlife +midline +midlines +midlives +midmonth +midmonths +midmost +midmosts +midnight +midnightly +midnights +midnoon +midnoons +midpoint +midpoints +midrange +midranges +midrash +midrashic +midrashim +midrashoth +midrib +midribs +midriff +midriffs +mids +midsagittal +midsection +midsections +midship +midshipman +midshipmen +midships +midsize +midsized +midsole +midsoles +midspace +midspaces +midst +midstories +midstory +midstream +midstreams +midsts +midsummer +midsummers +midterm +midterms +midtown +midtowns +midwatch +midwatches +midway +midways +midweek +midweekly +midweeks +midwestern +midwife +midwifed +midwiferies +midwifery +midwifes +midwifing +midwinter +midwinters +midwived +midwives +midwiving +midyear +midyears +mien +miens +miff +miffed +miffier +miffiest +miffing +miffs +miffy +mig +migg +miggle +miggles +miggs +might +mightier +mightiest +mightily +mightiness +mightinesses +mights +mighty +mignon +mignonette +mignonettes +mignonne +mignons +migraine +migraines +migrainous +migrant +migrants +migrate +migrated +migrates +migrating +migration +migrational +migrations +migrator +migrators +migratory +migs +mihrab +mihrabs +mijnheer +mijnheers +mikado +mikados +mike +miked +mikes +miking +mikra +mikron +mikrons +mikvah +mikvahs +mikveh +mikvehs +mikvoth +mil +miladi +miladies +miladis +milady +milage +milages +milch +milchig +mild +milden +mildened +mildening +mildens +milder +mildest +mildew +mildewed +mildewing +mildews +mildewy +mildly +mildness +mildnesses +mile +mileage +mileages +milepost +mileposts +miler +milers +miles +milesimo +milesimos +milestone +milestones +milfoil +milfoils +milia +miliaria +miliarial +miliarias +miliary +milieu +milieus +milieux +militance +militances +militancies +militancy +militant +militantly +militantness +militantnesses +militants +militaria +militaries +militarily +militarise +militarised +militarises +militarising +militarism +militarisms +militarist +militaristic +militaristically +militarists +militarization +militarizations +militarize +militarized +militarizes +militarizing +military +militate +militated +militates +militating +militia +militiaman +militiamen +militias +milium +milk +milked +milker +milkers +milkfish +milkfishes +milkier +milkiest +milkily +milkiness +milkinesses +milking +milkmaid +milkmaids +milkman +milkmen +milks +milkshed +milksheds +milksop +milksops +milkweed +milkweeds +milkwood +milkwoods +milkwort +milkworts +milky +mill +millable +millage +millages +millcake +millcakes +milldam +milldams +mille +milled +millefiori +millefioris +millefleur +millefleurs +millenarian +millenarianism +millenarianisms +millenarians +millenaries +millenary +millennia +millennial +millennialism +millennialisms +millennialist +millennialists +millennium +millenniums +milleped +millepeds +miller +millerite +millerites +millers +milles +millesimal +millesimally +millesimals +millet +millets +milliampere +milliamperes +milliard +milliards +milliare +milliares +milliaries +milliary +millibar +millibars +millicurie +millicuries +millidegree +millidegrees +millieme +milliemes +millier +milliers +milligal +milligals +milligram +milligrams +millihenries +millihenry +millihenrys +millilambert +millilamberts +milliliter +milliliters +milliluces +millilux +milliluxes +millime +millimes +millimeter +millimeters +millimho +millimhos +millimicron +millimicrons +millimolar +millimole +millimoles +milline +milliner +millineries +milliners +millinery +millines +milling +millings +milliohm +milliohms +million +millionaire +millionaires +millionairess +millionairesses +millionfold +millions +millionth +millionths +milliosmol +milliosmols +milliped +millipede +millipedes +millipeds +milliradian +milliradians +millirem +millirems +milliroentgen +milliroentgens +millisecond +milliseconds +millivolt +millivolts +milliwatt +milliwatts +millpond +millponds +millrace +millraces +millrun +millruns +mills +millstone +millstones +millstream +millstreams +millwork +millworks +millwright +millwrights +milneb +milnebs +milo +milord +milords +milos +milpa +milpas +milquetoast +milquetoasts +milreis +mils +milt +milted +milter +milters +miltier +miltiest +milting +milts +milty +mim +mimbar +mimbars +mime +mimed +mimeo +mimeoed +mimeograph +mimeographed +mimeographing +mimeographs +mimeoing +mimeos +mimer +mimers +mimes +mimesis +mimesises +mimetic +mimetically +mimetite +mimetites +mimic +mimical +mimicked +mimicker +mimickers +mimicking +mimicries +mimicry +mimics +miming +mimosa +mimosas +mina +minable +minacities +minacity +minae +minaret +minarets +minas +minatory +minaudiere +minaudieres +mince +minced +mincemeat +mincemeats +mincer +mincers +minces +mincier +minciest +mincing +mincingly +mincy +mind +mindblower +mindblowers +minded +mindedness +mindednesses +minder +minders +mindful +mindfully +mindfulness +mindfulnesses +minding +mindless +mindlessly +mindlessness +mindlessnesses +minds +mindset +mindsets +mine +mineable +mined +minefield +minefields +minelayer +minelayers +miner +mineral +mineralise +mineralised +mineralises +mineralising +mineralizable +mineralization +mineralizations +mineralize +mineralized +mineralizer +mineralizers +mineralizes +mineralizing +mineralocorticoid +mineralocorticoids +mineralogic +mineralogical +mineralogically +mineralogies +mineralogist +mineralogists +mineralogy +minerals +miners +mines +minestrone +minestrones +minesweeper +minesweepers +minesweeping +minesweepings +mingier +mingiest +mingle +mingled +mingler +minglers +mingles +mingling +mingy +mini +miniature +miniatures +miniaturist +miniaturistic +miniaturists +miniaturization +miniaturizations +miniaturize +miniaturized +miniaturizes +miniaturizing +minibike +minibiker +minibikers +minibikes +minibus +minibuses +minibusses +minicab +minicabs +minicamp +minicamps +minicar +minicars +minicomputer +minicomputers +minicourse +minicourses +minified +minifies +minify +minifying +minikin +minikins +minilab +minilabs +minim +minima +minimal +minimalism +minimalisms +minimalist +minimalists +minimally +minimals +minimax +minimaxes +minimill +minimills +minimise +minimised +minimises +minimising +minimization +minimizations +minimize +minimized +minimizer +minimizers +minimizes +minimizing +minims +minimum +minimums +mining +minings +minion +minions +minipark +miniparks +minis +minischool +minischools +miniscule +miniscules +miniseries +minish +minished +minishes +minishing +miniski +miniskirt +miniskirted +miniskirts +miniskis +ministate +ministates +minister +ministered +ministerial +ministerially +ministering +ministers +ministrant +ministrants +ministration +ministrations +ministries +ministry +minium +miniums +minivan +minivans +miniver +minivers +mink +minke +minkes +minks +minnesinger +minnesingers +minnies +minnow +minnows +minny +minor +minorca +minorcas +minored +minoring +minorities +minority +minors +minoxidil +minoxidils +minster +minsters +minstrel +minstrels +minstrelsies +minstrelsy +mint +mintage +mintages +minted +minter +minters +mintier +mintiest +minting +mints +minty +minuend +minuends +minuet +minuets +minus +minuscule +minuscules +minuses +minute +minuted +minutely +minuteman +minutemen +minuteness +minutenesses +minuter +minutes +minutest +minutia +minutiae +minutial +minuting +minx +minxes +minxish +minyan +minyanim +minyans +mioses +miosis +miotic +miotics +miquelet +miquelets +mir +miracidia +miracidial +miracidium +miracle +miracles +miraculous +miraculously +miraculousness +miraculousnesses +mirador +miradors +mirage +mirages +mire +mired +mires +mirex +mirexes +miri +mirier +miriest +miriness +mirinesses +miring +mirk +mirker +mirkest +mirkier +mirkiest +mirkily +mirks +mirky +mirliton +mirlitons +mirror +mirrored +mirroring +mirrorlike +mirrors +mirs +mirth +mirthful +mirthfully +mirthfulness +mirthfulnesses +mirthless +mirthlessly +mirths +miry +mirza +mirzas +mis +misact +misacted +misacting +misacts +misadapt +misadapted +misadapting +misadapts +misadd +misadded +misadding +misaddress +misaddressed +misaddresses +misaddressing +misadds +misadjust +misadjusted +misadjusting +misadjusts +misadministration +misadministrations +misadventure +misadventures +misadvise +misadvised +misadvises +misadvising +misagent +misagents +misaim +misaimed +misaiming +misaims +misalign +misaligned +misaligning +misalignment +misalignments +misaligns +misalliance +misalliances +misallied +misallies +misallocate +misallocated +misallocates +misallocating +misallocation +misallocations +misally +misallying +misalter +misaltered +misaltering +misalters +misanalyses +misanalysis +misandries +misandry +misanthrope +misanthropes +misanthropic +misanthropically +misanthropies +misanthropy +misapplication +misapplications +misapplied +misapplies +misapply +misapplying +misappraisal +misappraisals +misapprehend +misapprehended +misapprehending +misapprehends +misapprehension +misapprehensions +misappropriate +misappropriated +misappropriates +misappropriating +misappropriation +misappropriations +misarticulate +misarticulated +misarticulates +misarticulating +misassay +misassayed +misassaying +misassays +misassemble +misassembled +misassembles +misassembling +misassumption +misassumptions +misate +misatone +misatoned +misatones +misatoning +misattribute +misattributed +misattributes +misattributing +misattribution +misattributions +misaver +misaverred +misaverring +misavers +misaward +misawarded +misawarding +misawards +misbalance +misbalanced +misbalances +misbalancing +misbecame +misbecome +misbecomes +misbecoming +misbegan +misbegin +misbeginning +misbegins +misbegot +misbegotten +misbegun +misbehave +misbehaved +misbehaver +misbehavers +misbehaves +misbehaving +misbehavior +misbehaviors +misbelief +misbeliefs +misbelieve +misbelieved +misbeliever +misbelievers +misbelieves +misbelieving +misbias +misbiased +misbiases +misbiasing +misbiassed +misbiasses +misbiassing +misbill +misbilled +misbilling +misbills +misbind +misbinding +misbinds +misbound +misbrand +misbranded +misbranding +misbrands +misbuild +misbuilding +misbuilds +misbuilt +misbutton +misbuttoned +misbuttoning +misbuttons +miscalculate +miscalculated +miscalculates +miscalculating +miscalculation +miscalculations +miscall +miscalled +miscalling +miscalls +miscaption +miscaptioned +miscaptioning +miscaptions +miscarriage +miscarriages +miscarried +miscarries +miscarry +miscarrying +miscast +miscasting +miscasts +miscatalog +miscataloged +miscataloging +miscatalogs +miscegenation +miscegenational +miscegenations +miscellanea +miscellaneous +miscellaneously +miscellaneousness +miscellaneousnesses +miscellanies +miscellanist +miscellanists +miscellany +mischance +mischances +mischannel +mischanneled +mischanneling +mischannelled +mischannelling +mischannels +mischaracterization +mischaracterizations +mischaracterize +mischaracterized +mischaracterizes +mischaracterizing +mischarge +mischarged +mischarges +mischarging +mischief +mischiefs +mischievous +mischievously +mischievousness +mischievousnesses +mischoice +mischoices +miscibilities +miscibility +miscible +miscitation +miscitations +miscite +miscited +miscites +misciting +misclaim +misclaimed +misclaiming +misclaims +misclass +misclassed +misclasses +misclassification +misclassifications +misclassified +misclassifies +misclassify +misclassifying +misclassing +miscode +miscoded +miscodes +miscoding +miscoin +miscoined +miscoining +miscoins +miscolor +miscolored +miscoloring +miscolors +miscommunication +miscommunications +miscomprehension +miscomprehensions +miscomputation +miscomputations +miscompute +miscomputed +miscomputes +miscomputing +misconceive +misconceived +misconceiver +misconceivers +misconceives +misconceiving +misconception +misconceptions +misconduct +misconducted +misconducting +misconducts +misconnect +misconnected +misconnecting +misconnection +misconnections +misconnects +misconstruction +misconstructions +misconstrue +misconstrued +misconstrues +misconstruing +miscook +miscooked +miscooking +miscooks +miscopied +miscopies +miscopy +miscopying +miscorrelation +miscorrelations +miscount +miscounted +miscounting +miscounts +miscreant +miscreants +miscreate +miscreated +miscreates +miscreating +miscreation +miscreations +miscue +miscued +miscues +miscuing +miscut +miscuts +miscutting +misdate +misdated +misdates +misdating +misdeal +misdealing +misdeals +misdealt +misdeed +misdeeds +misdeem +misdeemed +misdeeming +misdeems +misdefine +misdefined +misdefines +misdefining +misdemeanant +misdemeanants +misdemeanor +misdemeanors +misdescribe +misdescribed +misdescribes +misdescribing +misdescription +misdescriptions +misdevelop +misdeveloped +misdeveloping +misdevelops +misdiagnose +misdiagnosed +misdiagnoses +misdiagnosing +misdiagnosis +misdial +misdialed +misdialing +misdialled +misdialling +misdials +misdid +misdirect +misdirected +misdirecting +misdirection +misdirections +misdirects +misdistribution +misdistributions +misdivision +misdivisions +misdo +misdoer +misdoers +misdoes +misdoing +misdoings +misdone +misdoubt +misdoubted +misdoubting +misdoubts +misdraw +misdrawing +misdrawn +misdraws +misdrew +misdrive +misdriven +misdrives +misdriving +misdrove +mise +misease +miseases +miseat +miseaten +miseating +miseats +misedit +misedited +misediting +misedits +miseducate +miseducated +miseducates +miseducating +miseducation +miseducations +misemphases +misemphasis +misemphasize +misemphasized +misemphasizes +misemphasizing +misemploy +misemployed +misemploying +misemployment +misemployments +misemploys +misenrol +misenroll +misenrolled +misenrolling +misenrolls +misenrols +misenter +misentered +misentering +misenters +misentries +misentry +miser +miserable +miserableness +miserablenesses +miserables +miserably +miserere +misereres +misericord +misericorde +misericordes +misericords +miseries +miserliness +miserlinesses +miserly +misers +misery +mises +misesteem +misesteemed +misesteeming +misesteems +misestimate +misestimated +misestimates +misestimating +misestimation +misestimations +misevaluate +misevaluated +misevaluates +misevaluating +misevaluation +misevaluations +misevent +misevents +misfaith +misfaiths +misfeasance +misfeasances +misfeasor +misfeasors +misfield +misfielded +misfielding +misfields +misfile +misfiled +misfiles +misfiling +misfire +misfired +misfires +misfiring +misfit +misfits +misfitted +misfitting +misfocus +misfocused +misfocuses +misfocusing +misfocussed +misfocusses +misfocussing +misform +misformed +misforming +misforms +misfortune +misfortunes +misframe +misframed +misframes +misframing +misfunction +misfunctioned +misfunctioning +misfunctions +misgauge +misgauged +misgauges +misgauging +misgave +misgive +misgiven +misgives +misgiving +misgivings +misgovern +misgoverned +misgoverning +misgovernment +misgovernments +misgoverns +misgrade +misgraded +misgrades +misgrading +misgraft +misgrafted +misgrafting +misgrafts +misgrew +misgrow +misgrowing +misgrown +misgrows +misguess +misguessed +misguesses +misguessing +misguidance +misguidances +misguide +misguided +misguidedly +misguidedness +misguidednesses +misguider +misguiders +misguides +misguiding +mishandle +mishandled +mishandles +mishandling +mishanter +mishanters +mishap +mishaps +mishear +misheard +mishearing +mishears +mishit +mishits +mishitting +mishmash +mishmashes +mishmosh +mishmoshes +misidentification +misidentifications +misidentified +misidentifies +misidentify +misidentifying +misimpression +misimpressions +misinfer +misinferred +misinferring +misinfers +misinform +misinformation +misinformations +misinformed +misinforming +misinforms +misinter +misinterpret +misinterpretation +misinterpretations +misinterpreted +misinterpreting +misinterprets +misinterred +misinterring +misinters +misjoin +misjoinder +misjoinders +misjoined +misjoining +misjoins +misjudge +misjudged +misjudges +misjudging +misjudgment +misjudgments +miskal +miskals +miskeep +miskeeping +miskeeps +miskept +miskick +miskicked +miskicking +miskicks +misknew +misknow +misknowing +misknowledge +misknowledges +misknown +misknows +mislabel +mislabeled +mislabeling +mislabelled +mislabelling +mislabels +mislabor +mislabored +mislaboring +mislabors +mislaid +mislain +mislay +mislayer +mislayers +mislaying +mislays +mislead +misleader +misleaders +misleading +misleadingly +misleads +misleared +mislearn +mislearned +mislearning +mislearns +mislearnt +misled +mislie +mislies +mislight +mislighted +mislighting +mislights +mislike +misliked +misliker +mislikers +mislikes +misliking +mislit +mislive +mislived +mislives +misliving +mislocate +mislocated +mislocates +mislocating +mislocation +mislocations +mislodge +mislodged +mislodges +mislodging +mislying +mismade +mismake +mismakes +mismaking +mismanage +mismanaged +mismanagement +mismanagements +mismanages +mismanaging +mismark +mismarked +mismarking +mismarks +mismarriage +mismarriages +mismatch +mismatched +mismatches +mismatching +mismate +mismated +mismates +mismating +mismeasurement +mismeasurements +mismeet +mismeeting +mismeets +mismet +mismove +mismoved +mismoves +mismoving +misname +misnamed +misnames +misnaming +misnomer +misnomered +misnomers +miso +misogamies +misogamist +misogamists +misogamy +misogynic +misogynies +misogynist +misogynistic +misogynists +misogyny +misologies +misology +misoneism +misoneisms +misorder +misordered +misordering +misorders +misorient +misorientation +misorientations +misoriented +misorienting +misorients +misos +mispackage +mispackaged +mispackages +mispackaging +mispage +mispaged +mispages +mispaging +mispaint +mispainted +mispainting +mispaints +misparse +misparsed +misparses +misparsing +mispart +misparted +misparting +misparts +mispatch +mispatched +mispatches +mispatching +mispen +mispenned +mispenning +mispens +misperceive +misperceived +misperceives +misperceiving +misperception +misperceptions +misplace +misplaced +misplacement +misplacements +misplaces +misplacing +misplan +misplanned +misplanning +misplans +misplant +misplanted +misplanting +misplants +misplay +misplayed +misplaying +misplays +misplead +mispleaded +mispleading +mispleads +mispled +mispoint +mispointed +mispointing +mispoints +mispoise +mispoised +mispoises +mispoising +misposition +mispositioned +mispositioning +mispositions +misprice +mispriced +misprices +mispricing +misprint +misprinted +misprinting +misprints +misprision +misprisions +misprize +misprized +misprizes +misprizing +misprogram +misprogramed +misprograming +misprogrammed +misprogramming +misprograms +mispronounce +mispronounced +mispronounces +mispronouncing +mispronunciation +mispronunciations +misquotation +misquotations +misquote +misquoted +misquotes +misquoting +misraise +misraised +misraises +misraising +misrate +misrated +misrates +misrating +misread +misreading +misreads +misreckon +misreckoned +misreckoning +misreckons +misrecollection +misrecollections +misrecord +misrecorded +misrecording +misrecords +misrefer +misreference +misreferences +misreferred +misreferring +misrefers +misregister +misregistered +misregistering +misregisters +misregistration +misregistrations +misrelate +misrelated +misrelates +misrelating +misrelied +misrelies +misrely +misrelying +misremember +misremembered +misremembering +misremembers +misrender +misrendered +misrendering +misrenders +misreport +misreported +misreporting +misreports +misrepresent +misrepresentation +misrepresentations +misrepresentative +misrepresented +misrepresenting +misrepresents +misroute +misrouted +misroutes +misrouting +misrule +misruled +misrules +misruling +miss +missable +missaid +missal +missals +missay +missaying +missays +misseat +misseated +misseating +misseats +missed +missel +missels +missend +missending +missends +missense +missenses +missent +misses +misset +missets +missetting +misshape +misshaped +misshapen +misshapenly +misshapes +misshaping +misshod +missies +missile +missileer +missileers +missileman +missilemen +missileries +missilery +missiles +missilries +missilry +missing +missiologies +missiology +mission +missionaries +missionary +missioned +missioner +missioners +missioning +missionization +missionizations +missionize +missionized +missionizer +missionizers +missionizes +missionizing +missions +missis +missises +missive +missives +missort +missorted +missorting +missorts +missound +missounded +missounding +missounds +missout +missouts +misspace +misspaced +misspaces +misspacing +misspeak +misspeaking +misspeaks +misspell +misspelled +misspelling +misspellings +misspells +misspelt +misspend +misspending +misspends +misspent +misspoke +misspoken +misstart +misstarted +misstarting +misstarts +misstate +misstated +misstatement +misstatements +misstates +misstating +missteer +missteered +missteering +missteers +misstep +missteps +misstop +misstopped +misstopping +misstops +misstricken +misstrike +misstrikes +misstriking +misstruck +misstyle +misstyled +misstyles +misstyling +missuit +missuited +missuiting +missuits +missus +missuses +missy +mist +mistakable +mistake +mistaken +mistakenly +mistaker +mistakers +mistakes +mistaking +mistaught +mistbow +mistbows +misteach +misteaches +misteaching +misted +mistend +mistended +mistending +mistends +mister +misterm +mistermed +misterming +misterms +misters +misteuk +misthink +misthinking +misthinks +misthought +misthrew +misthrow +misthrowing +misthrown +misthrows +mistier +mistiest +mistily +mistime +mistimed +mistimes +mistiming +mistiness +mistinesses +misting +mistitle +mistitled +mistitles +mistitling +mistletoe +mistletoes +mistook +mistouch +mistouched +mistouches +mistouching +mistrace +mistraced +mistraces +mistracing +mistrain +mistrained +mistraining +mistrains +mistral +mistrals +mistranscribe +mistranscribed +mistranscribes +mistranscribing +mistranscription +mistranscriptions +mistranslate +mistranslated +mistranslates +mistranslating +mistranslation +mistranslations +mistreat +mistreated +mistreating +mistreatment +mistreatments +mistreats +mistress +mistresses +mistrial +mistrials +mistrust +mistrusted +mistrustful +mistrustfully +mistrustfulness +mistrustfulnesses +mistrusting +mistrusts +mistruth +mistruths +mistryst +mistrysted +mistrysting +mistrysts +mists +mistune +mistuned +mistunes +mistuning +mistutor +mistutored +mistutoring +mistutors +misty +mistype +mistyped +mistypes +mistyping +misunderstand +misunderstanding +misunderstandings +misunderstands +misunderstood +misunion +misunions +misusage +misusages +misuse +misused +misuser +misusers +misuses +misusing +misutilization +misutilizations +misvalue +misvalued +misvalues +misvaluing +misvocalization +misvocalizations +misword +misworded +miswording +miswords +miswrit +miswrite +miswrites +miswriting +miswritten +miswrote +misyoke +misyoked +misyokes +misyoking +mite +miter +mitered +miterer +miterers +mitering +miters +miterwort +miterworts +mites +mither +mithers +mithridate +mithridates +miticidal +miticide +miticides +mitier +mitiest +mitigate +mitigated +mitigates +mitigating +mitigation +mitigations +mitigative +mitigator +mitigators +mitigatory +mitis +mitises +mitochondria +mitochondrial +mitochondrion +mitogen +mitogenic +mitogenicities +mitogenicity +mitogens +mitomycin +mitomycins +mitoses +mitosis +mitotic +mitotically +mitral +mitre +mitred +mitres +mitrewort +mitreworts +mitring +mitsvah +mitsvahs +mitsvoth +mitt +mitten +mittens +mittimus +mittimuses +mitts +mity +mitzvah +mitzvahs +mitzvoth +mix +mixable +mixed +mixer +mixers +mixes +mixible +mixing +mixologies +mixologist +mixologists +mixology +mixt +mixture +mixtures +mixup +mixups +mizen +mizens +mizzen +mizzenmast +mizzenmasts +mizzens +mizzle +mizzled +mizzles +mizzling +mizzly +mm +mnemonic +mnemonically +mnemonics +mo +moa +moan +moaned +moaner +moaners +moanful +moaning +moans +moas +moat +moated +moating +moatlike +moats +mob +mobbed +mobber +mobbers +mobbing +mobbish +mobcap +mobcaps +mobile +mobiles +mobilise +mobilised +mobilises +mobilising +mobilities +mobility +mobilization +mobilizations +mobilize +mobilized +mobilizes +mobilizing +mobled +mobocracies +mobocracy +mobocrat +mobocratic +mobocrats +mobs +mobster +mobsters +moc +moccasin +moccasins +mocha +mochas +mochila +mochilas +mock +mockable +mocked +mocker +mockeries +mockers +mockery +mocking +mockingbird +mockingbirds +mockingly +mocks +mockup +mockups +mocs +mod +modal +modalities +modality +modally +mode +model +modeled +modeler +modelers +modeling +modelings +modelist +modelists +modelled +modeller +modellers +modelling +models +modem +modems +moderate +moderated +moderately +moderateness +moderatenesses +moderates +moderating +moderation +moderations +moderato +moderator +moderators +moderatorship +moderatorships +moderatos +modern +moderne +moderner +modernest +modernisation +modernisations +modernise +modernised +modernises +modernising +modernism +modernisms +modernist +modernistic +modernists +modernities +modernity +modernization +modernizations +modernize +modernized +modernizer +modernizers +modernizes +modernizing +modernly +modernness +modernnesses +moderns +modes +modest +modester +modestest +modesties +modestly +modesty +modi +modica +modicum +modicums +modifiabilities +modifiability +modifiable +modification +modifications +modified +modifier +modifiers +modifies +modify +modifying +modillion +modillions +modioli +modiolus +modish +modishly +modishness +modishnesses +modiste +modistes +mods +modulabilities +modulability +modular +modularities +modularity +modularized +modularly +modulate +modulated +modulates +modulating +modulation +modulations +modulator +modulators +modulatory +module +modules +moduli +modulo +modulus +modus +mofette +mofettes +moffette +moffettes +mog +mogged +moggie +moggies +mogging +moggy +mogs +mogul +moguls +mohair +mohairs +mohalim +mohel +mohelim +mohels +mohur +mohurs +moidore +moidores +moieties +moiety +moil +moiled +moiler +moilers +moiling +moilingly +moils +moira +moirai +moire +moires +moist +moisten +moistened +moistener +moisteners +moistening +moistens +moister +moistest +moistful +moistly +moistness +moistnesses +moisture +moistures +moisturise +moisturised +moisturises +moisturising +moisturize +moisturized +moisturizer +moisturizers +moisturizes +moisturizing +mojarra +mojarras +mojo +mojoes +mojos +moke +mokes +mol +mola +molal +molalities +molality +molar +molarities +molarity +molars +molas +molasses +molasseses +mold +moldable +moldboard +moldboards +molded +molder +moldered +moldering +molders +moldier +moldiest +moldiness +moldinesses +molding +moldings +molds +moldwarp +moldwarps +moldy +mole +molecular +molecularly +molecule +molecules +molehill +molehills +moles +moleskin +moleskins +molest +molestation +molestations +molested +molester +molesters +molesting +molests +molies +moline +moll +mollah +mollahs +mollie +mollies +mollification +mollifications +mollified +mollifies +mollify +mollifying +molls +mollusc +molluscan +molluscicidal +molluscicide +molluscicides +molluscs +mollusk +molluskan +mollusks +molly +mollycoddle +mollycoddled +mollycoddler +mollycoddlers +mollycoddles +mollycoddling +moloch +molochs +mols +molt +molted +molten +moltenly +molter +molters +molting +molto +molts +moly +molybdate +molybdates +molybdenite +molybdenites +molybdenum +molybdenums +molybdic +mom +mome +moment +momenta +momentarily +momentariness +momentarinesses +momentary +momently +momento +momentoes +momentos +momentous +momentously +momentousness +momentousnesses +moments +momentum +momentums +momes +momi +momism +momisms +momma +mommas +mommies +mommy +moms +momser +momsers +momus +momuses +momzer +momzers +mon +monachal +monachism +monachisms +monacid +monacids +monad +monadal +monadelphous +monades +monadic +monadism +monadisms +monadnock +monadnocks +monads +monandries +monandry +monarch +monarchal +monarchial +monarchic +monarchical +monarchically +monarchies +monarchism +monarchisms +monarchist +monarchists +monarchs +monarchy +monarda +monardas +monas +monasteries +monastery +monastic +monastically +monasticism +monasticisms +monastics +monatomic +monaural +monaurally +monaxial +monaxon +monaxons +monazite +monazites +monde +mondes +mondo +mondos +monecian +monecious +monellin +monellins +moneran +monerans +monestrous +monetarily +monetarism +monetarisms +monetarist +monetarists +monetary +monetise +monetised +monetises +monetising +monetization +monetizations +monetize +monetized +monetizes +monetizing +money +moneybag +moneybags +moneyed +moneyer +moneyers +moneygrubbing +moneygrubbings +moneylender +moneylenders +moneymaker +moneymakers +moneymaking +moneymakings +moneyman +moneymen +moneys +moneywort +moneyworts +mongeese +monger +mongered +mongering +mongers +mongo +mongoe +mongoes +mongol +mongolism +mongolisms +mongoloid +mongoloids +mongols +mongoose +mongooses +mongos +mongrel +mongrelization +mongrelizations +mongrelize +mongrelized +mongrelizes +mongrelizing +mongrels +mongst +monicker +monickers +monie +monied +monies +moniker +monikers +moniliases +moniliasis +moniliform +monish +monished +monishes +monishing +monism +monisms +monist +monistic +monists +monition +monitions +monitive +monitor +monitored +monitorial +monitories +monitoring +monitors +monitorship +monitorships +monitory +monk +monkeries +monkery +monkey +monkeyed +monkeying +monkeypod +monkeypods +monkeys +monkeyshine +monkeyshines +monkfish +monkfishes +monkhood +monkhoods +monkish +monks +monkshood +monkshoods +mono +monoacid +monoacidic +monoacids +monoamine +monoaminergic +monoamines +monobasic +monocarboxylic +monocarp +monocarpic +monocarps +monochasia +monochasial +monochasium +monochord +monochords +monochromat +monochromatic +monochromatically +monochromaticities +monochromaticity +monochromatism +monochromatisms +monochromator +monochromators +monochromats +monochrome +monochromes +monochromic +monochromist +monochromists +monocle +monocled +monocles +monocline +monoclines +monoclinic +monoclonal +monoclonals +monocoque +monocoques +monocot +monocots +monocotyledon +monocotyledonous +monocotyledons +monocracies +monocracy +monocrat +monocratic +monocrats +monocrystal +monocrystalline +monocrystals +monocular +monocularly +monoculars +monocultural +monoculture +monocultures +monocyclic +monocyte +monocytes +monocytic +monodic +monodical +monodically +monodies +monodisperse +monodist +monodists +monodrama +monodramas +monodramatic +monody +monoecies +monoecious +monoecism +monoecisms +monoecy +monoester +monoesters +monofil +monofilament +monofilaments +monofils +monofuel +monofuels +monogamic +monogamies +monogamist +monogamists +monogamous +monogamously +monogamy +monogastric +monogenean +monogeneans +monogeneses +monogenesis +monogenetic +monogenic +monogenically +monogenies +monogeny +monogerm +monoglot +monoglots +monoglyceride +monoglycerides +monogram +monogramed +monograming +monogrammatic +monogrammed +monogrammer +monogrammers +monogramming +monograms +monograph +monographed +monographic +monographing +monographs +monogynies +monogynous +monogyny +monohull +monohulls +monohybrid +monohybrids +monohydric +monohydroxy +monolayer +monolayers +monolingual +monolinguals +monolith +monolithic +monolithically +monoliths +monolog +monologies +monologist +monologists +monologs +monologue +monologues +monologuist +monologuists +monology +monomania +monomaniac +monomaniacal +monomaniacally +monomaniacs +monomanias +monomer +monomeric +monomers +monometallic +monometallism +monometallisms +monometallist +monometallists +monometer +monometers +monomial +monomials +monomolecular +monomolecularly +monomorphemic +monomorphic +monomorphism +monomorphisms +mononuclear +mononuclears +mononucleate +mononucleated +mononucleoses +mononucleosis +mononucleosises +mononucleotide +mononucleotides +monophagies +monophagous +monophagy +monophonic +monophonically +monophonies +monophony +monophthong +monophthongal +monophthongs +monophyletic +monophylies +monophyly +monoplane +monoplanes +monoploid +monoploids +monopode +monopodes +monopodial +monopodially +monopodies +monopody +monopole +monopoles +monopolies +monopolise +monopolised +monopolises +monopolising +monopolist +monopolistic +monopolistically +monopolists +monopolization +monopolizations +monopolize +monopolized +monopolizer +monopolizers +monopolizes +monopolizing +monopoly +monopropellant +monopropellants +monopsonies +monopsonistic +monopsony +monorail +monorails +monorchid +monorchidism +monorchidisms +monorchids +monorhyme +monorhymed +monorhymes +monos +monosaccharide +monosaccharides +monosome +monosomes +monosomic +monosomics +monosomies +monosomy +monospecific +monospecificities +monospecificity +monostele +monosteles +monostelic +monostelies +monostely +monosyllabic +monosyllabically +monosyllabicities +monosyllabicity +monosyllable +monosyllables +monosynaptic +monosynaptically +monoterpene +monoterpenes +monotheism +monotheisms +monotheist +monotheistic +monotheistical +monotheistically +monotheists +monotint +monotints +monotone +monotones +monotonic +monotonically +monotonicities +monotonicity +monotonies +monotonous +monotonously +monotonousness +monotonousnesses +monotony +monotreme +monotremes +monotype +monotypes +monotypic +monounsaturate +monounsaturated +monounsaturates +monovalent +monovular +monoxide +monoxides +monozygotic +mons +monseigneur +monsieur +monsignor +monsignori +monsignorial +monsignors +monsoon +monsoonal +monsoons +monster +monstera +monsteras +monsters +monstrance +monstrances +monstrosities +monstrosity +monstrous +monstrously +monstrousness +monstrousnesses +montadale +montadales +montage +montaged +montages +montaging +montagnard +montagnards +montane +montanes +monte +monteith +monteiths +montero +monteros +montes +month +monthlies +monthlong +monthly +months +montmorillonite +montmorillonites +montmorillonitic +monument +monumental +monumentalities +monumentality +monumentalize +monumentalized +monumentalizes +monumentalizing +monumentally +monuments +monuron +monurons +mony +monzonite +monzonites +moo +mooch +mooched +moocher +moochers +mooches +mooching +mood +moodier +moodiest +moodily +moodiness +moodinesses +moods +moody +mooed +mooing +mool +moola +moolah +moolahs +moolas +mooley +mooleys +mools +moon +moonbeam +moonbeams +moonbow +moonbows +mooncalf +mooncalves +moondust +moondusts +mooned +mooneye +mooneyes +moonfaced +moonfish +moonfishes +moonflower +moonflowers +moonier +mooniest +moonily +mooning +moonish +moonishly +moonless +moonlet +moonlets +moonlight +moonlighted +moonlighter +moonlighters +moonlighting +moonlights +moonlike +moonlit +moonport +moonports +moonquake +moonquakes +moonrise +moonrises +moons +moonsail +moonsails +moonscape +moonscapes +moonseed +moonseeds +moonset +moonsets +moonshine +moonshiner +moonshiners +moonshines +moonshot +moonshots +moonstone +moonstones +moonstruck +moonwalk +moonwalks +moonward +moonwort +moonworts +moony +moor +moorage +moorages +moorcock +moorcocks +moored +moorfowl +moorfowls +moorhen +moorhens +moorier +mooriest +mooring +moorings +moorish +moorland +moorlands +moors +moorwort +moorworts +moory +moos +moose +moot +mooted +mooter +mooters +mooting +moots +mop +mopboard +mopboards +mope +moped +mopeds +moper +moperies +mopers +mopery +mopes +mopey +mopier +mopiest +moping +mopingly +mopish +mopishly +mopoke +mopokes +mopped +mopper +moppers +moppet +moppets +mopping +mops +mopy +moquette +moquettes +mor +mora +morae +morainal +moraine +moraines +morainic +moral +morale +morales +moralise +moralised +moralises +moralising +moralism +moralisms +moralist +moralistic +moralistically +moralists +moralities +morality +moralization +moralizations +moralize +moralized +moralizer +moralizers +moralizes +moralizing +morally +morals +moras +morass +morasses +morassy +moratoria +moratorium +moratoriums +moratory +moray +morays +morbid +morbidities +morbidity +morbidly +morbidness +morbidnesses +morbific +morbilli +morceau +morceaux +mordancies +mordancy +mordant +mordanted +mordanting +mordantly +mordants +mordent +mordents +more +moreen +moreens +morel +morelle +morelles +morello +morellos +morels +moreover +mores +moresque +moresques +morgan +morganatic +morganatically +morganite +morganites +morgans +morgen +morgens +morgue +morgues +moribund +moribundities +moribundity +morion +morions +morn +morning +mornings +morns +morocco +moroccos +moron +moronic +moronically +moronism +moronisms +moronities +moronity +morons +morose +morosely +moroseness +morosenesses +morosities +morosity +morph +morphactin +morphactins +morphallaxes +morphallaxis +morpheme +morphemes +morphemic +morphemically +morphemics +morphia +morphias +morphic +morphin +morphine +morphines +morphinism +morphinisms +morphins +morpho +morphogen +morphogeneses +morphogenesis +morphogenetic +morphogenetically +morphogenic +morphogens +morphologic +morphological +morphologically +morphologies +morphologist +morphologists +morphology +morphometric +morphometrically +morphometries +morphometry +morphophonemics +morphos +morphs +morrion +morrions +morris +morrises +morro +morros +morrow +morrows +mors +morse +morsel +morseled +morseling +morselled +morselling +morsels +mort +mortadella +mortadellas +mortal +mortalities +mortality +mortally +mortals +mortar +mortarboard +mortarboards +mortared +mortaring +mortarless +mortars +mortary +mortgage +mortgaged +mortgagee +mortgagees +mortgager +mortgagers +mortgages +mortgaging +mortgagor +mortgagors +mortice +morticed +mortices +mortician +morticians +morticing +mortification +mortifications +mortified +mortifies +mortify +mortifying +mortise +mortised +mortiser +mortisers +mortises +mortising +mortmain +mortmains +morts +mortuaries +mortuary +morula +morulae +morular +morulas +morulation +morulations +mos +mosaic +mosaically +mosaicism +mosaicisms +mosaicist +mosaicists +mosaicked +mosaicking +mosaiclike +mosaics +mosasaur +mosasaurs +moschate +mosey +moseyed +moseying +moseys +moshav +moshavim +mosk +mosks +mosque +mosques +mosquito +mosquitoes +mosquitoey +mosquitos +moss +mossback +mossbacked +mossbacks +mossed +mosser +mossers +mosses +mossier +mossiest +mossing +mosslike +mosso +mossy +most +moste +mostest +mostests +mostly +mosts +mot +mote +motel +motels +motes +motet +motets +motey +moth +mothball +mothballed +mothballing +mothballs +mother +motherboard +motherboards +mothered +motherfucker +motherfuckers +motherfucking +motherhood +motherhoods +motherhouse +motherhouses +mothering +motherland +motherlands +motherless +motherlessness +motherlessnesses +motherliness +motherlinesses +motherly +mothers +mothery +mothier +mothiest +mothlike +mothproof +mothproofed +mothproofer +mothproofers +mothproofing +mothproofs +moths +mothy +motif +motific +motifs +motile +motiles +motilities +motility +motion +motional +motioned +motioner +motioners +motioning +motionless +motionlessly +motionlessness +motionlessnesses +motions +motivate +motivated +motivates +motivating +motivation +motivational +motivationally +motivations +motivative +motivator +motivators +motive +motived +motiveless +motivelessly +motives +motivic +motiving +motivities +motivity +motley +motleyer +motleyest +motleys +motlier +motliest +motmot +motmots +motocross +motocrosses +motoneuron +motoneuronal +motoneurons +motor +motorbike +motorbiked +motorbikes +motorbiking +motorboat +motorboater +motorboaters +motorboating +motorboatings +motorboats +motorbus +motorbuses +motorbusses +motorcade +motorcaded +motorcades +motorcading +motorcar +motorcars +motorcycle +motorcycled +motorcycles +motorcycling +motorcyclist +motorcyclists +motordom +motordoms +motored +motoric +motorically +motoring +motorings +motorise +motorised +motorises +motorising +motorist +motorists +motorization +motorizations +motorize +motorized +motorizes +motorizing +motorless +motorman +motormen +motormouth +motormouths +motors +motortruck +motortrucks +motorway +motorways +mots +mott +motte +mottes +mottle +mottled +mottler +mottlers +mottles +mottling +motto +mottoes +mottos +motts +mouch +mouched +mouches +mouching +mouchoir +mouchoirs +moue +moues +moufflon +moufflons +mouflon +mouflons +mouille +moujik +moujiks +moulage +moulages +mould +moulded +moulder +mouldered +mouldering +moulders +mouldier +mouldiest +moulding +mouldings +moulds +mouldy +moulin +moulins +moult +moulted +moulter +moulters +moulting +moults +mound +mounded +mounding +mounds +mount +mountable +mountain +mountaineer +mountaineering +mountaineerings +mountaineers +mountainous +mountainously +mountainousness +mountainousnesses +mountains +mountainside +mountainsides +mountaintop +mountaintops +mountainy +mountebank +mountebanked +mountebankeries +mountebankery +mountebanking +mountebanks +mounted +mounter +mounters +mounting +mountings +mounts +mourn +mourned +mourner +mourners +mournful +mournfuller +mournfullest +mournfully +mournfulness +mournfulnesses +mourning +mourningly +mournings +mourns +mouse +moused +mouser +mousers +mouses +mousetrap +mousetrapped +mousetrapping +mousetraps +mousey +mousier +mousiest +mousily +mousiness +mousinesses +mousing +mousings +moussaka +moussakas +mousse +moussed +mousseline +mousselines +mousses +moussing +moustache +moustaches +moustachio +moustachios +mousy +mouth +mouthbreeder +mouthbreeders +mouthed +mouther +mouthers +mouthful +mouthfuls +mouthier +mouthiest +mouthily +mouthing +mouthlike +mouthpart +mouthparts +mouthpiece +mouthpieces +mouths +mouthwash +mouthwashes +mouthwatering +mouthwateringly +mouthy +mouton +moutons +movabilities +movability +movable +movableness +movablenesses +movables +movably +move +moveable +moveables +moveably +moved +moveless +movelessly +movelessness +movelessnesses +movement +movements +mover +movers +moves +movie +moviedom +moviedoms +moviegoer +moviegoers +moviegoing +moviegoings +moviemaker +moviemakers +moviemaking +moviemakings +movieola +movieolas +movies +moving +movingly +moviola +moviolas +mow +mowed +mower +mowers +mowing +mowings +mown +mows +moxa +moxas +moxie +moxies +mozetta +mozettas +mozette +mozo +mozos +mozzarella +mozzarellas +mozzetta +mozzettas +mozzette +mridanga +mridangam +mridangams +mridangas +mu +much +muchacho +muchachos +muches +muchly +muchness +muchnesses +mucid +mucidities +mucidity +mucilage +mucilages +mucilaginous +mucilaginously +mucin +mucinoid +mucinous +mucins +muck +muckamuck +muckamucks +mucked +mucker +muckers +muckier +muckiest +muckily +mucking +muckle +muckles +muckluck +mucklucks +muckrake +muckraked +muckraker +muckrakers +muckrakes +muckraking +mucks +muckworm +muckworms +mucky +mucluc +muclucs +mucocutaneous +mucoid +mucoidal +mucoids +mucolytic +mucopeptide +mucopeptides +mucopolysaccharide +mucopolysaccharides +mucoprotein +mucoproteins +mucor +mucors +mucosa +mucosae +mucosal +mucosas +mucose +mucosities +mucosity +mucous +mucro +mucronate +mucrones +mucus +mucuses +mud +mudcap +mudcapped +mudcapping +mudcaps +mudcat +mudcats +mudded +mudder +mudders +muddied +muddier +muddies +muddiest +muddily +muddiness +muddinesses +mudding +muddle +muddled +muddleheaded +muddleheadedly +muddleheadedness +muddleheadednesses +muddler +muddlers +muddles +muddling +muddly +muddy +muddying +mudfish +mudfishes +mudflat +mudflats +mudflow +mudflows +mudguard +mudguards +mudhole +mudholes +mudlark +mudlarks +mudpack +mudpacks +mudpuppies +mudpuppy +mudra +mudras +mudrock +mudrocks +mudroom +mudrooms +muds +mudsill +mudsills +mudskipper +mudskippers +mudslide +mudslides +mudslinger +mudslingers +mudslinging +mudslingings +mudstone +mudstones +mueddin +mueddins +muenster +muensters +muesli +mueslis +muezzin +muezzins +muff +muffed +muffin +muffing +muffins +muffle +muffled +muffler +mufflered +mufflers +muffles +muffling +muffs +mufti +muftis +mug +mugful +mugfuls +mugg +muggar +muggars +mugged +muggee +muggees +mugger +muggers +muggier +muggiest +muggily +mugginess +mugginesses +mugging +muggings +muggins +muggs +muggur +muggurs +muggy +mugs +mugwort +mugworts +mugwump +mugwumps +muhlies +muhly +mujahedeen +mujahedin +mujahideen +mujik +mujiks +mukluk +mukluks +muktuk +muktuks +mulatto +mulattoes +mulattos +mulberries +mulberry +mulch +mulched +mulches +mulching +mulct +mulcted +mulcting +mulcts +mule +muled +mules +muleta +muletas +muleteer +muleteers +muley +muleys +muliebrities +muliebrity +muling +mulish +mulishly +mulishness +mulishnesses +mull +mulla +mullah +mullahism +mullahisms +mullahs +mullas +mulled +mullein +mulleins +mullen +mullens +muller +mullers +mullet +mullets +mulley +mulleys +mulligan +mulligans +mulligatawnies +mulligatawny +mulling +mullion +mullioned +mullioning +mullions +mullite +mullites +mullock +mullocks +mullocky +mulls +multiage +multiagency +multiarmed +multiatom +multiauthor +multiaxial +multiband +multibank +multibarrel +multibarreled +multibillion +multibillionaire +multibillionaires +multibillions +multibladed +multibranched +multibuilding +multicampus +multicar +multicarbon +multicausal +multicell +multicelled +multicellular +multicellularities +multicellularity +multicenter +multichain +multichambered +multichannel +multichannels +multicharacter +multicity +multiclient +multicoated +multicolor +multicolored +multicolors +multicolumn +multicomponent +multiconductor +multicopy +multicounty +multicourse +multicourses +multicultural +multiculturalism +multiculturalisms +multicurie +multicurrency +multidialectal +multidimensional +multidimensionalities +multidimensionality +multidirectional +multidisciplinary +multidiscipline +multidisciplines +multidivisional +multidomain +multidrug +multielectrode +multielement +multiemployer +multiengine +multiengines +multienzyme +multiethnic +multifaceted +multifactor +multifactorial +multifactorially +multifamily +multifarious +multifariousness +multifariousnesses +multifid +multifilament +multifilaments +multiflash +multifocal +multifold +multiform +multiformities +multiformity +multifrequency +multifunction +multifunctional +multigenerational +multigenic +multigerm +multigrade +multigrain +multigrains +multigrid +multigroup +multihandicapped +multiheaded +multihospital +multihued +multihull +multihulls +multijet +multilane +multilateral +multilateralism +multilateralisms +multilateralist +multilateralists +multilaterally +multilayer +multilayered +multilevel +multileveled +multiline +multilingual +multilingualism +multilingualisms +multilingually +multilobed +multimanned +multimedia +multimedias +multimegaton +multimegatons +multimegawatt +multimegawatts +multimember +multimetallic +multimillennial +multimillion +multimillionaire +multimillionaires +multimillions +multimodal +multimode +multimolecular +multination +multinational +multinationals +multinomial +multinomials +multinuclear +multinucleate +multinucleated +multiorgasmic +multipage +multipaned +multiparameter +multiparous +multipart +multiparticle +multipartite +multiparty +multipath +multiped +multipeds +multiphase +multiphasic +multiphoton +multipicture +multipiece +multipion +multipiston +multiplant +multiplayer +multiple +multiples +multiplet +multiplets +multiplex +multiplexed +multiplexer +multiplexers +multiplexes +multiplexing +multiplexor +multiplexors +multiplicand +multiplicands +multiplication +multiplications +multiplicative +multiplicatively +multiplicities +multiplicity +multiplied +multiplier +multipliers +multiplies +multiply +multiplying +multipolar +multipolarities +multipolarity +multipole +multipotential +multipower +multiproblem +multiprocessing +multiprocessings +multiprocessor +multiprocessors +multiproduct +multiprogramming +multiprogrammings +multipronged +multipurpose +multiracial +multiracialism +multiracialisms +multirange +multiregional +multireligious +multiroom +multiscreen +multisense +multisensory +multiservice +multisided +multisite +multisize +multiskilled +multisource +multispecies +multispectral +multispeed +multisport +multistage +multistate +multistemmed +multistep +multistoried +multistory +multistranded +multisyllabic +multisystem +multitalented +multitasking +multitaskings +multiterminal +multitiered +multiton +multitone +multitowered +multitrack +multitracked +multitracking +multitracks +multitrillion +multitrillions +multitude +multitudes +multitudinous +multitudinously +multitudinousness +multitudinousnesses +multiunion +multiunit +multiuse +multiuser +multivalence +multivalences +multivalent +multivalents +multivariable +multivariate +multiversities +multiversity +multivitamin +multivitamins +multivoltine +multivolume +multiwall +multiwarhead +multiwavelength +multiyear +multure +multures +mum +mumble +mumbled +mumbler +mumblers +mumbles +mumbling +mumbly +mumm +mummed +mummer +mummeries +mummers +mummery +mummichog +mummichogs +mummied +mummies +mummification +mummifications +mummified +mummifies +mummify +mummifying +mumming +mumms +mummy +mummying +mump +mumped +mumper +mumpers +mumping +mumps +mums +mumu +mumus +mun +munch +munched +muncher +munchers +munches +munchies +munching +munchkin +munchkins +mundane +mundanely +mundaneness +mundanenesses +mundanities +mundanity +mundungo +mundungos +mundungus +mundunguses +mungo +mungoose +mungooses +mungos +muni +municipal +municipalities +municipality +municipalization +municipalizations +municipalize +municipalized +municipalizes +municipalizing +municipally +municipals +munificence +munificences +munificent +munificently +muniment +muniments +munis +munition +munitioned +munitioning +munitions +munnion +munnions +muns +munster +munsters +muntin +munting +muntings +muntins +muntjac +muntjacs +muntjak +muntjaks +muon +muonic +muonium +muoniums +muons +mura +muraenid +muraenids +mural +muralist +muralists +murals +muras +murder +murdered +murderee +murderees +murderer +murderers +murderess +murderesses +murdering +murderous +murderously +murderousness +murderousnesses +murders +mure +mured +murein +mureins +mures +murex +murexes +muriate +muriated +muriates +muricate +murices +murid +murids +murine +murines +muring +murk +murker +murkest +murkier +murkiest +murkily +murkiness +murkinesses +murkly +murks +murky +murmur +murmured +murmurer +murmurers +murmuring +murmurous +murmurously +murmurs +murphies +murphy +murr +murra +murrain +murrains +murras +murre +murrelet +murrelets +murres +murrey +murreys +murrha +murrhas +murrhine +murries +murrine +murrs +murry +murther +murthered +murthering +murthers +mus +musca +muscadel +muscadels +muscadet +muscadets +muscadine +muscadines +muscae +muscarine +muscarines +muscarinic +muscat +muscatel +muscatels +muscats +muscid +muscids +muscle +musclebound +muscled +muscles +muscling +muscly +muscovite +muscovites +muscular +muscularities +muscularity +muscularly +musculature +musculatures +musculoskeletal +muse +mused +museful +museological +museologies +museologist +museologists +museology +muser +musers +muses +musette +musettes +museum +museums +mush +mushed +musher +mushers +mushes +mushier +mushiest +mushily +mushiness +mushinesses +mushing +mushroom +mushroomed +mushrooming +mushrooms +mushy +music +musical +musicale +musicales +musicalise +musicalised +musicalises +musicalising +musicalities +musicality +musicalization +musicalizations +musicalize +musicalized +musicalizes +musicalizing +musically +musicals +musician +musicianly +musicians +musicianship +musicianships +musicological +musicologies +musicologist +musicologists +musicology +musics +musing +musingly +musings +musjid +musjids +musk +muskeg +muskegs +muskellunge +musket +musketeer +musketeers +musketries +musketry +muskets +muskie +muskier +muskies +muskiest +muskily +muskiness +muskinesses +muskit +muskits +muskmelon +muskmelons +muskrat +muskrats +musks +musky +muslin +muslins +muspike +muspikes +musquash +musquashes +muss +mussed +mussel +mussels +musses +mussier +mussiest +mussily +mussiness +mussinesses +mussing +mussy +must +mustache +mustached +mustaches +mustachio +mustachioed +mustachios +mustang +mustangs +mustard +mustards +mustardy +musted +mustee +mustees +muster +mustered +mustering +musters +musth +musths +mustier +mustiest +mustily +mustiness +mustinesses +musting +musts +musty +mut +mutabilities +mutability +mutable +mutably +mutagen +mutageneses +mutagenesis +mutagenic +mutagenically +mutagenicities +mutagenicity +mutagens +mutant +mutants +mutase +mutases +mutate +mutated +mutates +mutating +mutation +mutational +mutationally +mutations +mutative +mutch +mutches +mutchkin +mutchkins +mute +muted +mutedly +mutely +muteness +mutenesses +muter +mutes +mutest +muticous +mutilate +mutilated +mutilates +mutilating +mutilation +mutilations +mutilator +mutilators +mutine +mutined +mutineer +mutineered +mutineering +mutineers +mutines +muting +mutinied +mutinies +mutining +mutinous +mutinously +mutinousness +mutinousnesses +mutiny +mutinying +mutism +mutisms +muton +mutons +muts +mutt +mutter +muttered +mutterer +mutterers +muttering +mutters +mutton +muttonchops +muttonfish +muttonfishes +muttons +muttony +mutts +mutual +mutualism +mutualisms +mutualist +mutualistic +mutualists +mutualities +mutuality +mutualization +mutualizations +mutualize +mutualized +mutualizes +mutualizing +mutually +mutuel +mutuels +mutular +mutule +mutules +muumuu +muumuus +muzhik +muzhiks +muzjik +muzjiks +muzzier +muzziest +muzzily +muzziness +muzzinesses +muzzle +muzzled +muzzler +muzzlers +muzzles +muzzling +muzzy +my +myalgia +myalgias +myalgic +myases +myasis +myasthenia +myasthenias +myasthenic +myasthenics +mycele +myceles +mycelia +mycelial +mycelian +mycelium +myceloid +mycetoma +mycetomas +mycetomata +mycetomatous +mycetophagous +mycetozoan +mycetozoans +mycobacteria +mycobacterial +mycobacterium +mycoflora +mycoflorae +mycofloras +mycological +mycologically +mycologies +mycologist +mycologists +mycology +mycophagies +mycophagist +mycophagists +mycophagous +mycophagy +mycophile +mycophiles +mycoplasma +mycoplasmal +mycoplasmas +mycoplasmata +mycorrhiza +mycorrhizae +mycorrhizal +mycorrhizas +mycoses +mycosis +mycotic +mycotoxin +mycotoxins +mydriases +mydriasis +mydriatic +mydriatics +myelencephala +myelencephalic +myelencephalon +myelin +myelinated +myeline +myelines +myelinic +myelins +myelitides +myelitis +myeloblast +myeloblastic +myeloblasts +myelocyte +myelocytes +myelocytic +myelofibroses +myelofibrosis +myelofibrotic +myelogenous +myeloid +myeloma +myelomas +myelomata +myelomatous +myelopathic +myelopathies +myelopathy +myeloproliferative +myiases +myiasis +mylonite +mylonites +myna +mynah +mynahs +mynas +mynheer +mynheers +myoblast +myoblasts +myocardia +myocardial +myocarditis +myocarditises +myocardium +myoclonic +myoclonus +myoclonuses +myoelectric +myoelectrical +myofibril +myofibrillar +myofibrils +myofilament +myofilaments +myogenic +myoglobin +myoglobins +myograph +myographs +myoid +myoinositol +myoinositols +myologic +myologies +myology +myoma +myomas +myomata +myomatous +myoneural +myopathic +myopathies +myopathy +myope +myopes +myopia +myopias +myopic +myopically +myopies +myopy +myoscope +myoscopes +myoses +myosin +myosins +myosis +myositis +myositises +myosote +myosotes +myosotis +myosotises +myotic +myotics +myotome +myotomes +myotonia +myotonias +myotonic +myriad +myriads +myriapod +myriapods +myrica +myricas +myriopod +myriopods +myrmecological +myrmecologies +myrmecologist +myrmecologists +myrmecology +myrmecophile +myrmecophiles +myrmecophilous +myrmidon +myrmidons +myrobalan +myrobalans +myrrh +myrrhic +myrrhs +myrtle +myrtles +myself +mysid +mysids +mysost +mysosts +mystagog +mystagogies +mystagogs +mystagogue +mystagogues +mystagogy +mysteries +mysterious +mysteriously +mysteriousness +mysteriousnesses +mystery +mystic +mystical +mystically +mysticism +mysticisms +mysticly +mystics +mystification +mystifications +mystified +mystifier +mystifiers +mystifies +mystify +mystifying +mystifyingly +mystique +mystiques +myth +mythic +mythical +mythically +mythicize +mythicized +mythicizer +mythicizers +mythicizes +mythicizing +mythier +mythiest +mythmaker +mythmakers +mythmaking +mythmakings +mythographer +mythographers +mythographies +mythography +mythoi +mythologer +mythologers +mythologic +mythological +mythologically +mythologies +mythologist +mythologists +mythologize +mythologized +mythologizer +mythologizers +mythologizes +mythologizing +mythology +mythomania +mythomaniac +mythomaniacs +mythomanias +mythopoeia +mythopoeias +mythopoeic +mythopoetic +mythopoetical +mythos +myths +mythy +myxedema +myxedemas +myxedematous +myxocyte +myxocytes +myxoid +myxoma +myxomas +myxomata +myxomatoses +myxomatosis +myxomatosises +myxomatous +myxomycete +myxomycetes +myxoviral +myxovirus +myxoviruses +na +naan +naans +nab +nabbed +nabber +nabbers +nabbing +nabe +nabes +nabis +nabob +naboberies +nabobery +nabobess +nabobesses +nabobish +nabobism +nabobisms +nabobs +nabs +nacelle +nacelles +nachas +naches +nacho +nachos +nacre +nacred +nacreous +nacres +nada +nadas +nadir +nadiral +nadirs +nae +naething +naethings +naevi +naevoid +naevus +nag +nagana +naganas +nagged +nagger +naggers +naggier +naggiest +nagging +naggingly +naggy +nags +nah +naiad +naiades +naiads +naif +naifs +nail +nailbrush +nailbrushes +nailed +nailer +nailers +nailfold +nailfolds +nailhead +nailheads +nailing +nails +nailset +nailsets +nainsook +nainsooks +naira +naive +naively +naiveness +naivenesses +naiver +naives +naivest +naivete +naivetes +naiveties +naivety +naked +nakeder +nakedest +nakedly +nakedness +nakednesses +naled +naleds +nalorphine +nalorphines +naloxone +naloxones +naltrexone +naltrexones +nam +namable +name +nameable +named +nameless +namelessly +namelessness +namelessnesses +namely +nameplate +nameplates +namer +namers +names +namesake +namesakes +nametag +nametags +naming +nan +nana +nanas +nance +nances +nancies +nancy +nandin +nandina +nandinas +nandins +nanism +nanisms +nankeen +nankeens +nankin +nankins +nannie +nannies +nannoplankton +nannoplanktons +nanny +nanogram +nanograms +nanometer +nanometers +nanosecond +nanoseconds +nanotechnologies +nanotechnology +nanotesla +nanoteslas +nanowatt +nanowatts +nans +naoi +naos +nap +napalm +napalmed +napalming +napalms +nape +naperies +napery +napes +naphtha +naphthalene +naphthalenes +naphthas +naphthene +naphthenes +naphthenic +naphthol +naphthols +naphthyl +naphthylamine +naphthylamines +naphthyls +naphtol +naphtols +napiform +napkin +napkins +napless +napoleon +napoleons +nappe +napped +napper +nappers +nappes +nappie +nappier +nappies +nappiest +napping +nappy +naprapathies +naprapathy +naps +narc +narcein +narceine +narceines +narceins +narcism +narcisms +narcissi +narcissism +narcissisms +narcissist +narcissistic +narcissists +narcissus +narcissuses +narcist +narcists +narco +narcolepsies +narcolepsy +narcoleptic +narcoleptics +narcos +narcose +narcoses +narcosis +narcotic +narcotically +narcotics +narcotize +narcotized +narcotizes +narcotizing +narcs +nard +nardine +nards +nares +narghile +narghiles +nargile +nargileh +nargilehs +nargiles +narial +naric +narine +naris +nark +narked +narking +narks +narky +narrate +narrated +narrater +narraters +narrates +narrating +narration +narrational +narrations +narrative +narratively +narratives +narratological +narratologies +narratologist +narratologists +narratology +narrator +narrators +narrow +narrowband +narrowcasting +narrowcastings +narrowed +narrower +narrowest +narrowing +narrowly +narrowness +narrownesses +narrows +narthex +narthexes +narwal +narwals +narwhal +narwhale +narwhales +narwhals +nary +nasal +nasalise +nasalised +nasalises +nasalising +nasalities +nasality +nasalization +nasalizations +nasalize +nasalized +nasalizes +nasalizing +nasally +nasals +nascence +nascences +nascencies +nascency +nascent +nasial +nasion +nasions +nasogastric +nasopharyngeal +nasopharynges +nasopharynx +nasopharynxes +nastic +nastier +nasties +nastiest +nastily +nastiness +nastinesses +nasturtium +nasturtiums +nasty +natal +natalities +natality +natant +natantly +natation +natations +natatoria +natatorial +natatorium +natatoriums +natatory +natch +nates +natheless +nathless +nation +national +nationalise +nationalised +nationalises +nationalising +nationalism +nationalisms +nationalist +nationalistic +nationalistically +nationalists +nationalities +nationality +nationalization +nationalizations +nationalize +nationalized +nationalizer +nationalizers +nationalizes +nationalizing +nationally +nationals +nationhood +nationhoods +nations +nationwide +native +natively +nativeness +nativenesses +natives +nativism +nativisms +nativist +nativistic +nativists +nativities +nativity +natrium +natriums +natriureses +natriuresis +natriuretic +natriuretics +natrolite +natrolites +natron +natrons +natter +nattered +nattering +natters +nattier +nattiest +nattily +nattiness +nattinesses +natty +natural +naturalise +naturalised +naturalises +naturalising +naturalism +naturalisms +naturalist +naturalistic +naturalistically +naturalists +naturalization +naturalizations +naturalize +naturalized +naturalizes +naturalizing +naturally +naturalness +naturalnesses +naturals +nature +natured +natures +naturism +naturisms +naturist +naturists +naturopath +naturopathic +naturopathies +naturopaths +naturopathy +naught +naughtier +naughtiest +naughtily +naughtiness +naughtinesses +naughts +naughty +naumachia +naumachiae +naumachias +naumachies +naumachy +nauplial +nauplii +nauplius +nausea +nauseant +nauseants +nauseas +nauseate +nauseated +nauseates +nauseating +nauseatingly +nauseous +nauseously +nauseousness +nauseousnesses +nautch +nautches +nautical +nautically +nautili +nautiloid +nautiloids +nautilus +nautiluses +navaid +navaids +naval +navally +navar +navars +nave +navel +navels +naves +navette +navettes +navicert +navicerts +navicular +naviculars +navies +navigabilities +navigability +navigable +navigably +navigate +navigated +navigates +navigating +navigation +navigational +navigationally +navigations +navigator +navigators +navvies +navvy +navy +naw +nawab +nawabs +nay +nays +naysayer +naysayers +nazi +nazification +nazifications +nazified +nazifies +nazify +nazifying +nazis +ne +neap +neaps +near +nearby +neared +nearer +nearest +nearing +nearlier +nearliest +nearly +nearness +nearnesses +nears +nearshore +nearside +nearsides +nearsighted +nearsightedly +nearsightedness +nearsightednesses +neat +neaten +neatened +neatening +neatens +neater +neatest +neath +neatherd +neatherds +neatly +neatness +neatnesses +neats +neb +nebbish +nebbishes +nebbishy +nebenkern +nebenkerns +nebs +nebula +nebulae +nebular +nebulas +nebule +nebulise +nebulised +nebulises +nebulising +nebulization +nebulizations +nebulize +nebulized +nebulizer +nebulizers +nebulizes +nebulizing +nebulose +nebulosities +nebulosity +nebulous +nebulously +nebulousness +nebulousnesses +nebuly +necessaries +necessarily +necessary +necessitarian +necessitarianism +necessitarianisms +necessitarians +necessitate +necessitated +necessitates +necessitating +necessitation +necessitations +necessities +necessitous +necessitously +necessitousness +necessitousnesses +necessity +neck +neckband +neckbands +necked +necker +neckerchief +neckerchiefs +neckerchieves +neckers +necking +neckings +necklace +necklaces +neckless +necklike +neckline +necklines +necks +necktie +neckties +neckwear +necrological +necrologies +necrologist +necrologists +necrology +necromancer +necromancers +necromancies +necromancy +necromantic +necromantically +necrophagous +necrophilia +necrophiliac +necrophiliacs +necrophilias +necrophilic +necrophilism +necrophilisms +necropoleis +necropoles +necropoli +necropolis +necropolises +necropsied +necropsies +necropsy +necropsying +necrose +necrosed +necroses +necrosing +necrosis +necrotic +necrotizing +nectar +nectaries +nectarine +nectarines +nectarous +nectars +nectary +nee +need +needed +needer +needers +needful +needfully +needfulness +needfulnesses +needfuls +needier +neediest +needily +neediness +needinesses +needing +needle +needled +needlefish +needlefishes +needlelike +needlepoint +needlepoints +needler +needlers +needles +needless +needlessly +needlessness +needlessnesses +needlewoman +needlewomen +needlework +needleworker +needleworkers +needleworks +needling +needlings +needs +needy +neem +neems +neep +neeps +nefarious +nefariously +negate +negated +negater +negaters +negates +negating +negation +negational +negations +negative +negatived +negatively +negativeness +negativenesses +negatives +negativing +negativism +negativisms +negativist +negativistic +negativists +negativities +negativity +negaton +negatons +negator +negators +negatron +negatrons +neglect +neglected +neglecter +neglecters +neglectful +neglectfully +neglectfulness +neglectfulnesses +neglecting +neglects +neglige +negligee +negligees +negligence +negligences +negligent +negligently +negliges +negligibilities +negligibility +negligible +negligibly +negotiabilities +negotiability +negotiable +negotiant +negotiants +negotiate +negotiated +negotiates +negotiating +negotiation +negotiations +negotiator +negotiators +negotiatory +negritude +negritudes +negroid +negroids +negroni +negronis +negrophobe +negrophobes +negrophobia +negrophobias +negus +neguses +neif +neifs +neigh +neighbor +neighbored +neighborhood +neighborhoods +neighboring +neighborliness +neighborlinesses +neighborly +neighbors +neighbour +neighboured +neighbouring +neighbours +neighed +neighing +neighs +neist +neither +nekton +nektonic +nektons +nellie +nellies +nelly +nelson +nelsons +nelumbo +nelumbos +nema +nemas +nematic +nematicidal +nematicide +nematicides +nematocidal +nematocide +nematocides +nematocyst +nematocysts +nematode +nematodes +nematological +nematologies +nematologist +nematologists +nematology +nemertean +nemerteans +nemertine +nemertines +nemeses +nemesis +nemophila +nemophilas +nene +neoclassic +neoclassical +neoclassicism +neoclassicisms +neoclassicist +neoclassicists +neocolonial +neocolonialism +neocolonialisms +neocolonialist +neocolonialists +neoconservatism +neoconservatisms +neoconservative +neoconservatives +neocortex +neocortexes +neocortical +neocortices +neodymium +neodymiums +neoliberal +neoliberalism +neoliberalisms +neoliberals +neolith +neolithic +neoliths +neologic +neologies +neologism +neologisms +neologistic +neology +neomorph +neomorphs +neomycin +neomycins +neon +neonatal +neonatally +neonate +neonates +neonatologies +neonatologist +neonatologists +neonatology +neoned +neons +neoorthodox +neoorthodoxies +neoorthodoxy +neophilia +neophiliac +neophiliacs +neophilias +neophyte +neophytes +neoplasia +neoplasias +neoplasm +neoplasms +neoplastic +neoplasticism +neoplasticisms +neoplasticist +neoplasticists +neoprene +neoprenes +neorealism +neorealisms +neorealist +neorealistic +neorealists +neostigmine +neostigmines +neotenic +neotenies +neoteny +neoteric +neoterics +neotropics +neotype +neotypes +nepenthe +nepenthean +nepenthes +nepheline +nephelines +nephelinic +nephelinite +nephelinites +nephelinitic +nephelite +nephelites +nephelometer +nephelometers +nephelometric +nephelometrically +nephelometries +nephelometry +nephew +nephews +nephoscope +nephoscopes +nephrectomies +nephrectomize +nephrectomized +nephrectomizes +nephrectomizing +nephrectomy +nephric +nephridia +nephridial +nephridium +nephrism +nephrisms +nephrite +nephrites +nephritic +nephritides +nephritis +nephrologies +nephrologist +nephrologists +nephrology +nephron +nephrons +nephropathic +nephropathies +nephropathy +nephroses +nephrosis +nephrostome +nephrostomes +nephrotic +nephrotics +nephrotoxic +nephrotoxicities +nephrotoxicity +nepotic +nepotism +nepotisms +nepotist +nepotistic +nepotists +neptunium +neptuniums +nerd +nerdier +nerdiest +nerdish +nerds +nerdy +nereid +nereides +nereids +nereis +neritic +nerol +neroli +nerolis +nerols +nerts +nertz +nervate +nervation +nervations +nerve +nerved +nerveless +nervelessly +nervelessness +nervelessnesses +nerves +nervier +nerviest +nervily +nervine +nervines +nerviness +nervinesses +nerving +nervings +nervosities +nervosity +nervous +nervously +nervousness +nervousnesses +nervule +nervules +nervure +nervures +nervy +nescience +nesciences +nescient +nescients +ness +nesses +nest +nestable +nested +nester +nesters +nesting +nestle +nestled +nestler +nestlers +nestles +nestlike +nestling +nestlings +nestor +nestors +nests +net +nether +nethermost +netherworld +netherworlds +netless +netlike +netminder +netminders +netop +netops +nets +netsuke +netsukes +nett +nettable +netted +netter +netters +nettier +nettiest +netting +nettings +nettle +nettled +nettler +nettlers +nettles +nettlesome +nettlier +nettliest +nettling +nettly +netts +netty +network +networked +networking +networkings +networks +neuk +neuks +neum +neumatic +neume +neumes +neumic +neums +neural +neuralgia +neuralgias +neuralgic +neurally +neuraminidase +neuraminidases +neurasthenia +neurasthenias +neurasthenic +neurasthenically +neurasthenics +neuraxon +neuraxons +neurilemma +neurilemmal +neurilemmas +neurine +neurines +neuritic +neuritics +neuritides +neuritis +neuritises +neuroactive +neuroanatomic +neuroanatomical +neuroanatomies +neuroanatomist +neuroanatomists +neuroanatomy +neurobiological +neurobiologies +neurobiologist +neurobiologists +neurobiology +neuroblastoma +neuroblastomas +neuroblastomata +neurochemical +neurochemicals +neurochemist +neurochemistries +neurochemistry +neurochemists +neurodegenerative +neuroendocrine +neuroendocrinological +neuroendocrinologies +neuroendocrinologist +neuroendocrinologists +neuroendocrinology +neurofibril +neurofibrillary +neurofibrils +neurofibroma +neurofibromas +neurofibromata +neurofibromatoses +neurofibromatosis +neurofibromatosises +neurogenic +neurogenically +neuroglia +neuroglial +neuroglias +neurohormonal +neurohormone +neurohormones +neurohumor +neurohumoral +neurohumors +neurohypophyseal +neurohypophyses +neurohypophysial +neurohypophysis +neuroid +neuroleptic +neuroleptics +neurologic +neurological +neurologically +neurologies +neurologist +neurologists +neurology +neuroma +neuromas +neuromata +neuromuscular +neuron +neuronal +neurone +neurones +neuronic +neurons +neuropathic +neuropathically +neuropathies +neuropathologic +neuropathological +neuropathologies +neuropathologist +neuropathologists +neuropathology +neuropathy +neuropeptide +neuropeptides +neuropharmacologic +neuropharmacological +neuropharmacologies +neuropharmacologist +neuropharmacologists +neuropharmacology +neurophysiologic +neurophysiological +neurophysiologically +neurophysiologies +neurophysiologist +neurophysiologists +neurophysiology +neuropsychiatric +neuropsychiatrically +neuropsychiatries +neuropsychiatrist +neuropsychiatrists +neuropsychiatry +neuropsychological +neuropsychologies +neuropsychologist +neuropsychologists +neuropsychology +neuropteran +neuropterans +neuropterous +neuroradiological +neuroradiologies +neuroradiologist +neuroradiologists +neuroradiology +neurosal +neuroscience +neurosciences +neuroscientific +neuroscientist +neuroscientists +neurosecretion +neurosecretions +neurosecretory +neurosensory +neuroses +neurosis +neurospora +neurosporas +neurosurgeon +neurosurgeons +neurosurgeries +neurosurgery +neurosurgical +neurotic +neurotically +neuroticism +neuroticisms +neurotics +neurotoxic +neurotoxicities +neurotoxicity +neurotoxin +neurotoxins +neurotransmission +neurotransmissions +neurotransmitter +neurotransmitters +neurotropic +neurula +neurulae +neurulas +neurulation +neurulations +neuston +neustons +neuter +neutered +neutering +neuters +neutral +neutralise +neutralised +neutralises +neutralising +neutralism +neutralisms +neutralist +neutralistic +neutralists +neutralities +neutrality +neutralization +neutralizations +neutralize +neutralized +neutralizer +neutralizers +neutralizes +neutralizing +neutrally +neutralness +neutralnesses +neutrals +neutrino +neutrinoless +neutrinos +neutron +neutronic +neutrons +neutrophil +neutrophilic +neutrophils +neve +never +nevermore +nevertheless +neves +nevi +nevoid +nevus +new +newborn +newborns +newcomer +newcomers +newel +newels +newer +newest +newfangled +newfangledness +newfanglednesses +newfound +newie +newies +newish +newly +newlywed +newlyweds +newmarket +newmarkets +newmown +newness +newnesses +news +newsagent +newsagents +newsboy +newsboys +newsbreak +newsbreaks +newscast +newscaster +newscasters +newscasts +newsdealer +newsdealers +newshawk +newshawks +newshound +newshounds +newsie +newsier +newsies +newsiest +newsiness +newsinesses +newsless +newsletter +newsletters +newsmagazine +newsmagazines +newsman +newsmen +newsmonger +newsmongers +newspaper +newspapered +newspapering +newspaperman +newspapermen +newspapers +newspaperwoman +newspaperwomen +newspeak +newspeaks +newspeople +newsperson +newspersons +newsprint +newsprints +newsreader +newsreaders +newsreel +newsreels +newsroom +newsrooms +newsstand +newsstands +newsweeklies +newsweekly +newswoman +newswomen +newsworthiness +newsworthinesses +newsworthy +newswriting +newswritings +newsy +newt +newton +newtons +newts +next +nextdoor +nexus +nexuses +ngultrum +ngultrums +ngwee +niacin +niacinamide +niacinamides +niacins +nialamide +nialamides +nib +nibbed +nibbing +nibble +nibbled +nibbler +nibblers +nibbles +nibbling +niblick +niblicks +niblike +nibs +nicad +nicads +niccolite +niccolites +nice +nicely +niceness +nicenesses +nicer +nicest +niceties +nicety +niche +niched +niches +niching +nick +nicked +nickel +nickeled +nickelic +nickeliferous +nickeling +nickelled +nickelling +nickelodeon +nickelodeons +nickels +nicker +nickered +nickering +nickers +nicking +nickle +nickled +nickles +nickling +nicknack +nicknacks +nickname +nicknamed +nicknamer +nicknamers +nicknames +nicknaming +nicks +nicol +nicols +nicotiana +nicotianas +nicotin +nicotinamide +nicotinamides +nicotine +nicotines +nicotinic +nicotins +nictate +nictated +nictates +nictating +nictitate +nictitated +nictitates +nictitating +nidal +nide +nided +nidering +niderings +nides +nidget +nidgets +nidi +nidicolous +nidification +nidifications +nidified +nidifies +nidifugous +nidify +nidifying +niding +nidus +niduses +niece +nieces +nielli +niellist +niellists +niello +nielloed +nielloing +niellos +nieve +nieves +nifedipine +nifedipines +niffer +niffered +niffering +niffers +niftier +nifties +niftiest +niftily +nifty +niggard +niggarded +niggarding +niggardliness +niggardlinesses +niggardly +niggards +nigger +niggers +niggle +niggled +niggler +nigglers +niggles +niggling +nigglingly +nigglings +nigh +nighed +nigher +nighest +nighing +nighness +nighnesses +nighs +night +nightcap +nightcaps +nightclothes +nightclub +nightclubbed +nightclubber +nightclubbers +nightclubbing +nightclubs +nightdress +nightdresses +nightfall +nightfalls +nightglow +nightglows +nightgown +nightgowns +nighthawk +nighthawks +nightie +nighties +nightingale +nightingales +nightjar +nightjars +nightless +nightlife +nightlifes +nightlong +nightly +nightmare +nightmares +nightmarish +nightmarishly +nights +nightscope +nightscopes +nightshade +nightshades +nightshirt +nightshirts +nightside +nightsides +nightspot +nightspots +nightstand +nightstands +nightstick +nightsticks +nighttime +nighttimes +nightwalker +nightwalkers +nighty +nigrified +nigrifies +nigrify +nigrifying +nigrosin +nigrosins +nihil +nihilism +nihilisms +nihilist +nihilistic +nihilists +nihilities +nihility +nihils +nil +nilgai +nilgais +nilgau +nilgaus +nilghai +nilghais +nilghau +nilghaus +nill +nilled +nilling +nills +nilpotent +nils +nim +nimbi +nimble +nimbleness +nimblenesses +nimbler +nimblest +nimbly +nimbostrati +nimbostratus +nimbus +nimbused +nimbuses +nimieties +nimiety +nimious +nimmed +nimming +nimrod +nimrods +nims +nincompoop +nincompooperies +nincompoopery +nincompoops +nine +ninebark +ninebarks +ninefold +ninepin +ninepins +nines +nineteen +nineteens +nineteenth +nineteenths +nineties +ninetieth +ninetieths +ninety +ninhydrin +ninhydrins +ninja +ninjas +ninnies +ninny +ninnyhammer +ninnyhammers +ninnyish +ninon +ninons +ninth +ninthly +ninths +niobate +niobates +niobic +niobium +niobiums +niobous +nip +nipa +nipas +nipped +nipper +nippers +nippier +nippiest +nippily +nippiness +nippinesses +nipping +nippingly +nipple +nippled +nipples +nippy +nips +nirvana +nirvanas +nirvanic +nisei +niseis +nisi +nisus +nit +nitchie +nitchies +nite +niter +niterie +niteries +niters +nitery +nites +nitid +nitinol +nitinols +niton +nitons +nitpick +nitpicked +nitpicker +nitpickers +nitpickier +nitpickiest +nitpicking +nitpicks +nitpicky +nitrate +nitrated +nitrates +nitrating +nitration +nitrations +nitrator +nitrators +nitre +nitres +nitric +nitrid +nitride +nitrided +nitrides +nitriding +nitrids +nitrification +nitrifications +nitrified +nitrifier +nitrifiers +nitrifies +nitrify +nitrifying +nitril +nitrile +nitriles +nitrils +nitrite +nitrites +nitro +nitrobenzene +nitrobenzenes +nitrocellulose +nitrocelluloses +nitrofuran +nitrofurans +nitrogen +nitrogenase +nitrogenases +nitrogenous +nitrogens +nitroglycerin +nitroglycerine +nitroglycerines +nitroglycerins +nitrolic +nitromethane +nitromethanes +nitroparaffin +nitroparaffins +nitros +nitrosamine +nitrosamines +nitroso +nitrosyl +nitrosyls +nitrous +nits +nittier +nittiest +nitty +nitwit +nitwits +nival +niveous +nix +nixe +nixed +nixes +nixie +nixies +nixing +nixy +nizam +nizamate +nizamates +nizams +no +nob +nobbier +nobbiest +nobbily +nobble +nobbled +nobbler +nobblers +nobbles +nobbling +nobby +nobelium +nobeliums +nobilities +nobility +noble +nobleman +noblemen +nobleness +noblenesses +nobler +nobles +noblesse +noblesses +noblest +noblewoman +noblewomen +nobly +nobodies +nobody +nobs +nocent +nociceptive +nock +nocked +nocking +nocks +noctambulist +noctambulists +noctuid +noctuids +noctule +noctules +noctuoid +nocturn +nocturnal +nocturnally +nocturne +nocturnes +nocturns +nocuous +nocuously +nod +nodal +nodalities +nodality +nodally +nodded +nodder +nodders +noddies +nodding +noddle +noddled +noddles +noddling +noddy +node +nodes +nodi +nodical +nodose +nodosities +nodosity +nodous +nods +nodular +nodulation +nodulations +nodule +nodules +nodulose +nodulous +nodus +noel +noels +noes +noesis +noesises +noetic +nog +nogg +nogged +noggin +nogging +noggings +noggins +noggs +nogs +noh +nohow +noil +noils +noily +noir +noirish +noirs +noise +noised +noiseless +noiselessly +noisemaker +noisemakers +noisemaking +noisemakings +noises +noisette +noisettes +noisier +noisiest +noisily +noisiness +noisinesses +noising +noisome +noisomely +noisomeness +noisomenesses +noisy +nolo +nolos +nom +noma +nomad +nomadic +nomadism +nomadisms +nomads +nomarch +nomarchies +nomarchs +nomarchy +nomas +nombles +nombril +nombrils +nome +nomen +nomenclator +nomenclatorial +nomenclators +nomenclatural +nomenclature +nomenclatures +nomes +nomina +nominal +nominalism +nominalisms +nominalist +nominalistic +nominalists +nominally +nominals +nominate +nominated +nominates +nominating +nomination +nominations +nominative +nominatives +nominator +nominators +nominee +nominees +nomism +nomisms +nomistic +nomogram +nomograms +nomograph +nomographic +nomographies +nomographs +nomography +nomoi +nomological +nomologies +nomology +nomos +nomothetic +noms +nona +nonabrasive +nonabsorbable +nonabsorbent +nonabsorbents +nonabsorptive +nonabstract +nonacademic +nonacademics +nonacceptance +nonacceptances +nonaccountable +nonaccredited +nonaccrual +nonachievement +nonachievements +nonacid +nonacidic +nonacids +nonacquisitive +nonacting +nonaction +nonactions +nonactivated +nonactor +nonactors +nonadaptive +nonaddict +nonaddictive +nonaddicts +nonadditive +nonadditivities +nonadditivity +nonadhesive +nonadiabatic +nonadjacent +nonadmirer +nonadmirers +nonadmission +nonadmissions +nonadult +nonadults +nonaesthetic +nonaffiliated +nonaffluent +nonage +nonagenarian +nonagenarians +nonages +nonaggression +nonaggressions +nonaggressive +nonagon +nonagons +nonagricultural +nonalcoholic +nonalcoholics +nonaligned +nonalignment +nonalignments +nonallelic +nonallergenic +nonallergic +nonalphabetic +nonaluminum +nonambiguous +nonanalytic +nonanatomic +nonanimal +nonanswer +nonanswers +nonantagonistic +nonanthropological +nonanthropologist +nonanthropologists +nonantibiotic +nonantibiotics +nonantigenic +nonappearance +nonappearances +nonaquatic +nonaqueous +nonarable +nonarbitrariness +nonarbitrarinesses +nonarbitrary +nonarchitect +nonarchitects +nonarchitecture +nonarchitectures +nonargument +nonarguments +nonaristocratic +nonaromatic +nonart +nonartist +nonartistic +nonartists +nonarts +nonas +nonascetic +nonascetics +nonaspirin +nonaspirins +nonassertive +nonassociated +nonastronomical +nonathlete +nonathletes +nonathletic +nonatomic +nonattached +nonattachment +nonattachments +nonattendance +nonattendances +nonattender +nonattenders +nonauditory +nonauthor +nonauthoritarian +nonauthors +nonautomated +nonautomatic +nonautomotive +nonautonomous +nonavailabilities +nonavailability +nonbacterial +nonbank +nonbanking +nonbanks +nonbarbiturate +nonbarbiturates +nonbasic +nonbearing +nonbehavioral +nonbeing +nonbeings +nonbelief +nonbeliefs +nonbeliever +nonbelievers +nonbelligerencies +nonbelligerency +nonbelligerent +nonbelligerents +nonbetting +nonbibliographic +nonbinary +nonbinding +nonbiodegradable +nonbiodegradables +nonbiographical +nonbiological +nonbiologically +nonbiologist +nonbiologists +nonbiting +nonblack +nonblacks +nonbodies +nonbody +nonbonded +nonbonding +nonbook +nonbooks +nonbotanist +nonbotanists +nonbrand +nonbreakable +nonbreathing +nonbreeder +nonbreeders +nonbreeding +nonbreedings +nonbroadcast +nonbroadcasts +nonbuilding +nonbuildings +nonburnable +nonbusiness +nonbuying +noncabinet +noncabinets +noncaking +noncallable +noncaloric +noncampus +noncancelable +noncancerous +noncandidacies +noncandidacy +noncandidate +noncandidates +noncannibalistic +noncapital +noncapitalist +noncapitalists +noncapitals +noncarcinogen +noncarcinogenic +noncarcinogens +noncardiac +noncareer +noncarrier +noncarriers +noncash +noncasual +noncausal +nonce +noncelebration +noncelebrations +noncelebrities +noncelebrity +noncellular +noncellulosic +noncentral +noncertificated +noncertified +nonces +nonchalance +nonchalances +nonchalant +nonchalantly +noncharacter +noncharacters +noncharismatic +nonchauvinist +nonchauvinists +nonchemical +nonchemicals +nonchromosomal +nonchronological +nonchurch +nonchurchgoer +nonchurchgoers +noncircular +noncirculating +noncitizen +noncitizens +nonclandestine +nonclass +nonclasses +nonclassical +nonclassified +nonclassroom +nonclassrooms +nonclerical +nonclericals +noncling +nonclinical +nonclogging +noncoercive +noncognitive +noncoherent +noncoincidence +noncoincidences +noncoital +noncoking +noncola +noncollector +noncollectors +noncollege +noncolleges +noncollegiate +noncollinear +noncolor +noncolored +noncolorfast +noncolors +noncom +noncombat +noncombatant +noncombatants +noncombative +noncombustible +noncombustibles +noncommercial +noncommercials +noncommitment +noncommitments +noncommittal +noncommittally +noncommitted +noncommunicating +noncommunication +noncommunications +noncommunicative +noncommunist +noncommunists +noncommunities +noncommunity +noncommutative +noncommutativities +noncommutativity +noncomparabilities +noncomparability +noncomparable +noncompatible +noncompetition +noncompetitive +noncompetitor +noncompetitors +noncomplementary +noncomplex +noncompliance +noncompliances +noncompliant +noncomplicated +noncomplying +noncomplyings +noncomposer +noncomposers +noncompound +noncompounds +noncomprehension +noncomprehensions +noncompressible +noncomputer +noncomputerized +noncoms +nonconceptual +nonconcern +nonconcerns +nonconclusion +nonconclusions +nonconcur +nonconcurred +nonconcurrence +nonconcurrences +nonconcurrent +nonconcurring +nonconcurs +noncondensable +nonconditioned +nonconducting +nonconduction +nonconductions +nonconductive +nonconductor +nonconductors +nonconference +nonconferences +nonconfidence +nonconfidences +nonconfidential +nonconflicting +nonconform +nonconformance +nonconformances +nonconformed +nonconformer +nonconformers +nonconforming +nonconformism +nonconformisms +nonconformist +nonconformists +nonconformities +nonconformity +nonconforms +nonconfrontation +nonconfrontational +nonconfrontations +noncongruent +nonconjugated +nonconnection +nonconnections +nonconscious +nonconsecutive +nonconsensual +nonconservation +nonconservations +nonconservative +nonconservatives +nonconsolidated +nonconstant +nonconstants +nonconstitutional +nonconstruction +nonconstructions +nonconstructive +nonconsumer +nonconsumers +nonconsuming +nonconsumption +nonconsumptions +nonconsumptive +noncontact +noncontacts +noncontagious +noncontemporaries +noncontemporary +noncontiguous +noncontingent +noncontinuous +noncontract +noncontractual +noncontradiction +noncontradictions +noncontradictory +noncontributory +noncontrollable +noncontrolled +noncontrolling +noncontroversial +nonconventional +nonconvertible +noncooperation +noncooperationist +noncooperationists +noncooperations +noncooperative +noncooperator +noncooperators +noncoplanar +noncorporate +noncorrelation +noncorrelations +noncorrodible +noncorroding +noncorrodings +noncorrosive +noncountries +noncountry +noncounty +noncoverage +noncoverages +noncreative +noncreativities +noncreativity +noncredentialed +noncredit +noncrime +noncrimes +noncriminal +noncriminals +noncrises +noncrisis +noncritical +noncrossover +noncrushable +noncrystalline +nonculinary +noncultivated +noncultivation +noncultivations +noncultural +noncumulative +noncurrent +noncustodial +noncustomer +noncustomers +noncyclic +noncyclical +nondairy +nondance +nondancer +nondancers +nondances +nondeceptive +nondecision +nondecisions +nondecreasing +nondeductibilities +nondeductibility +nondeductible +nondeductive +nondefense +nondeferrable +nondeforming +nondegenerate +nondegenerates +nondegradable +nondegradables +nondegree +nondelegate +nondelegates +nondeliberate +nondelinquent +nondeliveries +nondelivery +nondemanding +nondemocratic +nondenominational +nondenominationalism +nondenominationalisms +nondepartmental +nondependent +nondependents +nondepletable +nondepleting +nondeposition +nondepositions +nondepressed +nonderivative +nonderivatives +nondescript +nondescriptive +nondescripts +nondesert +nondestructive +nondestructively +nondestructiveness +nondestructivenesses +nondetachable +nondeterministic +nondevelopment +nondevelopments +nondeviant +nondeviants +nondiabetic +nondiabetics +nondialyzable +nondiapausing +nondidactic +nondiffusible +nondimensional +nondiplomatic +nondirected +nondirectional +nondirective +nondisabled +nondisableds +nondisclosure +nondisclosures +nondiscount +nondiscretionary +nondiscrimination +nondiscriminations +nondiscriminatory +nondiscursive +nondisjunction +nondisjunctional +nondisjunctions +nondispersive +nondisruptive +nondistinctive +nondiversified +nondividing +nondoctor +nondoctors +nondoctrinaire +nondocumentaries +nondocumentary +nondogmatic +nondollar +nondomestic +nondomestics +nondominant +nondominants +nondormant +nondramatic +nondrinker +nondrinkers +nondrinking +nondriver +nondrivers +nondrug +nondurable +nondurables +none +nonearning +nonearnings +nonecclesiastical +noneconomic +noneconomist +noneconomists +nonedible +noneditorial +noneducation +noneducational +noneducations +noneffective +noneffectives +nonego +nonegos +nonelastic +nonelect +nonelected +nonelection +nonelections +nonelective +nonelectives +nonelectric +nonelectrical +nonelectrics +nonelectrolyte +nonelectrolytes +nonelectronic +nonelectronics +nonelementary +nonelite +nonemergencies +nonemergency +nonemotional +nonemphatic +nonempirical +nonemployee +nonemployees +nonemployment +nonemployments +nonempty +nonencapsulated +nonending +nonenergy +nonenforceabilities +nonenforceability +nonenforcement +nonenforcements +nonengagement +nonengagements +nonengineering +nonengineerings +nonentertainment +nonentertainments +nonentities +nonentity +nonentries +nonentry +nonenzymatic +nonenzymic +nonequal +nonequals +nonequilibria +nonequilibrium +nonequilibriums +nonequivalence +nonequivalences +nonequivalent +nonequivalents +nonerotic +nones +nonessential +nonessentials +nonestablished +nonestablishment +nonestablishments +nonesterified +nonesuch +nonesuches +nonet +nonetheless +nonethical +nonethnic +nonets +nonevaluative +nonevent +nonevents +nonevidence +nonevidences +nonexclusive +nonexecutive +nonexecutives +nonexempt +nonexistence +nonexistences +nonexistent +nonexistential +nonexotic +nonexpendable +nonexperimental +nonexpert +nonexperts +nonexplanatory +nonexploitation +nonexploitations +nonexploitative +nonexploitive +nonexplosive +nonexplosives +nonexposed +nonextant +nonfact +nonfactor +nonfactors +nonfacts +nonfactual +nonfaculty +nonfading +nonfamilial +nonfamilies +nonfamily +nonfan +nonfans +nonfarm +nonfarmer +nonfarmers +nonfat +nonfatal +nonfattening +nonfatty +nonfeasance +nonfeasances +nonfederal +nonfederated +nonfeminist +nonfeminists +nonferrous +nonfiction +nonfictional +nonfictions +nonfigurative +nonfilamentous +nonfilterable +nonfinal +nonfinancial +nonfinite +nonfissionable +nonflammability +nonflammable +nonflowering +nonfluencies +nonfluency +nonfluid +nonfluids +nonfluorescent +nonflying +nonfocal +nonfood +nonforfeitable +nonforfeiture +nonforfeitures +nonformal +nonfossil +nonfraternization +nonfraternizations +nonfreezing +nonfrivolous +nonfrozen +nonfuel +nonfulfillment +nonfulfillments +nonfunctional +nonfunctioning +nongame +nongaseous +nongay +nongays +nongenetic +nongenital +nongeometrical +nonghetto +nonglamorous +nonglare +nongolfer +nongolfers +nongonococcal +nongovernment +nongovernmental +nongovernments +nongraded +nongraduate +nongraduates +nongrammatical +nongranular +nongravitational +nongreasy +nongreen +nongregarious +nongrowing +nongrowth +nonguest +nonguests +nonguilt +nonguilts +nonhalogenated +nonhandicapped +nonhappening +nonhappenings +nonhardy +nonharmonic +nonhazardous +nonheme +nonhemolytic +nonhereditary +nonhero +nonheroes +nonhierarchical +nonhistone +nonhistorical +nonhome +nonhomogeneous +nonhomologous +nonhomosexual +nonhomosexuals +nonhormonal +nonhospital +nonhospitalized +nonhospitals +nonhostile +nonhousing +nonhousings +nonhuman +nonhunter +nonhunters +nonhunting +nonhygroscopic +nonhysterical +nonideal +nonidentical +nonidentities +nonidentity +nonideological +nonillion +nonillions +nonimage +nonimitative +nonimmigrant +nonimmigrants +nonimmune +nonimpact +nonimplication +nonimplications +nonimportation +nonimportations +noninclusion +noninclusions +nonincreasing +nonincumbent +nonincumbents +nonindependence +nonindependences +nonindigenous +nonindividual +noninductive +nonindustrial +nonindustrialized +nonindustry +noninfected +noninfectious +noninfective +noninfested +noninflammable +noninflammatory +noninflationary +noninflectional +noninfluence +noninfluences +noninformation +noninformations +noninitial +noninitiate +noninitiates +noninjury +noninsect +noninsecticidal +noninsects +noninstallment +noninstitutional +noninstitutionalized +noninstructional +noninstrumental +noninsurance +noninsurances +noninsured +nonintegral +nonintegrated +nonintellectual +nonintellectuals +noninteracting +noninteractive +noninterchangeable +nonintercourse +nonintercourses +noninterest +noninterests +noninterference +noninterferences +nonintersecting +nonintervention +noninterventionist +noninterventionists +noninterventions +nonintimidating +nonintoxicant +nonintoxicating +nonintrusive +nonintuitive +noninvasive +noninvolved +noninvolvement +noninvolvements +nonionic +nonionizing +noniron +nonirradiated +nonirrigated +nonirritant +nonirritating +nonissue +nonissues +nonjoinder +nonjoinders +nonjoiner +nonjoiners +nonjudgmental +nonjudicial +nonjuring +nonjuror +nonjurors +nonjury +nonjusticiable +nonkosher +nonlabor +nonlandowner +nonlandowners +nonlanguage +nonlanguages +nonlawyer +nonlawyers +nonleaded +nonleafy +nonleague +nonlegal +nonlegume +nonlegumes +nonleguminous +nonlethal +nonlexical +nonlibrarian +nonlibrarians +nonlibraries +nonlibrary +nonlife +nonlineal +nonlinear +nonlinearities +nonlinearity +nonlinguistic +nonliquid +nonliquids +nonliteral +nonliterary +nonliterate +nonliterates +nonlives +nonliving +nonlocal +nonlocals +nonlogical +nonluminous +nonmagnetic +nonmainstream +nonmajor +nonmajors +nonmalignant +nonmalleable +nonman +nonmanagement +nonmanagements +nonmanagerial +nonmanual +nonmanufacturing +nonmanufacturings +nonmarital +nonmarket +nonmaterial +nonmaterialistic +nonmathematical +nonmathematician +nonmathematicians +nonmatriculated +nonmeaningful +nonmeasurable +nonmeat +nonmechanical +nonmechanistic +nonmedical +nonmeeting +nonmeetings +nonmember +nonmembers +nonmembership +nonmemberships +nonmen +nonmental +nonmercurial +nonmetal +nonmetallic +nonmetals +nonmetameric +nonmetaphorical +nonmetric +nonmetrical +nonmetro +nonmetropolitan +nonmetropolitans +nonmicrobial +nonmigrant +nonmigrants +nonmigratory +nonmilitant +nonmilitants +nonmilitary +nonmimetic +nonminority +nonmobile +nonmodal +nonmolecular +nonmonetarist +nonmonetarists +nonmonetary +nonmoney +nonmonogamous +nonmoral +nonmotile +nonmotilities +nonmotility +nonmotorized +nonmoving +nonmunicipal +nonmusic +nonmusical +nonmusician +nonmusicians +nonmusics +nonmutant +nonmutants +nonmyelinated +nonmystical +nonnarrative +nonnarratives +nonnational +nonnationals +nonnative +nonnatives +nonnatural +nonnaval +nonnecessities +nonnecessity +nonnegative +nonnegligent +nonnegotiable +nonnetwork +nonnews +nonnitrogenous +nonnormative +nonnovel +nonnovels +nonnuclear +nonnucleated +nonnumerical +nonnumericals +nonnutritious +nonnutritive +nonobese +nonobjective +nonobjectivism +nonobjectivisms +nonobjectivist +nonobjectivists +nonobjectivities +nonobjectivity +nonobscene +nonobservance +nonobservances +nonobservant +nonobvious +nonoccupational +nonoccurrence +nonoccurrences +nonofficial +nonohmic +nonoily +nonoperatic +nonoperating +nonoperational +nonoperative +nonoptimal +nonorganic +nonorgasmic +nonorthodox +nonoverlapping +nonoverlappings +nonowner +nonowners +nonoxidizing +nonpagan +nonpagans +nonpaid +nonpapal +nonpar +nonparallel +nonparallels +nonparametric +nonparasitic +nonpareil +nonpareils +nonparticipant +nonparticipants +nonparticipating +nonparticipation +nonparticipations +nonparticipatory +nonpartisan +nonpartisans +nonpartisanship +nonpartisanships +nonparty +nonpasserine +nonpassive +nonpast +nonpasts +nonpathogenic +nonpaying +nonpayment +nonpayments +nonpeak +nonperformance +nonperformances +nonperformer +nonperformers +nonperforming +nonperishable +nonperishables +nonpermissive +nonpersistent +nonperson +nonpersonal +nonpersons +nonpetroleum +nonpetroleums +nonphilosopher +nonphilosophers +nonphilosophical +nonphonemic +nonphonetic +nonphosphate +nonphosphates +nonphotographic +nonphysical +nonphysician +nonphysicians +nonplanar +nonplastic +nonplastics +nonplay +nonplaying +nonplays +nonplus +nonplused +nonpluses +nonplusing +nonplussed +nonplusses +nonplussing +nonpoetic +nonpoint +nonpoisonous +nonpolar +nonpolarizable +nonpolice +nonpolitical +nonpolitically +nonpolitician +nonpoliticians +nonpolluting +nonpoor +nonporous +nonpossession +nonpossessions +nonpractical +nonpracticing +nonpregnant +nonprescription +nonprint +nonproblem +nonproblems +nonproducing +nonproductive +nonproductiveness +nonproductivenesses +nonprofessional +nonprofessionally +nonprofessionals +nonprofessorial +nonprofit +nonprofits +nonprogram +nonprogrammer +nonprogrammers +nonprograms +nonprogressive +nonprogressives +nonproliferation +nonproliferations +nonproprietaries +nonproprietary +nonpros +nonprossed +nonprosses +nonprossing +nonprotein +nonpsychiatric +nonpsychiatrist +nonpsychiatrists +nonpsychological +nonpsychotic +nonpublic +nonpunitive +nonpurposive +nonquantifiable +nonquantitative +nonquota +nonracial +nonracially +nonradioactive +nonrailroad +nonrandom +nonrandomness +nonrandomnesses +nonrated +nonrational +nonreactive +nonreactor +nonreactors +nonreader +nonreaders +nonreading +nonrealistic +nonreappointment +nonreappointments +nonreceipt +nonreceipts +nonreciprocal +nonreciprocals +nonrecognition +nonrecognitions +nonrecombinant +nonrecombinants +nonrecourse +nonrecurrent +nonrecurring +nonrecyclable +nonrecyclables +nonreducing +nonredundant +nonrefillable +nonreflecting +nonrefundable +nonregulated +nonregulation +nonregulations +nonrelative +nonrelatives +nonrelativistic +nonrelativistically +nonrelevant +nonreligious +nonrenewable +nonrenewal +nonrenewals +nonrepayable +nonrepresentational +nonrepresentationalism +nonrepresentationalisms +nonrepresentative +nonrepresentatives +nonreproducible +nonreproductive +nonresidence +nonresidences +nonresidencies +nonresidency +nonresident +nonresidential +nonresidents +nonresistance +nonresistances +nonresistant +nonresistants +nonresonant +nonrespondent +nonrespondents +nonresponder +nonresponders +nonresponse +nonresponses +nonresponsive +nonrestricted +nonrestrictive +nonretractile +nonretroactive +nonreturnable +nonreturnables +nonreusable +nonreusables +nonreversible +nonrevolutionaries +nonrevolutionary +nonrigid +nonrioter +nonrioters +nonrioting +nonrival +nonrivals +nonrotating +nonroutine +nonroutines +nonroyal +nonrubber +nonruling +nonruminant +nonruminants +nonrural +nonsalable +nonsaline +nonsaponifiable +nonscheduled +nonschizophrenic +nonschool +nonscience +nonsciences +nonscientific +nonscientist +nonscientists +nonseasonal +nonsecretor +nonsecretories +nonsecretors +nonsecretory +nonsectarian +nonsecure +nonsedimentable +nonsegregated +nonsegregation +nonsegregations +nonselected +nonselective +nonself +nonselves +nonsensational +nonsense +nonsenses +nonsensical +nonsensically +nonsensicalness +nonsensicalnesses +nonsensitive +nonsensuous +nonsentence +nonsentences +nonseptate +nonsequential +nonserious +nonsexist +nonsexual +nonshrink +nonshrinkable +nonsigner +nonsigners +nonsignificant +nonsignificantly +nonsimultaneous +nonsinkable +nonskater +nonskaters +nonsked +nonskeds +nonskeletal +nonskid +nonskier +nonskiers +nonslip +nonsmoker +nonsmokers +nonsmoking +nonsocial +nonsocialist +nonsocialists +nonsolar +nonsolid +nonsolids +nonsolution +nonsolutions +nonspatial +nonspeaker +nonspeakers +nonspeaking +nonspecialist +nonspecialists +nonspecific +nonspecifically +nonspectacular +nonspeculative +nonspeech +nonspherical +nonsporting +nonstandard +nonstarter +nonstarters +nonstationaries +nonstationary +nonstatistical +nonsteady +nonsteroid +nonsteroidal +nonsteroids +nonstick +nonstop +nonstories +nonstory +nonstrategic +nonstructural +nonstructured +nonstudent +nonstudents +nonstyle +nonstyles +nonsubject +nonsubjective +nonsubjects +nonsubsidized +nonsuccess +nonsuccesses +nonsuch +nonsuches +nonsugar +nonsugars +nonsuit +nonsuited +nonsuiting +nonsuits +nonsuperimposable +nonsupervisory +nonsupport +nonsupports +nonsurgical +nonswimmer +nonswimmers +nonsyllabic +nonsymbolic +nonsymmetric +nonsymmetrical +nonsynchronous +nonsystem +nonsystematic +nonsystemic +nonsystems +nontarget +nontariff +nontax +nontaxable +nontaxables +nontaxes +nonteaching +nontechnical +nontemporal +nontemporals +nontenured +nonterminal +nonterminating +nontheatrical +nontheist +nontheistic +nontheists +nontheological +nontheoretical +nontherapeutic +nonthermal +nonthinking +nonthinkings +nonthreatening +nontidal +nontitle +nontobacco +nontobaccos +nontonal +nontotalitarian +nontoxic +nontraditional +nontransferable +nontreatment +nontreatments +nontrivial +nontropical +nontrump +nontruth +nontruths +nonturbulent +nontypical +nonunanimous +nonuniform +nonuniformities +nonuniformity +nonunion +nonunionized +nonunions +nonunique +nonuniqueness +nonuniquenesses +nonuniversal +nonuniversals +nonuniversities +nonuniversity +nonuple +nonuples +nonurban +nonurgent +nonuse +nonuser +nonusers +nonuses +nonusing +nonutilitarian +nonutilitarians +nonutilities +nonutility +nonutopian +nonvalid +nonvalidities +nonvalidity +nonvanishing +nonvascular +nonvector +nonvectors +nonvegetarian +nonvegetarians +nonvenomous +nonverbal +nonverbally +nonveteran +nonveterans +nonviable +nonviewer +nonviewers +nonvintage +nonviolence +nonviolences +nonviolent +nonviolently +nonviral +nonvirgin +nonvirgins +nonviscous +nonvisual +nonvocal +nonvocational +nonvolatile +nonvolcanic +nonvoluntary +nonvoter +nonvoters +nonvoting +nonwar +nonwars +nonwhite +nonwhites +nonwinning +nonwoody +nonword +nonwords +nonwork +nonworker +nonworkers +nonworking +nonwoven +nonwovens +nonwriter +nonwriters +nonyellowing +nonyl +nonyls +nonzero +noo +noodge +noodged +noodges +noodging +noodle +noodled +noodles +noodling +nook +nookies +nooklike +nooks +nooky +noon +noonday +noondays +nooning +noonings +noons +noontide +noontides +noontime +noontimes +noose +noosed +nooser +noosers +nooses +noosing +noosphere +noospheres +nopal +nopals +nope +nor +noradrenalin +noradrenaline +noradrenalines +noradrenalins +noradrenergic +nordic +norepinephrine +norepinephrines +norethindrone +norethindrones +nori +noria +norias +noris +norite +norites +noritic +norland +norlands +norm +normal +normalcies +normalcy +normalise +normalised +normalises +normalising +normalities +normality +normalizable +normalization +normalizations +normalize +normalized +normalizer +normalizers +normalizes +normalizing +normally +normals +normande +normative +normatively +normativeness +normativenesses +normed +normless +normotensive +normotensives +normothermia +normothermias +normothermic +norms +north +northbound +northeast +northeaster +northeasterly +northeastern +northeasternmost +northeasters +northeasts +northeastward +northeastwards +norther +northerlies +northerly +northern +northerner +northerners +northernmost +northerns +northers +northing +northings +northland +northlands +norths +northward +northwards +northwest +northwester +northwesterly +northwestern +northwesternmost +northwesters +northwests +northwestward +northwestwards +nortriptyline +nortriptylines +nos +nose +nosebag +nosebags +noseband +nosebands +nosebleed +nosebleeds +nosed +nosedive +nosedives +nosegay +nosegays +noseguard +noseguards +noseless +noselike +nosepiece +nosepieces +noses +nosewheel +nosewheels +nosey +nosh +noshed +nosher +noshers +noshes +noshing +nosier +nosiest +nosily +nosiness +nosinesses +nosing +nosings +nosocomial +nosologic +nosological +nosologically +nosologies +nosology +nostalgia +nostalgias +nostalgic +nostalgically +nostalgics +nostalgist +nostalgists +nostoc +nostocs +nostril +nostrils +nostrum +nostrums +nosy +not +nota +notabilities +notability +notable +notableness +notablenesses +notables +notably +notal +notarial +notarially +notaries +notarization +notarizations +notarize +notarized +notarizes +notarizing +notary +notate +notated +notates +notating +notation +notational +notations +notch +notchback +notchbacks +notched +notcher +notchers +notches +notching +note +notebook +notebooks +notecase +notecases +noted +notedly +notedness +notednesses +noteless +notepad +notepads +notepaper +notepapers +noter +noters +notes +noteworthily +noteworthiness +noteworthinesses +noteworthy +nother +nothing +nothingness +nothingnesses +nothings +notice +noticeable +noticeably +noticed +noticer +noticers +notices +noticing +notifiable +notification +notifications +notified +notifier +notifiers +notifies +notify +notifying +noting +notion +notional +notionalities +notionality +notionally +notions +notochord +notochordal +notochords +notorieties +notoriety +notorious +notoriously +notornis +notturni +notturno +notum +notwithstanding +nougat +nougats +nought +noughts +noumena +noumenal +noumenon +noun +nounal +nounally +nounless +nouns +nourish +nourished +nourisher +nourishers +nourishes +nourishing +nourishment +nourishments +nous +nouses +nouveau +nouvelle +nova +novaculite +novaculites +novae +novalike +novas +novation +novations +novel +novelette +novelettes +novelettish +novelise +novelised +novelises +novelising +novelist +novelistic +novelistically +novelists +novelization +novelizations +novelize +novelized +novelizes +novelizing +novella +novellas +novelle +novelly +novels +novelties +novelty +novemdecillion +novemdecillions +novena +novenae +novenas +novercal +novice +novices +novitiate +novitiates +novobiocin +novobiocins +novocaine +novocaines +now +nowadays +noway +noways +nowhere +nowheres +nowhither +nowise +nowness +nownesses +nows +nowt +nowts +noxious +noxiously +noxiousness +noxiousnesses +noyade +noyades +nozzle +nozzles +nth +nu +nuance +nuanced +nuances +nub +nubbier +nubbiest +nubbin +nubbins +nubble +nubbles +nubblier +nubbliest +nubbly +nubby +nubia +nubias +nubile +nubilities +nubility +nubilose +nubilous +nubs +nucellar +nucelli +nucellus +nucha +nuchae +nuchal +nuchals +nucleal +nuclear +nuclease +nucleases +nucleate +nucleated +nucleates +nucleating +nucleation +nucleations +nucleator +nucleators +nuclei +nuclein +nucleins +nucleocapsid +nucleocapsids +nucleoid +nucleoids +nucleolar +nucleole +nucleoles +nucleoli +nucleolus +nucleon +nucleonic +nucleonics +nucleons +nucleophile +nucleophiles +nucleophilic +nucleophilically +nucleophilicities +nucleophilicity +nucleoplasm +nucleoplasmic +nucleoplasms +nucleoprotein +nucleoproteins +nucleoside +nucleosides +nucleosomal +nucleosome +nucleosomes +nucleosyntheses +nucleosynthesis +nucleosynthetic +nucleotidase +nucleotidases +nucleotide +nucleotides +nucleus +nucleuses +nuclide +nuclides +nuclidic +nude +nudely +nudeness +nudenesses +nuder +nudes +nudest +nudge +nudged +nudger +nudgers +nudges +nudging +nudibranch +nudibranchs +nudicaul +nudie +nudies +nudism +nudisms +nudist +nudists +nudities +nudity +nudnick +nudnicks +nudnik +nudniks +nudzh +nudzhed +nudzhes +nudzhing +nugatory +nugget +nuggets +nuggety +nuisance +nuisances +nuke +nuked +nukes +nuking +null +nullah +nullahs +nulled +nullification +nullificationist +nullificationists +nullifications +nullified +nullifier +nullifiers +nullifies +nullify +nullifying +nulling +nulliparous +nullities +nullity +nulls +numb +numbat +numbats +numbed +number +numberable +numbered +numberer +numberers +numbering +numberless +numbers +numbest +numbfish +numbfishes +numbing +numbingly +numbles +numbly +numbness +numbnesses +numbs +numbskull +numbskulls +numen +numerable +numeracies +numeracy +numeral +numerally +numerals +numerary +numerate +numerated +numerates +numerating +numeration +numerations +numerator +numerators +numeric +numerical +numerically +numerics +numerological +numerologies +numerologist +numerologists +numerology +numerous +numerously +numerousness +numerousnesses +numina +numinous +numinouses +numinousness +numinousnesses +numismatic +numismatically +numismatics +numismatist +numismatists +nummary +nummular +numskull +numskulls +nun +nunatak +nunataks +nunchaku +nunchakus +nunciature +nunciatures +nuncio +nuncios +nuncle +nuncles +nuncupative +nunlike +nunneries +nunnery +nunnish +nuns +nuptial +nuptialities +nuptiality +nuptials +nurd +nurds +nurl +nurled +nurling +nurls +nurse +nursed +nursemaid +nursemaids +nurser +nurseries +nursers +nursery +nurseryman +nurserymen +nurses +nursing +nursings +nursling +nurslings +nurtural +nurturance +nurturances +nurturant +nurture +nurtured +nurturer +nurturers +nurtures +nurturing +nus +nut +nutant +nutate +nutated +nutates +nutating +nutation +nutational +nutations +nutbrown +nutcase +nutcases +nutcracker +nutcrackers +nutgall +nutgalls +nutgrass +nutgrasses +nuthatch +nuthatches +nuthouse +nuthouses +nutlet +nutlets +nutlike +nutmeat +nutmeats +nutmeg +nutmegs +nutpick +nutpicks +nutria +nutrias +nutrient +nutrients +nutriment +nutriments +nutrition +nutritional +nutritionally +nutritionist +nutritionists +nutritions +nutritious +nutritiously +nutritiousness +nutritiousnesses +nutritive +nutritively +nuts +nutsedge +nutsedges +nutshell +nutshells +nutsier +nutsiest +nutsy +nutted +nutter +nutters +nuttier +nuttiest +nuttily +nuttiness +nuttinesses +nutting +nuttings +nutty +nutwood +nutwoods +nuzzle +nuzzled +nuzzler +nuzzlers +nuzzles +nuzzling +nyala +nyalas +nyctalopia +nyctalopias +nylghai +nylghais +nylghau +nylghaus +nylon +nylons +nymph +nympha +nymphae +nymphal +nymphalid +nymphalids +nymphean +nymphet +nymphets +nymphette +nymphettes +nympho +nympholepsies +nympholepsy +nympholept +nympholeptic +nympholepts +nymphomania +nymphomaniac +nymphomaniacal +nymphomaniacs +nymphomanias +nymphos +nymphs +nystagmic +nystagmus +nystagmuses +nystatin +nystatins +oaf +oafish +oafishly +oafishness +oafishnesses +oafs +oak +oaken +oaklike +oakmoss +oakmosses +oaks +oakum +oakums +oar +oared +oarfish +oarfishes +oaring +oarless +oarlike +oarlock +oarlocks +oars +oarsman +oarsmanship +oarsmanships +oarsmen +oarswoman +oarswomen +oases +oasis +oast +oasthouse +oasthouses +oasts +oat +oatcake +oatcakes +oaten +oater +oaters +oath +oaths +oatlike +oatmeal +oatmeals +oats +oaves +obbligati +obbligato +obbligatos +obconic +obcordate +obduracies +obduracy +obdurate +obdurately +obdurateness +obduratenesses +obe +obeah +obeahism +obeahisms +obeahs +obedience +obediences +obedient +obediently +obeisance +obeisances +obeisant +obeisantly +obeli +obelia +obelias +obelise +obelised +obelises +obelising +obelisk +obelisks +obelism +obelisms +obelize +obelized +obelizes +obelizing +obelus +obes +obese +obesely +obesities +obesity +obey +obeyable +obeyed +obeyer +obeyers +obeying +obeys +obfuscate +obfuscated +obfuscates +obfuscating +obfuscation +obfuscations +obfuscatory +obi +obia +obias +obiism +obiisms +obis +obit +obits +obituaries +obituarist +obituarists +obituary +object +objected +objectification +objectifications +objectified +objectifies +objectify +objectifying +objecting +objection +objectionable +objectionableness +objectionablenesses +objectionably +objections +objective +objectively +objectiveness +objectivenesses +objectives +objectivism +objectivisms +objectivist +objectivistic +objectivists +objectivities +objectivity +objectless +objectlessness +objectlessnesses +objector +objectors +objects +objet +objets +objurgate +objurgated +objurgates +objurgating +objurgation +objurgations +objurgatory +oblanceolate +oblast +oblasti +oblasts +oblate +oblately +oblateness +oblatenesses +oblates +oblation +oblations +oblatory +obligate +obligated +obligately +obligates +obligati +obligating +obligation +obligations +obligato +obligatorily +obligatory +obligatos +oblige +obliged +obligee +obligees +obliger +obligers +obliges +obliging +obligingly +obligingness +obligingnesses +obligor +obligors +oblique +obliqued +obliquely +obliqueness +obliquenesses +obliques +obliquing +obliquities +obliquity +obliterate +obliterated +obliterates +obliterating +obliteration +obliterations +obliterative +obliterator +obliterators +oblivion +oblivions +oblivious +obliviously +obliviousness +obliviousnesses +oblong +oblongly +oblongs +obloquies +obloquy +obnoxious +obnoxiously +obnoxiousness +obnoxiousnesses +obnubilate +obnubilated +obnubilates +obnubilating +obnubilation +obnubilations +oboe +oboes +oboist +oboists +obol +obole +oboles +oboli +obols +obolus +obovate +obovoid +obscene +obscenely +obscener +obscenest +obscenities +obscenity +obscurant +obscurantic +obscurantism +obscurantisms +obscurantist +obscurantists +obscurants +obscuration +obscurations +obscure +obscured +obscurely +obscureness +obscurenesses +obscurer +obscures +obscurest +obscuring +obscurities +obscurity +obsequies +obsequious +obsequiously +obsequiousness +obsequiousnesses +obsequy +observabilities +observability +observable +observables +observably +observance +observances +observant +observantly +observants +observation +observational +observationally +observations +observatories +observatory +observe +observed +observer +observers +observes +observing +observingly +obsess +obsessed +obsesses +obsessing +obsession +obsessional +obsessionally +obsessions +obsessive +obsessively +obsessiveness +obsessivenesses +obsessives +obsessor +obsessors +obsidian +obsidians +obsolesce +obsolesced +obsolescence +obsolescences +obsolescent +obsolescently +obsolesces +obsolescing +obsolete +obsoleted +obsoletely +obsoleteness +obsoletenesses +obsoletes +obsoleting +obstacle +obstacles +obstetric +obstetrical +obstetrically +obstetrician +obstetricians +obstetrics +obstinacies +obstinacy +obstinate +obstinately +obstinateness +obstinatenesses +obstreperous +obstreperously +obstreperousness +obstreperousnesses +obstruct +obstructed +obstructing +obstruction +obstructionism +obstructionisms +obstructionist +obstructionistic +obstructionists +obstructions +obstructive +obstructively +obstructiveness +obstructivenesses +obstructives +obstructor +obstructors +obstructs +obtain +obtainabilities +obtainability +obtainable +obtained +obtainer +obtainers +obtaining +obtainment +obtainments +obtains +obtect +obtected +obtest +obtested +obtesting +obtests +obtrude +obtruded +obtruder +obtruders +obtrudes +obtruding +obtrusion +obtrusions +obtrusive +obtrusively +obtrusiveness +obtrusivenesses +obtund +obtunded +obtunding +obtunds +obturate +obturated +obturates +obturating +obturation +obturations +obturator +obturators +obtuse +obtusely +obtuseness +obtusenesses +obtuser +obtusest +obtusities +obtusity +obverse +obversely +obverses +obvert +obverted +obverting +obverts +obviable +obviate +obviated +obviates +obviating +obviation +obviations +obviator +obviators +obvious +obviously +obviousness +obviousnesses +obvolute +oca +ocarina +ocarinas +ocas +occasion +occasional +occasionally +occasioned +occasioning +occasions +occident +occidental +occidentalize +occidentalized +occidentalizes +occidentalizing +occidentally +occidents +occipita +occipital +occipitally +occipitals +occiput +occiputs +occlude +occluded +occludes +occluding +occlusal +occlusion +occlusions +occlusive +occult +occultation +occultations +occulted +occulter +occulters +occulting +occultism +occultisms +occultist +occultists +occultly +occults +occupancies +occupancy +occupant +occupants +occupation +occupational +occupationally +occupations +occupied +occupier +occupiers +occupies +occupy +occupying +occur +occurred +occurrence +occurrences +occurrent +occurrents +occurring +occurs +ocean +oceanaria +oceanarium +oceanariums +oceanaut +oceanauts +oceanfront +oceanfronts +oceangoing +oceanic +oceanographer +oceanographers +oceanographic +oceanographical +oceanographically +oceanographies +oceanography +oceanologies +oceanologist +oceanologists +oceanology +oceans +ocellar +ocellate +ocelli +ocellus +oceloid +ocelot +ocelots +ocher +ochered +ochering +ocherous +ochers +ochery +ochlocracies +ochlocracy +ochlocrat +ochlocratic +ochlocratical +ochlocrats +ochone +ochre +ochrea +ochreae +ochred +ochreous +ochres +ochring +ochroid +ochrous +ochry +ocker +ockers +ocotillo +ocotillos +ocrea +ocreae +ocreate +octad +octadic +octads +octagon +octagonal +octagonally +octagons +octahedra +octahedral +octahedrally +octahedron +octahedrons +octal +octameter +octameters +octan +octane +octanes +octangle +octangles +octanol +octanols +octans +octant +octantal +octants +octapeptide +octapeptides +octarchies +octarchy +octaval +octave +octaves +octavo +octavos +octet +octets +octette +octettes +octillion +octillions +octodecillion +octodecillions +octogenarian +octogenarians +octonaries +octonary +octopi +octoploid +octoploids +octopod +octopodes +octopods +octopus +octopuses +octoroon +octoroons +octosyllabic +octosyllabics +octosyllable +octosyllables +octothorp +octothorps +octroi +octrois +octuple +octupled +octuples +octuplet +octuplets +octuplex +octupling +octuply +octyl +octyls +ocular +ocularist +ocularists +ocularly +oculars +oculi +oculist +oculists +oculomotor +oculus +od +odalisk +odalisks +odalisque +odalisques +odd +oddball +oddballs +odder +oddest +oddish +oddities +oddity +oddly +oddment +oddments +oddness +oddnesses +odds +oddsmaker +oddsmakers +ode +odea +odeon +odeons +odes +odeum +odeums +odic +odious +odiously +odiousness +odiousnesses +odist +odists +odium +odiums +odograph +odographs +odometer +odometers +odometries +odometry +odonate +odonates +odontoblast +odontoblastic +odontoblasts +odontoglossum +odontoglossums +odontoid +odontoids +odor +odorant +odorants +odored +odorful +odoriferous +odoriferously +odoriferousness +odoriferousnesses +odorize +odorized +odorizes +odorizing +odorless +odorous +odorously +odorousness +odorousnesses +odors +odour +odourful +odours +ods +odyl +odyle +odyles +odyls +odyssey +odysseys +oe +oecologies +oecology +oecumenical +oedema +oedemas +oedemata +oedipal +oedipally +oedipean +oeillade +oeillades +oenologies +oenology +oenomel +oenomels +oenophile +oenophiles +oersted +oersteds +oes +oesophagi +oesophagus +oestrin +oestrins +oestriol +oestriols +oestrone +oestrones +oestrous +oestrum +oestrums +oestrus +oestruses +oeuvre +oeuvres +of +ofay +ofays +off +offal +offals +offbeat +offbeats +offcast +offcasts +offcut +offcuts +offed +offence +offences +offend +offended +offender +offenders +offending +offends +offense +offenseless +offenses +offensive +offensively +offensiveness +offensivenesses +offensives +offer +offered +offerer +offerers +offering +offerings +offeror +offerors +offers +offertories +offertory +offhand +offhanded +offhandedly +offhandedness +offhandednesses +office +officeholder +officeholders +officer +officered +officering +officers +offices +official +officialdom +officialdoms +officialese +officialeses +officialism +officialisms +officially +officials +officiant +officiants +officiaries +officiary +officiate +officiated +officiates +officiating +officiation +officiations +officinal +officious +officiously +officiousness +officiousnesses +offing +offings +offish +offishly +offishness +offishnesses +offkey +offload +offloaded +offloading +offloads +offprint +offprinted +offprinting +offprints +offramp +offramps +offs +offscouring +offscourings +offscreen +offset +offsets +offsetting +offshoot +offshoots +offshore +offside +offsides +offspring +offsprings +offstage +offstages +offtrack +oft +often +oftener +oftenest +oftentimes +ofter +oftest +ofttimes +ogam +ogams +ogdoad +ogdoads +ogee +ogees +ogham +oghamic +oghamist +oghamists +oghams +ogival +ogive +ogives +ogle +ogled +ogler +oglers +ogles +ogling +ogre +ogreish +ogreism +ogreisms +ogres +ogress +ogresses +ogrish +ogrishly +ogrism +ogrisms +oh +ohed +ohia +ohias +ohing +ohm +ohmage +ohmages +ohmic +ohmically +ohmmeter +ohmmeters +ohms +oho +ohs +oidia +oidium +oil +oilbird +oilbirds +oilcamp +oilcamps +oilcan +oilcans +oilcloth +oilcloths +oilcup +oilcups +oiled +oiler +oilers +oilhole +oilholes +oilier +oiliest +oilily +oiliness +oilinesses +oiling +oilman +oilmen +oilpaper +oilpapers +oilproof +oils +oilseed +oilseeds +oilskin +oilskins +oilstone +oilstones +oiltight +oilway +oilways +oily +oink +oinked +oinking +oinks +oinologies +oinology +oinomel +oinomels +ointment +ointments +oiticica +oiticicas +oka +okapi +okapis +okas +okay +okayed +okaying +okays +oke +okeh +okehs +okes +okeydoke +okeydokey +okra +okras +old +olden +older +oldest +oldfangled +oldie +oldies +oldish +oldness +oldnesses +olds +oldsquaw +oldsquaws +oldster +oldsters +oldstyle +oldstyles +oldwife +oldwives +oldy +ole +olea +oleaginous +oleaginously +oleaginousness +oleaginousnesses +oleander +oleanders +oleandomycin +oleandomycins +oleaster +oleasters +oleate +oleates +olecranon +olecranons +olefin +olefine +olefines +olefinic +olefins +oleic +olein +oleine +oleines +oleins +oleo +oleograph +oleographs +oleomargarine +oleomargarines +oleoresin +oleoresinous +oleoresins +oleos +oles +oleum +oleums +olfaction +olfactions +olfactometer +olfactometers +olfactory +olibanum +olibanums +oligarch +oligarchic +oligarchical +oligarchies +oligarchs +oligarchy +oligochaete +oligochaetes +oligoclase +oligoclases +oligodendrocyte +oligodendrocytes +oligodendroglia +oligodendroglial +oligodendroglias +oligomer +oligomeric +oligomerization +oligomerizations +oligomers +oligonucleotide +oligonucleotides +oligophagies +oligophagous +oligophagy +oligopolies +oligopolistic +oligopoly +oligopsonies +oligopsonistic +oligopsony +oligosaccharide +oligosaccharides +oligotrophic +oliguria +oligurias +olio +olios +olivaceous +olivary +olive +olivenite +olivenites +olives +olivine +olivines +olivinic +olivinitic +olla +ollas +ologies +ologist +ologists +ology +ololiuqui +ololiuquis +oloroso +olorosos +olympiad +olympiads +om +omasa +omasum +omber +ombers +ombre +ombres +ombudsman +ombudsmanship +ombudsmanships +ombudsmen +omega +omegas +omelet +omelets +omelette +omelettes +omen +omened +omening +omens +omenta +omental +omentum +omentums +omer +omers +omicron +omicrons +omikron +omikrons +ominous +ominously +ominousness +ominousnesses +omissible +omission +omissions +omissive +omit +omits +omitted +omitter +omitters +omitting +ommatidia +ommatidial +ommatidium +omniarch +omniarchs +omnibus +omnibuses +omnicompetence +omnicompetences +omnicompetent +omnidirectional +omnifarious +omnific +omnificent +omniform +omnimode +omnipotence +omnipotences +omnipotent +omnipotently +omnipotents +omnipresence +omnipresences +omnipresent +omnirange +omniranges +omniscience +omnisciences +omniscient +omnisciently +omnivora +omnivore +omnivores +omnivorous +omnivorously +omophagies +omophagy +omphali +omphalos +omphaloskepses +omphaloskepsis +oms +on +onager +onagers +onagri +onanism +onanisms +onanist +onanistic +onanists +onboard +once +onchocerciases +onchocerciasis +oncidium +oncidiums +oncogene +oncogenes +oncogeneses +oncogenesis +oncogenic +oncogenicities +oncogenicity +oncologic +oncological +oncologies +oncologist +oncologists +oncology +oncoming +oncomings +oncornavirus +oncornaviruses +ondogram +ondograms +one +onefold +oneiric +oneirically +oneiromancies +oneiromancy +oneness +onenesses +onerier +oneriest +onerous +onerously +onerousness +onerousnesses +onery +ones +oneself +onetime +ongoing +ongoingness +ongoingnesses +onion +onions +onionskin +onionskins +oniony +onium +onlooker +onlookers +onlooking +only +onomastic +onomastically +onomastician +onomasticians +onomastics +onomatologies +onomatologist +onomatologists +onomatology +onomatopoeia +onomatopoeias +onomatopoeic +onomatopoeically +onomatopoetic +onomatopoetically +onrush +onrushes +onrushing +ons +onset +onsets +onshore +onside +onslaught +onslaughts +onstage +onstream +ontic +ontically +onto +ontogeneses +ontogenesis +ontogenetic +ontogenetically +ontogenies +ontogeny +ontological +ontologically +ontologies +ontologist +ontologists +ontology +onus +onuses +onward +onwards +onychophoran +onychophorans +onyx +onyxes +oocyst +oocysts +oocyte +oocytes +oodles +oodlins +oogamete +oogametes +oogamies +oogamous +oogamy +oogeneses +oogenesis +oogenetic +oogenies +oogeny +oogonia +oogonial +oogonium +oogoniums +ooh +oohed +oohing +oohs +oolachan +oolachans +oolite +oolites +oolith +ooliths +oolitic +oologic +oologies +oologist +oologists +oology +oolong +oolongs +oomiac +oomiack +oomiacks +oomiacs +oomiak +oomiaks +oompah +oompahed +oompahing +oompahs +oomph +oomphs +oophorectomies +oophorectomy +oophyte +oophytes +oophytic +oops +oorali +ooralis +oorie +oosperm +oosperms +oosphere +oospheres +oospore +oospores +oosporic +oot +ootheca +oothecae +oothecal +ootid +ootids +oots +ooze +oozed +oozes +oozier +ooziest +oozily +ooziness +oozinesses +oozing +oozy +op +opacified +opacifies +opacify +opacifying +opacities +opacity +opah +opahs +opal +opalesce +opalesced +opalescence +opalescences +opalescent +opalescently +opalesces +opalescing +opaline +opalines +opals +opaque +opaqued +opaquely +opaqueness +opaquenesses +opaquer +opaques +opaquest +opaquing +ope +oped +open +openabilities +openability +openable +opencast +opened +opener +openers +openest +openhanded +openhandedly +openhandedness +openhandednesses +openhearted +openheartedly +openheartedness +openheartednesses +opening +openings +openly +openmouthed +openmouthedly +openmouthedness +openmouthednesses +openness +opennesses +opens +openwork +openworks +opera +operabilities +operability +operable +operably +operagoer +operagoers +operagoing +operagoings +operand +operands +operant +operantly +operants +operas +operate +operated +operates +operatic +operatically +operatics +operating +operation +operational +operationalism +operationalisms +operationalist +operationalistic +operationalists +operationally +operationism +operationisms +operationist +operationists +operations +operative +operatively +operativeness +operativenesses +operatives +operator +operatorless +operators +opercele +operceles +opercula +opercular +operculars +operculate +operculated +opercule +opercules +operculum +operculums +operetta +operettas +operettist +operettists +operon +operons +operose +operosely +operoseness +operosenesses +opes +ophidian +ophidians +ophite +ophites +ophitic +ophiuroid +ophiuroids +ophthalmia +ophthalmias +ophthalmic +ophthalmologic +ophthalmological +ophthalmologically +ophthalmologies +ophthalmologist +ophthalmologists +ophthalmology +ophthalmoscope +ophthalmoscopes +ophthalmoscopic +ophthalmoscopies +ophthalmoscopy +opiate +opiated +opiates +opiating +opine +opined +opines +oping +opining +opinion +opinionated +opinionatedly +opinionatedness +opinionatednesses +opinionative +opinionatively +opinionativeness +opinionativenesses +opinioned +opinions +opioid +opioids +opisthobranch +opisthobranchs +opium +opiumism +opiumisms +opiums +opossum +opossums +oppidan +oppidans +oppilant +oppilate +oppilated +oppilates +oppilating +opponent +opponents +opportune +opportunely +opportuneness +opportunenesses +opportunism +opportunisms +opportunist +opportunistic +opportunistically +opportunists +opportunities +opportunity +opposabilities +opposability +opposable +oppose +opposed +opposeless +opposer +opposers +opposes +opposing +opposite +oppositely +oppositeness +oppositenesses +opposites +opposition +oppositional +oppositionist +oppositionists +oppositions +oppress +oppressed +oppresses +oppressing +oppression +oppressions +oppressive +oppressively +oppressiveness +oppressivenesses +oppressor +oppressors +opprobrious +opprobriously +opprobriousness +opprobriousnesses +opprobrium +opprobriums +oppugn +oppugned +oppugner +oppugners +oppugning +oppugns +ops +opsin +opsins +opsonic +opsonified +opsonifies +opsonify +opsonifying +opsonin +opsonins +opsonize +opsonized +opsonizes +opsonizing +opt +optative +optatively +optatives +opted +optic +optical +optically +optician +opticians +opticist +opticists +optics +optima +optimal +optimalities +optimality +optimally +optime +optimes +optimisation +optimisations +optimise +optimised +optimises +optimising +optimism +optimisms +optimist +optimistic +optimistically +optimists +optimization +optimizations +optimize +optimized +optimizer +optimizers +optimizes +optimizing +optimum +optimums +opting +option +optional +optionalities +optionality +optionally +optionals +optioned +optionee +optionees +optioning +options +optoelectronic +optoelectronics +optokinetic +optometric +optometries +optometrist +optometrists +optometry +opts +opulence +opulences +opulencies +opulency +opulent +opulently +opuntia +opuntias +opus +opuscula +opuscule +opuscules +opusculum +opuses +oquassa +oquassas +or +ora +orach +orache +oraches +oracle +oracles +oracular +oracularities +oracularity +oracularly +orad +oral +oralism +oralisms +oralist +oralists +oralities +orality +orally +orals +orang +orange +orangeade +orangeades +orangerie +orangeries +orangery +oranges +orangewood +orangewoods +orangey +orangier +orangiest +orangish +orangs +orangutan +orangutans +orangy +orate +orated +orates +orating +oration +orations +orator +oratorical +oratorically +oratories +oratorio +oratorios +orators +oratory +oratress +oratresses +oratrices +oratrix +orb +orbed +orbicular +orbicularly +orbiculate +orbier +orbiest +orbing +orbit +orbital +orbitals +orbited +orbiter +orbiters +orbiting +orbits +orbs +orby +orc +orca +orcas +orcein +orceins +orchard +orchardist +orchardists +orchards +orchestra +orchestral +orchestrally +orchestras +orchestrate +orchestrated +orchestrater +orchestraters +orchestrates +orchestrating +orchestration +orchestrational +orchestrations +orchestrator +orchestrators +orchid +orchidaceous +orchidlike +orchids +orchil +orchils +orchis +orchises +orchitic +orchitis +orchitises +orcin +orcinol +orcinols +orcins +orcs +ordain +ordained +ordainer +ordainers +ordaining +ordainment +ordainments +ordains +ordeal +ordeals +order +orderable +ordered +orderer +orderers +ordering +orderless +orderlies +orderliness +orderlinesses +orderly +orders +ordinal +ordinals +ordinance +ordinances +ordinand +ordinands +ordinarier +ordinaries +ordinariest +ordinarily +ordinariness +ordinarinesses +ordinary +ordinate +ordinates +ordination +ordinations +ordines +ordnance +ordnances +ordo +ordonnance +ordonnances +ordos +ordure +ordures +ore +oread +oreads +orectic +orective +oregano +oreganos +oreide +oreides +ores +orfray +orfrays +organ +organa +organdie +organdies +organdy +organelle +organelles +organic +organically +organicism +organicisms +organicist +organicists +organicities +organicity +organics +organisation +organisations +organise +organised +organiser +organisers +organises +organising +organism +organismal +organismic +organismically +organisms +organist +organists +organizable +organization +organizational +organizationally +organizations +organize +organized +organizer +organizers +organizes +organizing +organochlorine +organochlorines +organogeneses +organogenesis +organogenetic +organoleptic +organoleptically +organologies +organology +organomercurial +organomercurials +organometallic +organometallics +organon +organons +organophosphate +organophosphates +organophosphorous +organophosphorus +organophosphoruses +organs +organum +organums +organza +organzas +organzine +organzines +orgasm +orgasmic +orgasms +orgastic +orgeat +orgeats +orgiac +orgiastic +orgiastically +orgic +orgies +orgone +orgones +orgulous +orgy +oribatid +oribatids +oribi +oribis +oriel +oriels +orient +oriental +orientalism +orientalisms +orientalist +orientalists +orientalize +orientalized +orientalizes +orientalizing +orientally +orientals +orientate +orientated +orientates +orientating +orientation +orientational +orientationally +orientations +oriented +orienteer +orienteering +orienteerings +orienteers +orienting +orients +orifice +orifices +orificial +oriflamme +oriflammes +origami +origamis +origan +origans +origanum +origanums +origin +original +originalities +originality +originally +originals +originate +originated +originates +originating +origination +originations +originative +originatively +originator +originators +origins +orinasal +orinasals +oriole +orioles +orismological +orismologies +orismology +orison +orisons +orle +orles +orlop +orlops +ormer +ormers +ormolu +ormolus +ornament +ornamental +ornamentally +ornamentals +ornamentation +ornamentations +ornamented +ornamenting +ornaments +ornate +ornately +ornateness +ornatenesses +ornerier +orneriest +orneriness +ornerinesses +ornery +ornis +ornithes +ornithic +ornithine +ornithines +ornithischian +ornithischians +ornithologic +ornithological +ornithologically +ornithologies +ornithologist +ornithologists +ornithology +ornithopod +ornithopods +ornithopter +ornithopters +ornithoses +ornithosis +orogeneses +orogenesis +orogenetic +orogenic +orogenies +orogeny +orographic +orographical +orographies +orography +oroide +oroides +orologies +orology +orometer +orometers +oropharyngeal +oropharynges +oropharynx +oropharynxes +orotund +orotundities +orotundity +orphan +orphanage +orphanages +orphaned +orphanhood +orphanhoods +orphaning +orphans +orphic +orphical +orphically +orphrey +orphreys +orpiment +orpiments +orpin +orpine +orpines +orpins +orra +orreries +orrery +orrice +orrices +orris +orrises +orrisroot +orrisroots +ors +ort +orthicon +orthicons +ortho +orthocenter +orthocenters +orthochromatic +orthoclase +orthoclases +orthodontia +orthodontias +orthodontic +orthodontically +orthodontics +orthodontist +orthodontists +orthodox +orthodoxes +orthodoxies +orthodoxly +orthodoxy +orthoepic +orthoepically +orthoepies +orthoepist +orthoepists +orthoepy +orthogeneses +orthogenesis +orthogenetic +orthogenetically +orthogonal +orthogonalities +orthogonality +orthogonalization +orthogonalizations +orthogonalize +orthogonalized +orthogonalizes +orthogonalizing +orthogonally +orthograde +orthographic +orthographical +orthographically +orthographies +orthography +orthomolecular +orthonormal +orthopaedic +orthopaedics +orthopedic +orthopedically +orthopedics +orthopedist +orthopedists +orthophosphate +orthophosphates +orthopsychiatric +orthopsychiatries +orthopsychiatrist +orthopsychiatrists +orthopsychiatry +orthoptera +orthopteran +orthopterans +orthopterist +orthopterists +orthopteroid +orthopteroids +orthorhombic +orthoscopic +orthoses +orthosis +orthostatic +orthotic +orthotics +orthotist +orthotists +orthotropous +ortolan +ortolans +orts +oryx +oryxes +orzo +orzos +os +osar +oscillate +oscillated +oscillates +oscillating +oscillation +oscillational +oscillations +oscillator +oscillators +oscillatory +oscillogram +oscillograms +oscillograph +oscillographic +oscillographically +oscillographies +oscillographs +oscillography +oscilloscope +oscilloscopes +oscilloscopic +oscine +oscines +oscinine +oscitant +oscula +osculant +oscular +osculate +osculated +osculates +osculating +osculation +osculations +osculatory +oscule +oscules +osculum +ose +oses +osier +osiers +osmatic +osmeteria +osmeterium +osmic +osmics +osmious +osmiridium +osmiridiums +osmium +osmiums +osmol +osmolal +osmolalities +osmolality +osmolar +osmolarities +osmolarity +osmole +osmoles +osmols +osmometer +osmometers +osmometric +osmometries +osmometry +osmoregulation +osmoregulations +osmoregulatory +osmose +osmosed +osmoses +osmosing +osmosis +osmotic +osmotically +osmous +osmund +osmunda +osmundas +osmunds +osnaburg +osnaburgs +osprey +ospreys +ossa +ossein +osseins +osseous +ossia +ossicle +ossicles +ossicular +ossific +ossification +ossifications +ossified +ossifier +ossifiers +ossifies +ossifrage +ossifrages +ossify +ossifying +ossuaries +ossuary +osteal +osteitic +osteitides +osteitis +ostensible +ostensibly +ostensive +ostensively +ostensoria +ostensorium +ostentation +ostentations +ostentatious +ostentatiously +ostentatiousness +ostentatiousnesses +osteoarthritic +osteoarthritides +osteoarthritis +osteoblast +osteoblastic +osteoblasts +osteoclast +osteoclastic +osteoclasts +osteocyte +osteocytes +osteogeneses +osteogenesis +osteogenic +osteoid +osteoids +osteological +osteologies +osteologist +osteologists +osteology +osteoma +osteomalacia +osteomalacias +osteomas +osteomata +osteomyelitides +osteomyelitis +osteopath +osteopathic +osteopathically +osteopathies +osteopaths +osteopathy +osteoplastic +osteoplasties +osteoplasty +osteoporoses +osteoporosis +osteoporotic +osteosarcoma +osteosarcomas +osteosarcomata +osteoses +osteosis +osteosises +ostia +ostiaries +ostiary +ostinato +ostinatos +ostiolar +ostiole +ostioles +ostium +ostler +ostlers +ostmark +ostmarks +ostomies +ostomy +ostoses +ostosis +ostosises +ostraca +ostracise +ostracised +ostracises +ostracising +ostracism +ostracisms +ostracize +ostracized +ostracizes +ostracizing +ostracod +ostracode +ostracoderm +ostracoderms +ostracodes +ostracods +ostracon +ostrich +ostriches +ostrichlike +otalgia +otalgias +otalgic +otalgies +otalgy +other +otherguess +otherness +othernesses +others +otherwhere +otherwhile +otherwhiles +otherwise +otherworld +otherworldliness +otherworldlinesses +otherworldly +otherworlds +otic +otiose +otiosely +otioseness +otiosenesses +otiosities +otiosity +otitic +otitides +otitis +otocyst +otocystic +otocysts +otolaryngological +otolaryngologies +otolaryngologist +otolaryngologists +otolaryngology +otolith +otolithic +otoliths +otologies +otology +otorhinolaryngological +otorhinolaryngologies +otorhinolaryngologist +otorhinolaryngologists +otorhinolaryngology +otoscleroses +otosclerosis +otoscope +otoscopes +otoscopies +otoscopy +ototoxic +ototoxicities +ototoxicity +ottar +ottars +ottava +ottavas +otter +otters +otto +ottoman +ottomans +ottos +ouabain +ouabains +oubliette +oubliettes +ouch +ouched +ouches +ouching +oud +ouds +ought +oughted +oughting +oughts +ouguiya +ouistiti +ouistitis +ounce +ounces +ouph +ouphe +ouphes +ouphs +our +ourang +ourangs +ourari +ouraris +ourebi +ourebis +ourie +ours +ourself +ourselves +ousel +ousels +oust +ousted +ouster +ousters +ousting +ousts +out +outachieve +outachieved +outachieves +outachieving +outact +outacted +outacting +outacts +outadd +outadded +outadding +outadds +outage +outages +outargue +outargued +outargues +outarguing +outask +outasked +outasking +outasks +outate +outback +outbacks +outbake +outbaked +outbakes +outbaking +outbalance +outbalanced +outbalances +outbalancing +outbargain +outbargained +outbargaining +outbargains +outbark +outbarked +outbarking +outbarks +outbawl +outbawled +outbawling +outbawls +outbeam +outbeamed +outbeaming +outbeams +outbeg +outbegged +outbegging +outbegs +outbid +outbidden +outbidding +outbids +outbitch +outbitched +outbitches +outbitching +outblaze +outblazed +outblazes +outblazing +outbleat +outbleated +outbleating +outbleats +outbless +outblessed +outblesses +outblessing +outbloom +outbloomed +outblooming +outblooms +outbluff +outbluffed +outbluffing +outbluffs +outblush +outblushed +outblushes +outblushing +outboard +outboards +outboast +outboasted +outboasting +outboasts +outbought +outbound +outbox +outboxed +outboxes +outboxing +outbrag +outbragged +outbragging +outbrags +outbrave +outbraved +outbraves +outbraving +outbrawl +outbrawled +outbrawling +outbrawls +outbreak +outbreaks +outbred +outbreed +outbreeding +outbreedings +outbreeds +outbribe +outbribed +outbribes +outbribing +outbuild +outbuilding +outbuildings +outbuilds +outbuilt +outbulk +outbulked +outbulking +outbulks +outbullied +outbullies +outbully +outbullying +outburn +outburned +outburning +outburns +outburnt +outburst +outbursts +outbuy +outbuying +outbuys +outby +outbye +outcaper +outcapered +outcapering +outcapers +outcast +outcaste +outcastes +outcasts +outcatch +outcatches +outcatching +outcaught +outcavil +outcaviled +outcaviling +outcavilled +outcavilling +outcavils +outcharge +outcharged +outcharges +outcharging +outcharm +outcharmed +outcharming +outcharms +outcheat +outcheated +outcheating +outcheats +outchid +outchidden +outchide +outchided +outchides +outchiding +outclass +outclassed +outclasses +outclassing +outclimb +outclimbed +outclimbing +outclimbs +outclomb +outcoach +outcoached +outcoaches +outcoaching +outcome +outcomes +outcompete +outcompeted +outcompetes +outcompeting +outcook +outcooked +outcooking +outcooks +outcount +outcounted +outcounting +outcounts +outcrawl +outcrawled +outcrawling +outcrawls +outcried +outcries +outcrop +outcropped +outcropping +outcroppings +outcrops +outcross +outcrossed +outcrosses +outcrossing +outcrow +outcrowed +outcrowing +outcrows +outcry +outcrying +outcurse +outcursed +outcurses +outcursing +outcurve +outcurves +outdance +outdanced +outdances +outdancing +outdare +outdared +outdares +outdaring +outdate +outdated +outdatedly +outdatedness +outdatednesses +outdates +outdating +outdazzle +outdazzled +outdazzles +outdazzling +outdebate +outdebated +outdebates +outdebating +outdeliver +outdelivered +outdelivering +outdelivers +outdesign +outdesigned +outdesigning +outdesigns +outdid +outdistance +outdistanced +outdistances +outdistancing +outdo +outdodge +outdodged +outdodges +outdodging +outdoer +outdoers +outdoes +outdoing +outdone +outdoor +outdoors +outdoorsman +outdoorsmanship +outdoorsmanships +outdoorsmen +outdoorsy +outdrag +outdragged +outdragging +outdrags +outdrank +outdraw +outdrawing +outdrawn +outdraws +outdream +outdreamed +outdreaming +outdreams +outdreamt +outdress +outdressed +outdresses +outdressing +outdrew +outdrink +outdrinking +outdrinks +outdrive +outdriven +outdrives +outdriving +outdrop +outdropped +outdropping +outdrops +outdrove +outdrunk +outduel +outdueled +outdueling +outduelled +outduelling +outduels +outearn +outearned +outearning +outearns +outeat +outeaten +outeating +outeats +outecho +outechoed +outechoes +outechoing +outed +outer +outercoat +outercoats +outermost +outers +outerwear +outfable +outfabled +outfables +outfabling +outface +outfaced +outfaces +outfacing +outfall +outfalls +outfast +outfasted +outfasting +outfasts +outfawn +outfawned +outfawning +outfawns +outfeast +outfeasted +outfeasting +outfeasts +outfeel +outfeeling +outfeels +outfelt +outfield +outfielder +outfielders +outfields +outfight +outfighting +outfights +outfigure +outfigured +outfigures +outfiguring +outfind +outfinding +outfinds +outfire +outfired +outfires +outfiring +outfish +outfished +outfishes +outfishing +outfit +outfits +outfitted +outfitter +outfitters +outfitting +outflank +outflanked +outflanking +outflanks +outflew +outflies +outflow +outflowed +outflowing +outflown +outflows +outfly +outflying +outfool +outfooled +outfooling +outfools +outfoot +outfooted +outfooting +outfoots +outfought +outfound +outfox +outfoxed +outfoxes +outfoxing +outfrown +outfrowned +outfrowning +outfrowns +outfumble +outfumbled +outfumbles +outfumbling +outgain +outgained +outgaining +outgains +outgas +outgassed +outgasses +outgassing +outgave +outgeneral +outgeneraled +outgeneraling +outgenerals +outgive +outgiven +outgives +outgiving +outgivings +outglare +outglared +outglares +outglaring +outglitter +outglittered +outglittering +outglitters +outglow +outglowed +outglowing +outglows +outgnaw +outgnawed +outgnawing +outgnawn +outgnaws +outgo +outgoes +outgoing +outgoingness +outgoingnesses +outgoings +outgone +outgrew +outgrin +outgrinned +outgrinning +outgrins +outgross +outgrossed +outgrosses +outgrossing +outgroup +outgroups +outgrow +outgrowing +outgrown +outgrows +outgrowth +outgrowths +outguess +outguessed +outguesses +outguessing +outguide +outguided +outguides +outguiding +outgun +outgunned +outgunning +outguns +outgush +outgushes +outhaul +outhauls +outhear +outheard +outhearing +outhears +outhit +outhits +outhitting +outhomer +outhomered +outhomering +outhomers +outhouse +outhouses +outhowl +outhowled +outhowling +outhowls +outhumor +outhumored +outhumoring +outhumors +outhunt +outhunted +outhunting +outhunts +outhustle +outhustled +outhustles +outhustling +outing +outings +outintrigue +outintrigued +outintrigues +outintriguing +outjinx +outjinxed +outjinxes +outjinxing +outjump +outjumped +outjumping +outjumps +outjut +outjuts +outjutted +outjutting +outkeep +outkeeping +outkeeps +outkept +outkick +outkicked +outkicking +outkicks +outkill +outkilled +outkilling +outkills +outkiss +outkissed +outkisses +outkissing +outlaid +outlain +outland +outlander +outlanders +outlandish +outlandishly +outlandishness +outlandishnesses +outlands +outlast +outlasted +outlasting +outlasts +outlaugh +outlaughed +outlaughing +outlaughs +outlaw +outlawed +outlawing +outlawries +outlawry +outlaws +outlay +outlaying +outlays +outleap +outleaped +outleaping +outleaps +outleapt +outlearn +outlearned +outlearning +outlearns +outlearnt +outlet +outlets +outlie +outlier +outliers +outlies +outline +outlined +outliner +outliners +outlines +outlining +outlive +outlived +outliver +outlivers +outlives +outliving +outlook +outlooks +outlove +outloved +outloves +outloving +outlying +outman +outmaneuver +outmaneuvered +outmaneuvering +outmaneuvers +outmanipulate +outmanipulated +outmanipulates +outmanipulating +outmanned +outmanning +outmans +outmarch +outmarched +outmarches +outmarching +outmatch +outmatched +outmatches +outmatching +outmode +outmoded +outmodes +outmoding +outmost +outmove +outmoved +outmoves +outmoving +outmuscle +outmuscled +outmuscles +outmuscling +outnumber +outnumbered +outnumbering +outnumbers +outorganize +outorganized +outorganizes +outorganizing +outpace +outpaced +outpaces +outpacing +outpaint +outpainted +outpainting +outpaints +outpass +outpassed +outpasses +outpassing +outpatient +outpatients +outperform +outperformed +outperforming +outperforms +outpitch +outpitched +outpitches +outpitching +outpitied +outpities +outpity +outpitying +outplacement +outplacements +outplan +outplanned +outplanning +outplans +outplay +outplayed +outplaying +outplays +outplod +outplodded +outplodding +outplods +outplot +outplots +outplotted +outplotting +outpoint +outpointed +outpointing +outpoints +outpolitick +outpoliticked +outpoliticking +outpoliticks +outpoll +outpolled +outpolling +outpolls +outpopulate +outpopulated +outpopulates +outpopulating +outport +outports +outpost +outposts +outpour +outpoured +outpouring +outpourings +outpours +outpower +outpowered +outpowering +outpowers +outpray +outprayed +outpraying +outprays +outpreach +outpreached +outpreaches +outpreaching +outpreen +outpreened +outpreening +outpreens +outpress +outpressed +outpresses +outpressing +outprice +outpriced +outprices +outpricing +outproduce +outproduced +outproduces +outproducing +outpromise +outpromised +outpromises +outpromising +outpull +outpulled +outpulling +outpulls +outpunch +outpunched +outpunches +outpunching +outpush +outpushed +outpushes +outpushing +output +outputs +outputted +outputting +outquote +outquoted +outquotes +outquoting +outrace +outraced +outraces +outracing +outrage +outraged +outrageous +outrageously +outrageousness +outrageousnesses +outrages +outraging +outraise +outraised +outraises +outraising +outran +outrance +outrances +outrang +outrange +outranged +outranges +outranging +outrank +outranked +outranking +outranks +outrate +outrated +outrates +outrating +outrave +outraved +outraves +outraving +outre +outreach +outreached +outreaches +outreaching +outread +outreading +outreads +outrebound +outrebounded +outrebounding +outrebounds +outreproduce +outreproduced +outreproduces +outreproducing +outridden +outride +outrider +outriders +outrides +outriding +outrigger +outriggers +outright +outrightly +outring +outringing +outrings +outrival +outrivaled +outrivaling +outrivalled +outrivalling +outrivals +outroar +outroared +outroaring +outroars +outrock +outrocked +outrocking +outrocks +outrode +outroll +outrolled +outrolling +outrolls +outroot +outrooted +outrooting +outroots +outrow +outrowed +outrowing +outrows +outrun +outrung +outrunning +outruns +outrush +outrushed +outrushes +outrushing +outs +outsail +outsailed +outsailing +outsails +outsang +outsat +outsavor +outsavored +outsavoring +outsavors +outsaw +outscheme +outschemed +outschemes +outscheming +outscold +outscolded +outscolding +outscolds +outscoop +outscooped +outscooping +outscoops +outscore +outscored +outscores +outscoring +outscorn +outscorned +outscorning +outscorns +outsee +outseeing +outseen +outsees +outsell +outselling +outsells +outsert +outserts +outserve +outserved +outserves +outserving +outset +outsets +outshame +outshamed +outshames +outshaming +outshine +outshined +outshines +outshining +outshone +outshoot +outshooting +outshoots +outshot +outshout +outshouted +outshouting +outshouts +outside +outsider +outsiderness +outsidernesses +outsiders +outsides +outsight +outsights +outsin +outsing +outsinging +outsings +outsinned +outsinning +outsins +outsit +outsits +outsitting +outsize +outsized +outsizes +outskate +outskated +outskates +outskating +outskirt +outskirts +outsleep +outsleeping +outsleeps +outslept +outslick +outslicked +outslicking +outslicks +outsmart +outsmarted +outsmarting +outsmarts +outsmile +outsmiled +outsmiles +outsmiling +outsmoke +outsmoked +outsmokes +outsmoking +outsnore +outsnored +outsnores +outsnoring +outsoar +outsoared +outsoaring +outsoars +outsold +outsole +outsoles +outsourcing +outsourcings +outspan +outspanned +outspanning +outspans +outsparkle +outsparkled +outsparkles +outsparkling +outspeak +outspeaking +outspeaks +outsped +outspeed +outspeeded +outspeeding +outspeeds +outspell +outspelled +outspelling +outspells +outspelt +outspend +outspending +outspends +outspent +outspoke +outspoken +outspokenly +outspokenness +outspokennesses +outspread +outspreading +outspreads +outsprint +outsprinted +outsprinting +outsprints +outstand +outstanding +outstandingly +outstands +outstare +outstared +outstares +outstaring +outstart +outstarted +outstarting +outstarts +outstate +outstated +outstates +outstating +outstation +outstations +outstay +outstayed +outstaying +outstays +outsteer +outsteered +outsteering +outsteers +outstood +outstretch +outstretched +outstretches +outstretching +outstridden +outstride +outstrides +outstriding +outstrip +outstripped +outstripping +outstrips +outstrode +outstudied +outstudies +outstudy +outstudying +outstunt +outstunted +outstunting +outstunts +outsulk +outsulked +outsulking +outsulks +outsung +outswam +outsware +outswear +outswearing +outswears +outswim +outswimming +outswims +outswore +outsworn +outswum +outtake +outtakes +outtalk +outtalked +outtalking +outtalks +outtask +outtasked +outtasking +outtasks +outtell +outtelling +outtells +outthank +outthanked +outthanking +outthanks +outthink +outthinking +outthinks +outthought +outthrew +outthrob +outthrobbed +outthrobbing +outthrobs +outthrow +outthrowing +outthrown +outthrows +outthrust +outthrusting +outthrusts +outtold +outtower +outtowered +outtowering +outtowers +outtrade +outtraded +outtrades +outtrading +outtrick +outtricked +outtricking +outtricks +outtrot +outtrots +outtrotted +outtrotting +outtrump +outtrumped +outtrumping +outtrumps +outturn +outturns +outvalue +outvalued +outvalues +outvaluing +outvaunt +outvaunted +outvaunting +outvaunts +outvie +outvied +outvies +outvoice +outvoiced +outvoices +outvoicing +outvote +outvoted +outvotes +outvoting +outvying +outwait +outwaited +outwaiting +outwaits +outwalk +outwalked +outwalking +outwalks +outwar +outward +outwardly +outwardness +outwardnesses +outwards +outwarred +outwarring +outwars +outwash +outwashes +outwaste +outwasted +outwastes +outwasting +outwatch +outwatched +outwatches +outwatching +outwear +outwearied +outwearies +outwearing +outwears +outweary +outwearying +outweep +outweeping +outweeps +outweigh +outweighed +outweighing +outweighs +outwent +outwept +outwhirl +outwhirled +outwhirling +outwhirls +outwile +outwiled +outwiles +outwiling +outwill +outwilled +outwilling +outwills +outwind +outwinded +outwinding +outwinds +outwish +outwished +outwishes +outwishing +outwit +outwits +outwitted +outwitting +outwore +outwork +outworked +outworker +outworkers +outworking +outworks +outworn +outwrestle +outwrestled +outwrestles +outwrestling +outwrit +outwrite +outwrites +outwriting +outwritten +outwrote +outwrought +outyell +outyelled +outyelling +outyells +outyelp +outyelped +outyelping +outyelps +outyield +outyielded +outyielding +outyields +ouzel +ouzels +ouzo +ouzos +ova +oval +ovalbumin +ovalbumins +ovalities +ovality +ovally +ovalness +ovalnesses +ovals +ovarial +ovarian +ovariectomies +ovariectomized +ovariectomy +ovaries +ovariole +ovarioles +ovariotomies +ovariotomy +ovaritides +ovaritis +ovary +ovate +ovately +ovation +ovations +oven +ovenbird +ovenbirds +ovenlike +ovenproof +ovens +ovenware +ovenwares +over +overable +overabstract +overabstracted +overabstracting +overabstracts +overabundance +overabundances +overabundant +overaccentuate +overaccentuated +overaccentuates +overaccentuating +overachieve +overachieved +overachievement +overachievements +overachiever +overachievers +overachieves +overachieving +overact +overacted +overacting +overaction +overactions +overactive +overactivities +overactivity +overacts +overadjustment +overadjustments +overadvertise +overadvertised +overadvertises +overadvertising +overage +overaged +overages +overaggressive +overalert +overall +overalled +overalls +overambitious +overambitiousness +overambitiousnesses +overamplified +overanalyses +overanalysis +overanalytical +overanalyze +overanalyzed +overanalyzes +overanalyzing +overanxieties +overanxiety +overanxious +overapplication +overapplications +overapt +overarch +overarched +overarches +overarching +overarm +overarousal +overarousals +overarrange +overarranged +overarranges +overarranging +overarticulate +overarticulated +overarticulates +overarticulating +overassert +overasserted +overasserting +overassertion +overassertions +overassertive +overasserts +overassessment +overassessments +overate +overattention +overattentions +overawe +overawed +overawes +overawing +overbake +overbaked +overbakes +overbaking +overbalance +overbalanced +overbalances +overbalancing +overbear +overbearing +overbearingly +overbears +overbeat +overbeaten +overbeating +overbeats +overbed +overbejeweled +overbet +overbets +overbetted +overbetting +overbid +overbidden +overbidding +overbids +overbig +overbill +overbilled +overbilling +overbills +overbite +overbites +overbleach +overbleached +overbleaches +overbleaching +overblew +overblouse +overblouses +overblow +overblowing +overblown +overblows +overboard +overboil +overboiled +overboiling +overboils +overbold +overbook +overbooked +overbooking +overbooks +overbore +overborn +overborne +overborrow +overborrowed +overborrowing +overborrows +overbought +overbreathing +overbred +overbrief +overbright +overbroad +overbrowse +overbrowsed +overbrowses +overbrowsing +overbrutal +overbuild +overbuilding +overbuilds +overbuilt +overburden +overburdened +overburdening +overburdens +overburn +overburned +overburning +overburns +overburnt +overbusy +overbuy +overbuying +overbuys +overcall +overcalled +overcalling +overcalls +overcame +overcapacities +overcapacity +overcapitalization +overcapitalizations +overcapitalize +overcapitalized +overcapitalizes +overcapitalizing +overcareful +overcast +overcasted +overcasting +overcastings +overcasts +overcaution +overcautioned +overcautioning +overcautions +overcautious +overcentralization +overcentralizations +overcentralize +overcentralized +overcentralizes +overcentralizing +overcharge +overcharged +overcharges +overcharging +overchill +overchilled +overchilling +overchills +overcivilized +overclaim +overclaimed +overclaiming +overclaims +overclassification +overclassifications +overclassified +overclassifies +overclassify +overclassifying +overclean +overcleaned +overcleaning +overcleans +overclear +overcleared +overclearing +overclears +overcloud +overclouded +overclouding +overclouds +overcoach +overcoached +overcoaches +overcoaching +overcoat +overcoats +overcold +overcome +overcomer +overcomers +overcomes +overcoming +overcommercialization +overcommercializations +overcommercialize +overcommercialized +overcommercializes +overcommercializing +overcommit +overcommitment +overcommitments +overcommits +overcommitted +overcommitting +overcommunicate +overcommunicated +overcommunicates +overcommunicating +overcommunication +overcommunications +overcompensate +overcompensated +overcompensates +overcompensating +overcompensation +overcompensations +overcompensatory +overcomplex +overcompliance +overcompliances +overcomplicate +overcomplicated +overcomplicates +overcomplicating +overcompress +overcompressed +overcompresses +overcompressing +overconcentration +overconcentrations +overconcern +overconcerned +overconcerning +overconcerns +overconfidence +overconfidences +overconfident +overconfidently +overconscientious +overconscious +overconservative +overconstruct +overconstructed +overconstructing +overconstructs +overconsume +overconsumed +overconsumes +overconsuming +overconsumption +overconsumptions +overcontrol +overcontrolled +overcontrolling +overcontrols +overcook +overcooked +overcooking +overcooks +overcool +overcooled +overcooling +overcools +overcorrect +overcorrected +overcorrecting +overcorrection +overcorrections +overcorrects +overcount +overcounted +overcounting +overcounts +overcoy +overcram +overcrammed +overcramming +overcrams +overcredulous +overcritical +overcrop +overcropped +overcropping +overcrops +overcrowd +overcrowded +overcrowding +overcrowds +overcultivation +overcultivations +overcure +overcured +overcures +overcuring +overcut +overcuts +overcutting +overdare +overdared +overdares +overdaring +overdear +overdeck +overdecked +overdecking +overdecks +overdecorate +overdecorated +overdecorates +overdecorating +overdecoration +overdecorations +overdemanding +overdependence +overdependences +overdependent +overdesign +overdesigned +overdesigning +overdesigns +overdetermined +overdevelop +overdeveloped +overdeveloping +overdevelopment +overdevelopments +overdevelops +overdid +overdifferentiation +overdifferentiations +overdirect +overdirected +overdirecting +overdirects +overdiscount +overdiscounted +overdiscounting +overdiscounts +overdiversities +overdiversity +overdo +overdocument +overdocumented +overdocumenting +overdocuments +overdoer +overdoers +overdoes +overdog +overdogs +overdoing +overdominance +overdominances +overdominant +overdone +overdosage +overdosages +overdose +overdosed +overdoses +overdosing +overdraft +overdrafts +overdramatic +overdramatize +overdramatized +overdramatizes +overdramatizing +overdrank +overdraw +overdrawing +overdrawn +overdraws +overdress +overdressed +overdresses +overdressing +overdrew +overdried +overdries +overdrink +overdrinking +overdrinks +overdrive +overdriven +overdrives +overdriving +overdrove +overdrunk +overdry +overdrying +overdub +overdubbed +overdubbing +overdubs +overdue +overdye +overdyed +overdyeing +overdyes +overeager +overeagerness +overeagernesses +overearnest +overeasy +overeat +overeaten +overeater +overeaters +overeating +overeats +overed +overedit +overedited +overediting +overedits +overeducate +overeducated +overeducates +overeducating +overeducation +overeducations +overelaborate +overelaborated +overelaborates +overelaborating +overelaboration +overelaborations +overembellish +overembellished +overembellishes +overembellishing +overembellishment +overembellishments +overemote +overemoted +overemotes +overemoting +overemotional +overemphases +overemphasis +overemphasize +overemphasized +overemphasizes +overemphasizing +overemphatic +overenamored +overencourage +overencouraged +overencourages +overencouraging +overenergetic +overengineer +overengineered +overengineering +overengineers +overenrolled +overentertained +overenthusiasm +overenthusiasms +overenthusiastic +overenthusiastically +overequipped +overestimate +overestimated +overestimates +overestimating +overestimation +overestimations +overevaluation +overevaluations +overexaggerate +overexaggerated +overexaggerates +overexaggerating +overexaggeration +overexaggerations +overexcite +overexcited +overexcites +overexciting +overexercise +overexercised +overexercises +overexercising +overexert +overexerted +overexerting +overexertion +overexertions +overexerts +overexpand +overexpanded +overexpanding +overexpands +overexpansion +overexpansions +overexpectation +overexpectations +overexplain +overexplained +overexplaining +overexplains +overexplicit +overexploit +overexploitation +overexploitations +overexploited +overexploiting +overexploits +overexpose +overexposed +overexposes +overexposing +overexposure +overexposures +overextend +overextended +overextending +overextends +overextension +overextensions +overextraction +overextractions +overextrapolation +overextrapolations +overextravagant +overexuberant +overfacile +overfamiliar +overfamiliarities +overfamiliarity +overfar +overfast +overfastidious +overfat +overfatigue +overfatigued +overfatigues +overfavor +overfavored +overfavoring +overfavors +overfear +overfeared +overfearing +overfears +overfed +overfeed +overfeeding +overfeeds +overfertilization +overfertilizations +overfertilize +overfertilized +overfertilizes +overfertilizing +overfill +overfilled +overfilling +overfills +overfish +overfished +overfishes +overfishing +overflew +overflies +overflight +overflights +overflow +overflowed +overflowing +overflown +overflows +overfly +overflying +overfocus +overfocused +overfocuses +overfocusing +overfocussed +overfocusses +overfocussing +overfond +overfoul +overfree +overfulfill +overfulfilled +overfulfilling +overfulfills +overfull +overfund +overfunded +overfunding +overfunds +overfussy +overgarment +overgarments +overgeneralization +overgeneralizations +overgeneralize +overgeneralized +overgeneralizes +overgeneralizing +overgenerosities +overgenerosity +overgenerous +overgenerously +overgild +overgilded +overgilding +overgilds +overgilt +overgird +overgirded +overgirding +overgirds +overgirt +overglad +overglamorize +overglamorized +overglamorizes +overglamorizing +overglaze +overglazes +overgoad +overgoaded +overgoading +overgoads +overgovern +overgoverned +overgoverning +overgoverns +overgraze +overgrazed +overgrazes +overgrazing +overgrew +overgrow +overgrowing +overgrown +overgrows +overgrowth +overgrowths +overhand +overhanded +overhanding +overhandle +overhandled +overhandles +overhandling +overhands +overhang +overhanging +overhangs +overhard +overharvest +overharvested +overharvesting +overharvests +overhasty +overhate +overhated +overhates +overhating +overhaul +overhauled +overhauling +overhauls +overhead +overheads +overheap +overheaped +overheaping +overheaps +overhear +overheard +overhearing +overhears +overheat +overheated +overheating +overheats +overheld +overhigh +overhold +overholding +overholds +overholy +overhomogenize +overhomogenized +overhomogenizes +overhomogenizing +overhope +overhoped +overhopes +overhoping +overhot +overhung +overhunt +overhunted +overhunting +overhuntings +overhunts +overhype +overhyped +overhypes +overhyping +overidealize +overidealized +overidealizes +overidealizing +overidentification +overidentifications +overidentified +overidentifies +overidentify +overidentifying +overidle +overimaginative +overimpress +overimpressed +overimpresses +overimpressing +overindebtedness +overindebtednesses +overindulge +overindulged +overindulgence +overindulgences +overindulgent +overindulges +overindulging +overindustrialize +overindustrialized +overindustrializes +overindustrializing +overinflate +overinflated +overinflates +overinflating +overinflation +overinflations +overinform +overinformed +overinforming +overinforms +overing +overingenious +overingenuities +overingenuity +overinsistent +overinsure +overinsured +overinsures +overinsuring +overintellectualization +overintellectualizations +overintellectualize +overintellectualized +overintellectualizes +overintellectualizing +overintense +overintensities +overintensity +overinterpretation +overinterpretations +overinvestment +overinvestments +overissuance +overissuances +overissue +overissued +overissues +overissuing +overjoy +overjoyed +overjoying +overjoys +overjust +overkeen +overkill +overkilled +overkilling +overkills +overkind +overlabor +overlabored +overlaboring +overlabors +overlade +overladed +overladen +overlades +overlading +overlaid +overlain +overland +overlands +overlap +overlapped +overlapping +overlaps +overlarge +overlate +overlavish +overlax +overlay +overlaying +overlays +overleaf +overleap +overleaped +overleaping +overleaps +overleapt +overlearn +overlearned +overlearning +overlearns +overlend +overlending +overlends +overlength +overlengthen +overlengthened +overlengthening +overlengthens +overlent +overlet +overlets +overletting +overlewd +overlie +overlies +overlight +overlighted +overlighting +overlights +overlit +overliteral +overliterary +overlive +overlived +overlives +overliving +overload +overloaded +overloading +overloads +overlong +overlook +overlooked +overlooking +overlooks +overlord +overlorded +overlording +overlords +overlordship +overlordships +overloud +overlove +overloved +overloves +overloving +overlush +overly +overlying +overman +overmanage +overmanaged +overmanages +overmanaging +overmanned +overmannered +overmanning +overmans +overmantel +overmantels +overmany +overmaster +overmastered +overmastering +overmasters +overmatch +overmatched +overmatches +overmatching +overmature +overmaturities +overmaturity +overmedicate +overmedicated +overmedicates +overmedicating +overmedication +overmedications +overmeek +overmelt +overmelted +overmelting +overmelts +overmen +overmighty +overmild +overmilk +overmilked +overmilking +overmilks +overmine +overmined +overmines +overmining +overmix +overmixed +overmixes +overmixing +overmodest +overmodestly +overmodulated +overmuch +overmuches +overmuscled +overnear +overneat +overnew +overnice +overnight +overnighted +overnighter +overnighters +overnighting +overnights +overnourish +overnourished +overnourishes +overnourishing +overnutrition +overnutritions +overobvious +overoperate +overoperated +overoperates +overoperating +overopinionated +overoptimism +overoptimisms +overoptimist +overoptimistic +overoptimistically +overoptimists +overorchestrate +overorchestrated +overorchestrates +overorchestrating +overorganize +overorganized +overorganizes +overorganizing +overornament +overornamented +overornamenting +overornaments +overpackage +overpackaged +overpackages +overpackaging +overpaid +overparticular +overpass +overpassed +overpasses +overpassing +overpast +overpay +overpaying +overpayment +overpayments +overpays +overpedal +overpedaled +overpedaling +overpedalled +overpedalling +overpedals +overpeople +overpeopled +overpeoples +overpeopling +overpersuade +overpersuaded +overpersuades +overpersuading +overpersuasion +overpersuasions +overpert +overplaid +overplaided +overplaids +overplan +overplanned +overplanning +overplans +overplant +overplanted +overplanting +overplants +overplay +overplayed +overplaying +overplays +overplied +overplies +overplot +overplots +overplotted +overplotting +overplus +overpluses +overply +overplying +overpopulate +overpopulated +overpopulates +overpopulating +overpopulation +overpopulations +overpotent +overpower +overpowered +overpowering +overpoweringly +overpowers +overpraise +overpraised +overpraises +overpraising +overprecise +overprescribe +overprescribed +overprescribes +overprescribing +overprescription +overprescriptions +overpressure +overpressures +overprice +overpriced +overprices +overpricing +overprint +overprinted +overprinting +overprints +overprivileged +overprize +overprized +overprizes +overprizing +overprocess +overprocessed +overprocesses +overprocessing +overproduce +overproduced +overproduces +overproducing +overproduction +overproductions +overprogram +overprogramed +overprograming +overprogrammed +overprogramming +overprograms +overpromise +overpromised +overpromises +overpromising +overpromote +overpromoted +overpromotes +overpromoting +overproof +overproportion +overproportionate +overproportionately +overproportioned +overproportioning +overproportions +overprotect +overprotected +overprotecting +overprotection +overprotections +overprotective +overprotectiveness +overprotectivenesses +overprotects +overpump +overpumped +overpumping +overpumps +overqualified +overran +overrank +overrash +overrate +overrated +overrates +overrating +overreach +overreached +overreacher +overreachers +overreaches +overreaching +overreact +overreacted +overreacting +overreaction +overreactions +overreacts +overrefined +overrefinement +overrefinements +overregulate +overregulated +overregulates +overregulating +overregulation +overregulations +overreliance +overreliances +overreport +overreported +overreporting +overreports +overrepresentation +overrepresentations +overrepresented +overrespond +overresponded +overresponding +overresponds +overrich +overridden +override +overrides +overriding +overrife +overrigid +overripe +overrode +overrude +overruff +overruffed +overruffing +overruffs +overrule +overruled +overrules +overruling +overrun +overrunning +overruns +overs +oversad +oversale +oversales +oversalt +oversalted +oversalting +oversalts +oversanguine +oversaturate +oversaturated +oversaturates +oversaturating +oversaturation +oversaturations +oversauce +oversauced +oversauces +oversaucing +oversave +oversaved +oversaves +oversaving +oversaw +overscale +overscaled +overscrupulous +oversea +overseas +oversecretion +oversecretions +oversee +overseed +overseeded +overseeding +overseeds +overseeing +overseen +overseer +overseers +oversees +oversell +overselling +oversells +oversensitive +oversensitiveness +oversensitivenesses +oversensitivities +oversensitivity +overserious +overseriously +overservice +overserviced +overservices +overservicing +overset +oversets +oversetting +oversew +oversewed +oversewing +oversewn +oversews +oversexed +overshadow +overshadowed +overshadowing +overshadows +overshirt +overshirts +overshoe +overshoes +overshoot +overshooting +overshoots +overshot +overshots +oversick +overside +oversides +oversight +oversights +oversimple +oversimplification +oversimplifications +oversimplified +oversimplifies +oversimplify +oversimplifying +oversimplistic +oversimply +oversize +oversized +oversizes +overskirt +overskirts +overslaugh +overslaughed +overslaughing +overslaughs +oversleep +oversleeping +oversleeps +overslept +overslip +overslipped +overslipping +overslips +overslipt +overslow +oversmoke +oversmoked +oversmokes +oversmoking +oversoak +oversoaked +oversoaking +oversoaks +oversoft +oversold +oversolicitous +oversoon +oversophisticated +oversoul +oversouls +overspecialization +overspecializations +overspecialize +overspecialized +overspecializes +overspecializing +overspeculate +overspeculated +overspeculates +overspeculating +overspeculation +overspeculations +overspend +overspender +overspenders +overspending +overspends +overspent +overspill +overspills +overspin +overspins +overspread +overspreading +overspreads +overstabilities +overstability +overstaff +overstaffed +overstaffing +overstaffs +overstate +overstated +overstatement +overstatements +overstates +overstating +overstay +overstayed +overstaying +overstays +oversteer +oversteers +overstep +overstepped +overstepping +oversteps +overstimulate +overstimulated +overstimulates +overstimulating +overstimulation +overstimulations +overstir +overstirred +overstirring +overstirs +overstock +overstocked +overstocking +overstocks +overstories +overstory +overstrain +overstrained +overstraining +overstrains +overstress +overstressed +overstresses +overstressing +overstretch +overstretched +overstretches +overstretching +overstrew +overstrewed +overstrewing +overstrewn +overstrews +overstridden +overstride +overstrides +overstriding +overstrike +overstrikes +overstriking +overstrode +overstruck +overstructured +overstrung +overstuff +overstuffed +overstuffing +overstuffs +oversubscribe +oversubscribed +oversubscribes +oversubscribing +oversubscription +oversubscriptions +oversubtle +oversuds +oversudsed +oversudses +oversudsing +oversup +oversupped +oversupping +oversupplied +oversupplies +oversupply +oversupplying +oversups +oversure +oversuspicious +oversweet +oversweeten +oversweetened +oversweetening +oversweetens +oversweetness +oversweetnesses +overswing +overswinging +overswings +overswung +overt +overtake +overtaken +overtakes +overtaking +overtalk +overtalkative +overtalked +overtalking +overtalks +overtame +overtart +overtask +overtasked +overtasking +overtasks +overtax +overtaxation +overtaxations +overtaxed +overtaxes +overtaxing +overthin +overthink +overthinking +overthinks +overthought +overthrew +overthrow +overthrowing +overthrown +overthrows +overtighten +overtightened +overtightening +overtightens +overtime +overtimed +overtimes +overtiming +overtip +overtipped +overtipping +overtips +overtire +overtired +overtires +overtiring +overtly +overtness +overtnesses +overtoil +overtoiled +overtoiling +overtoils +overtone +overtones +overtook +overtop +overtopped +overtopping +overtops +overtrade +overtraded +overtrades +overtrading +overtrain +overtrained +overtraining +overtrains +overtreat +overtreated +overtreating +overtreatment +overtreatments +overtreats +overtrick +overtricks +overtrim +overtrimmed +overtrimming +overtrims +overtrump +overtrumped +overtrumping +overtrumps +overture +overtured +overtures +overturing +overturn +overturned +overturning +overturns +overurge +overurged +overurges +overurging +overuse +overused +overuses +overusing +overutilization +overutilizations +overutilize +overutilized +overutilizes +overutilizing +overvaluation +overvaluations +overvalue +overvalued +overvalues +overvaluing +overview +overviews +overviolent +overvivid +overvoltage +overvoltages +overvote +overvoted +overvotes +overvoting +overwarm +overwarmed +overwarming +overwarms +overwary +overwater +overwatered +overwatering +overwaters +overweak +overwear +overwearing +overwears +overweary +overween +overweened +overweening +overweeningly +overweens +overweigh +overweighed +overweighing +overweighs +overweight +overweighted +overweighting +overweights +overwet +overwets +overwetted +overwetting +overwhelm +overwhelmed +overwhelming +overwhelmingly +overwhelms +overwide +overwily +overwind +overwinding +overwinds +overwinter +overwintered +overwintering +overwinters +overwise +overwithheld +overwithhold +overwithholding +overwithholds +overword +overwords +overwore +overwork +overworked +overworking +overworks +overworn +overwound +overwrite +overwrites +overwriting +overwritten +overwrote +overwrought +overzeal +overzealous +overzealously +overzealousness +overzealousnesses +overzeals +ovibos +ovicidal +ovicide +ovicides +oviducal +oviduct +oviductal +oviducts +oviform +ovine +ovines +ovipara +oviparous +oviposit +oviposited +ovipositing +oviposition +ovipositional +ovipositions +ovipositor +ovipositors +oviposits +ovisac +ovisacs +ovoid +ovoidal +ovoids +ovolactovegetarian +ovolactovegetarians +ovoli +ovolo +ovolos +ovonic +ovonics +ovotestes +ovotestis +ovoviviparous +ovoviviparously +ovoviviparousness +ovoviviparousnesses +ovular +ovulary +ovulate +ovulated +ovulates +ovulating +ovulation +ovulations +ovulatory +ovule +ovules +ovum +ow +owe +owed +owes +owing +owl +owlet +owlets +owlish +owlishly +owlishness +owlishnesses +owllike +owls +own +ownable +owned +owner +owners +ownership +ownerships +owning +owns +owse +owsen +ox +oxacillin +oxacillins +oxalacetate +oxalacetates +oxalate +oxalated +oxalates +oxalating +oxalic +oxalis +oxalises +oxaloacetate +oxaloacetates +oxazepam +oxazepams +oxazine +oxazines +oxblood +oxbloods +oxbow +oxbows +oxcart +oxcarts +oxen +oxes +oxeye +oxeyes +oxford +oxfords +oxheart +oxhearts +oxid +oxidable +oxidant +oxidants +oxidase +oxidases +oxidasic +oxidate +oxidated +oxidates +oxidating +oxidation +oxidations +oxidative +oxidatively +oxide +oxides +oxidic +oxidise +oxidised +oxidiser +oxidisers +oxidises +oxidising +oxidizable +oxidize +oxidized +oxidizer +oxidizers +oxidizes +oxidizing +oxidoreductase +oxidoreductases +oxids +oxim +oxime +oximes +oxims +oxlip +oxlips +oxo +oxpecker +oxpeckers +oxtail +oxtails +oxter +oxters +oxtongue +oxtongues +oxy +oxyacetylene +oxyacid +oxyacids +oxygen +oxygenate +oxygenated +oxygenates +oxygenating +oxygenation +oxygenations +oxygenator +oxygenators +oxygenic +oxygenless +oxygens +oxyhemoglobin +oxyhemoglobins +oxyhydrogen +oxymora +oxymoron +oxymoronic +oxymoronically +oxymorons +oxyphenbutazone +oxyphenbutazones +oxyphil +oxyphile +oxyphiles +oxyphilic +oxyphils +oxysalt +oxysalts +oxysome +oxysomes +oxytetracycline +oxytetracyclines +oxytocic +oxytocics +oxytocin +oxytocins +oxytone +oxytones +oxyuriases +oxyuriasis +oy +oyer +oyers +oyes +oyesses +oyez +oyster +oystercatcher +oystercatchers +oystered +oysterer +oysterers +oystering +oysterings +oysterman +oystermen +oysters +ozocerite +ozocerites +ozokerite +ozokerites +ozonate +ozonated +ozonates +ozonating +ozonation +ozonations +ozone +ozones +ozonic +ozonide +ozonides +ozonise +ozonised +ozonises +ozonising +ozonization +ozonizations +ozonize +ozonized +ozonizer +ozonizers +ozonizes +ozonizing +ozonosphere +ozonospheres +ozonous +pa +pablum +pablums +pabular +pabulum +pabulums +pac +paca +pacas +pace +paced +pacemaker +pacemakers +pacemaking +pacemakings +pacer +pacers +paces +pacesetter +pacesetters +pacesetting +pacha +pachadom +pachadoms +pachalic +pachalics +pachas +pachinko +pachinkos +pachisi +pachisis +pachouli +pachoulis +pachuco +pachucos +pachyderm +pachydermatous +pachyderms +pachysandra +pachysandras +pachytene +pachytenes +pacifiable +pacific +pacifically +pacification +pacifications +pacificator +pacificators +pacificism +pacificisms +pacificist +pacificists +pacified +pacifier +pacifiers +pacifies +pacifism +pacifisms +pacifist +pacifistic +pacifistically +pacifists +pacify +pacifying +pacing +pack +packabilities +packability +packable +package +packaged +packager +packagers +packages +packaging +packboard +packboards +packed +packer +packers +packet +packeted +packeting +packets +packhorse +packhorses +packing +packinghouse +packinghouses +packings +packly +packman +packmen +packness +packnesses +packs +packsack +packsacks +packsaddle +packsaddles +packthread +packthreads +packwax +packwaxes +pacs +pact +paction +pactions +pacts +pad +padauk +padauks +padded +padder +padders +paddies +padding +paddings +paddle +paddleball +paddleballs +paddleboard +paddleboards +paddleboat +paddleboats +paddled +paddlefish +paddlefishes +paddler +paddlers +paddles +paddling +paddlings +paddock +paddocked +paddocking +paddocks +paddy +padi +padis +padishah +padishahs +padle +padles +padlock +padlocked +padlocking +padlocks +padnag +padnags +padouk +padouks +padre +padres +padri +padrone +padrones +padroni +pads +padshah +padshahs +paduasoy +paduasoys +paean +paeanism +paeanisms +paeans +paediatric +paediatrician +paediatricians +paediatrics +paedogeneses +paedogenesis +paedogenetic +paedogenetically +paedogenic +paedomorphic +paedomorphism +paedomorphisms +paedomorphoses +paedomorphosis +paella +paellas +paeon +paeons +paesan +paesani +paesano +paesanos +paesans +pagan +pagandom +pagandoms +paganise +paganised +paganises +paganish +paganising +paganism +paganisms +paganist +paganists +paganize +paganized +paganizer +paganizers +paganizes +paganizing +pagans +page +pageant +pageantries +pageantry +pageants +pageboy +pageboys +paged +pager +pagers +pages +paginal +paginate +paginated +paginates +paginating +pagination +paginations +paging +pagings +pagod +pagoda +pagodas +pagods +pagurian +pagurians +pagurid +pagurids +pah +pahlavi +pahlavis +pahoehoe +pahoehoes +paid +paik +paiked +paiking +paiks +pail +pailful +pailfuls +paillard +paillards +paillette +paillettes +pails +pailsful +pain +painch +painches +pained +painful +painfuller +painfullest +painfully +painfulness +painfulnesses +paining +painkiller +painkillers +painkilling +painless +painlessly +painlessness +painlessnesses +pains +painstaking +painstakingly +painstakings +paint +paintbrush +paintbrushes +painted +painter +painterliness +painterlinesses +painterly +painters +paintier +paintiest +painting +paintings +paints +paintwork +paintworks +painty +pair +paired +pairing +pairings +pairs +paisa +paisan +paisana +paisanas +paisano +paisanos +paisans +paisas +paise +paisley +paisleys +pajama +pajamaed +pajamas +pakeha +pakehas +pal +palabra +palabras +palace +palaced +palaces +paladin +paladins +palaestra +palaestrae +palais +palanquin +palanquins +palatabilities +palatability +palatable +palatableness +palatablenesses +palatably +palatal +palatalization +palatalizations +palatalize +palatalized +palatalizes +palatalizing +palatally +palatals +palate +palates +palatial +palatially +palatialness +palatialnesses +palatinate +palatinates +palatine +palatines +palaver +palavered +palavering +palavers +palazzi +palazzo +palazzos +pale +palea +paleae +paleal +paled +paleface +palefaces +palely +paleness +palenesses +paleoanthropological +paleoanthropologies +paleoanthropologist +paleoanthropologists +paleoanthropology +paleobiologic +paleobiological +paleobiologies +paleobiologist +paleobiologists +paleobiology +paleobotanic +paleobotanical +paleobotanically +paleobotanies +paleobotanist +paleobotanists +paleobotany +paleoclimatologies +paleoclimatologist +paleoclimatologists +paleoclimatology +paleoecologic +paleoecological +paleoecologies +paleoecologist +paleoecologists +paleoecology +paleogeographic +paleogeographical +paleogeographically +paleogeographies +paleogeography +paleographer +paleographers +paleographic +paleographical +paleographically +paleographies +paleography +paleomagnetic +paleomagnetically +paleomagnetism +paleomagnetisms +paleomagnetist +paleomagnetists +paleontologic +paleontological +paleontologies +paleontologist +paleontologists +paleontology +paleopathological +paleopathologies +paleopathologist +paleopathologists +paleopathology +paleosol +paleosols +paleozoological +paleozoologies +paleozoologist +paleozoologists +paleozoology +paler +pales +palest +palestra +palestrae +palestras +palet +paletot +paletots +palets +palette +palettes +paleways +palewise +palfrey +palfreys +palier +paliest +palikar +palikars +palimonies +palimony +palimpsest +palimpsests +palindrome +palindromes +palindromic +palindromist +palindromists +paling +palingeneses +palingenesis +palingenetic +palings +palinode +palinodes +palisade +palisaded +palisades +palisading +palish +pall +palladia +palladic +palladium +palladiums +palladous +pallbearer +pallbearers +palled +pallet +palletise +palletised +palletises +palletising +palletization +palletizations +palletize +palletized +palletizer +palletizers +palletizes +palletizing +pallets +pallette +pallettes +pallia +pallial +palliasse +palliasses +palliate +palliated +palliates +palliating +palliation +palliations +palliative +palliatively +palliatives +palliator +palliators +pallid +pallidly +pallidness +pallidnesses +pallier +palliest +palling +pallium +palliums +pallor +pallors +palls +pally +palm +palmar +palmary +palmate +palmated +palmately +palmation +palmations +palmed +palmer +palmers +palmerworm +palmerworms +palmette +palmettes +palmetto +palmettoes +palmettos +palmier +palmiest +palming +palmist +palmistries +palmistry +palmists +palmitate +palmitates +palmitin +palmitins +palmlike +palms +palmy +palmyra +palmyras +palomino +palominos +palooka +palookas +paloverde +paloverdes +palp +palpabilities +palpability +palpable +palpably +palpal +palpate +palpated +palpates +palpating +palpation +palpations +palpator +palpators +palpebra +palpebrae +palpebral +palpi +palpitant +palpitate +palpitated +palpitates +palpitating +palpitation +palpitations +palps +palpus +pals +palsgrave +palsgraves +palship +palships +palsied +palsies +palsy +palsying +palter +paltered +palterer +palterers +paltering +palters +paltrier +paltriest +paltrily +paltriness +paltrinesses +paltry +paludal +paludism +paludisms +paly +palynologic +palynological +palynologically +palynologies +palynologist +palynologists +palynology +pam +pampa +pampas +pampean +pampeans +pamper +pampered +pamperer +pamperers +pampering +pampero +pamperos +pampers +pamphlet +pamphleteer +pamphleteered +pamphleteering +pamphleteers +pamphlets +pams +pan +panacea +panacean +panaceas +panache +panaches +panada +panadas +panama +panamas +panatela +panatelas +panbroil +panbroiled +panbroiling +panbroils +pancake +pancaked +pancakes +pancaking +pancetta +pancettas +panchax +panchaxes +panchromatic +pancratium +pancratiums +pancreas +pancreases +pancreatectomies +pancreatectomized +pancreatectomy +pancreatic +pancreatin +pancreatins +pancreatitides +pancreatitis +pancreozymin +pancreozymins +pancytopenia +pancytopenias +panda +pandani +pandanus +pandanuses +pandas +pandect +pandects +pandemic +pandemics +pandemonium +pandemoniums +pander +pandered +panderer +panderers +pandering +panders +pandied +pandies +pandit +pandits +pandoor +pandoors +pandora +pandoras +pandore +pandores +pandour +pandours +pandowdies +pandowdy +pandura +panduras +pandy +pandying +pane +paned +panegyric +panegyrical +panegyrically +panegyrics +panegyrist +panegyrists +panel +paneled +paneling +panelings +panelist +panelists +panelled +panelling +panellings +panels +panes +panetela +panetelas +panettone +panettones +panfish +panfishes +panfried +panfries +panfry +panfrying +panful +panfuls +pang +panga +pangas +panged +pangen +pangene +pangenes +pangeneses +pangenesis +pangenetic +pangens +panging +pangolin +pangolins +pangs +panhandle +panhandled +panhandler +panhandlers +panhandles +panhandling +panhuman +panic +panicked +panickier +panickiest +panicking +panicky +panicle +panicled +panicles +panics +paniculate +panicum +panicums +panier +paniers +panjandra +panjandrum +panjandrums +panleukopenia +panleukopenias +panmictic +panmixes +panmixia +panmixias +panmixis +panmixises +panne +panned +pannes +pannier +panniers +pannikin +pannikins +panning +panocha +panochas +panoche +panoches +panoplied +panoplies +panoply +panoptic +panorama +panoramas +panoramic +panoramically +panpipe +panpipes +pans +pansexual +pansexualities +pansexuality +pansies +pansophies +pansophy +pansy +pant +pantalets +pantalettes +pantalone +pantalones +pantaloon +pantaloons +pantdress +pantdresses +pantechnicon +pantechnicons +panted +pantheism +pantheisms +pantheist +pantheistic +pantheistical +pantheistically +pantheists +pantheon +pantheons +panther +panthers +pantie +panties +pantile +pantiled +pantiles +panting +pantisocracies +pantisocracy +pantisocratic +pantisocratical +pantisocratist +pantisocratists +panto +pantofle +pantofles +pantograph +pantographic +pantographs +pantomime +pantomimed +pantomimes +pantomimic +pantomiming +pantomimist +pantomimists +pantos +pantothenate +pantothenates +pantoum +pantoums +pantries +pantropic +pantropical +pantry +pantryman +pantrymen +pants +pantsuit +pantsuited +pantsuits +panty +pantyhose +pantywaist +pantywaists +panzer +panzers +pap +papa +papacies +papacy +papain +papains +papal +papally +paparazzi +paparazzo +papas +papaverine +papaverines +papaw +papaws +papaya +papayan +papayas +paper +paperback +paperbacked +paperbacks +paperboard +paperboards +paperbound +paperbounds +paperboy +paperboys +papered +paperer +paperers +paperhanger +paperhangers +paperhanging +paperhangings +paperiness +paperinesses +papering +paperless +papermaker +papermakers +papermaking +papermakings +papers +paperweight +paperweights +paperwork +paperworks +papery +papeterie +papeteries +paphian +paphians +papilionaceous +papilla +papillae +papillar +papillary +papillate +papilloma +papillomas +papillomata +papillomatous +papillomavirus +papillomaviruses +papillon +papillons +papillose +papillote +papillotes +papist +papistic +papistries +papistry +papists +papoose +papooses +papovavirus +papovaviruses +pappi +pappier +pappies +pappiest +pappoose +pappooses +pappose +pappous +pappus +pappy +paprica +papricas +paprika +paprikas +paps +papula +papulae +papular +papule +papules +papulose +papyral +papyri +papyrian +papyrine +papyrologies +papyrologist +papyrologists +papyrology +papyrus +papyruses +par +para +parabioses +parabiosis +parabiotic +parabiotically +parable +parables +parabola +parabolas +parabolic +parabolically +paraboloid +paraboloidal +paraboloids +parachor +parachors +parachute +parachuted +parachutes +parachutic +parachuting +parachutist +parachutists +parade +paraded +parader +paraders +parades +paradichlorobenzene +paradichlorobenzenes +paradiddle +paradiddles +paradigm +paradigmatic +paradigmatically +paradigms +parading +paradisaic +paradisaical +paradisaically +paradisal +paradise +paradises +paradisiac +paradisiacal +paradisiacally +paradisial +paradisical +parador +paradores +paradors +parados +paradoses +paradox +paradoxes +paradoxical +paradoxicalities +paradoxicality +paradoxically +paradoxicalness +paradoxicalnesses +paradrop +paradropped +paradropping +paradrops +paraesthesia +paraesthesias +paraffin +paraffined +paraffinic +paraffining +paraffins +paraform +paraformaldehyde +paraformaldehydes +paraforms +parageneses +paragenesis +paragenetic +paragenetically +paragoge +paragoges +paragon +paragoned +paragoning +paragons +paragraph +paragraphed +paragrapher +paragraphers +paragraphic +paragraphing +paragraphs +parainfluenza +parainfluenzas +parajournalism +parajournalisms +parakeet +parakeets +parakite +parakites +paralanguage +paralanguages +paraldehyde +paraldehydes +paralegal +paralegals +paralinguistic +paralinguistics +parallactic +parallax +parallaxes +parallel +paralleled +parallelepiped +parallelepipeds +paralleling +parallelism +parallelisms +parallelled +parallelling +parallelogram +parallelograms +parallels +paralogism +paralogisms +paralyse +paralysed +paralyses +paralysing +paralysis +paralytic +paralytically +paralytics +paralyzation +paralyzations +paralyze +paralyzed +paralyzer +paralyzers +paralyzes +paralyzing +paralyzingly +paramagnet +paramagnetic +paramagnetically +paramagnetism +paramagnetisms +paramagnets +paramecia +paramecium +parameciums +paramedic +paramedical +paramedicals +paramedics +parament +paramenta +paraments +parameter +parameterization +parameterizations +parameterize +parameterized +parameterizes +parameterizing +parameters +parametric +parametrically +parametrization +parametrizations +parametrize +parametrized +parametrizes +parametrizing +paramilitary +paramnesia +paramnesias +paramo +paramos +paramount +paramountcies +paramountcy +paramountly +paramounts +paramour +paramours +paramylum +paramylums +paramyxovirus +paramyxoviruses +parang +parangs +paranoea +paranoeas +paranoia +paranoiac +paranoiacs +paranoias +paranoic +paranoically +paranoics +paranoid +paranoidal +paranoids +paranormal +paranormalities +paranormality +paranormally +paranormals +paranymph +paranymphs +parapet +parapeted +parapets +paraph +paraphernalia +paraphrasable +paraphrase +paraphrased +paraphraser +paraphrasers +paraphrases +paraphrasing +paraphrastic +paraphrastically +paraphs +paraphyses +paraphysis +paraplegia +paraplegias +paraplegic +paraplegics +parapodia +parapodial +parapodium +paraprofessional +paraprofessionals +parapsychological +parapsychologies +parapsychologist +parapsychologists +parapsychology +paraquat +paraquats +paraquet +paraquets +pararosaniline +pararosanilines +paras +parasailing +parasailings +parasang +parasangs +parasexual +parasexualities +parasexuality +parashah +parashioth +parashoth +parasite +parasites +parasitic +parasitical +parasitically +parasiticidal +parasiticide +parasiticides +parasitise +parasitised +parasitises +parasitising +parasitism +parasitisms +parasitization +parasitizations +parasitize +parasitized +parasitizes +parasitizing +parasitoid +parasitoids +parasitologic +parasitological +parasitologically +parasitologies +parasitologist +parasitologists +parasitology +parasitoses +parasitosis +parasol +parasols +parasympathetic +parasympathetics +parasympathomimetic +parasyntheses +parasynthesis +parasynthetic +paratactic +paratactical +paratactically +parataxes +parataxis +parathion +parathions +parathormone +parathormones +parathyroid +parathyroidectomies +parathyroidectomized +parathyroidectomy +parathyroids +paratroop +paratrooper +paratroopers +paratroops +paratyphoid +paratyphoids +paravane +paravanes +parawing +parawings +parazoan +parazoans +parboil +parboiled +parboiling +parboils +parbuckle +parbuckled +parbuckles +parbuckling +parcel +parceled +parceling +parcelled +parcelling +parcels +parcenaries +parcenary +parcener +parceners +parch +parched +parches +parchesi +parchesis +parching +parchisi +parchisis +parchment +parchments +pard +pardah +pardahs +pardee +pardi +pardie +pardine +pardner +pardners +pardon +pardonable +pardonableness +pardonablenesses +pardonably +pardoned +pardoner +pardoners +pardoning +pardons +pards +pardy +pare +parecism +parecisms +pared +paregoric +paregorics +pareira +pareiras +parenchyma +parenchymal +parenchymas +parenchymata +parenchymatous +parent +parentage +parentages +parental +parentally +parented +parenteral +parenterally +parentheses +parenthesis +parenthesize +parenthesized +parenthesizes +parenthesizing +parenthetic +parenthetical +parenthetically +parenthood +parenthoods +parenting +parentings +parentless +parents +pareo +pareos +parer +parerga +parergon +parers +pares +pareses +paresis +paresthesia +paresthesias +paresthetic +paretic +paretics +pareu +pareus +pareve +parfait +parfaits +parfleche +parfleches +parflesh +parfleshes +parfocal +parfocalities +parfocality +parfocalize +parfocalized +parfocalizes +parfocalizing +parge +parged +parges +parget +pargeted +pargeting +pargets +pargetted +pargetting +parging +pargings +pargo +pargos +pargyline +pargylines +parhelia +parhelic +parhelion +pariah +pariahs +parian +parians +paries +parietal +parietals +parietes +parimutuel +paring +parings +paris +parises +parish +parishes +parishioner +parishioners +parities +parity +park +parka +parkas +parked +parker +parkers +parking +parkings +parkinsonian +parkinsonism +parkinsonisms +parkland +parklands +parklike +parks +parkway +parkways +parlance +parlances +parlando +parlante +parlay +parlayed +parlaying +parlays +parle +parled +parles +parley +parleyed +parleyer +parleyers +parleying +parleys +parliament +parliamentarian +parliamentarians +parliamentary +parliaments +parling +parlor +parlors +parlour +parlours +parlous +parlously +parmigiana +parmigiano +parochial +parochialism +parochialisms +parochially +parodic +parodied +parodies +parodist +parodistic +parodists +parodoi +parodos +parody +parodying +parol +parole +paroled +parolee +parolees +paroles +paroling +parols +paronomasia +paronomasias +paronomastic +paronym +paronymous +paronyms +paroquet +paroquets +parotic +parotid +parotids +parotitis +parotitises +parotoid +parotoids +parous +paroxysm +paroxysmal +paroxysms +parquet +parqueted +parqueting +parquetries +parquetry +parquets +parr +parrakeet +parrakeets +parral +parrals +parred +parrel +parrels +parricidal +parricide +parricides +parridge +parridges +parried +parries +parring +parritch +parritches +parroket +parrokets +parrot +parroted +parroter +parroters +parroting +parrots +parroty +parrs +parry +parrying +pars +parsable +parse +parsec +parsecs +parsed +parser +parsers +parses +parsimonies +parsimonious +parsimoniously +parsimony +parsing +parsley +parsleyed +parsleys +parslied +parsnip +parsnips +parson +parsonage +parsonages +parsonic +parsons +part +partake +partaken +partaker +partakers +partakes +partaking +partan +partans +parted +parterre +parterres +parthenocarpic +parthenocarpies +parthenocarpy +parthenogeneses +parthenogenesis +parthenogenetic +parthenogenetically +partial +partialities +partiality +partially +partials +partibilities +partibility +partible +participant +participants +participate +participated +participates +participating +participation +participational +participations +participative +participator +participators +participatory +participial +participially +participle +participles +particle +particleboard +particleboards +particles +particular +particularise +particularised +particularises +particularising +particularism +particularisms +particularist +particularistic +particularists +particularities +particularity +particularization +particularizations +particularize +particularized +particularizes +particularizing +particularly +particulars +particulate +particulates +partied +partier +partiers +parties +parting +partings +partisan +partisanly +partisans +partisanship +partisanships +partita +partitas +partite +partition +partitioned +partitioner +partitioners +partitioning +partitionist +partitionists +partitions +partitive +partitively +partizan +partizans +partlet +partlets +partly +partner +partnered +partnering +partnerless +partners +partnership +partnerships +parton +partons +partook +partridge +partridgeberries +partridgeberry +partridges +parts +parturient +parturients +parturition +parturitions +partway +party +partyer +partyers +partying +parura +paruras +parure +parures +parve +parvenu +parvenue +parvenus +parvis +parvise +parvises +parvo +parvolin +parvolins +parvos +parvovirus +parvoviruses +pas +pascal +pascals +paschal +paschals +pase +paseo +paseos +pases +pash +pasha +pashadom +pashadoms +pashalic +pashalics +pashalik +pashaliks +pashas +pashed +pashes +pashing +pasqueflower +pasqueflowers +pasquil +pasquils +pasquinade +pasquinaded +pasquinades +pasquinading +pass +passable +passably +passacaglia +passacaglias +passade +passades +passado +passadoes +passados +passage +passaged +passages +passageway +passageways +passagework +passageworks +passaging +passant +passband +passbands +passbook +passbooks +passe +passed +passee +passel +passels +passementerie +passementeries +passenger +passengers +passer +passerby +passerine +passerines +passers +passersby +passes +passible +passim +passing +passings +passion +passional +passionate +passionately +passionateness +passionatenesses +passionflower +passionflowers +passionless +passions +passivate +passivated +passivates +passivating +passivation +passivations +passive +passively +passiveness +passivenesses +passives +passivism +passivisms +passivist +passivists +passivities +passivity +passkey +passkeys +passless +passover +passovers +passport +passports +passus +passuses +password +passwords +past +pasta +pastas +paste +pasteboard +pasteboards +pasted +pastedown +pastedowns +pastel +pastelist +pastelists +pastellist +pastellists +pastels +paster +pastern +pasterns +pasters +pastes +pasteup +pasteups +pasteurise +pasteurised +pasteurises +pasteurising +pasteurization +pasteurizations +pasteurize +pasteurized +pasteurizer +pasteurizers +pasteurizes +pasteurizing +pasticci +pasticcio +pasticcios +pastiche +pastiches +pasticheur +pasticheurs +pastie +pastier +pasties +pastiest +pastil +pastille +pastilles +pastils +pastime +pastimes +pastina +pastinas +pastiness +pastinesses +pasting +pastis +pastises +pastless +pastness +pastnesses +pastor +pastoral +pastorale +pastorales +pastoralism +pastoralisms +pastoralist +pastoralists +pastorally +pastoralness +pastoralnesses +pastorals +pastorate +pastorates +pastored +pastoring +pastors +pastorship +pastorships +pastrami +pastramis +pastries +pastromi +pastromis +pastry +pasts +pasturage +pasturages +pastural +pasture +pastured +pastureland +pasturelands +pasturer +pasturers +pastures +pasturing +pasty +pat +pataca +patacas +patagia +patagial +patagium +patamar +patamars +patch +patchboard +patchboards +patched +patcher +patchers +patches +patchier +patchiest +patchily +patchiness +patchinesses +patching +patchouli +patchoulies +patchoulis +patchouly +patchwork +patchworks +patchy +pate +pated +patella +patellae +patellar +patellas +patelliform +paten +patencies +patency +patens +patent +patentabilities +patentability +patentable +patented +patentee +patentees +patenting +patently +patentor +patentors +patents +pater +paterfamilias +paternal +paternalism +paternalisms +paternalist +paternalistic +paternalistically +paternalists +paternally +paternities +paternity +paternoster +paternosters +paters +pates +path +pathbreaking +pathetic +pathetical +pathetically +pathfinder +pathfinders +pathfinding +pathfindings +pathless +pathlessness +pathlessnesses +pathobiologies +pathobiology +pathogen +pathogeneses +pathogenesis +pathogenetic +pathogenic +pathogenicities +pathogenicity +pathogens +pathognomonic +pathologic +pathological +pathologically +pathologies +pathologist +pathologists +pathology +pathophysiologic +pathophysiological +pathophysiologies +pathophysiology +pathos +pathoses +paths +pathway +pathways +patience +patiences +patient +patienter +patientest +patiently +patients +patin +patina +patinae +patinas +patinate +patinated +patinates +patinating +patination +patinations +patine +patined +patines +patining +patinize +patinized +patinizes +patinizing +patins +patio +patios +patisserie +patisseries +patissier +patissiers +patly +patness +patnesses +patois +patresfamilias +patriarch +patriarchal +patriarchate +patriarchates +patriarchies +patriarchs +patriarchy +patrician +patricians +patriciate +patriciates +patricidal +patricide +patricides +patrilineal +patrimonial +patrimonies +patrimony +patriot +patriotic +patriotically +patriotism +patriotisms +patriots +patristic +patristical +patristics +patrol +patrolled +patroller +patrollers +patrolling +patrolman +patrolmen +patrols +patron +patronage +patronages +patronal +patroness +patronesses +patronise +patronised +patronises +patronising +patronization +patronizations +patronize +patronized +patronizes +patronizing +patronizingly +patronly +patrons +patronymic +patronymics +patroon +patroons +pats +patsies +patsy +pattamar +pattamars +patted +pattee +patten +pattens +patter +pattered +patterer +patterers +pattering +pattern +patterned +patterning +patternings +patternless +patterns +patters +pattie +patties +patting +patty +pattypan +pattypans +patulent +patulous +paty +patzer +patzers +paucities +paucity +paughty +pauldron +pauldrons +paulin +paulins +paulownia +paulownias +paunch +paunched +paunches +paunchier +paunchiest +paunchiness +paunchinesses +paunchy +pauper +paupered +paupering +pauperism +pauperisms +pauperize +pauperized +pauperizes +pauperizing +paupers +paupiette +paupiettes +pausal +pause +paused +pauser +pausers +pauses +pausing +pavan +pavane +pavanes +pavans +pave +paved +paveed +pavement +pavements +paver +pavers +paves +pavid +pavilion +pavilioned +pavilioning +pavilions +pavillon +pavillons +pavin +paving +pavings +pavins +pavior +paviors +paviour +paviours +pavis +pavise +paviser +pavisers +pavises +pavlova +pavlovas +pavonine +paw +pawed +pawer +pawers +pawing +pawkier +pawkiest +pawkily +pawky +pawl +pawls +pawn +pawnable +pawnage +pawnages +pawnbroker +pawnbrokers +pawnbroking +pawnbrokings +pawned +pawnee +pawnees +pawner +pawners +pawning +pawnor +pawnors +pawns +pawnshop +pawnshops +pawpaw +pawpaws +paws +pax +paxes +paxwax +paxwaxes +pay +payable +payables +payably +payback +paybacks +paycheck +paychecks +payday +paydays +payed +payee +payees +payer +payers +paygrade +paygrades +paying +payload +payloads +paymaster +paymasters +payment +payments +paynim +paynims +payoff +payoffs +payola +payolas +payor +payors +payout +payouts +payroll +payrolls +pays +pazazz +pazazzes +pe +pea +peace +peaceable +peaceableness +peaceablenesses +peaceably +peaced +peaceful +peacefuller +peacefullest +peacefully +peacefulness +peacefulnesses +peacekeeper +peacekeepers +peacekeeping +peacekeepings +peacemaker +peacemakers +peacemaking +peacemakings +peacenik +peaceniks +peaces +peacetime +peacetimes +peach +peached +peacher +peachers +peaches +peachier +peachiest +peaching +peachy +peacing +peacoat +peacoats +peacock +peacocked +peacockier +peacockiest +peacocking +peacockish +peacocks +peacocky +peafowl +peafowls +peag +peage +peages +peags +peahen +peahens +peak +peaked +peakedness +peakednesses +peakier +peakiest +peaking +peakish +peakless +peaklike +peaks +peaky +peal +pealed +pealike +pealing +peals +pean +peans +peanut +peanuts +pear +pearl +pearlash +pearlashes +pearled +pearler +pearlers +pearlescence +pearlescences +pearlescent +pearlier +pearliest +pearling +pearlite +pearlites +pearlitic +pearlized +pearls +pearly +pearmain +pearmains +pears +peart +pearter +peartest +peartly +peas +peasant +peasantries +peasantry +peasants +peascod +peascods +pease +peasecod +peasecods +peasen +peases +peashooter +peashooters +peat +peatier +peatiest +peats +peaty +peavey +peaveys +peavies +peavy +pebble +pebbled +pebbles +pebblier +pebbliest +pebbling +pebbly +pec +pecan +pecans +peccable +peccadillo +peccadilloes +peccadillos +peccancies +peccancy +peccant +peccantly +peccaries +peccary +peccavi +peccavis +pech +pechan +pechans +peched +peching +pechs +peck +pecked +pecker +peckers +peckerwood +peckerwoods +peckier +peckiest +pecking +peckish +pecks +pecky +pecorini +pecorino +pecorinos +pecs +pectase +pectases +pectate +pectates +pecten +pectens +pectic +pectin +pectinaceous +pectinate +pectination +pectinations +pectines +pectinesterase +pectinesterases +pectins +pectize +pectized +pectizes +pectizing +pectoral +pectorals +peculate +peculated +peculates +peculating +peculation +peculations +peculator +peculators +peculia +peculiar +peculiarities +peculiarity +peculiarly +peculiars +peculium +pecuniarily +pecuniary +ped +pedagog +pedagogic +pedagogical +pedagogically +pedagogics +pedagogies +pedagogs +pedagogue +pedagogues +pedagogy +pedal +pedaled +pedalfer +pedalfers +pedalier +pedaliers +pedaling +pedalled +pedalling +pedalo +pedalos +pedals +pedant +pedantic +pedantically +pedantries +pedantry +pedants +pedate +pedately +peddle +peddled +peddler +peddleries +peddlers +peddlery +peddles +peddling +pederast +pederastic +pederasties +pederasts +pederasty +pedes +pedestal +pedestaled +pedestaling +pedestalled +pedestalling +pedestals +pedestrian +pedestrianism +pedestrianisms +pedestrians +pediatric +pediatrician +pediatricians +pediatrics +pediatrist +pediatrists +pedicab +pedicabs +pedicel +pedicellate +pedicels +pedicle +pedicled +pedicles +pediculate +pediculates +pediculoses +pediculosis +pediculosises +pediculous +pedicure +pedicured +pedicures +pedicuring +pedicurist +pedicurists +pediform +pedigree +pedigreed +pedigrees +pediment +pedimental +pedimented +pediments +pedipalp +pedipalps +pedlar +pedlaries +pedlars +pedlary +pedler +pedleries +pedlers +pedlery +pedocal +pedocalic +pedocals +pedogeneses +pedogenesis +pedogenetic +pedogenic +pedologic +pedological +pedologies +pedologist +pedologists +pedology +pedometer +pedometers +pedophile +pedophiles +pedophilia +pedophiliac +pedophilias +pedophilic +pedro +pedros +peds +peduncle +peduncled +peduncles +peduncular +pedunculate +pedunculated +pee +peebeen +peebeens +peed +peeing +peek +peekaboo +peekaboos +peeked +peeking +peeks +peel +peelable +peeled +peeler +peelers +peeling +peelings +peels +peen +peened +peening +peens +peep +peeped +peeper +peepers +peephole +peepholes +peeping +peeps +peepshow +peepshows +peepul +peepuls +peer +peerage +peerages +peered +peeress +peeresses +peerie +peeries +peering +peerless +peerlessly +peers +peery +pees +peesweep +peesweeps +peetweet +peetweets +peeve +peeved +peeves +peeving +peevish +peevishly +peevishness +peevishnesses +peewee +peewees +peewit +peewits +peg +pegboard +pegboards +pegbox +pegboxes +pegged +pegging +pegless +peglike +pegmatite +pegmatites +pegmatitic +pegs +peh +pehs +peignoir +peignoirs +pein +peined +peining +peins +peise +peised +peises +peising +pejorative +pejoratively +pejoratives +pekan +pekans +peke +pekes +pekin +pekins +pekoe +pekoes +pelage +pelages +pelagial +pelagic +pelargonium +pelargoniums +pele +pelecypod +pelecypods +pelerine +pelerines +peles +pelf +pelfs +pelican +pelicans +pelisse +pelisses +pelite +pelites +pelitic +pellagra +pellagras +pellagrin +pellagrins +pellagrous +pellet +pelletal +pelleted +pelleting +pelletise +pelletised +pelletises +pelletising +pelletization +pelletizations +pelletize +pelletized +pelletizer +pelletizers +pelletizes +pelletizing +pellets +pellicle +pellicles +pellitories +pellitory +pellmell +pellmells +pellucid +pellucidly +pelmet +pelmets +pelon +peloria +pelorian +pelorias +peloric +pelorus +peloruses +pelota +pelotas +pelt +peltast +peltasts +peltate +pelted +pelter +peltered +peltering +pelters +pelting +peltries +peltry +pelts +pelves +pelvic +pelvics +pelvis +pelvises +pelycosaur +pelycosaurs +pembina +pembinas +pemican +pemicans +pemmican +pemmicans +pemoline +pemolines +pemphigus +pemphiguses +pemphix +pemphixes +pen +penal +penalise +penalised +penalises +penalising +penalities +penality +penalization +penalizations +penalize +penalized +penalizes +penalizing +penally +penalties +penalty +penance +penanced +penances +penancing +penang +penangs +penates +pence +pencel +pencels +penchant +penchants +pencil +penciled +penciler +pencilers +penciling +pencilings +pencilled +pencilling +pencillings +pencils +pend +pendant +pendants +pended +pendencies +pendency +pendent +pendentive +pendentives +pendents +pending +pends +pendular +pendulous +pendulousness +pendulousnesses +pendulum +pendulums +peneplain +peneplains +peneplane +peneplanes +penes +penetrabilities +penetrability +penetrable +penetralia +penetrance +penetrances +penetrant +penetrants +penetrate +penetrated +penetrates +penetrating +penetratingly +penetration +penetrations +penetrative +penetrometer +penetrometers +pengo +pengos +penguin +penguins +penholder +penholders +penial +penicil +penicillamine +penicillamines +penicillate +penicillia +penicillin +penicillinase +penicillinases +penicillins +penicillium +penicils +penile +peninsula +peninsular +peninsulas +penis +penises +penitence +penitences +penitent +penitential +penitentially +penitentiaries +penitentiary +penitently +penitents +penknife +penknives +penlight +penlights +penlite +penlites +penman +penmanship +penmanships +penmen +penna +pennae +penname +pennames +pennant +pennants +pennate +pennated +penne +penned +penner +penners +penni +pennia +pennies +penniless +pennine +pennines +penning +pennis +pennon +pennoncel +pennoncels +pennoned +pennons +penny +pennycress +pennycresses +pennyroyal +pennyroyals +pennyweight +pennyweights +pennywhistle +pennywhistles +pennywort +pennyworth +pennyworths +pennyworts +penoche +penoches +penological +penologies +penologist +penologists +penology +penoncel +penoncels +penpoint +penpoints +pens +pensee +pensees +pensil +pensile +pensils +pension +pensionable +pensionaries +pensionary +pensione +pensioned +pensioner +pensioners +pensiones +pensioning +pensionless +pensions +pensive +pensively +pensiveness +pensivenesses +penstemon +penstemons +penster +pensters +penstock +penstocks +pent +pentachlorophenol +pentachlorophenols +pentacle +pentacles +pentad +pentads +pentagon +pentagonal +pentagonally +pentagonals +pentagons +pentagram +pentagrams +pentahedra +pentahedral +pentahedron +pentahedrons +pentamerous +pentameter +pentameters +pentamidine +pentamidines +pentane +pentanes +pentangle +pentangles +pentanol +pentanols +pentapeptide +pentapeptides +pentaploid +pentaploidies +pentaploids +pentaploidy +pentarch +pentarchies +pentarchs +pentarchy +pentathlete +pentathletes +pentathlon +pentathlons +pentatonic +pentavalent +pentazocine +pentazocines +pentene +pentenes +penthouse +penthouses +pentlandite +pentlandites +pentobarbital +pentobarbitals +pentobarbitone +pentobarbitones +pentode +pentodes +pentomic +pentosan +pentosans +pentose +pentoses +pentoxide +pentoxides +pentstemon +pentstemons +pentyl +pentylenetetrazol +pentylenetetrazols +pentyls +penuche +penuches +penuchi +penuchis +penuchle +penuchles +penuckle +penuckles +penult +penultima +penultimas +penultimate +penultimately +penults +penumbra +penumbrae +penumbral +penumbras +penuries +penurious +penuriously +penuriousness +penuriousnesses +penury +peon +peonage +peonages +peones +peonies +peonism +peonisms +peons +peony +people +peopled +peoplehood +peoplehoods +peopleless +peopler +peoplers +peoples +peopling +pep +peperomia +peperomias +peperoni +peperonis +pepla +peplos +peploses +peplum +peplumed +peplums +peplus +pepluses +pepo +peponida +peponidas +peponium +peponiums +pepos +pepped +pepper +pepperbox +pepperboxes +peppercorn +peppercorns +peppered +pepperer +pepperers +peppergrass +peppergrasses +pepperiness +pepperinesses +peppering +peppermint +peppermints +pepperminty +pepperoni +pepperonis +peppers +peppertree +peppertrees +peppery +peppier +peppiest +peppily +peppiness +peppinesses +pepping +peppy +peps +pepsin +pepsine +pepsines +pepsinogen +pepsinogens +pepsins +peptic +peptics +peptid +peptidase +peptidases +peptide +peptides +peptidic +peptidoglycan +peptidoglycans +peptids +peptize +peptized +peptizer +peptizers +peptizes +peptizing +peptone +peptones +peptonic +per +peracid +peracids +peradventure +peradventures +perambulate +perambulated +perambulates +perambulating +perambulation +perambulations +perambulator +perambulators +perambulatory +perborate +perborates +percale +percales +percaline +percalines +perceivable +perceivably +perceive +perceived +perceiver +perceivers +perceives +perceiving +percent +percentage +percentages +percentile +percentiles +percents +percept +perceptibilities +perceptibility +perceptible +perceptibly +perception +perceptional +perceptions +perceptive +perceptively +perceptiveness +perceptivenesses +perceptivities +perceptivity +percepts +perceptual +perceptually +perch +perchance +perched +percher +perchers +perches +perching +perchlorate +perchlorates +perchloroethylene +perchloroethylenes +percipience +percipiences +percipient +percipiently +percipients +percoid +percoids +percolate +percolated +percolates +percolating +percolation +percolations +percolator +percolators +percuss +percussed +percusses +percussing +percussion +percussionist +percussionists +percussions +percussive +percussively +percussiveness +percussivenesses +percutaneous +percutaneously +perdie +perdition +perditions +perdu +perdue +perdues +perdurabilities +perdurability +perdurable +perdurably +perdure +perdured +perdures +perduring +perdus +perdy +perea +peregrin +peregrinate +peregrinated +peregrinates +peregrinating +peregrination +peregrinations +peregrine +peregrines +peregrins +pereia +pereion +pereiopod +pereiopods +peremptorily +peremptoriness +peremptorinesses +peremptory +perennate +perennated +perennates +perennating +perennation +perennations +perennial +perennially +perennials +pereon +pereopod +pereopods +perestroika +perestroikas +perfect +perfecta +perfectas +perfected +perfecter +perfecters +perfectest +perfectibilities +perfectibility +perfectible +perfecting +perfection +perfectionism +perfectionisms +perfectionist +perfectionistic +perfectionists +perfections +perfective +perfectively +perfectiveness +perfectivenesses +perfectives +perfectivities +perfectivity +perfectly +perfectness +perfectnesses +perfecto +perfectos +perfects +perfervid +perfidies +perfidious +perfidiously +perfidiousness +perfidiousnesses +perfidy +perfoliate +perforate +perforated +perforates +perforating +perforation +perforations +perforator +perforators +perforce +perform +performabilities +performability +performable +performance +performances +performative +performatives +performatory +performed +performer +performers +performing +performs +perfume +perfumed +perfumer +perfumeries +perfumers +perfumery +perfumes +perfuming +perfunctorily +perfunctoriness +perfunctorinesses +perfunctory +perfusate +perfusates +perfuse +perfused +perfuses +perfusing +perfusion +perfusionist +perfusionists +perfusions +pergola +pergolas +perhaps +perhapses +peri +perianth +perianths +periapt +periapts +periblem +periblems +pericardia +pericardial +pericarditides +pericarditis +pericardium +pericarp +pericarps +perichondral +perichondria +perichondrium +pericopae +pericope +pericopes +pericrania +pericranial +pericranium +pericycle +pericycles +pericyclic +periderm +periderms +peridia +peridial +peridium +peridot +peridotic +peridotite +peridotites +peridotitic +peridots +perigeal +perigean +perigee +perigees +perigon +perigons +perigynies +perigynous +perigyny +perihelia +perihelial +perihelion +perikarya +perikaryal +perikaryon +peril +periled +periling +perilla +perillas +perilled +perilling +perilous +perilously +perilousness +perilousnesses +perils +perilune +perilunes +perilymph +perilymphs +perimeter +perimeters +perimysia +perimysium +perinatal +perinatally +perinea +perineal +perineum +perineuria +perineurium +period +periodic +periodical +periodically +periodicals +periodicities +periodicity +periodid +periodids +periodization +periodizations +periodontal +periodontally +periodontics +periodontist +periodontists +periodontologies +periodontology +periods +perionychia +perionychium +periostea +periosteal +periosteum +periostites +periostitides +periostitis +periostitises +periotic +peripatetic +peripatetically +peripatetics +peripatus +peripatuses +peripeteia +peripeteias +peripeties +peripety +peripheral +peripherally +peripherals +peripheries +periphery +periphrases +periphrasis +periphrastic +periphrastically +periphytic +periphyton +periphytons +periplast +periplasts +peripter +peripters +perique +periques +peris +perisarc +perisarcs +periscope +periscopes +periscopic +perish +perishabilities +perishability +perishable +perishables +perished +perishes +perishing +perissodactyl +perissodactyls +peristalses +peristalsis +peristaltic +peristome +peristomes +peristomial +peristyle +peristyles +perithecia +perithecial +perithecium +peritonea +peritoneal +peritoneally +peritoneum +peritoneums +peritonites +peritonitides +peritonitis +peritonitises +peritrichous +peritrichously +periwig +periwigged +periwigs +periwinkle +periwinkles +perjure +perjured +perjurer +perjurers +perjures +perjuries +perjuring +perjurious +perjuriously +perjury +perk +perked +perkier +perkiest +perkily +perkiness +perkinesses +perking +perkish +perks +perky +perlite +perlites +perlitic +perm +permafrost +permafrosts +permanence +permanences +permanencies +permanency +permanent +permanently +permanentness +permanentnesses +permanents +permanganate +permanganates +permeabilities +permeability +permeable +permeant +permease +permeases +permeate +permeated +permeates +permeating +permeation +permeations +permeative +permed +permethrin +permethrins +permillage +permillages +perming +permissibilities +permissibility +permissible +permissibleness +permissiblenesses +permissibly +permission +permissions +permissive +permissively +permissiveness +permissivenesses +permit +permits +permitted +permittee +permittees +permitter +permitters +permitting +permittivities +permittivity +perms +permutable +permutation +permutational +permutations +permute +permuted +permutes +permuting +pernicious +perniciously +perniciousness +perniciousnesses +pernickety +peroneal +peroral +perorally +perorate +perorated +perorates +perorating +peroration +perorational +perorations +perovskite +perovskites +peroxid +peroxidase +peroxidases +peroxide +peroxided +peroxides +peroxidic +peroxiding +peroxids +peroxisomal +peroxisome +peroxisomes +peroxy +perpend +perpended +perpendicular +perpendicularities +perpendicularity +perpendicularly +perpendiculars +perpending +perpends +perpent +perpents +perpetrate +perpetrated +perpetrates +perpetrating +perpetration +perpetrations +perpetrator +perpetrators +perpetual +perpetually +perpetuate +perpetuated +perpetuates +perpetuating +perpetuation +perpetuations +perpetuator +perpetuators +perpetuities +perpetuity +perphenazine +perphenazines +perplex +perplexed +perplexedly +perplexes +perplexing +perplexities +perplexity +perquisite +perquisites +perries +perron +perrons +perry +persalt +persalts +perse +persecute +persecuted +persecutee +persecutees +persecutes +persecuting +persecution +persecutions +persecutive +persecutor +persecutors +persecutory +perses +perseverance +perseverances +perseverate +perseverated +perseverates +perseverating +perseveration +perseverations +persevere +persevered +perseveres +persevering +perseveringly +persiflage +persiflages +persimmon +persimmons +persist +persisted +persistence +persistences +persistencies +persistency +persistent +persistently +persister +persisters +persisting +persists +persnicketiness +persnicketinesses +persnickety +person +persona +personable +personableness +personablenesses +personae +personage +personages +personal +personalise +personalised +personalises +personalising +personalism +personalisms +personalist +personalistic +personalists +personalities +personality +personalization +personalizations +personalize +personalized +personalizes +personalizing +personally +personals +personalties +personalty +personas +personate +personated +personates +personating +personation +personations +personative +personator +personators +personhood +personhoods +personification +personifications +personified +personifier +personifiers +personifies +personify +personifying +personnel +personnels +persons +perspectival +perspective +perspectively +perspectives +perspicacious +perspicaciously +perspicaciousness +perspicaciousnesses +perspicacities +perspicacity +perspicuities +perspicuity +perspicuous +perspicuously +perspicuousness +perspicuousnesses +perspiration +perspirations +perspiratory +perspire +perspired +perspires +perspiring +perspiry +persuadable +persuade +persuaded +persuader +persuaders +persuades +persuading +persuasible +persuasion +persuasions +persuasive +persuasively +persuasiveness +persuasivenesses +pert +pertain +pertained +pertaining +pertains +perter +pertest +pertinacious +pertinaciously +pertinaciousness +pertinaciousnesses +pertinacities +pertinacity +pertinence +pertinences +pertinencies +pertinency +pertinent +pertinently +pertly +pertness +pertnesses +perturb +perturbable +perturbation +perturbational +perturbations +perturbed +perturbing +perturbs +pertussis +pertussises +peruke +peruked +perukes +perusal +perusals +peruse +perused +peruser +perusers +peruses +perusing +pervade +pervaded +pervader +pervaders +pervades +pervading +pervasion +pervasions +pervasive +pervasively +pervasiveness +pervasivenesses +perverse +perversely +perverseness +perversenesses +perversion +perversions +perversities +perversity +perversive +pervert +perverted +pervertedly +pervertedness +pervertednesses +perverter +perverters +perverting +perverts +pervious +perviousness +perviousnesses +pes +pesade +pesades +peseta +pesetas +pesewa +pesewas +peskier +peskiest +peskily +pesky +peso +pesos +pessaries +pessary +pessimism +pessimisms +pessimist +pessimistic +pessimistically +pessimists +pest +pester +pestered +pesterer +pesterers +pestering +pesters +pesthole +pestholes +pesthouse +pesthouses +pesticide +pesticides +pestier +pestiest +pestiferous +pestiferously +pestiferousness +pestiferousnesses +pestilence +pestilences +pestilent +pestilential +pestilentially +pestilently +pestle +pestled +pestles +pestling +pesto +pestos +pests +pesty +pet +petal +petaled +petaline +petalled +petallike +petalodies +petalody +petaloid +petalous +petals +petard +petards +petasos +petasoses +petasus +petasuses +petcock +petcocks +petechia +petechiae +petechial +peter +petered +petering +peters +petiolar +petiolate +petiole +petioled +petioles +petiolule +petiolules +petit +petite +petiteness +petitenesses +petites +petition +petitionary +petitioned +petitioner +petitioners +petitioning +petitions +petnap +petnapped +petnapping +petnaps +petrale +petrales +petrel +petrels +petrifaction +petrifactions +petrification +petrifications +petrified +petrifies +petrify +petrifying +petrochemical +petrochemicals +petrochemistries +petrochemistry +petrodollar +petrodollars +petrogeneses +petrogenesis +petrogenetic +petroglyph +petroglyphs +petrographer +petrographers +petrographic +petrographical +petrographically +petrographies +petrography +petrol +petrolatum +petrolatums +petroleum +petroleums +petrolic +petrologic +petrological +petrologically +petrologies +petrologist +petrologists +petrology +petrols +petronel +petronels +petrosal +petrous +pets +petsai +petsais +petted +pettedly +petter +petters +petti +petticoat +petticoated +petticoats +pettier +pettiest +pettifog +pettifogged +pettifogger +pettifoggeries +pettifoggers +pettifoggery +pettifogging +pettifoggings +pettifogs +pettily +pettiness +pettinesses +petting +pettings +pettish +pettishly +pettishness +pettishnesses +pettitoes +pettle +pettled +pettles +pettling +petto +petty +petulance +petulances +petulancies +petulancy +petulant +petulantly +petunia +petunias +petuntse +petuntses +petuntze +petuntzes +pew +pewee +pewees +pewholder +pewholders +pewit +pewits +pews +pewter +pewterer +pewterers +pewters +peyote +peyotes +peyotl +peyotls +peytral +peytrals +peytrel +peytrels +pfennig +pfennige +pfennigs +pfft +pfui +phaeton +phaetons +phage +phages +phagocyte +phagocytes +phagocytic +phagocytize +phagocytized +phagocytizes +phagocytizing +phagocytose +phagocytosed +phagocytoses +phagocytosing +phagocytosis +phagocytotic +phalange +phalangeal +phalanger +phalangers +phalanges +phalansteries +phalanstery +phalanx +phalanxes +phalarope +phalaropes +phalli +phallic +phallically +phallicism +phallicisms +phallism +phallisms +phallist +phallists +phallocentric +phallus +phalluses +phanerogam +phanerogams +phanerophyte +phanerophytes +phantasied +phantasies +phantasm +phantasma +phantasmagoria +phantasmagorias +phantasmagoric +phantasmagorical +phantasmal +phantasmata +phantasmic +phantasms +phantast +phantasts +phantasy +phantasying +phantom +phantomlike +phantoms +pharaoh +pharaohs +pharaonic +pharisaic +pharisaical +pharisaically +pharisaicalness +pharisaicalnesses +pharisaism +pharisaisms +pharisee +pharisees +pharmaceutical +pharmaceutically +pharmaceuticals +pharmacies +pharmacist +pharmacists +pharmacodynamic +pharmacodynamically +pharmacodynamics +pharmacognosies +pharmacognostic +pharmacognostical +pharmacognosy +pharmacokinetic +pharmacokinetics +pharmacologic +pharmacological +pharmacologically +pharmacologies +pharmacologist +pharmacologists +pharmacology +pharmacopeia +pharmacopeial +pharmacopeias +pharmacopoeia +pharmacopoeial +pharmacopoeias +pharmacotherapies +pharmacotherapy +pharmacy +pharos +pharoses +pharyngeal +pharynges +pharyngitides +pharyngitis +pharynx +pharynxes +phase +phaseal +phased +phasedown +phasedowns +phaseout +phaseouts +phases +phasic +phasing +phasis +phasmid +phasmids +phat +phatic +phatically +pheasant +pheasants +phellem +phellems +phelloderm +phelloderms +phellogen +phellogens +phelonia +phelonion +phelonions +phenacaine +phenacaines +phenacetin +phenacetins +phenacite +phenacites +phenakite +phenakites +phenanthrene +phenanthrenes +phenate +phenates +phenazin +phenazine +phenazines +phenazins +phencyclidine +phencyclidines +phenetic +pheneticist +pheneticists +phenetics +phenetol +phenetols +phenix +phenixes +phenmetrazine +phenmetrazines +phenobarbital +phenobarbitals +phenobarbitone +phenobarbitones +phenocopies +phenocopy +phenocryst +phenocrystic +phenocrysts +phenol +phenolate +phenolated +phenolates +phenolic +phenolics +phenological +phenologically +phenologies +phenology +phenolphthalein +phenolphthaleins +phenols +phenom +phenomena +phenomenal +phenomenalism +phenomenalisms +phenomenalist +phenomenalistic +phenomenalistically +phenomenalists +phenomenally +phenomenas +phenomenological +phenomenologically +phenomenologies +phenomenologist +phenomenologists +phenomenology +phenomenon +phenomenons +phenoms +phenothiazine +phenothiazines +phenotype +phenotypes +phenotypic +phenotypical +phenotypically +phenoxide +phenoxides +phenoxy +phentolamine +phentolamines +phenyl +phenylalanine +phenylalanines +phenylbutazone +phenylbutazones +phenylephrine +phenylephrines +phenylethylamine +phenylethylamines +phenylic +phenylketonuria +phenylketonurias +phenylketonuric +phenylketonurics +phenylpropanolamine +phenylpropanolamines +phenyls +phenylthiocarbamide +phenylthiocarbamides +phenylthiourea +phenylthioureas +phenytoin +phenytoins +pheochromocytoma +pheochromocytomas +pheochromocytomata +pheromonal +pheromone +pheromones +phew +phi +phial +phials +philabeg +philabegs +philadelphus +philadelphuses +philander +philandered +philanderer +philanderers +philandering +philanders +philanthropic +philanthropical +philanthropically +philanthropies +philanthropist +philanthropists +philanthropoid +philanthropoids +philanthropy +philatelic +philatelically +philatelies +philatelist +philatelists +philately +philharmonic +philharmonics +philhellene +philhellenes +philhellenic +philhellenism +philhellenisms +philhellenist +philhellenists +philibeg +philibegs +philippic +philippics +philistia +philistine +philistines +philistinism +philistinisms +phillumenist +phillumenists +philodendra +philodendron +philodendrons +philological +philologically +philologies +philologist +philologists +philology +philomel +philomels +philoprogenitive +philoprogenitiveness +philoprogenitivenesses +philosophe +philosopher +philosophers +philosophes +philosophic +philosophical +philosophically +philosophies +philosophise +philosophised +philosophises +philosophising +philosophize +philosophized +philosophizer +philosophizers +philosophizes +philosophizing +philosophy +philter +philtered +philtering +philters +philtra +philtre +philtred +philtres +philtring +philtrum +phimoses +phimosis +phimotic +phis +phiz +phizes +phlebitides +phlebitis +phlebogram +phlebograms +phlebographic +phlebographies +phlebography +phlebologies +phlebology +phlebotomies +phlebotomist +phlebotomists +phlebotomy +phlegm +phlegmatic +phlegmatically +phlegmier +phlegmiest +phlegms +phlegmy +phloem +phloems +phlogistic +phlogiston +phlogistons +phlogopite +phlogopites +phlox +phloxes +phobia +phobias +phobic +phobics +phocine +phoebe +phoebes +phoebus +phoebuses +phoenix +phoenixes +phoenixlike +phon +phonal +phonate +phonated +phonates +phonating +phonation +phonations +phone +phoned +phonematic +phoneme +phonemes +phonemic +phonemically +phonemicist +phonemicists +phonemics +phones +phonetic +phonetically +phonetician +phoneticians +phonetics +phoney +phoneyed +phoneying +phoneys +phonic +phonically +phonics +phonied +phonier +phonies +phoniest +phonily +phoniness +phoninesses +phoning +phono +phonocardiogram +phonocardiograms +phonocardiograph +phonocardiographic +phonocardiographies +phonocardiographs +phonocardiography +phonogram +phonogramic +phonogramically +phonogrammic +phonogrammically +phonograms +phonograph +phonographer +phonographers +phonographic +phonographically +phonographies +phonographs +phonography +phonolite +phonolites +phonologic +phonological +phonologically +phonologies +phonologist +phonologists +phonology +phonon +phonons +phonos +phonotactic +phonotactics +phons +phony +phonying +phooey +phorate +phorates +phoronid +phoronids +phosgene +phosgenes +phosphatase +phosphatases +phosphate +phosphates +phosphatic +phosphatide +phosphatides +phosphatidic +phosphatidyl +phosphatidylcholine +phosphatidylcholines +phosphatidylethanolamine +phosphatidylethanolamines +phosphatidyls +phosphatization +phosphatizations +phosphatize +phosphatized +phosphatizes +phosphatizing +phosphaturia +phosphaturias +phosphene +phosphenes +phosphid +phosphide +phosphides +phosphids +phosphin +phosphine +phosphines +phosphins +phosphite +phosphites +phosphocreatine +phosphocreatines +phosphodiesterase +phosphodiesterases +phosphoenolpyruvate +phosphoenolpyruvates +phosphofructokinase +phosphofructokinases +phosphoglucomutase +phosphoglucomutases +phosphoglyceraldehyde +phosphoglyceraldehydes +phosphoglycerate +phosphoglycerates +phosphokinase +phosphokinases +phospholipase +phospholipases +phospholipid +phospholipids +phosphomonoesterase +phosphomonoesterases +phosphonium +phosphoniums +phosphoprotein +phosphoproteins +phosphor +phosphore +phosphores +phosphoresce +phosphoresced +phosphorescence +phosphorescences +phosphorescent +phosphorescently +phosphoresces +phosphorescing +phosphoric +phosphorite +phosphorites +phosphoritic +phosphorolyses +phosphorolysis +phosphorolytic +phosphorous +phosphors +phosphorus +phosphoruses +phosphoryl +phosphorylase +phosphorylases +phosphorylate +phosphorylated +phosphorylates +phosphorylating +phosphorylation +phosphorylations +phosphorylative +phosphoryls +phot +photic +photically +photics +photo +photoautotroph +photoautotrophic +photoautotrophically +photoautotrophs +photobiologic +photobiological +photobiologies +photobiologist +photobiologists +photobiology +photocathode +photocathodes +photocell +photocells +photochemical +photochemically +photochemist +photochemistries +photochemistry +photochemists +photochromic +photochromism +photochromisms +photocoagulation +photocoagulations +photocompose +photocomposed +photocomposer +photocomposers +photocomposes +photocomposing +photocomposition +photocompositions +photoconductive +photoconductivities +photoconductivity +photocopied +photocopier +photocopiers +photocopies +photocopy +photocopying +photocurrent +photocurrents +photodecomposition +photodecompositions +photodegradable +photodetector +photodetectors +photodiode +photodiodes +photodisintegrate +photodisintegrated +photodisintegrates +photodisintegrating +photodisintegration +photodisintegrations +photodissociate +photodissociated +photodissociates +photodissociating +photodissociation +photodissociations +photoduplicate +photoduplicated +photoduplicates +photoduplicating +photoduplication +photoduplications +photodynamic +photodynamically +photoed +photoelectric +photoelectrically +photoelectron +photoelectronic +photoelectrons +photoemission +photoemissions +photoemissive +photoengrave +photoengraved +photoengraver +photoengravers +photoengraves +photoengraving +photoengravings +photoexcitation +photoexcitations +photoexcited +photofinisher +photofinishers +photofinishing +photofinishings +photoflash +photoflashes +photoflood +photofloods +photofluorographies +photofluorography +photog +photogenic +photogenically +photogeologic +photogeological +photogeologies +photogeologist +photogeologists +photogeology +photogram +photogrammetric +photogrammetries +photogrammetrist +photogrammetrists +photogrammetry +photograms +photograph +photographed +photographer +photographers +photographic +photographically +photographies +photographing +photographs +photography +photogravure +photogravures +photogs +photoinduced +photoinduction +photoinductions +photoinductive +photoing +photointerpretation +photointerpretations +photointerpreter +photointerpreters +photoionization +photoionizations +photoionize +photoionized +photoionizes +photoionizing +photojournalism +photojournalisms +photojournalist +photojournalistic +photojournalists +photokineses +photokinesis +photokinetic +photolithograph +photolithographed +photolithographic +photolithographically +photolithographies +photolithographing +photolithographs +photolithography +photolyses +photolysis +photolytic +photolytically +photolyzable +photolyze +photolyzed +photolyzes +photolyzing +photomap +photomapped +photomapping +photomaps +photomask +photomasks +photomechanical +photomechanically +photometer +photometers +photometric +photometrically +photometries +photometry +photomicrograph +photomicrographic +photomicrographies +photomicrographs +photomicrography +photomontage +photomontages +photomorphogeneses +photomorphogenesis +photomorphogenic +photomosaic +photomosaics +photomultiplier +photomultipliers +photomural +photomurals +photon +photonegative +photonic +photonics +photons +photonuclear +photooxidation +photooxidations +photooxidative +photooxidize +photooxidized +photooxidizes +photooxidizing +photoperiod +photoperiodic +photoperiodically +photoperiodism +photoperiodisms +photoperiods +photophase +photophases +photophobia +photophobias +photophobic +photophore +photophores +photophosphorylation +photophosphorylations +photopia +photopias +photopic +photoplay +photoplays +photopolarimeter +photopolarimeters +photopolymer +photopolymers +photopositive +photoproduct +photoproduction +photoproductions +photoproducts +photoreaction +photoreactions +photoreactivating +photoreactivation +photoreactivations +photoreception +photoreceptions +photoreceptive +photoreceptor +photoreceptors +photoreconnaissance +photoreconnaissances +photoreduce +photoreduced +photoreduces +photoreducing +photoreduction +photoreductions +photoreproduction +photoreproductions +photoresist +photoresists +photorespiration +photorespirations +photos +photosensitive +photosensitivities +photosensitivity +photosensitization +photosensitizations +photosensitize +photosensitized +photosensitizer +photosensitizers +photosensitizes +photosensitizing +photoset +photosets +photosetter +photosetters +photosetting +photosphere +photospheres +photospheric +photostat +photostated +photostatic +photostating +photostats +photostatted +photostatting +photosynthate +photosynthates +photosyntheses +photosynthesis +photosynthesize +photosynthesized +photosynthesizes +photosynthesizing +photosynthetic +photosynthetically +photosystem +photosystems +phototactic +phototactically +phototaxes +phototaxis +phototelegraphies +phototelegraphy +phototoxic +phototoxicities +phototoxicity +phototropic +phototropically +phototropism +phototropisms +phototube +phototubes +phototypesetter +phototypesetters +phototypesetting +phototypesettings +photovoltaic +photovoltaics +phots +phpht +phragmoplast +phragmoplasts +phrasal +phrasally +phrase +phrased +phrasemaker +phrasemakers +phrasemaking +phrasemakings +phrasemonger +phrasemongering +phrasemongerings +phrasemongers +phraseological +phraseologies +phraseologist +phraseologists +phraseology +phrases +phrasing +phrasings +phratral +phratric +phratries +phratry +phreatic +phreatophyte +phreatophytes +phreatophytic +phrenetic +phrenic +phrenological +phrenologies +phrenologist +phrenologists +phrenology +phrensied +phrensies +phrensy +phrensying +pht +phthalic +phthalin +phthalins +phthalocyanine +phthalocyanines +phthises +phthisic +phthisical +phthisics +phthisis +phut +phuts +phycocyanin +phycocyanins +phycoerythrin +phycoerythrins +phycological +phycologies +phycologist +phycologists +phycology +phycomycete +phycomycetes +phycomycetous +phyla +phylacteries +phylactery +phylae +phylar +phylaxis +phylaxises +phyle +phyleses +phylesis +phylesises +phyletic +phyletically +phylic +phyllaries +phyllary +phyllite +phyllites +phyllo +phylloclade +phylloclades +phyllode +phyllodes +phyllodia +phyllodium +phylloid +phylloids +phyllome +phyllomes +phyllos +phyllotactic +phyllotaxes +phyllotaxies +phyllotaxis +phyllotaxy +phylloxera +phylloxerae +phylloxeras +phylogenetic +phylogenetically +phylogenies +phylogeny +phylon +phylum +physed +physeds +physes +physiatrist +physiatrists +physic +physical +physicalism +physicalisms +physicalist +physicalistic +physicalists +physicalities +physicality +physically +physicalness +physicalnesses +physicals +physician +physicians +physicist +physicists +physicked +physicking +physicochemical +physicochemically +physics +physiocratic +physiognomic +physiognomical +physiognomically +physiognomies +physiognomy +physiographer +physiographers +physiographic +physiographical +physiographies +physiography +physiologic +physiological +physiologically +physiologies +physiologist +physiologists +physiology +physiopathologic +physiopathological +physiopathologies +physiopathology +physiotherapies +physiotherapist +physiotherapists +physiotherapy +physique +physiques +physis +physostigmine +physostigmines +phytane +phytanes +phytoalexin +phytoalexins +phytochemical +phytochemically +phytochemist +phytochemistries +phytochemistry +phytochemists +phytochrome +phytochromes +phytoflagellate +phytoflagellates +phytogeographer +phytogeographers +phytogeographic +phytogeographical +phytogeographically +phytogeographies +phytogeography +phytohemagglutinin +phytohemagglutinins +phytohormone +phytohormones +phytoid +phytol +phytols +phyton +phytonic +phytons +phytopathogen +phytopathogenic +phytopathogens +phytopathological +phytopathologies +phytopathology +phytophagous +phytoplankter +phytoplankters +phytoplankton +phytoplanktonic +phytoplanktons +phytosociological +phytosociologies +phytosociology +phytosterol +phytosterols +phytotoxic +phytotoxicities +phytotoxicity +pi +pia +piacular +piaffe +piaffed +piaffer +piaffers +piaffes +piaffing +pial +pian +pianic +pianism +pianisms +pianissimi +pianissimo +pianissimos +pianist +pianistic +pianistically +pianists +piano +pianoforte +pianofortes +pianos +pians +pias +piasaba +piasabas +piasava +piasavas +piassaba +piassabas +piassava +piassavas +piaster +piasters +piastre +piastres +piazza +piazzas +piazze +pibal +pibals +pibroch +pibrochs +pic +pica +picacho +picachos +picador +picadores +picadors +pical +picaninnies +picaninny +picara +picaras +picaresque +picaresques +picaro +picaroon +picarooned +picarooning +picaroons +picaros +picas +picayune +picayunes +picayunish +piccalilli +piccalillis +piccolo +piccoloist +piccoloists +piccolos +pice +piceous +piciform +pick +pickaback +pickabacked +pickabacking +pickabacks +pickadil +pickadils +pickaninnies +pickaninny +pickaroon +pickaroons +pickax +pickaxe +pickaxed +pickaxes +pickaxing +picked +pickeer +pickeered +pickeering +pickeers +picker +pickerel +pickerels +pickerelweed +pickerelweeds +pickers +picket +picketboat +picketboats +picketed +picketer +picketers +picketing +pickets +pickier +pickiest +picking +pickings +pickle +pickled +pickles +pickling +picklock +picklocks +pickoff +pickoffs +pickpocket +pickpockets +pickproof +picks +pickthank +pickthanks +pickup +pickups +pickwick +pickwicks +picky +picloram +piclorams +picnic +picnicked +picnicker +picnickers +picnicking +picnicky +picnics +picofarad +picofarads +picogram +picograms +picolin +picoline +picolines +picolins +picomole +picomoles +picornavirus +picornaviruses +picosecond +picoseconds +picot +picoted +picotee +picotees +picoting +picots +picquet +picquets +picrate +picrated +picrates +picric +picrite +picrites +picritic +picrotoxin +picrotoxins +pics +pictogram +pictograms +pictograph +pictographic +pictographies +pictographs +pictography +pictorial +pictorialism +pictorialisms +pictorialist +pictorialists +pictorialization +pictorializations +pictorialize +pictorialized +pictorializes +pictorializing +pictorially +pictorialness +pictorialnesses +pictorials +picture +pictured +picturephone +picturephones +pictures +picturesque +picturesquely +picturesqueness +picturesquenesses +picturing +picturization +picturizations +picturize +picturized +picturizes +picturizing +picul +piculs +piddle +piddled +piddler +piddlers +piddles +piddling +piddly +piddock +piddocks +pidgin +pidginization +pidginizations +pidginize +pidginized +pidginizes +pidginizing +pidgins +pie +piebald +piebalds +piece +pieced +piecemeal +piecer +piecers +pieces +piecewise +piecework +pieceworker +pieceworkers +pieceworks +piecing +piecings +piecrust +piecrusts +pied +piedfort +piedforts +piedmont +piedmonts +piefort +pieforts +pieing +pieplant +pieplants +pier +pierce +pierced +piercer +piercers +pierces +piercing +piercingly +pierogi +pierogies +pierrot +pierrots +piers +pies +pieta +pietas +pieties +pietism +pietisms +pietist +pietistic +pietistically +pietists +piety +piezoelectric +piezoelectrically +piezoelectricities +piezoelectricity +piezometer +piezometers +piezometric +piffle +piffled +piffles +piffling +pig +pigboat +pigboats +pigeon +pigeonhole +pigeonholed +pigeonholer +pigeonholers +pigeonholes +pigeonholing +pigeonite +pigeonites +pigeons +pigeonwing +pigeonwings +pigfish +pigfishes +pigged +piggeries +piggery +piggie +piggier +piggies +piggiest +piggin +pigging +piggins +piggish +piggishly +piggishness +piggishnesses +piggy +piggyback +piggybacked +piggybacking +piggybacks +pigheaded +pigheadedly +pigheadedness +pigheadednesses +piglet +piglets +piglike +pigment +pigmentary +pigmentation +pigmentations +pigmented +pigmenting +pigments +pigmies +pigmy +pignoli +pignolia +pignolias +pignolis +pignora +pignus +pignut +pignuts +pigout +pigouts +pigpen +pigpens +pigs +pigskin +pigskins +pigsney +pigsneys +pigstick +pigsticked +pigsticker +pigstickers +pigsticking +pigsticks +pigsties +pigsty +pigtail +pigtailed +pigtails +pigweed +pigweeds +piing +pika +pikake +pikakes +pikas +pike +piked +pikeman +pikemen +piker +pikers +pikes +pikestaff +pikestaffs +pikestaves +piki +piking +pikis +pilaf +pilaff +pilaffs +pilafs +pilar +pilaster +pilasters +pilau +pilaus +pilaw +pilaws +pilchard +pilchards +pile +pilea +pileate +pileated +piled +pilei +pileless +pileous +piles +pileum +pileup +pileups +pileus +pilewort +pileworts +pilfer +pilferable +pilferage +pilferages +pilfered +pilferer +pilferers +pilfering +pilferproof +pilfers +pilgarlic +pilgarlics +pilgrim +pilgrimage +pilgrimaged +pilgrimages +pilgrimaging +pilgrims +pili +piliform +piling +pilings +pilis +pill +pillage +pillaged +pillager +pillagers +pillages +pillaging +pillar +pillared +pillaring +pillarless +pillars +pillbox +pillboxes +pilled +pilling +pillion +pillions +pilloried +pillories +pillory +pillorying +pillow +pillowcase +pillowcases +pillowed +pillowing +pillows +pillowy +pills +pilocarpine +pilocarpines +pilose +pilosities +pilosity +pilot +pilotage +pilotages +piloted +pilothouse +pilothouses +piloting +pilotings +pilotless +pilots +pilous +pilsener +pilseners +pilsner +pilsners +pilular +pilule +pilules +pilus +pily +pima +pimas +pimento +pimentos +pimiento +pimientos +pimp +pimped +pimpernel +pimpernels +pimping +pimple +pimpled +pimples +pimplier +pimpliest +pimply +pimpmobile +pimpmobiles +pimps +pin +pina +pinafore +pinafored +pinafores +pinang +pinangs +pinas +pinaster +pinasters +pinata +pinatas +pinball +pinballs +pinbone +pinbones +pincer +pincerlike +pincers +pinch +pinchbeck +pinchbecks +pinchbug +pinchbugs +pincheck +pinchecks +pinched +pincher +pinchers +pinches +pinching +pinchpenny +pincushion +pincushions +pinder +pinders +pindling +pine +pineal +pinealectomies +pinealectomize +pinealectomized +pinealectomizes +pinealectomizing +pinealectomy +pineals +pineapple +pineapples +pinecone +pinecones +pined +pinedrops +pineland +pinelands +pinelike +pinene +pinenes +pineries +pinery +pines +pinesap +pinesaps +pineta +pinetum +pinewood +pinewoods +piney +pinfeather +pinfeathers +pinfish +pinfishes +pinfold +pinfolded +pinfolding +pinfolds +ping +pinged +pinger +pingers +pinging +pingo +pingos +pingrass +pingrasses +pings +pinguid +pinhead +pinheaded +pinheadedness +pinheadednesses +pinheads +pinhole +pinholes +pinier +piniest +pining +pinion +pinioned +pinioning +pinions +pinite +pinites +pinitol +pinitols +pink +pinked +pinken +pinkened +pinkening +pinkens +pinker +pinkers +pinkest +pinkey +pinkeye +pinkeyes +pinkeys +pinkie +pinkies +pinking +pinkings +pinkish +pinkishness +pinkishnesses +pinkly +pinkness +pinknesses +pinko +pinkoes +pinkos +pinkroot +pinkroots +pinks +pinky +pinna +pinnace +pinnaces +pinnacle +pinnacled +pinnacles +pinnacling +pinnae +pinnal +pinnas +pinnate +pinnated +pinnately +pinnatifid +pinned +pinner +pinners +pinnies +pinning +pinniped +pinnipeds +pinnula +pinnulae +pinnular +pinnule +pinnules +pinny +pinochle +pinochles +pinocle +pinocles +pinocytic +pinocytoses +pinocytosis +pinocytotic +pinocytotically +pinole +pinoles +pinon +pinones +pinons +pinot +pinots +pinpoint +pinpointed +pinpointing +pinpoints +pinprick +pinpricked +pinpricking +pinpricks +pins +pinscher +pinschers +pinsetter +pinsetters +pinspotter +pinspotters +pinstripe +pinstriped +pinstripes +pint +pinta +pintada +pintadas +pintado +pintadoes +pintados +pintail +pintails +pintano +pintanos +pintas +pintle +pintles +pinto +pintoes +pintos +pints +pintsize +pinup +pinups +pinwale +pinwales +pinweed +pinweeds +pinwheel +pinwheeled +pinwheeling +pinwheels +pinwork +pinworks +pinworm +pinworms +piny +pinyin +pinyon +pinyons +piolet +piolets +pion +pioneer +pioneered +pioneering +pioneers +pionic +pions +piosities +piosity +pious +piously +piousness +piousnesses +pip +pipage +pipages +pipal +pipals +pipe +pipeage +pipeages +piped +pipefish +pipefishes +pipeful +pipefuls +pipeless +pipelike +pipeline +pipelined +pipelines +pipelining +piper +piperazine +piperazines +piperidine +piperidines +piperine +piperines +piperonal +piperonals +pipers +pipes +pipestem +pipestems +pipestone +pipestones +pipet +pipets +pipette +pipetted +pipettes +pipetting +pipier +pipiest +pipiness +pipinesses +piping +pipingly +pipings +pipit +pipits +pipkin +pipkins +pipped +pippin +pipping +pippins +pips +pipsissewa +pipsissewas +pipsqueak +pipsqueaks +pipy +piquance +piquances +piquancies +piquancy +piquant +piquantly +piquantness +piquantnesses +pique +piqued +piques +piquet +piquets +piquing +piracies +piracy +piragua +piraguas +pirana +piranas +piranha +piranhas +pirarucu +pirarucus +pirate +pirated +pirates +piratic +piratical +piratically +pirating +piraya +pirayas +piriform +pirn +pirns +pirog +pirogen +piroghi +pirogi +pirogies +pirogue +pirogues +pirojki +piroplasm +piroplasma +piroplasmata +piroplasms +piroque +piroques +piroshki +pirouette +pirouetted +pirouettes +pirouetting +pirozhki +pirozhok +pis +piscaries +piscary +piscator +piscatorial +piscators +piscatory +pisciculture +piscicultures +piscina +piscinae +piscinal +piscinas +piscine +piscivorous +pisco +piscos +pish +pished +pishes +pishing +pishoge +pishoges +pishogue +pishogues +pisiform +pisiforms +pismire +pismires +piso +pisolite +pisolites +pisolitic +pisos +piss +pissant +pissants +pissed +pisser +pissers +pisses +pissing +pissoir +pissoirs +pistache +pistaches +pistachio +pistachios +pistareen +pistareens +piste +pistes +pistil +pistillate +pistils +pistol +pistole +pistoled +pistoleer +pistoleers +pistoles +pistoling +pistolled +pistolling +pistols +piston +pistons +pit +pita +pitapat +pitapats +pitapatted +pitapatting +pitas +pitch +pitchblende +pitchblendes +pitched +pitcher +pitcherful +pitcherfuls +pitchers +pitchersful +pitches +pitchfork +pitchforked +pitchforking +pitchforks +pitchier +pitchiest +pitchily +pitching +pitchman +pitchmen +pitchout +pitchouts +pitchpole +pitchpoled +pitchpoles +pitchpoling +pitchwoman +pitchwomen +pitchy +piteous +piteously +piteousness +piteousnesses +pitfall +pitfalls +pith +pithead +pitheads +pithecanthropi +pithecanthropine +pithecanthropines +pithecanthropus +pithed +pithier +pithiest +pithily +pithiness +pithinesses +pithing +pithless +piths +pithy +pitiable +pitiableness +pitiablenesses +pitiably +pitied +pitier +pitiers +pities +pitiful +pitifuller +pitifullest +pitifully +pitifulness +pitifulnesses +pitiless +pitilessly +pitilessness +pitilessnesses +pitman +pitmans +pitmen +piton +pitons +pits +pitsaw +pitsaws +pittance +pittances +pitted +pitting +pittings +pittosporum +pittosporums +pituitaries +pituitary +pity +pitying +pityingly +pityriases +pityriasis +piu +pivot +pivotable +pivotal +pivotally +pivoted +pivoting +pivotman +pivotmen +pivots +pix +pixel +pixels +pixes +pixie +pixieish +pixies +pixilated +pixilation +pixilations +pixillated +pixiness +pixinesses +pixy +pixyish +pizazz +pizazzes +pizazzy +pizza +pizzalike +pizzas +pizzeria +pizzerias +pizzicati +pizzicato +pizzle +pizzles +placabilities +placability +placable +placably +placard +placarded +placarding +placards +placate +placated +placater +placaters +placates +placating +placatingly +placation +placations +placative +placatory +place +placeable +placebo +placeboes +placebos +placed +placeholder +placeholders +placekick +placekicked +placekicker +placekickers +placekicking +placekicks +placeless +placelessly +placeman +placemen +placement +placements +placenta +placentae +placental +placentals +placentas +placentation +placentations +placer +placers +places +placet +placets +placid +placidities +placidity +placidly +placidness +placidnesses +placing +plack +placket +plackets +placks +placoid +placoids +plafond +plafonds +plagal +plage +plages +plagiaries +plagiarise +plagiarised +plagiarises +plagiarising +plagiarism +plagiarisms +plagiarist +plagiaristic +plagiarists +plagiarize +plagiarized +plagiarizer +plagiarizers +plagiarizes +plagiarizing +plagiary +plagioclase +plagioclases +plagiotropic +plague +plagued +plaguer +plaguers +plagues +plaguey +plaguily +plaguing +plaguy +plaice +plaices +plaid +plaided +plaids +plain +plainchant +plainchants +plainclothes +plainclothesman +plainclothesmen +plained +plainer +plainest +plaining +plainly +plainness +plainnesses +plains +plainsman +plainsmen +plainsong +plainsongs +plainspoken +plainspokenness +plainspokennesses +plaint +plaintext +plaintexts +plaintful +plaintiff +plaintiffs +plaintive +plaintively +plaintiveness +plaintivenesses +plaints +plaister +plaistered +plaistering +plaisters +plait +plaited +plaiter +plaiters +plaiting +plaitings +plaits +plan +planar +planaria +planarian +planarians +planarias +planarities +planarity +planate +planation +planations +planch +planche +planches +planchet +planchets +planchette +planchettes +plane +planed +planeload +planeloads +planer +planers +planes +planet +planetaria +planetarium +planetariums +planetary +planetesimal +planetesimals +planetlike +planetoid +planetoidal +planetoids +planetological +planetologies +planetologist +planetologists +planetology +planets +planetwide +planform +planforms +plangencies +plangency +plangent +plangently +planimeter +planimeters +planimetric +planimetrically +planing +planish +planished +planisher +planishers +planishes +planishing +planisphere +planispheres +planispheric +plank +planked +planking +plankings +planks +plankter +plankters +plankton +planktonic +planktons +planless +planlessly +planlessness +planlessnesses +planned +planner +planners +planning +plannings +planographic +planographies +planography +planosol +planosols +plans +plant +plantable +plantain +plantains +plantar +plantation +plantations +planted +planter +planters +plantigrade +plantigrades +planting +plantings +plantlet +plantlets +plantlike +plantocracies +plantocracy +plants +plantsman +plantsmen +planula +planulae +planular +plaque +plaques +plash +plashed +plasher +plashers +plashes +plashier +plashiest +plashing +plashy +plasm +plasma +plasmagel +plasmagels +plasmagene +plasmagenes +plasmalemma +plasmalemmas +plasmaphereses +plasmapheresis +plasmas +plasmasol +plasmasols +plasmatic +plasmic +plasmid +plasmids +plasmin +plasminogen +plasminogens +plasmins +plasmodesm +plasmodesma +plasmodesmas +plasmodesmata +plasmodesms +plasmodia +plasmodium +plasmogamies +plasmogamy +plasmoid +plasmoids +plasmolyses +plasmolysis +plasmolytic +plasmolyze +plasmolyzed +plasmolyzes +plasmolyzing +plasmon +plasmons +plasms +plaster +plasterboard +plasterboards +plastered +plasterer +plasterers +plastering +plasterings +plasters +plasterwork +plasterworks +plastery +plastic +plastically +plasticene +plasticenes +plasticine +plasticines +plasticities +plasticity +plasticization +plasticizations +plasticize +plasticized +plasticizer +plasticizers +plasticizes +plasticizing +plasticky +plastics +plastid +plastidial +plastids +plastisol +plastisols +plastocyanin +plastocyanins +plastoquinone +plastoquinones +plastral +plastron +plastrons +plastrum +plastrums +plat +platan +platane +platanes +platans +plate +plateau +plateaued +plateauing +plateaus +plateaux +plated +plateful +platefuls +plateglass +platelet +platelets +platelike +platemaker +platemakers +platemaking +platemakings +platen +platens +plater +plateresque +platers +plates +platesful +platform +platforms +platier +platies +platiest +platina +platinas +plating +platings +platinic +platinize +platinized +platinizes +platinizing +platinocyanide +platinocyanides +platinum +platinums +platitude +platitudes +platitudinal +platitudinarian +platitudinarians +platitudinize +platitudinized +platitudinizes +platitudinizing +platitudinous +platitudinously +platonic +platonically +platoon +platooned +platooning +platoons +plats +platted +platter +platterful +platterfuls +platters +plattersful +platting +platy +platyfish +platyfishes +platyhelminth +platyhelminthic +platyhelminths +platypi +platypus +platypuses +platyrrhine +platyrrhines +platys +plaudit +plaudits +plausibilities +plausibility +plausible +plausibleness +plausiblenesses +plausibly +plausive +play +playa +playabilities +playability +playable +playact +playacted +playacting +playactings +playacts +playas +playback +playbacks +playbill +playbills +playbook +playbooks +playboy +playboys +playdate +playdates +playday +playdays +playdown +playdowns +played +player +players +playfellow +playfellows +playfield +playfields +playful +playfully +playfulness +playfulnesses +playgirl +playgirls +playgoer +playgoers +playground +playgrounds +playhouse +playhouses +playing +playland +playlands +playless +playlet +playlets +playlike +playlist +playlists +playmaker +playmakers +playmaking +playmakings +playmate +playmates +playoff +playoffs +playpen +playpens +playroom +playrooms +plays +playsuit +playsuits +plaything +playthings +playtime +playtimes +playwear +playwright +playwrighting +playwrightings +playwrights +playwriting +playwritings +plaza +plazas +plea +pleach +pleached +pleaches +pleaching +plead +pleadable +pleaded +pleader +pleaders +pleading +pleadingly +pleadings +pleads +pleas +pleasance +pleasances +pleasant +pleasanter +pleasantest +pleasantly +pleasantness +pleasantnesses +pleasantries +pleasantry +please +pleased +pleaser +pleasers +pleases +pleasing +pleasingly +pleasingness +pleasingnesses +pleasurabilities +pleasurability +pleasurable +pleasurableness +pleasurablenesses +pleasurably +pleasure +pleasured +pleasureless +pleasures +pleasuring +pleat +pleated +pleater +pleaters +pleating +pleatless +pleats +pleb +plebe +plebeian +plebeianism +plebeianisms +plebeianly +plebeians +plebes +plebiscitary +plebiscite +plebiscites +plebs +plecopteran +plecopterans +plectra +plectron +plectrons +plectrum +plectrums +pled +pledge +pledged +pledgee +pledgees +pledgeor +pledgeors +pledger +pledgers +pledges +pledget +pledgets +pledging +pledgor +pledgors +pleiad +pleiades +pleiads +pleinairism +pleinairisms +pleinairist +pleinairists +pleiotropic +pleiotropies +pleiotropy +plena +plenary +plench +plenches +plenipotent +plenipotentiaries +plenipotentiary +plenish +plenished +plenishes +plenishing +plenism +plenisms +plenist +plenists +plenitude +plenitudes +plenitudinous +plenteous +plenteously +plenteousness +plenteousnesses +plenties +plentiful +plentifully +plentifulness +plentifulnesses +plentitude +plentitudes +plenty +plenum +plenums +pleochroic +pleochroism +pleochroisms +pleomorphic +pleomorphism +pleomorphisms +pleonasm +pleonasms +pleonastic +pleonastically +pleopod +pleopods +plerocercoid +plerocercoids +plesiosaur +plesiosaurs +plessor +plessors +plethora +plethoras +plethoric +plethysmogram +plethysmograms +plethysmograph +plethysmographic +plethysmographically +plethysmographies +plethysmographs +plethysmography +pleura +pleurae +pleural +pleuras +pleurisies +pleurisy +pleuritic +pleuron +pleuropneumonia +pleuropneumonias +pleuston +pleustonic +pleustons +plew +plews +plexal +plexiform +plexor +plexors +plexus +plexuses +pliabilities +pliability +pliable +pliableness +pliablenesses +pliably +pliancies +pliancy +pliant +pliantly +pliantness +pliantnesses +plica +plicae +plical +plicate +plicated +plication +plications +plie +plied +plier +pliers +plies +plight +plighted +plighter +plighters +plighting +plights +plimsol +plimsole +plimsoles +plimsoll +plimsolls +plimsols +plink +plinked +plinker +plinkers +plinking +plinks +plinth +plinths +pliotron +pliotrons +pliskie +pliskies +plisky +plisse +plisses +plod +plodded +plodder +plodders +plodding +ploddingly +plods +ploidies +ploidy +plonk +plonked +plonking +plonks +plop +plopped +plopping +plops +plosion +plosions +plosive +plosives +plot +plotless +plotlessness +plotlessnesses +plotline +plotlines +plots +plottage +plottages +plotted +plotter +plotters +plottier +plotties +plottiest +plotting +plotty +plotz +plotzed +plotzes +plotzing +plough +ploughed +plougher +ploughers +ploughing +ploughs +plover +plovers +plow +plowable +plowback +plowbacks +plowboy +plowboys +plowed +plower +plowers +plowhead +plowheads +plowing +plowland +plowlands +plowman +plowmen +plows +plowshare +plowshares +ploy +ployed +ploying +ploys +pluck +plucked +plucker +pluckers +pluckier +pluckiest +pluckily +pluckiness +pluckinesses +plucking +plucks +plucky +plug +plugged +plugger +pluggers +plugging +plugless +plugola +plugolas +plugs +pluguglies +plugugly +plum +plumage +plumaged +plumages +plumate +plumb +plumbago +plumbagos +plumbed +plumber +plumberies +plumbers +plumbery +plumbic +plumbing +plumbings +plumbism +plumbisms +plumbous +plumbs +plumbum +plumbums +plume +plumed +plumelet +plumelets +plumeria +plumerias +plumes +plumier +plumiest +pluming +plumiped +plumipeds +plumlike +plummet +plummeted +plummeting +plummets +plummier +plummiest +plummy +plumose +plump +plumped +plumpen +plumpened +plumpening +plumpens +plumper +plumpers +plumpest +plumping +plumpish +plumply +plumpness +plumpnesses +plumps +plums +plumular +plumule +plumules +plumy +plunder +plundered +plunderer +plunderers +plundering +plunderous +plunders +plunge +plunged +plunger +plungers +plunges +plunging +plunk +plunked +plunker +plunkers +plunking +plunks +pluperfect +pluperfects +plural +pluralism +pluralisms +pluralist +pluralistic +pluralistically +pluralists +pluralities +plurality +pluralization +pluralizations +pluralize +pluralized +pluralizes +pluralizing +plurally +plurals +pluripotent +plus +pluses +plush +plusher +plushes +plushest +plushier +plushiest +plushily +plushiness +plushinesses +plushly +plushness +plushnesses +plushy +plussage +plussages +plusses +plutei +pluteus +plutocracies +plutocracy +plutocrat +plutocratic +plutocratically +plutocrats +pluton +plutonian +plutonic +plutonium +plutoniums +plutons +pluvial +pluvials +pluvian +pluviose +pluvious +ply +plyer +plyers +plying +plyingly +plywood +plywoods +pneuma +pneumas +pneumatic +pneumatically +pneumaticities +pneumaticity +pneumatologies +pneumatology +pneumatolytic +pneumatophore +pneumatophores +pneumococcal +pneumococci +pneumococcus +pneumoconioses +pneumoconiosis +pneumograph +pneumographs +pneumonectomies +pneumonectomy +pneumonia +pneumonias +pneumonic +pneumonites +pneumonitides +pneumonitis +pneumonitises +pneumothoraces +pneumothorax +pneumothoraxes +poaceous +poach +poached +poacher +poachers +poaches +poachier +poachiest +poaching +poachy +pochard +pochards +pock +pocked +pocket +pocketable +pocketbook +pocketbooks +pocketed +pocketer +pocketers +pocketful +pocketfuls +pocketing +pocketknife +pocketknives +pockets +pocketsful +pockier +pockiest +pockily +pocking +pockmark +pockmarked +pockmarking +pockmarks +pocks +pocky +poco +pococurante +pococurantism +pococurantisms +pocosin +pocosins +pod +podagra +podagral +podagras +podagric +podded +podding +podesta +podestas +podgier +podgiest +podgily +podgy +podia +podiatric +podiatries +podiatrist +podiatrists +podiatry +podite +podites +poditic +podium +podiums +podlike +podocarp +podomere +podomeres +podophylli +podophyllin +podophyllins +podophyllum +podophyllums +pods +podsol +podsolic +podsolization +podsolizations +podsols +podzol +podzolic +podzolization +podzolizations +podzolize +podzolized +podzolizes +podzolizing +podzols +poechore +poechores +poem +poems +poesies +poesy +poet +poetaster +poetasters +poetess +poetesses +poetic +poetical +poetically +poeticalness +poeticalnesses +poeticism +poeticisms +poeticize +poeticized +poeticizes +poeticizing +poetics +poetise +poetised +poetiser +poetisers +poetises +poetising +poetize +poetized +poetizer +poetizers +poetizes +poetizing +poetless +poetlike +poetries +poetry +poets +pogey +pogeys +pogies +pogonia +pogonias +pogonip +pogonips +pogonophoran +pogonophorans +pogrom +pogromed +pogroming +pogromist +pogromists +pogroms +pogy +poh +poi +poignance +poignances +poignancies +poignancy +poignant +poignantly +poikilotherm +poikilothermic +poikilotherms +poilu +poilus +poinciana +poincianas +poind +poinded +poinding +poinds +poinsettia +poinsettias +point +pointe +pointed +pointedly +pointedness +pointednesses +pointelle +pointelles +pointer +pointers +pointes +pointier +pointiest +pointillism +pointillisms +pointillist +pointillistic +pointillists +pointing +pointless +pointlessly +pointlessness +pointlessnesses +pointman +pointmen +points +pointtillist +pointy +pois +poise +poised +poiser +poisers +poises +poisha +poising +poison +poisoned +poisoner +poisoners +poisoning +poisonings +poisonous +poisonously +poisons +poisonwood +poisonwoods +poitrel +poitrels +poke +pokeberries +pokeberry +poked +poker +pokeroot +pokeroots +pokers +pokes +pokeweed +pokeweeds +pokey +pokeys +pokier +pokies +pokiest +pokily +pokiness +pokinesses +poking +poky +pol +polar +polarimeter +polarimeters +polarimetric +polarimetries +polarimetry +polariscope +polariscopes +polariscopic +polarise +polarised +polarises +polarising +polarities +polarity +polarizabilities +polarizability +polarizable +polarization +polarizations +polarize +polarized +polarizer +polarizers +polarizes +polarizing +polarographic +polarographically +polarographies +polarography +polaron +polarons +polars +polder +polders +pole +poleax +poleaxe +poleaxed +poleaxes +poleaxing +polecat +polecats +poled +poleis +poleless +polemic +polemical +polemically +polemicist +polemicists +polemicize +polemicized +polemicizes +polemicizing +polemics +polemist +polemists +polemize +polemized +polemizes +polemizing +polemonium +polemoniums +polenta +polentas +poler +polers +poles +polestar +polestars +poleward +poleyn +poleyns +police +policed +policeman +policemen +polices +policewoman +policewomen +policies +policing +policy +policyholder +policyholders +poling +polio +poliomyelitides +poliomyelitis +polios +poliovirus +polioviruses +polis +polish +polished +polisher +polishers +polishes +polishing +politburo +politburos +polite +politely +politeness +politenesses +politer +politesse +politesses +politest +politic +political +politicalization +politicalizations +politicalize +politicalized +politicalizes +politicalizing +politically +politician +politicians +politicise +politicised +politicises +politicising +politicization +politicizations +politicize +politicized +politicizes +politicizing +politick +politicked +politicker +politickers +politicking +politicks +politico +politicoes +politicos +politics +polities +polity +polka +polkaed +polkaing +polkas +poll +pollack +pollacks +pollard +pollarded +pollarding +pollards +polled +pollee +pollees +pollen +pollened +pollening +pollenizer +pollenizers +pollenoses +pollenosis +pollenosises +pollens +poller +pollers +pollex +pollical +pollices +pollinate +pollinated +pollinates +pollinating +pollination +pollinations +pollinator +pollinators +polling +pollinia +pollinic +pollinium +pollinizer +pollinizers +pollinoses +pollinosis +pollinosises +pollist +pollists +polliwog +polliwogs +pollock +pollocks +polls +pollster +pollsters +pollutant +pollutants +pollute +polluted +polluter +polluters +pollutes +polluting +pollution +pollutions +pollutive +pollywog +pollywogs +polo +poloist +poloists +polonaise +polonaises +polonium +poloniums +polos +pols +poltergeist +poltergeists +poltroon +poltrooneries +poltroonery +poltroons +poly +polyacrylamide +polyacrylamides +polyacrylonitrile +polyacrylonitriles +polyalcohol +polyalcohols +polyamide +polyamides +polyamine +polyamines +polyandries +polyandrous +polyandry +polyantha +polyanthas +polyanthi +polyanthus +polyanthuses +polyatomic +polybrid +polybrids +polybutadiene +polybutadienes +polycarbonate +polycarbonates +polycentric +polycentrism +polycentrisms +polychaete +polychaetes +polychotomies +polychotomous +polychotomy +polychromatic +polychromatophilia +polychromatophilias +polychromatophilic +polychrome +polychromed +polychromes +polychromies +polychroming +polychromy +polycistronic +polyclinic +polyclinics +polyclonal +polycondensation +polycondensations +polycot +polycots +polycrystal +polycrystalline +polycrystals +polycyclic +polycystic +polycythemia +polycythemias +polycythemic +polydactyl +polydactylies +polydactyly +polydipsia +polydipsias +polydipsic +polydisperse +polydispersities +polydispersity +polyelectrolyte +polyelectrolytes +polyembryonic +polyembryonies +polyembryony +polyene +polyenes +polyenic +polyester +polyesterification +polyesterifications +polyesters +polyestrous +polyethylene +polyethylenes +polygala +polygalas +polygamic +polygamies +polygamist +polygamists +polygamize +polygamized +polygamizes +polygamizing +polygamous +polygamy +polygene +polygenes +polygeneses +polygenesis +polygenetic +polygenic +polyglot +polyglotism +polyglotisms +polyglots +polyglottism +polyglottisms +polygon +polygonal +polygonally +polygonies +polygons +polygonum +polygonums +polygony +polygraph +polygrapher +polygraphers +polygraphic +polygraphist +polygraphists +polygraphs +polygynies +polygynous +polygyny +polyhedra +polyhedral +polyhedron +polyhedrons +polyhedroses +polyhedrosis +polyhistor +polyhistoric +polyhistors +polyhydroxy +polylysine +polylysines +polymath +polymathic +polymathies +polymaths +polymathy +polymer +polymerase +polymerases +polymeric +polymerisation +polymerisations +polymerise +polymerised +polymerises +polymerising +polymerism +polymerisms +polymerization +polymerizations +polymerize +polymerized +polymerizes +polymerizing +polymers +polymorph +polymorphic +polymorphically +polymorphism +polymorphisms +polymorphonuclear +polymorphonuclears +polymorphous +polymorphously +polymorphs +polymyxin +polymyxins +polyneuritides +polyneuritis +polyneuritises +polynomial +polynomials +polynuclear +polynucleotide +polynucleotides +polynya +polynyas +polynyi +polyolefin +polyolefins +polyoma +polyomas +polyonymous +polyp +polyparies +polypary +polypeptide +polypeptides +polypeptidic +polypetalous +polyphagia +polyphagias +polyphagies +polyphagous +polyphagy +polyphase +polyphasic +polyphenol +polyphenolic +polyphenols +polyphiloprogenitive +polyphone +polyphones +polyphonic +polyphonically +polyphonies +polyphonous +polyphonously +polyphony +polyphyletic +polyphyletically +polypi +polypide +polypides +polyploid +polyploidies +polyploids +polyploidy +polypnea +polypneas +polypod +polypodies +polypods +polypody +polypoid +polypore +polypores +polypous +polypropylene +polypropylenes +polyps +polyptych +polyptychs +polypus +polypuses +polyrhythm +polyrhythmic +polyrhythmically +polyrhythms +polyribonucleotide +polyribonucleotides +polyribosomal +polyribosome +polyribosomes +polys +polysaccharide +polysaccharides +polysemies +polysemous +polysemy +polysome +polysomes +polysorbate +polysorbates +polystichous +polystyrene +polystyrenes +polysulfide +polysulfides +polysyllabic +polysyllabically +polysyllable +polysyllables +polysynaptic +polysynaptically +polysyndeton +polysyndetons +polytechnic +polytechnics +polytene +polytenies +polyteny +polytheism +polytheisms +polytheist +polytheistic +polytheistical +polytheists +polythene +polythenes +polytonal +polytonalities +polytonality +polytonally +polytype +polytypes +polytypic +polyunsaturated +polyurethane +polyurethanes +polyuria +polyurias +polyuric +polyvalence +polyvalences +polyvalent +polyvinyl +polywater +polywaters +polyzoan +polyzoans +polyzoic +pom +pomace +pomaceous +pomaces +pomade +pomaded +pomades +pomading +pomander +pomanders +pomatum +pomatums +pome +pomegranate +pomegranates +pomelo +pomelos +pomes +pomfret +pomfrets +pommee +pommel +pommeled +pommeling +pommelled +pommelling +pommels +pommie +pommies +pommy +pomological +pomologies +pomologist +pomologists +pomology +pomp +pompadour +pompadoured +pompadours +pompano +pompanos +pompom +pompoms +pompon +pompons +pomposities +pomposity +pompous +pompously +pompousness +pompousnesses +pomps +poms +ponce +ponced +ponces +poncho +ponchos +poncing +pond +ponded +ponder +ponderable +pondered +ponderer +ponderers +pondering +ponderosa +ponderosas +ponderous +ponderously +ponderousness +ponderousnesses +ponders +ponding +ponds +pondweed +pondweeds +pone +ponent +pones +pong +ponged +pongee +pongees +pongid +pongids +ponging +pongs +poniard +poniarded +poniarding +poniards +ponied +ponies +pons +pontes +pontifex +pontiff +pontiffs +pontific +pontifical +pontifically +pontificals +pontificate +pontificated +pontificates +pontificating +pontification +pontifications +pontificator +pontificators +pontifices +pontil +pontils +pontine +ponton +pontons +pontoon +pontoons +pony +ponying +ponytail +ponytailed +ponytails +pooch +pooched +pooches +pooching +pood +poodle +poodles +poods +poof +poofs +pooftah +pooftahs +poofter +poofters +poofy +pooh +poohed +poohing +poohs +pool +pooled +poolhall +poolhalls +pooling +poolroom +poolrooms +pools +poolside +poolsides +poon +poons +poop +pooped +pooping +poops +poor +poorer +poorest +poorhouse +poorhouses +poori +pooris +poorish +poorly +poorness +poornesses +poortith +poortiths +poove +pooves +pop +popcorn +popcorns +pope +popedom +popedoms +popeless +popelike +poperies +popery +popes +popeyed +popgun +popguns +popinjay +popinjays +popish +popishly +poplar +poplars +poplin +poplins +popliteal +poplitic +popover +popovers +poppa +poppas +popped +popper +poppers +poppet +poppets +poppied +poppies +popping +popple +poppled +popples +poppling +poppy +poppycock +poppycocks +poppyhead +poppyheads +pops +popsie +popsies +popsy +populace +populaces +popular +popularise +popularised +popularises +popularising +popularities +popularity +popularization +popularizations +popularize +popularized +popularizer +popularizers +popularizes +popularizing +popularly +populate +populated +populates +populating +population +populational +populations +populism +populisms +populist +populistic +populists +populous +populously +populousness +populousnesses +porbeagle +porbeagles +porcelain +porcelainize +porcelainized +porcelainizes +porcelainizing +porcelainlike +porcelains +porcelaneous +porcellaneous +porch +porches +porcine +porcini +porcino +porcupine +porcupines +pore +pored +pores +porgies +porgy +poring +porism +porisms +pork +porker +porkers +porkier +porkies +porkiest +porkpie +porkpies +porks +porkwood +porkwoods +porky +porn +pornier +porniest +porno +pornographer +pornographers +pornographic +pornographically +pornographies +pornography +pornos +porns +porny +porose +porosities +porosity +porous +porously +porousness +porousnesses +porphyria +porphyrias +porphyries +porphyrin +porphyrins +porphyritic +porphyropsin +porphyropsins +porphyry +porpoise +porpoises +porrect +porridge +porridges +porridgy +porringer +porringers +port +portabilities +portability +portable +portables +portably +portage +portaged +portages +portaging +portal +portaled +portals +portamenti +portamento +portance +portances +portapack +portapacks +portapak +portapaks +portative +portcullis +portcullises +ported +portend +portended +portending +portends +portent +portentous +portentously +portentousness +portentousnesses +portents +porter +porterage +porterages +portered +porterhouse +porterhouses +portering +porters +portfolio +portfolios +porthole +portholes +portico +porticoes +porticos +portiere +portieres +porting +portion +portioned +portioning +portionless +portions +portless +portlier +portliest +portliness +portlinesses +portly +portmanteau +portmanteaus +portmanteaux +portrait +portraitist +portraitists +portraits +portraiture +portraitures +portray +portrayal +portrayals +portrayed +portrayer +portrayers +portraying +portrays +portress +portresses +ports +portulaca +portulacas +posada +posadas +pose +posed +poser +posers +poses +poseur +poseurs +posh +posher +poshest +poshly +poshness +poshnesses +posies +posing +posingly +posit +posited +positing +position +positional +positionally +positioned +positioning +positions +positive +positively +positiveness +positivenesses +positiver +positives +positivest +positivism +positivisms +positivist +positivistic +positivistically +positivists +positivities +positivity +positron +positronium +positroniums +positrons +posits +posologies +posology +posse +posses +possess +possessed +possessedly +possessedness +possessednesses +possesses +possessing +possession +possessional +possessionless +possessions +possessive +possessively +possessiveness +possessivenesses +possessives +possessor +possessors +possessory +posset +possets +possibilities +possibility +possible +possibler +possiblest +possibly +possum +possums +post +postabortion +postaccident +postadolescent +postadolescents +postage +postages +postal +postally +postals +postamputation +postanal +postapocalyptic +postarrest +postatomic +postattack +postaxial +postbaccalaureate +postbag +postbags +postbase +postbellum +postbiblical +postbourgeois +postbox +postboxes +postboy +postboys +postburn +postcapitalist +postcard +postcardlike +postcards +postcava +postcavae +postcaval +postclassic +postclassical +postcode +postcodes +postcoital +postcollege +postcolleges +postcollegiate +postcolonial +postconception +postconcert +postconquest +postconsonantal +postconvention +postcopulatory +postcoronary +postcoup +postcranial +postcranially +postcrash +postcrises +postcrisis +postdate +postdated +postdates +postdating +postdeadline +postdebate +postdebutante +postdebutantes +postdelivery +postdepositional +postdepression +postdevaluation +postdiluvian +postdiluvians +postdive +postdivestiture +postdivorce +postdoc +postdocs +postdoctoral +postdoctorate +postdrug +posted +postediting +posteditings +posteen +posteens +postelection +postembryonal +postembryonic +postemergence +postemergency +postencephalitic +postepileptic +poster +posterior +posteriorities +posteriority +posteriorly +posteriors +posterities +posterity +postern +posterns +posterolateral +posters +posteruptive +postexercise +postexilic +postexperience +postexperimental +postexposure +postface +postfaces +postfault +postfeminist +postfire +postfix +postfixed +postfixes +postfixing +postflight +postform +postformed +postforming +postforms +postfracture +postfractures +postfreeze +postgame +postganglionic +postglacial +postgraduate +postgraduates +postgraduation +postharvest +posthaste +posthastes +postheat +postheats +posthemorrhagic +posthole +postholes +postholiday +postholocaust +posthospital +posthumous +posthumously +posthumousness +posthumousnesses +posthypnotic +postiche +postiches +postilion +postilions +postillion +postillions +postimpact +postimperial +postin +postinaugural +postindependence +postindustrial +postinfection +posting +postings +postinjection +postinoculation +postins +postique +postiques +postirradiation +postischemic +postisolation +postlanding +postlapsarian +postlaunch +postliberation +postliterate +postlude +postludes +postman +postmarital +postmark +postmarked +postmarking +postmarks +postmastectomy +postmaster +postmasters +postmastership +postmasterships +postmating +postmedieval +postmen +postmenopausal +postmidnight +postmillenarian +postmillenarianism +postmillenarianisms +postmillenarians +postmillennial +postmillennialism +postmillennialisms +postmillennialist +postmillennialists +postmistress +postmistresses +postmodern +postmodernism +postmodernisms +postmodernist +postmodernists +postmortem +postmortems +postnatal +postnatally +postneonatal +postnuptial +postoperative +postoperatively +postoral +postorbital +postorgasmic +postpaid +postpartum +postpollination +postponable +postpone +postponed +postponement +postponements +postponer +postponers +postpones +postponing +postposition +postpositional +postpositionally +postpositions +postpositive +postpositively +postprandial +postpresidential +postprimary +postprison +postproduction +postproductions +postpsychoanalytic +postpuberty +postpubescent +postpubescents +postrace +postrecession +postresurrection +postresurrections +postretirement +postrevolutionary +postriot +postromantic +posts +postscript +postscripts +postseason +postseasons +postsecondary +postshow +poststimulation +poststimulatory +poststimulus +poststrike +postsurgical +postsynaptic +postsynaptically +postsync +postsynced +postsyncing +postsyncs +posttax +postteen +posttension +posttensioned +posttensioning +posttensions +posttest +posttests +posttranscriptional +posttransfusion +posttranslational +posttraumatic +posttreatment +posttrial +postulancies +postulancy +postulant +postulants +postulate +postulated +postulates +postulating +postulation +postulational +postulations +postulator +postulators +postural +posture +postured +posturer +posturers +postures +posturing +posturings +postvaccinal +postvaccination +postvagotomy +postvasectomy +postvocalic +postwar +postweaning +postworkshop +posy +pot +potabilities +potability +potable +potableness +potablenesses +potables +potage +potages +potamic +potash +potashes +potassic +potassium +potassiums +potation +potations +potato +potatoes +potatory +potbellied +potbellies +potbelly +potboil +potboiled +potboiler +potboilers +potboiling +potboils +potboy +potboys +poteen +poteens +potence +potences +potencies +potency +potent +potentate +potentates +potential +potentialities +potentiality +potentially +potentials +potentiate +potentiated +potentiates +potentiating +potentiation +potentiations +potentiator +potentiators +potentilla +potentillas +potentiometer +potentiometers +potentiometric +potently +potful +potfuls +pothead +potheads +potheen +potheens +pother +potherb +potherbs +pothered +pothering +pothers +potholder +potholders +pothole +potholed +potholes +pothook +pothooks +pothouse +pothouses +pothunter +pothunters +pothunting +pothuntings +potiche +potiches +potion +potions +potlach +potlache +potlaches +potlatch +potlatched +potlatches +potlatching +potlike +potline +potlines +potluck +potlucks +potman +potmen +potometer +potometers +potpie +potpies +potpourri +potpourris +pots +potshard +potshards +potsherd +potsherds +potshot +potshots +potshotting +potsie +potsies +potstone +potstones +potsy +pottage +pottages +potted +potteen +potteens +potter +pottered +potterer +potterers +potteries +pottering +potteringly +potters +pottery +pottier +potties +pottiest +potting +pottle +pottles +potto +pottos +potty +potzer +potzers +pouch +pouched +pouches +pouchier +pouchiest +pouching +pouchy +pouf +poufed +pouff +pouffe +pouffed +pouffes +pouffs +poufs +poulard +poularde +poulardes +poulards +poult +poulter +poulterer +poulterers +poulters +poultice +poulticed +poultices +poulticing +poultries +poultry +poultryman +poultrymen +poults +pounce +pounced +pouncer +pouncers +pounces +pouncing +pound +poundage +poundages +poundal +poundals +pounded +pounder +pounders +pounding +pounds +pour +pourable +pourboire +pourboires +poured +pourer +pourers +pouring +pouringly +pourparler +pourparlers +pourpoint +pourpoints +pours +poussette +poussetted +poussettes +poussetting +poussie +poussies +pout +pouted +pouter +pouters +poutful +poutier +poutiest +pouting +pouts +pouty +poverties +poverty +pow +powder +powdered +powderer +powderers +powdering +powderless +powderlike +powders +powdery +power +powerboat +powerboats +powerbroker +powerbrokers +powered +powerful +powerfully +powerhouse +powerhouses +powering +powerless +powerlessly +powerlessness +powerlessnesses +powers +pows +powter +powters +powwow +powwowed +powwowing +powwows +pox +poxed +poxes +poxing +poxvirus +poxviruses +poyou +poyous +pozzolan +pozzolana +pozzolanas +pozzolanic +pozzolans +praam +praams +practic +practicabilities +practicability +practicable +practicableness +practicablenesses +practicably +practical +practicalities +practicality +practically +practicalness +practicalnesses +practicals +practice +practiced +practicer +practicers +practices +practicing +practicum +practicums +practise +practised +practises +practising +practitioner +practitioners +praecipe +praecipes +praedial +praefect +praefects +praelect +praelected +praelecting +praelects +praemunire +praemunires +praenomen +praenomens +praenomina +praesidia +praesidium +praesidiums +praetor +praetorial +praetorian +praetorians +praetors +praetorship +praetorships +pragmatic +pragmatical +pragmatically +pragmaticism +pragmaticisms +pragmaticist +pragmaticists +pragmatics +pragmatism +pragmatisms +pragmatist +pragmatistic +pragmatists +prahu +prahus +prairie +prairies +praise +praised +praiser +praisers +praises +praiseworthily +praiseworthiness +praiseworthinesses +praiseworthy +praising +praline +pralines +pralltriller +pralltrillers +pram +prams +prance +pranced +prancer +prancers +prances +prancing +prandial +prang +pranged +pranging +prangs +prank +pranked +pranking +prankish +prankishly +prankishness +prankishnesses +pranks +prankster +pranksters +prao +praos +prase +praseodymium +praseodymiums +prases +prat +prate +prated +prater +praters +prates +pratfall +pratfalls +pratincole +pratincoles +prating +pratingly +pratique +pratiques +prats +prattle +prattled +prattler +prattlers +prattles +prattling +prattlingly +prau +praus +prawn +prawned +prawner +prawners +prawning +prawns +praxeological +praxeologies +praxeology +praxes +praxis +praxises +pray +prayed +prayer +prayerful +prayerfully +prayerfulness +prayerfulnesses +prayers +praying +prays +preach +preached +preacher +preachers +preaches +preachier +preachiest +preachified +preachifies +preachify +preachifying +preachily +preachiness +preachinesses +preaching +preachingly +preachment +preachments +preachy +preact +preacted +preacting +preacts +preadapt +preadaptation +preadaptations +preadapted +preadapting +preadaptive +preadapts +preadmission +preadmissions +preadmit +preadmits +preadmitted +preadmitting +preadolescence +preadolescences +preadolescent +preadolescents +preadopt +preadopted +preadopting +preadopts +preadult +preaged +preagricultural +preallot +preallots +preallotted +preallotting +preamble +preambles +preamp +preamplifier +preamplifiers +preamps +preanal +preanesthetic +preanesthetics +preannounce +preannounced +preannounces +preannouncing +preapprove +preapproved +preapproves +preapproving +prearm +prearmed +prearming +prearms +prearrange +prearranged +prearrangement +prearrangements +prearranges +prearranging +preassembled +preassign +preassigned +preassigning +preassigns +preatomic +preaudit +preaudits +preaver +preaverred +preaverring +preavers +preaxial +prebake +prebaked +prebakes +prebaking +prebasal +prebattle +prebend +prebendal +prebendaries +prebendary +prebends +prebiblical +prebill +prebilled +prebilling +prebills +prebind +prebinding +prebinds +prebiologic +prebiological +prebiotic +prebless +preblessed +preblesses +preblessing +preboil +preboiled +preboiling +preboils +prebook +prebooked +prebooking +prebooks +preboom +prebound +prebreakfast +precalculi +precalculus +precalculuses +precancel +precanceled +precanceling +precancellation +precancellations +precancelled +precancelling +precancels +precancerous +precapitalist +precapitalists +precarious +precariously +precariousness +precariousnesses +precast +precasting +precasts +precatory +precaution +precautionary +precautioned +precautioning +precautions +precava +precavae +precaval +precede +preceded +precedence +precedences +precedencies +precedency +precedent +precedents +precedes +preceding +precensor +precensored +precensoring +precensors +precent +precented +precenting +precentor +precentorial +precentors +precentorship +precentorships +precents +precept +preceptive +preceptor +preceptorial +preceptorials +preceptories +preceptors +preceptorship +preceptorships +preceptory +precepts +precertification +precertifications +precertified +precertifies +precertify +precertifying +precess +precessed +precesses +precessing +precession +precessional +precessions +precheck +prechecked +prechecking +prechecks +prechill +prechilled +prechilling +prechills +precieuse +precieux +precinct +precincts +preciosities +preciosity +precious +preciouses +preciously +preciousness +preciousnesses +precipe +precipes +precipice +precipices +precipitable +precipitance +precipitances +precipitancies +precipitancy +precipitant +precipitantly +precipitantness +precipitantnesses +precipitants +precipitate +precipitated +precipitately +precipitateness +precipitatenesses +precipitates +precipitating +precipitation +precipitations +precipitative +precipitator +precipitators +precipitin +precipitinogen +precipitinogens +precipitins +precipitous +precipitously +precipitousness +precipitousnesses +precis +precise +precised +precisely +preciseness +precisenesses +preciser +precises +precisest +precisian +precisians +precising +precision +precisionist +precisionists +precisions +precited +preclean +precleaned +precleaning +precleans +preclear +preclearance +preclearances +precleared +preclearing +preclears +preclinical +preclude +precluded +precludes +precluding +preclusion +preclusions +preclusive +preclusively +precocial +precocious +precociously +precociousness +precociousnesses +precocities +precocity +precode +precoded +precodes +precoding +precognition +precognitions +precognitive +precoital +precollege +precolleges +precollegiate +precolonial +precombustion +precombustions +precommitment +precompute +precomputed +precomputer +precomputers +precomputes +precomputing +preconceive +preconceived +preconceives +preconceiving +preconception +preconceptions +preconcert +preconcerted +preconcerting +preconcerts +precondition +preconditioned +preconditioning +preconditions +preconquest +preconscious +preconsciouses +preconsciously +preconsonantal +preconstructed +precontact +preconvention +preconventions +preconviction +preconvictions +precook +precooked +precooking +precooks +precool +precooled +precooling +precools +precopulatory +precoup +precrash +precrease +precreased +precreases +precreasing +precrisis +precritical +precure +precured +precures +precuring +precursor +precursors +precursory +precut +precuts +precutting +predaceous +predaceousness +predaceousnesses +predacious +predacities +predacity +predate +predated +predates +predating +predation +predations +predator +predators +predatory +predawn +predawns +predecease +predeceased +predeceases +predeceasing +predecessor +predecessors +predefine +predefined +predefines +predefining +predeliveries +predelivery +predeparture +predepartures +predesignate +predesignated +predesignates +predesignating +predestinarian +predestinarianism +predestinarianisms +predestinarians +predestinate +predestinated +predestinates +predestinating +predestination +predestinations +predestinator +predestinators +predestine +predestined +predestines +predestining +predetermination +predeterminations +predetermine +predetermined +predeterminer +predeterminers +predetermines +predetermining +predevaluation +predevaluations +predevelopment +predevelopments +prediabetes +prediabeteses +prediabetic +prediabetics +predial +predicable +predicables +predicament +predicaments +predicate +predicated +predicates +predicating +predication +predications +predicative +predicatively +predicatory +predict +predictabilities +predictability +predictable +predictably +predicted +predicting +prediction +predictions +predictive +predictively +predictor +predictors +predicts +predigest +predigested +predigesting +predigestion +predigestions +predigests +predilection +predilections +predinner +predischarge +predischarged +predischarges +predischarging +prediscoveries +prediscovery +predispose +predisposed +predisposes +predisposing +predisposition +predispositions +predive +prednisolone +prednisolones +prednisone +prednisones +predoctoral +predominance +predominances +predominancies +predominancy +predominant +predominantly +predominate +predominated +predominately +predominates +predominating +predomination +predominations +predrill +predrilled +predrilling +predrills +predusk +predusks +predynastic +pree +preeclampsia +preeclampsias +preeclamptic +preed +preedit +preedited +preediting +preedits +preeing +preelect +preelected +preelecting +preelection +preelections +preelectric +preelects +preembargo +preemergence +preemergent +preemie +preemies +preeminence +preeminences +preeminent +preeminently +preemployment +preemployments +preempt +preempted +preempting +preemption +preemptions +preemptive +preemptively +preemptor +preemptors +preemptory +preempts +preen +preenact +preenacted +preenacting +preenacts +preened +preener +preeners +preening +preenrollment +preenrollments +preens +preerect +preerected +preerecting +preerects +prees +preestablish +preestablished +preestablishes +preestablishing +preethical +preexilic +preexist +preexisted +preexistence +preexistences +preexistent +preexisting +preexists +preexperiment +preexperiments +prefab +prefabbed +prefabbing +prefabricate +prefabricated +prefabricates +prefabricating +prefabrication +prefabrications +prefabs +preface +prefaced +prefacer +prefacers +prefaces +prefacing +prefade +prefaded +prefades +prefading +prefascist +prefascists +prefatory +prefect +prefects +prefectural +prefecture +prefectures +prefer +preferabilities +preferability +preferable +preferably +preference +preferences +preferential +preferentially +preferment +preferments +preferred +preferrer +preferrers +preferring +prefers +prefeudal +prefight +prefiguration +prefigurations +prefigurative +prefiguratively +prefigurativeness +prefigurativenesses +prefigure +prefigured +prefigurement +prefigurements +prefigures +prefiguring +prefile +prefiled +prefiles +prefiling +prefilled +prefinance +prefinanced +prefinances +prefinancing +prefire +prefired +prefires +prefiring +prefix +prefixal +prefixed +prefixes +prefixing +preflame +preflight +prefocus +prefocused +prefocuses +prefocusing +prefocussed +prefocusses +prefocussing +preform +preformat +preformation +preformationist +preformationists +preformations +preformats +preformatted +preformatting +preformed +preforming +preforms +preformulate +preformulated +preformulates +preformulating +prefrank +prefranked +prefranking +prefranks +prefreeze +prefreezes +prefreezing +prefreshman +prefreshmen +prefrontal +prefrontals +prefroze +prefrozen +pregame +preganglionic +pregenital +preggers +pregnabilities +pregnability +pregnable +pregnancies +pregnancy +pregnant +pregnantly +pregnenolone +pregnenolones +preharvest +preharvests +preheadache +preheat +preheated +preheater +preheaters +preheating +preheats +prehensile +prehensilities +prehensility +prehension +prehensions +prehiring +prehistorian +prehistorians +prehistoric +prehistorical +prehistorically +prehistories +prehistory +preholiday +prehominid +prehominids +prehuman +prehumans +preignition +preignitions +preimplantation +preinaugural +preincorporation +preincorporations +preinduction +preinductions +preindustrial +preinterview +preinterviewed +preinterviewing +preinterviews +preinvasion +prejudge +prejudged +prejudger +prejudgers +prejudges +prejudging +prejudgment +prejudgments +prejudice +prejudiced +prejudices +prejudicial +prejudicially +prejudicialness +prejudicialnesses +prejudicing +prekindergarten +prekindergartens +prelacies +prelacy +prelapsarian +prelate +prelates +prelatic +prelature +prelatures +prelaunch +prelect +prelected +prelecting +prelection +prelections +prelects +prelegal +prelibation +prelibations +prelife +prelim +preliminaries +preliminarily +preliminary +prelimit +prelimited +prelimiting +prelimits +prelims +preliterary +preliterate +preliterates +prelives +prelogical +prelude +preluded +preluder +preluders +preludes +preluding +prelunch +preluncheon +prelusion +prelusions +prelusive +prelusively +premade +premalignant +preman +premanufacture +premanufactured +premanufactures +premanufacturing +premarital +premaritally +premarket +premarketing +premarketings +premarriage +premarriages +premature +prematurely +prematureness +prematurenesses +prematures +prematurities +prematurity +premaxilla +premaxillae +premaxillaries +premaxillary +premaxillas +premeal +premeasure +premeasured +premeasures +premeasuring +premed +premedic +premedical +premedics +premedieval +premeditate +premeditated +premeditatedly +premeditates +premeditating +premeditation +premeditations +premeditative +premeditator +premeditators +premeds +premeet +premeiotic +premen +premenopausal +premenstrual +premenstrually +premerger +premie +premier +premiere +premiered +premieres +premiering +premiers +premiership +premierships +premies +premigration +premillenarian +premillenarianism +premillenarianisms +premillenarians +premillennial +premillennialism +premillennialisms +premillennialist +premillennialists +premillennially +premise +premised +premises +premising +premiss +premisses +premium +premiums +premix +premixed +premixes +premixing +premixt +premodern +premodification +premodifications +premodified +premodifies +premodify +premodifying +premoisten +premoistened +premoistening +premoistens +premolar +premolars +premold +premolded +premolding +premolds +premolt +premonish +premonished +premonishes +premonishing +premonition +premonitions +premonitorily +premonitory +premoral +premorse +premune +premunition +premunitions +premycotic +prename +prenames +prenatal +prenatally +prenomen +prenomens +prenomina +prenominate +prenominated +prenominates +prenominating +prenomination +prenominations +prenoon +prenotification +prenotifications +prenotified +prenotifies +prenotify +prenotifying +prenotion +prenotions +prentice +prenticed +prentices +prenticing +prenumber +prenumbered +prenumbering +prenumbers +prenuptial +preoccupancies +preoccupancy +preoccupation +preoccupations +preoccupied +preoccupies +preoccupy +preoccupying +preopening +preoperational +preoperative +preoperatively +preordain +preordained +preordaining +preordainment +preordainments +preordains +preorder +preordered +preordering +preorders +preordination +preordinations +preovulatory +prep +prepack +prepackage +prepackaged +prepackages +prepackaging +prepacked +prepacking +prepacks +prepaid +preparation +preparations +preparative +preparatively +preparatives +preparator +preparatorily +preparators +preparatory +prepare +prepared +preparedly +preparedness +preparednesses +preparer +preparers +prepares +preparing +prepaste +prepasted +prepastes +prepasting +prepay +prepaying +prepayment +prepayments +prepays +prepense +prepensely +preperformance +preperformances +prepill +preplace +preplaced +preplaces +preplacing +preplan +preplanned +preplanning +preplans +preplant +preplanting +preponderance +preponderances +preponderancies +preponderancy +preponderant +preponderantly +preponderate +preponderated +preponderately +preponderates +preponderating +preponderation +preponderations +preportion +preportioned +preportioning +preportions +preposition +prepositional +prepositionally +prepositions +prepositive +prepositively +prepossess +prepossessed +prepossesses +prepossessing +prepossession +prepossessions +preposterous +preposterously +preposterousness +preposterousnesses +prepotencies +prepotency +prepotent +prepotently +prepped +preppie +preppier +preppies +preppiest +preppily +preppiness +preppinesses +prepping +preppy +preprandial +prepreg +prepregs +preprepared +prepresidential +preprice +prepriced +preprices +prepricing +preprimary +preprint +preprinted +preprinting +preprints +preprocess +preprocessed +preprocesses +preprocessing +preprocessor +preprocessors +preproduction +preproductions +preprofessional +preprogram +preprogramed +preprograming +preprogrammed +preprogramming +preprograms +preps +prepsychedelic +prepuberal +prepubertal +prepuberties +prepuberty +prepubescence +prepubescences +prepubescent +prepubescents +prepublication +prepublications +prepuce +prepuces +prepunch +prepunched +prepunches +prepunching +prepupal +prepurchase +prepurchased +prepurchases +prepurchasing +preputial +prequalification +prequalifications +prequalified +prequalifies +prequalify +prequalifying +prequel +prequels +prerace +prerecession +prerecord +prerecorded +prerecording +prerecords +preregister +preregistered +preregistering +preregisters +preregistration +preregistrations +prerehearsal +prerelease +prereleases +prerenal +prerequire +prerequired +prerequires +prerequiring +prerequisite +prerequisites +preretirement +preretirements +prereturn +prereview +prerevisionist +prerevisionists +prerevolution +prerevolutionary +prerinse +prerinses +preriot +prerock +prerogative +prerogatived +prerogatives +preromantic +presa +presage +presaged +presageful +presager +presagers +presages +presaging +presale +presanctified +presbyope +presbyopes +presbyopia +presbyopias +presbyopic +presbyopics +presbyter +presbyterate +presbyterates +presbyterial +presbyterially +presbyterials +presbyterian +presbyteries +presbyters +presbytery +preschedule +prescheduled +preschedules +prescheduling +preschool +preschooler +preschoolers +preschools +prescience +presciences +prescient +prescientific +presciently +prescind +prescinded +prescinding +prescinds +prescore +prescored +prescores +prescoring +prescreen +prescreened +prescreening +prescreens +prescribe +prescribed +prescriber +prescribers +prescribes +prescribing +prescript +prescription +prescriptions +prescriptive +prescriptively +prescripts +prese +preseason +preseasons +preselect +preselected +preselecting +preselection +preselections +preselects +presell +preselling +presells +presence +presences +present +presentabilities +presentability +presentable +presentableness +presentablenesses +presentably +presentation +presentational +presentations +presentative +presented +presentee +presentees +presentence +presentenced +presentences +presentencing +presentencings +presenter +presenters +presentient +presentiment +presentimental +presentiments +presenting +presentism +presentisms +presentist +presently +presentment +presentments +presentness +presentnesses +presents +preservabilities +preservability +preservable +preservation +preservationist +preservationists +preservations +preservative +preservatives +preserve +preserved +preserver +preservers +preserves +preservice +preserving +preset +presets +presetting +presettlement +presettlements +preshape +preshaped +preshapes +preshaping +preshow +preshowed +preshowing +preshown +preshows +preshrank +preshrink +preshrinking +preshrinks +preshrunk +preshrunken +preside +presided +presidencies +presidency +president +presidential +presidentially +presidents +presidentship +presidentships +presider +presiders +presides +presidia +presidial +presidiary +presiding +presidio +presidios +presidium +presidiums +presift +presifted +presifting +presifts +presignified +presignifies +presignify +presignifying +preslaughter +presleep +preslice +presliced +preslices +preslicing +presoak +presoaked +presoaking +presoaks +presold +presong +presort +presorted +presorting +presorts +prespecified +prespecifies +prespecify +prespecifying +presplit +press +pressboard +pressboards +pressed +presser +pressers +presses +pressing +pressingly +pressings +pressman +pressmark +pressmarks +pressmen +pressor +pressors +pressroom +pressrooms +pressrun +pressruns +pressure +pressured +pressureless +pressures +pressuring +pressurise +pressurised +pressurises +pressurising +pressurization +pressurizations +pressurize +pressurized +pressurizer +pressurizers +pressurizes +pressurizing +presswork +pressworks +prest +prestamp +prestamped +prestamping +prestamps +prester +presterilize +presterilized +presterilizes +presterilizing +presters +prestidigitation +prestidigitations +prestidigitator +prestidigitators +prestige +prestigeful +prestiges +prestigious +prestigiously +prestigiousness +prestigiousnesses +prestissimo +presto +prestorage +prestorages +prestos +prestress +prestressed +prestresses +prestressing +prestrike +prestructure +prestructured +prestructures +prestructuring +prests +presumable +presumably +presume +presumed +presumedly +presumer +presumers +presumes +presuming +presumingly +presummit +presumption +presumptions +presumptive +presumptively +presumptuous +presumptuously +presumptuousness +presumptuousnesses +presuppose +presupposed +presupposes +presupposing +presupposition +presuppositional +presuppositions +presurgery +presweeten +presweetened +presweetening +presweetens +presymptomatic +presynaptic +presynaptically +pretape +pretaped +pretapes +pretaping +pretaste +pretasted +pretastes +pretasting +pretax +pretechnological +preteen +preteens +pretelevision +pretence +pretences +pretend +pretended +pretendedly +pretender +pretenders +pretending +pretends +pretense +pretenses +pretension +pretensioned +pretensioning +pretensionless +pretensions +pretentious +pretentiously +pretentiousness +pretentiousnesses +preterit +preterite +preterites +preterits +preterm +preterminal +pretermination +preterminations +pretermission +pretermissions +pretermit +pretermits +pretermitted +pretermitting +preternatural +preternaturally +preternaturalness +preternaturalnesses +pretest +pretested +pretesting +pretests +pretext +pretexted +pretexting +pretexts +pretheater +pretor +pretorian +pretorians +pretors +pretournament +pretournaments +pretrain +pretrained +pretraining +pretrains +pretravel +pretreat +pretreated +pretreating +pretreatment +pretreatments +pretreats +pretrial +pretrials +pretrim +pretrimmed +pretrimming +pretrims +prettied +prettier +pretties +prettiest +prettification +prettifications +prettified +prettifier +prettifiers +prettifies +prettify +prettifying +prettily +prettiness +prettinesses +pretty +prettying +prettyish +pretype +pretyped +pretypes +pretyping +pretzel +pretzels +preunification +preunion +preunions +preunite +preunited +preunites +preuniting +preuniversity +prevail +prevailed +prevailing +prevails +prevalence +prevalences +prevalent +prevalently +prevalents +prevaricate +prevaricated +prevaricates +prevaricating +prevarication +prevarications +prevaricator +prevaricators +prevenient +preveniently +prevent +preventabilities +preventability +preventable +preventative +preventatives +prevented +preventer +preventers +preventible +preventing +prevention +preventions +preventive +preventively +preventiveness +preventivenesses +preventives +prevents +preverbal +previable +preview +previewed +previewer +previewers +previewing +previews +previous +previously +previousness +previousnesses +previse +prevised +previses +prevising +prevision +previsional +previsionary +previsioned +previsioning +previsions +previsor +previsors +prevocalic +prevocational +prevue +prevued +prevues +prevuing +prewar +prewarm +prewarmed +prewarming +prewarms +prewarn +prewarned +prewarning +prewarns +prewash +prewashed +prewashes +prewashing +preweaning +prework +prewrap +prewrapped +prewrapping +prewraps +prewriting +prewritings +prex +prexes +prexies +prexy +prey +preyed +preyer +preyers +preying +preys +prez +prezes +priapean +priapi +priapic +priapism +priapisms +priapus +priapuses +price +priced +priceless +pricelessly +pricer +pricers +prices +pricey +pricier +priciest +pricing +prick +pricked +pricker +prickers +pricket +prickets +prickier +prickiest +pricking +prickings +prickle +prickled +prickles +pricklier +prickliest +prickliness +pricklinesses +prickling +prickly +pricks +pricky +pricy +pride +prided +prideful +pridefully +pridefulness +pridefulnesses +prides +priding +pried +priedieu +priedieus +priedieux +prier +priers +pries +priest +priested +priestess +priestesses +priesthood +priesthoods +priesting +priestlier +priestliest +priestliness +priestlinesses +priestly +priests +prig +prigged +priggeries +priggery +prigging +priggish +priggishly +priggishness +priggishnesses +priggism +priggisms +prigs +prill +prilled +prilling +prills +prim +prima +primacies +primacy +primage +primages +primal +primalities +primality +primaries +primarily +primary +primas +primatal +primatals +primate +primates +primateship +primateships +primatial +primatological +primatologies +primatologist +primatologists +primatology +prime +primed +primely +primeness +primenesses +primer +primero +primeros +primers +primes +primeval +primevally +primi +primine +primines +priming +primings +primipara +primiparae +primiparas +primiparous +primitive +primitively +primitiveness +primitivenesses +primitives +primitivism +primitivisms +primitivist +primitivistic +primitivists +primitivities +primitivity +primly +primmed +primmer +primmest +primming +primness +primnesses +primo +primogenitor +primogenitors +primogeniture +primogenitures +primordia +primordial +primordially +primordium +primos +primp +primped +primping +primps +primrose +primroses +prims +primsie +primula +primulas +primus +primuses +prince +princedom +princedoms +princelet +princelets +princelier +princeliest +princeliness +princelinesses +princeling +princelings +princely +princes +princeship +princeships +princess +princesse +princesses +principal +principalities +principality +principally +principals +principalship +principalships +principe +principi +principia +principium +principle +principled +principles +princock +princocks +princox +princoxes +prink +prinked +prinker +prinkers +prinking +prinks +print +printabilities +printability +printable +printed +printer +printeries +printers +printery +printhead +printheads +printing +printings +printless +printmaker +printmakers +printmaking +printmakings +printout +printouts +prints +prion +prions +prior +priorate +priorates +prioress +prioresses +priories +priorities +prioritization +prioritizations +prioritize +prioritized +prioritizes +prioritizing +priority +priorly +priors +priorship +priorships +priory +prise +prised +prisere +priseres +prises +prising +prism +prismatic +prismatically +prismatoid +prismatoids +prismoid +prismoidal +prismoids +prisms +prison +prisoned +prisoner +prisoners +prisoning +prisons +priss +prissed +prisses +prissier +prissies +prissiest +prissily +prissiness +prissinesses +prissing +prissy +pristane +pristanes +pristine +pristinely +prithee +privacies +privacy +privatdocent +privatdocents +privatdozent +privatdozents +private +privateer +privateered +privateering +privateers +privately +privateness +privatenesses +privater +privates +privatest +privation +privations +privatise +privatised +privatises +privatising +privatism +privatisms +privative +privatively +privatives +privatization +privatizations +privatize +privatized +privatizes +privatizing +privet +privets +privier +privies +priviest +privilege +privileged +privileges +privileging +privily +privities +privity +privy +prize +prized +prizefight +prizefighter +prizefighters +prizefighting +prizefightings +prizefights +prizer +prizers +prizes +prizewinner +prizewinners +prizewinning +prizing +pro +proa +proabortion +proactive +proas +probabilism +probabilisms +probabilist +probabilistic +probabilistically +probabilists +probabilities +probability +probable +probables +probably +proband +probands +probang +probangs +probate +probated +probates +probating +probation +probational +probationally +probationary +probationer +probationers +probations +probative +probatory +probe +probed +probenecid +probenecids +prober +probers +probes +probing +probit +probities +probits +probity +problem +problematic +problematical +problematically +problematics +problems +proboscidean +proboscideans +proboscides +proboscidian +proboscidians +proboscis +proboscises +procaine +procaines +procambia +procambial +procambium +procambiums +procarbazine +procarbazines +procarp +procarps +procaryote +procaryotes +procathedral +procathedrals +procedural +procedurally +procedurals +procedure +procedures +proceed +proceeded +proceeding +proceedings +proceeds +procephalic +procercoid +procercoids +process +processabilities +processability +processable +processed +processes +processibilities +processibility +processible +processing +procession +processional +processionally +processionals +processioned +processioning +processions +processor +processors +prochain +prochein +proclaim +proclaimed +proclaimer +proclaimers +proclaiming +proclaims +proclamation +proclamations +proclitic +proclitics +proclivities +proclivity +proconsul +proconsular +proconsulate +proconsulates +proconsuls +proconsulship +proconsulships +procrastinate +procrastinated +procrastinates +procrastinating +procrastination +procrastinations +procrastinator +procrastinators +procreant +procreate +procreated +procreates +procreating +procreation +procreations +procreative +procreator +procreators +procrustean +procryptic +proctodaea +proctodaeum +proctodaeums +proctologic +proctological +proctologies +proctologist +proctologists +proctology +proctor +proctored +proctorial +proctoring +proctors +proctorship +proctorships +procumbent +procurable +procural +procurals +procuration +procurations +procurator +procuratorial +procurators +procure +procured +procurement +procurements +procurer +procurers +procures +procuring +prod +prodded +prodder +prodders +prodding +prodigal +prodigalities +prodigality +prodigally +prodigals +prodigies +prodigious +prodigiously +prodigiousness +prodigiousnesses +prodigy +prodromal +prodromata +prodrome +prodromes +prods +produce +produced +producer +producers +produces +producible +producing +product +production +productional +productions +productive +productively +productiveness +productivenesses +productivities +productivity +products +proem +proemial +proems +proenzyme +proenzymes +proestrus +proestruses +proette +proettes +prof +profanation +profanations +profanatory +profane +profaned +profanely +profaneness +profanenesses +profaner +profaners +profanes +profaning +profanities +profanity +profess +professed +professedly +professes +professing +profession +professional +professionalism +professionalisms +professionalization +professionalizations +professionalize +professionalized +professionalizes +professionalizing +professionally +professionals +professions +professor +professorate +professorates +professorial +professorially +professoriat +professoriate +professoriates +professoriats +professors +professorship +professorships +proffer +proffered +proffering +proffers +proficiencies +proficiency +proficient +proficiently +proficients +profile +profiled +profiler +profilers +profiles +profiling +profit +profitabilities +profitability +profitable +profitableness +profitablenesses +profitably +profited +profiteer +profiteered +profiteering +profiteers +profiter +profiterole +profiteroles +profiters +profiting +profitless +profits +profitwise +profligacies +profligacy +profligate +profligately +profligates +profluent +profound +profounder +profoundest +profoundly +profoundness +profoundnesses +profounds +profs +profundities +profundity +profuse +profusely +profuseness +profusenesses +profusion +profusions +prog +progenies +progenitor +progenitors +progeny +progeria +progerias +progestational +progesterone +progesterones +progestin +progestins +progestogen +progestogenic +progestogens +progged +progger +proggers +progging +proglottid +proglottides +proglottids +proglottis +prognathism +prognathisms +prognathous +prognose +prognosed +prognoses +prognosing +prognosis +prognostic +prognosticate +prognosticated +prognosticates +prognosticating +prognostication +prognostications +prognosticative +prognosticator +prognosticators +prognostics +prograde +program +programed +programer +programers +programing +programings +programmabilities +programmability +programmable +programmables +programmatic +programmatically +programme +programmed +programmer +programmers +programmes +programming +programmings +programs +progress +progressed +progresses +progressing +progression +progressional +progressions +progressive +progressively +progressiveness +progressivenesses +progressives +progressivism +progressivisms +progressivist +progressivistic +progressivists +progressivities +progressivity +progs +prohibit +prohibited +prohibiting +prohibition +prohibitionist +prohibitionists +prohibitions +prohibitive +prohibitively +prohibitiveness +prohibitivenesses +prohibitory +prohibits +proinsulin +proinsulins +project +projectable +projected +projectile +projectiles +projecting +projection +projectional +projectionist +projectionists +projections +projective +projectively +projector +projectors +projects +projet +projets +prokaryote +prokaryotes +prokaryotic +prolabor +prolactin +prolactins +prolamin +prolamine +prolamines +prolamins +prolan +prolans +prolapse +prolapsed +prolapses +prolapsing +prolate +prole +proleg +prolegomena +prolegomenon +prolegomenous +prolegs +prolepses +prolepsis +proleptic +proleptically +proles +proletarian +proletarianise +proletarianised +proletarianises +proletarianising +proletarianization +proletarianizations +proletarianize +proletarianized +proletarianizes +proletarianizing +proletarians +proletariat +proletariats +proliferate +proliferated +proliferates +proliferating +proliferation +proliferations +proliferative +prolific +prolificacies +prolificacy +prolifically +prolificities +prolificity +prolificness +prolificnesses +proline +prolines +prolix +prolixities +prolixity +prolixly +prolocutor +prolocutors +prolog +prologed +prologing +prologize +prologized +prologizes +prologizing +prologs +prologue +prologued +prologues +prologuing +prologuize +prologuized +prologuizes +prologuizing +prolong +prolongation +prolongations +prolonge +prolonged +prolonger +prolongers +prolonges +prolonging +prolongs +prolusion +prolusions +prolusory +prom +promenade +promenaded +promenader +promenaders +promenades +promenading +promethium +promethiums +promine +prominence +prominences +prominent +prominently +promines +promiscuities +promiscuity +promiscuous +promiscuously +promiscuousness +promiscuousnesses +promise +promised +promisee +promisees +promiser +promisers +promises +promising +promisingly +promisor +promisors +promissory +promo +promontories +promontory +promos +promotabilities +promotability +promotable +promote +promoted +promoter +promoters +promotes +promoting +promotion +promotional +promotions +promotive +promotiveness +promotivenesses +prompt +promptbook +promptbooks +prompted +prompter +prompters +promptest +prompting +promptitude +promptitudes +promptly +promptness +promptnesses +prompts +proms +promulgate +promulgated +promulgates +promulgating +promulgation +promulgations +promulgator +promulgators +promulge +promulged +promulges +promulging +pronate +pronated +pronates +pronating +pronation +pronations +pronator +pronatores +pronators +prone +pronely +proneness +pronenesses +pronephric +pronephros +pronephroses +prong +pronged +pronghorn +pronghorns +pronging +prongs +pronominal +pronominally +pronota +pronotum +pronoun +pronounce +pronounceabilities +pronounceability +pronounceable +pronounced +pronouncedly +pronouncement +pronouncements +pronouncer +pronouncers +pronounces +pronouncing +pronouns +pronto +pronuclear +pronuclei +pronucleus +pronucleuses +pronunciamento +pronunciamentoes +pronunciamentos +pronunciation +pronunciational +pronunciations +proof +proofed +proofer +proofers +proofing +proofread +proofreader +proofreaders +proofreading +proofreads +proofroom +proofrooms +proofs +prop +propaedeutic +propaedeutics +propagable +propaganda +propagandas +propagandist +propagandistic +propagandistically +propagandists +propagandize +propagandized +propagandizer +propagandizers +propagandizes +propagandizing +propagate +propagated +propagates +propagating +propagation +propagations +propagative +propagator +propagators +propagule +propagules +propane +propanes +propel +propellant +propellants +propelled +propellent +propellents +propeller +propellers +propelling +propellor +propellors +propels +propend +propended +propending +propends +propene +propenes +propenol +propenols +propense +propensities +propensity +propenyl +proper +properdin +properdins +properer +properest +properly +properness +propernesses +propers +propertied +properties +property +propertyless +propertylessness +propertylessnesses +prophage +prophages +prophase +prophases +prophasic +prophecies +prophecy +prophesied +prophesier +prophesiers +prophesies +prophesy +prophesying +prophet +prophetess +prophetesses +prophethood +prophethoods +prophetic +prophetical +prophetically +prophets +prophylactic +prophylactically +prophylactics +prophylaxes +prophylaxis +propine +propined +propines +propining +propinquities +propinquity +propionate +propionates +propitiate +propitiated +propitiates +propitiating +propitiation +propitiations +propitiator +propitiators +propitiatory +propitious +propitiously +propitiousness +propitiousnesses +propjet +propjets +proplastid +proplastids +propman +propmen +propolis +propolises +propone +proponed +proponent +proponents +propones +proponing +proportion +proportionable +proportionably +proportional +proportionalities +proportionality +proportionally +proportionals +proportionate +proportionated +proportionately +proportionates +proportionating +proportioned +proportioning +proportions +proposal +proposals +propose +proposed +proposer +proposers +proposes +proposing +propositi +proposition +propositional +propositioned +propositioning +propositions +propositus +propound +propounded +propounder +propounders +propounding +propounds +propoxyphene +propoxyphenes +propped +propping +propraetor +propraetors +propranolol +propranolols +propretor +propretors +proprietaries +proprietary +proprieties +proprietor +proprietorial +proprietors +proprietorship +proprietorships +proprietress +proprietresses +propriety +proprioception +proprioceptions +proprioceptive +proprioceptor +proprioceptors +props +proptoses +proptosis +propulsion +propulsions +propulsive +propyl +propyla +propylaea +propylaeum +propylene +propylenes +propylic +propylon +propyls +prorate +prorated +prorates +prorating +proration +prorations +prorogate +prorogated +prorogates +prorogating +prorogation +prorogations +prorogue +prorogued +prorogues +proroguing +pros +prosaic +prosaically +prosaism +prosaisms +prosaist +prosaists +prosateur +prosateurs +prosauropod +prosauropods +proscenium +prosceniums +prosciutti +prosciutto +prosciuttos +proscribe +proscribed +proscriber +proscribers +proscribes +proscribing +proscription +proscriptions +proscriptive +proscriptively +prose +prosect +prosected +prosecting +prosector +prosectors +prosects +prosecutable +prosecute +prosecuted +prosecutes +prosecuting +prosecution +prosecutions +prosecutor +prosecutorial +prosecutors +prosed +proselyte +proselyted +proselytes +proselyting +proselytise +proselytised +proselytises +proselytising +proselytism +proselytisms +proselytization +proselytizations +proselytize +proselytized +proselytizer +proselytizers +proselytizes +proselytizing +proseminar +proseminars +prosencephala +prosencephalic +prosencephalon +proser +prosers +proses +prosier +prosiest +prosily +prosimian +prosimians +prosiness +prosinesses +prosing +prosit +proso +prosobranch +prosobranchs +prosodic +prosodical +prosodically +prosodies +prosodist +prosodists +prosody +prosoma +prosomal +prosomas +prosopographical +prosopographies +prosopography +prosopopoeia +prosopopoeias +prosos +prospect +prospected +prospecting +prospective +prospectively +prospector +prospectors +prospects +prospectus +prospectuses +prosper +prospered +prospering +prosperities +prosperity +prosperous +prosperously +prosperousness +prosperousnesses +prospers +pross +prosses +prossie +prossies +prost +prostacyclin +prostacyclins +prostaglandin +prostaglandins +prostate +prostatectomies +prostatectomy +prostates +prostatic +prostatism +prostatisms +prostatites +prostatitides +prostatitis +prostatitises +prostheses +prosthesis +prosthetic +prosthetically +prosthetics +prosthetist +prosthetists +prosthodontics +prosthodontist +prosthodontists +prostie +prosties +prostitute +prostituted +prostitutes +prostituting +prostitution +prostitutions +prostitutor +prostitutors +prostomia +prostomial +prostomium +prostrate +prostrated +prostrates +prostrating +prostration +prostrations +prostyle +prostyles +prosy +protactinium +protactiniums +protagonist +protagonists +protamin +protamine +protamines +protamins +protases +protasis +protatic +protea +protean +proteans +proteas +protease +proteases +protect +protectant +protectants +protected +protecting +protection +protectionism +protectionisms +protectionist +protectionists +protections +protective +protectively +protectiveness +protectivenesses +protector +protectoral +protectorate +protectorates +protectories +protectors +protectorship +protectorships +protectory +protectress +protectresses +protects +protege +protegee +protegees +proteges +protei +proteid +proteide +proteides +proteids +protein +proteinaceous +proteinase +proteinases +proteins +proteinuria +proteinurias +protend +protended +protending +protends +protensive +protensively +proteoglycan +proteoglycans +proteolyses +proteolysis +proteolytic +proteolytically +proteose +proteoses +protest +protestant +protestants +protestation +protestations +protested +protester +protesters +protesting +protestor +protestors +protests +proteus +proteuses +prothalamia +prothalamion +prothalamium +prothalli +prothallia +prothallium +prothallus +prothalluses +protheses +prothesis +prothetic +prothonotarial +prothonotaries +prothonotary +prothoraces +prothoracic +prothorax +prothoraxes +prothrombin +prothrombins +protist +protistan +protistans +protists +protium +protiums +protocol +protocoled +protocoling +protocolled +protocolling +protocols +protoderm +protoderms +protogalaxies +protogalaxy +protohistorian +protohistorians +protohistoric +protohistories +protohistory +protohuman +protohumans +protolanguage +protolanguages +protomartyr +protomartyrs +proton +protonate +protonated +protonates +protonating +protonation +protonations +protonema +protonemal +protonemata +protonematal +protonic +protonotaries +protonotary +protons +protopathic +protophloem +protophloems +protoplanet +protoplanetary +protoplanets +protoplasm +protoplasmic +protoplasms +protoplast +protoplasts +protopod +protopods +protoporphyrin +protoporphyrins +protostar +protostars +protostele +protosteles +protostelic +protostome +protostomes +prototroph +prototrophic +prototrophies +prototrophs +prototrophy +prototypal +prototype +prototyped +prototypes +prototypic +prototypical +prototypically +prototyping +protoxid +protoxids +protoxylem +protoxylems +protozoa +protozoal +protozoan +protozoans +protozoologies +protozoologist +protozoologists +protozoology +protozoon +protract +protracted +protractile +protracting +protraction +protractions +protractive +protractor +protractors +protracts +protreptic +protreptics +protrude +protruded +protrudes +protruding +protrusible +protrusion +protrusions +protrusive +protrusively +protrusiveness +protrusivenesses +protuberance +protuberances +protuberant +protuberantly +protyl +protyle +protyles +protyls +proud +prouder +proudest +proudful +proudhearted +proudly +prounion +proustite +proustites +provable +provableness +provablenesses +provably +provascular +prove +proved +proven +provenance +provenances +provender +provenders +provenience +proveniences +provenly +proventriculi +proventriculus +prover +proverb +proverbed +proverbial +proverbially +proverbing +proverbs +provers +proves +provide +provided +providence +providences +provident +providential +providentially +providently +provider +providers +provides +providing +province +provinces +provincial +provincialism +provincialisms +provincialist +provincialists +provincialities +provinciality +provincialization +provincializations +provincialize +provincialized +provincializes +provincializing +provincially +provincials +proving +proviral +provirus +proviruses +provision +provisional +provisionally +provisionals +provisionary +provisioned +provisioner +provisioners +provisioning +provisions +proviso +provisoes +provisory +provisos +provitamin +provitamins +provocateur +provocateurs +provocation +provocations +provocative +provocatively +provocativeness +provocativenesses +provocatives +provoke +provoked +provoker +provokers +provokes +provoking +provokingly +provolone +provolones +provost +provosts +prow +prowar +prower +prowess +prowesses +prowest +prowl +prowled +prowler +prowlers +prowling +prowls +prows +proxemic +proxemics +proxies +proximal +proximally +proximate +proximately +proximateness +proximatenesses +proximities +proximity +proximo +proxy +prude +prudence +prudences +prudent +prudential +prudentially +prudently +pruderies +prudery +prudes +prudish +prudishly +prudishness +prudishnesses +pruinose +prunable +prune +pruned +prunella +prunellas +prunelle +prunelles +prunello +prunellos +pruner +pruners +prunes +pruning +prunus +prunuses +prurience +pruriences +pruriencies +pruriency +prurient +pruriently +prurigo +prurigos +pruritic +pruritus +prurituses +prussianise +prussianised +prussianises +prussianising +prussianization +prussianizations +prussianize +prussianized +prussianizes +prussianizing +prussic +pruta +prutah +prutot +prutoth +pry +pryer +pryers +prying +pryingly +prythee +psalm +psalmbook +psalmbooks +psalmed +psalmic +psalming +psalmist +psalmists +psalmodies +psalmody +psalms +psalter +psalteria +psalteries +psalterium +psalters +psaltery +psaltries +psaltry +psammite +psammites +psammon +psammons +pschent +pschents +psephite +psephites +psephological +psephologies +psephologist +psephologists +psephology +pseud +pseudepigraph +pseudepigrapha +pseudepigraphies +pseudepigraphon +pseudepigraphs +pseudepigraphy +pseudo +pseudoallele +pseudoalleles +pseudocholinesterase +pseudocholinesterases +pseudoclassic +pseudoclassicism +pseudoclassicisms +pseudoclassics +pseudocoel +pseudocoelomate +pseudocoelomates +pseudocoels +pseudocyeses +pseudocyesis +pseudomonad +pseudomonades +pseudomonads +pseudomonas +pseudomorph +pseudomorphic +pseudomorphism +pseudomorphisms +pseudomorphous +pseudomorphs +pseudonym +pseudonymities +pseudonymity +pseudonymous +pseudonymously +pseudonymousness +pseudonymousnesses +pseudonyms +pseudoparenchyma +pseudoparenchymas +pseudoparenchymata +pseudoparenchymatous +pseudopod +pseudopodal +pseudopodia +pseudopodial +pseudopodium +pseudopods +pseudopregnancies +pseudopregnancy +pseudopregnant +pseudorandom +pseudos +pseudoscience +pseudosciences +pseudoscientific +pseudoscientist +pseudoscientists +pseudoscorpion +pseudoscorpions +pseudosophisticated +pseudosophistication +pseudosophistications +pseudotuberculoses +pseudotuberculosis +pseuds +pshaw +pshawed +pshawing +pshaws +psi +psilocin +psilocins +psilocybin +psilocybins +psilophyte +psilophytes +psilophytic +psiloses +psilosis +psilotic +psis +psittacine +psittacines +psittacoses +psittacosis +psittacosises +psittacotic +psoae +psoai +psoas +psoatic +psocid +psocids +psoralea +psoraleas +psoralen +psoralens +psoriases +psoriasis +psoriatic +psoriatics +psst +psych +psychasthenia +psychasthenias +psychasthenic +psychasthenics +psyche +psyched +psychedelia +psychedelias +psychedelic +psychedelically +psychedelics +psyches +psychiatric +psychiatrically +psychiatries +psychiatrist +psychiatrists +psychiatry +psychic +psychical +psychically +psychics +psyching +psycho +psychoacoustic +psychoacoustics +psychoactive +psychoanalyses +psychoanalysis +psychoanalyst +psychoanalysts +psychoanalytic +psychoanalytical +psychoanalytically +psychoanalyze +psychoanalyzed +psychoanalyzes +psychoanalyzing +psychobabble +psychobabbler +psychobabblers +psychobabbles +psychobiographer +psychobiographers +psychobiographical +psychobiographies +psychobiography +psychobiologic +psychobiological +psychobiologies +psychobiologist +psychobiologists +psychobiology +psychochemical +psychochemicals +psychodrama +psychodramas +psychodramatic +psychodynamic +psychodynamically +psychodynamics +psychogeneses +psychogenesis +psychogenetic +psychogenic +psychogenically +psychograph +psychographs +psychohistorian +psychohistorians +psychohistorical +psychohistories +psychohistory +psychokineses +psychokinesis +psychokinetic +psycholinguist +psycholinguistic +psycholinguistics +psycholinguists +psychologic +psychological +psychologically +psychologies +psychologise +psychologised +psychologises +psychologising +psychologism +psychologisms +psychologist +psychologists +psychologize +psychologized +psychologizes +psychologizing +psychology +psychometric +psychometrically +psychometrician +psychometricians +psychometrics +psychometries +psychometry +psychomotor +psychoneuroses +psychoneurosis +psychoneurotic +psychoneurotics +psychopath +psychopathic +psychopathically +psychopathics +psychopathies +psychopathologic +psychopathological +psychopathologically +psychopathologies +psychopathologist +psychopathologists +psychopathology +psychopaths +psychopathy +psychopharmacologic +psychopharmacological +psychopharmacologies +psychopharmacologist +psychopharmacologists +psychopharmacology +psychophysical +psychophysically +psychophysicist +psychophysicists +psychophysics +psychophysiologic +psychophysiological +psychophysiologically +psychophysiologies +psychophysiologist +psychophysiologists +psychophysiology +psychos +psychoses +psychosexual +psychosexualities +psychosexuality +psychosexually +psychosis +psychosocial +psychosocially +psychosomatic +psychosomatically +psychosomatics +psychosurgeon +psychosurgeons +psychosurgeries +psychosurgery +psychosurgical +psychosyntheses +psychosynthesis +psychotherapeutic +psychotherapeutically +psychotherapies +psychotherapist +psychotherapists +psychotherapy +psychotic +psychotically +psychotics +psychotomimetic +psychotomimetically +psychotomimetics +psychotropic +psychotropics +psychrometer +psychrometers +psychrometric +psychrometries +psychrometry +psychrophilic +psychs +psylla +psyllas +psyllid +psyllids +psyllium +psylliums +psywar +psywars +ptarmigan +ptarmigans +pteranodon +pteranodons +pteridine +pteridines +pteridological +pteridologies +pteridologist +pteridologists +pteridology +pteridophyte +pteridophytes +pteridosperm +pteridosperms +pterin +pterins +pterodactyl +pterodactyls +pteropod +pteropods +pterosaur +pterosaurs +pterygia +pterygium +pterygiums +pterygoid +pterygoids +pteryla +pterylae +ptisan +ptisans +ptomain +ptomaine +ptomaines +ptomains +ptoses +ptosis +ptotic +ptyalin +ptyalins +ptyalism +ptyalisms +pub +puberal +pubertal +puberties +puberty +puberulent +pubes +pubescence +pubescences +pubescent +pubic +pubis +public +publically +publican +publicans +publication +publications +publicise +publicised +publicises +publicising +publicist +publicists +publicities +publicity +publicize +publicized +publicizes +publicizing +publicly +publicness +publicnesses +publics +publish +publishable +published +publisher +publishers +publishes +publishing +publishings +pubs +puccoon +puccoons +puce +puces +puck +pucka +pucker +puckered +puckerer +puckerers +puckerier +puckeriest +puckering +puckers +puckery +puckish +puckishly +puckishness +puckishnesses +pucks +pud +pudding +puddings +puddle +puddled +puddler +puddlers +puddles +puddlier +puddliest +puddling +puddlings +puddly +pudencies +pudency +pudenda +pudendal +pudendum +pudgier +pudgiest +pudgily +pudginess +pudginesses +pudgy +pudibund +pudic +puds +pueblo +pueblos +puerile +puerilely +puerilism +puerilisms +puerilities +puerility +puerperal +puerperia +puerperium +puff +puffball +puffballs +puffed +puffer +pufferies +puffers +puffery +puffier +puffiest +puffily +puffin +puffiness +puffinesses +puffing +puffins +puffs +puffy +pug +pugaree +pugarees +puggaree +puggarees +pugged +puggier +puggiest +pugging +puggish +puggree +puggrees +puggries +puggry +puggy +pugh +pugilism +pugilisms +pugilist +pugilistic +pugilists +pugmark +pugmarks +pugnacious +pugnaciously +pugnaciousness +pugnaciousnesses +pugnacities +pugnacity +pugree +pugrees +pugs +puisne +puisnes +puissance +puissances +puissant +puja +pujah +pujahs +pujas +puke +puked +pukes +puking +pukka +pul +pula +pulchritude +pulchritudes +pulchritudinous +pule +puled +puler +pulers +pules +puli +pulicene +pulicide +pulicides +pulik +puling +pulingly +pulings +pulis +pull +pullback +pullbacks +pulled +puller +pullers +pullet +pullets +pulley +pulleys +pulling +pullman +pullmans +pullout +pullouts +pullover +pullovers +pulls +pullulate +pullulated +pullulates +pullulating +pullulation +pullulations +pullup +pullups +pulmonary +pulmonate +pulmonates +pulmonic +pulmotor +pulmotors +pulp +pulpal +pulpally +pulped +pulper +pulpers +pulpier +pulpiest +pulpily +pulpiness +pulpinesses +pulping +pulpit +pulpital +pulpits +pulpless +pulpous +pulps +pulpwood +pulpwoods +pulpy +pulque +pulques +puls +pulsant +pulsar +pulsars +pulsate +pulsated +pulsates +pulsatile +pulsating +pulsation +pulsations +pulsator +pulsators +pulse +pulsed +pulsejet +pulsejets +pulser +pulsers +pulses +pulsing +pulsion +pulsions +pulsojet +pulsojets +pulverable +pulverise +pulverised +pulverises +pulverising +pulverizable +pulverization +pulverizations +pulverize +pulverized +pulverizer +pulverizers +pulverizes +pulverizing +pulverulent +pulvilli +pulvillus +pulvinar +pulvini +pulvinus +puma +pumas +pumelo +pumelos +pumice +pumiced +pumiceous +pumicer +pumicers +pumices +pumicing +pumicite +pumicites +pummel +pummeled +pummeling +pummelled +pummelling +pummelo +pummelos +pummels +pump +pumped +pumper +pumpernickel +pumpernickels +pumpers +pumping +pumpkin +pumpkins +pumpkinseed +pumpkinseeds +pumpless +pumplike +pumps +pun +puna +punas +punch +punchball +punchballs +punchboard +punchboards +punched +puncheon +puncheons +puncher +punchers +punches +punchier +punchiest +punchily +punchinello +punchinellos +punching +punchless +punchy +punctate +punctation +punctations +punctilio +punctilios +punctilious +punctiliously +punctiliousness +punctiliousnesses +punctual +punctualities +punctuality +punctually +punctuate +punctuated +punctuates +punctuating +punctuation +punctuations +punctuator +punctuators +puncture +punctured +punctures +puncturing +pundit +punditic +punditries +punditry +pundits +pung +pungencies +pungency +pungent +pungently +pungle +pungled +pungles +pungling +pungs +punier +puniest +punily +puniness +puninesses +punish +punishabilities +punishability +punishable +punished +punisher +punishers +punishes +punishing +punishment +punishments +punition +punitions +punitive +punitively +punitiveness +punitivenesses +punitory +punk +punka +punkah +punkahs +punkas +punker +punkers +punkest +punkey +punkeys +punkie +punkier +punkies +punkiest +punkin +punkiness +punkinesses +punkins +punkish +punks +punky +punned +punner +punners +punnet +punnets +punnier +punniest +punning +punny +puns +punster +punsters +punt +punted +punter +punters +punties +punting +punto +puntos +punts +punty +puny +pup +pupa +pupae +pupal +puparia +puparial +puparium +pupas +pupate +pupated +pupates +pupating +pupation +pupations +pupfish +pupfishes +pupil +pupilage +pupilages +pupilar +pupilary +pupillage +pupillages +pupillary +pupils +pupped +puppet +puppeteer +puppeteers +puppetlike +puppetries +puppetry +puppets +puppies +pupping +puppy +puppydom +puppydoms +puppyhood +puppyhoods +puppyish +puppylike +pups +pur +purana +puranas +puranic +purblind +purblindly +purblindness +purblindnesses +purchasable +purchase +purchased +purchaser +purchasers +purchases +purchasing +purda +purdah +purdahs +purdas +pure +pureblood +purebloods +purebred +purebreds +puree +pureed +pureeing +purees +purely +pureness +purenesses +purer +purest +purfle +purfled +purfles +purfling +purflings +purgation +purgations +purgative +purgatives +purgatorial +purgatories +purgatory +purge +purged +purger +purgers +purges +purging +purgings +puri +purification +purifications +purificator +purificators +purificatory +purified +purifier +purifiers +purifies +purify +purifying +purin +purine +purines +purins +puris +purism +purisms +purist +puristic +puristically +purists +puritan +puritanical +puritanically +puritanism +puritanisms +puritans +purities +purity +purl +purled +purlieu +purlieus +purlin +purline +purlines +purling +purlins +purloin +purloined +purloiner +purloiners +purloining +purloins +purls +puromycin +puromycins +purple +purpled +purpleheart +purplehearts +purpler +purples +purplest +purpling +purplish +purply +purport +purported +purportedly +purporting +purports +purpose +purposed +purposeful +purposefully +purposefulness +purposefulnesses +purposeless +purposelessly +purposelessness +purposelessnesses +purposely +purposes +purposing +purposive +purposively +purposiveness +purposivenesses +purpura +purpuras +purpure +purpures +purpuric +purpurin +purpurins +purr +purred +purring +purringly +purrs +purs +purse +pursed +purselike +purser +pursers +purses +pursier +pursiest +pursily +pursiness +pursinesses +pursing +purslane +purslanes +pursuance +pursuances +pursuant +pursue +pursued +pursuer +pursuers +pursues +pursuing +pursuit +pursuits +pursuivant +pursuivants +pursy +purtenance +purtenances +purulence +purulences +purulent +purvey +purveyance +purveyances +purveyed +purveying +purveyor +purveyors +purveys +purview +purviews +pus +puses +push +pushball +pushballs +pushcart +pushcarts +pushchair +pushchairs +pushdown +pushdowns +pushed +pusher +pushers +pushes +pushful +pushfulness +pushfulnesses +pushier +pushiest +pushily +pushiness +pushinesses +pushing +pushover +pushovers +pushpin +pushpins +pushrod +pushrods +pushup +pushups +pushy +pusillanimities +pusillanimity +pusillanimous +pusillanimously +pusley +pusleys +puslike +puss +pusses +pussier +pussies +pussiest +pussley +pussleys +pusslies +pusslike +pussly +pussy +pussycat +pussycats +pussyfoot +pussyfooted +pussyfooter +pussyfooters +pussyfooting +pussyfoots +pussytoes +pustulant +pustulants +pustular +pustulated +pustulation +pustulations +pustule +pustuled +pustules +put +putamen +putamina +putative +putatively +putlog +putlogs +putoff +putoffs +puton +putons +putout +putouts +putrefaction +putrefactions +putrefactive +putrefied +putrefies +putrefy +putrefying +putrescence +putrescences +putrescent +putrescible +putrescine +putrescines +putrid +putridities +putridity +putridly +puts +putsch +putsches +putschist +putschists +putt +putted +puttee +puttees +putter +puttered +putterer +putterers +puttering +putters +putti +puttied +puttier +puttiers +putties +putting +putto +putts +putty +puttying +puttyless +puttylike +puttyroot +puttyroots +putz +putzed +putzes +putzing +puzzle +puzzled +puzzleheaded +puzzleheadedness +puzzleheadednesses +puzzlement +puzzlements +puzzler +puzzlers +puzzles +puzzling +puzzlingly +pya +pyaemia +pyaemias +pyaemic +pyas +pycnidia +pycnidial +pycnidium +pycnogonid +pycnogonids +pycnometer +pycnometers +pycnoses +pycnosis +pycnotic +pye +pyelitic +pyelitis +pyelitises +pyelonephritic +pyelonephritides +pyelonephritis +pyemia +pyemias +pyemic +pyes +pygidia +pygidial +pygidium +pygmaean +pygmean +pygmies +pygmoid +pygmy +pygmyish +pygmyism +pygmyisms +pyic +pyin +pyins +pyjamas +pyknic +pyknics +pyknoses +pyknosis +pyknotic +pylon +pylons +pylori +pyloric +pylorus +pyloruses +pyoderma +pyodermas +pyogenic +pyoid +pyorrhea +pyorrheas +pyoses +pyosis +pyracantha +pyracanthas +pyralid +pyralids +pyramid +pyramidal +pyramidally +pyramided +pyramidical +pyramiding +pyramids +pyran +pyranoid +pyranose +pyranoses +pyranoside +pyranosides +pyrans +pyrargyrite +pyrargyrites +pyre +pyrene +pyrenes +pyrenoid +pyrenoids +pyres +pyrethrin +pyrethrins +pyrethroid +pyrethroids +pyrethrum +pyrethrums +pyretic +pyrexia +pyrexial +pyrexias +pyrexic +pyrheliometer +pyrheliometers +pyrheliometric +pyric +pyridic +pyridine +pyridines +pyridoxal +pyridoxals +pyridoxamine +pyridoxamines +pyridoxine +pyridoxines +pyriform +pyrimethamine +pyrimethamines +pyrimidine +pyrimidines +pyrite +pyrites +pyritic +pyritous +pyrocatechol +pyrocatechols +pyroclastic +pyroelectric +pyroelectricities +pyroelectricity +pyrogallol +pyrogallols +pyrogen +pyrogenic +pyrogenicities +pyrogenicity +pyrogens +pyrola +pyrolas +pyrolize +pyrolized +pyrolizes +pyrolizing +pyrologies +pyrology +pyrolusite +pyrolusites +pyrolysate +pyrolysates +pyrolyses +pyrolysis +pyrolytic +pyrolytically +pyrolyzable +pyrolyzate +pyrolyzates +pyrolyze +pyrolyzed +pyrolyzer +pyrolyzers +pyrolyzes +pyrolyzing +pyromancies +pyromancy +pyromania +pyromaniac +pyromaniacal +pyromaniacs +pyromanias +pyrometallurgical +pyrometallurgies +pyrometallurgy +pyrometer +pyrometers +pyrometric +pyrometrically +pyrometries +pyrometry +pyromorphite +pyromorphites +pyrone +pyrones +pyronine +pyronines +pyroninophilic +pyrope +pyropes +pyrophoric +pyrophosphate +pyrophosphates +pyrophyllite +pyrophyllites +pyrosis +pyrosises +pyrostat +pyrostats +pyrotechnic +pyrotechnical +pyrotechnically +pyrotechnics +pyrotechnist +pyrotechnists +pyroxene +pyroxenes +pyroxenic +pyroxenite +pyroxenites +pyroxenitic +pyroxenoid +pyroxenoids +pyroxylin +pyroxylins +pyrrhic +pyrrhics +pyrrhotite +pyrrhotites +pyrrol +pyrrole +pyrroles +pyrrolic +pyrrols +pyruvate +pyruvates +python +pythoness +pythonesses +pythonic +pythons +pyuria +pyurias +pyx +pyxes +pyxides +pyxidia +pyxidium +pyxie +pyxies +pyxis +qaid +qaids +qanat +qanats +qat +qats +qindar +qindarka +qindars +qintar +qintars +qiviut +qiviuts +qoph +qophs +qua +quaalude +quaaludes +quack +quacked +quackeries +quackery +quacking +quackish +quackism +quackisms +quacks +quacksalver +quacksalvers +quad +quadded +quadding +quadplex +quadplexes +quadrangle +quadrangles +quadrangular +quadrans +quadrant +quadrantal +quadrantes +quadrants +quadraphonic +quadraphonics +quadrat +quadrate +quadrated +quadrates +quadratic +quadratically +quadratics +quadrating +quadrats +quadrature +quadratures +quadrennia +quadrennial +quadrennially +quadrennials +quadrennium +quadrenniums +quadric +quadricentennial +quadricentennials +quadriceps +quadricepses +quadrics +quadriga +quadrigae +quadrilateral +quadrilaterals +quadrille +quadrilles +quadrillion +quadrillions +quadrillionth +quadrillionths +quadripartite +quadriphonic +quadriphonics +quadriplegia +quadriplegias +quadriplegic +quadriplegics +quadrivalent +quadrivalents +quadrivia +quadrivial +quadrivium +quadriviums +quadroon +quadroons +quadrumanous +quadrumvir +quadrumvirate +quadrumvirates +quadrumvirs +quadruped +quadrupedal +quadrupeds +quadruple +quadrupled +quadruples +quadruplet +quadruplets +quadruplicate +quadruplicated +quadruplicates +quadruplicating +quadruplication +quadruplications +quadruplicities +quadruplicity +quadrupling +quadruply +quadrupole +quadrupoles +quads +quaere +quaeres +quaestor +quaestors +quaff +quaffed +quaffer +quaffers +quaffing +quaffs +quag +quagga +quaggas +quaggier +quaggiest +quaggy +quagmire +quagmires +quagmirier +quagmiriest +quagmiry +quags +quahaug +quahaugs +quahog +quahogs +quai +quaich +quaiches +quaichs +quaigh +quaighs +quail +quailed +quailing +quails +quaint +quainter +quaintest +quaintly +quaintness +quaintnesses +quais +quake +quaked +quaker +quakers +quakes +quakier +quakiest +quakily +quaking +quaky +quale +qualia +qualifiable +qualification +qualifications +qualified +qualifiedly +qualifier +qualifiers +qualifies +qualify +qualifying +qualitative +qualitatively +qualities +quality +qualm +qualmier +qualmiest +qualmish +qualmishly +qualmishness +qualmishnesses +qualms +qualmy +quamash +quamashes +quandang +quandangs +quandaries +quandary +quandong +quandongs +quango +quangos +quant +quanta +quantal +quanted +quantic +quantics +quantifiable +quantification +quantificational +quantificationally +quantifications +quantified +quantifier +quantifiers +quantifies +quantify +quantifying +quantile +quantiles +quanting +quantitate +quantitated +quantitates +quantitating +quantitation +quantitations +quantitative +quantitatively +quantitativeness +quantitativenesses +quantities +quantity +quantization +quantizations +quantize +quantized +quantizer +quantizers +quantizes +quantizing +quantong +quantongs +quants +quantum +quarantine +quarantined +quarantines +quarantining +quare +quark +quarks +quarrel +quarreled +quarreler +quarrelers +quarreling +quarrelled +quarreller +quarrellers +quarrelling +quarrels +quarrelsome +quarrelsomely +quarrelsomeness +quarrelsomenesses +quarried +quarrier +quarriers +quarries +quarry +quarrying +quarryings +quarryman +quarrymen +quart +quartan +quartans +quarte +quarter +quarterage +quarterages +quarterback +quarterbacked +quarterbacking +quarterbacks +quarterdeck +quarterdecks +quartered +quarterfinal +quarterfinalist +quarterfinalists +quarterfinals +quartering +quarterings +quarterlies +quarterly +quartermaster +quartermasters +quartern +quarterns +quarters +quartersawed +quartersawn +quarterstaff +quarterstaves +quartes +quartet +quartets +quartette +quartettes +quartic +quartics +quartile +quartiles +quarto +quartos +quarts +quartz +quartzes +quartzite +quartzites +quartzitic +quartzose +quasar +quasars +quash +quashed +quasher +quashers +quashes +quashing +quasi +quasiparticle +quasiparticles +quasiperiodic +quasiperiodicities +quasiperiodicity +quass +quasses +quassia +quassias +quassin +quassins +quate +quatercentenaries +quatercentenary +quaternaries +quaternary +quaternion +quaternions +quaternities +quaternity +quatorze +quatorzes +quatrain +quatrains +quatre +quatrefoil +quatrefoils +quatres +quattrocento +quattrocentos +quattuordecillion +quattuordecillions +quaver +quavered +quaverer +quaverers +quavering +quaveringly +quavers +quavery +quay +quayage +quayages +quaylike +quays +quayside +quaysides +quean +queans +queasier +queasiest +queasily +queasiness +queasinesses +queasy +queazier +queaziest +queazy +quebracho +quebrachos +queen +queendom +queendoms +queened +queening +queenlier +queenliest +queenliness +queenlinesses +queenly +queens +queenship +queenships +queenside +queensides +queer +queered +queerer +queerest +queering +queerish +queerly +queerness +queernesses +queers +quell +quelled +queller +quellers +quelling +quells +quench +quenchable +quenched +quencher +quenchers +quenches +quenching +quenchless +quenelle +quenelles +quercetin +quercetins +quercine +quercitron +quercitrons +querida +queridas +queried +querier +queriers +queries +querist +querists +quern +querns +querulous +querulously +querulousness +querulousnesses +query +querying +quesadilla +quesadillas +quest +quested +quester +questers +questing +question +questionable +questionableness +questionablenesses +questionably +questionaries +questionary +questioned +questioner +questioners +questioning +questionless +questionnaire +questionnaires +questions +questor +questors +quests +quetzal +quetzales +quetzals +queue +queued +queueing +queuer +queuers +queues +queuing +quey +queys +quezal +quezales +quezals +quibble +quibbled +quibbler +quibblers +quibbles +quibbling +quiche +quiches +quick +quicken +quickened +quickener +quickeners +quickening +quickens +quicker +quickest +quickie +quickies +quicklime +quicklimes +quickly +quickness +quicknesses +quicks +quicksand +quicksands +quickset +quicksets +quicksilver +quicksilvers +quickstep +quicksteps +quid +quiddities +quiddity +quidnunc +quidnuncs +quids +quiescence +quiescences +quiescent +quiescently +quiet +quieted +quieten +quietened +quietening +quietens +quieter +quieters +quietest +quieting +quietism +quietisms +quietist +quietistic +quietists +quietly +quietness +quietnesses +quiets +quietude +quietudes +quietus +quietuses +quiff +quiffs +quill +quillai +quillaia +quillaias +quillais +quillaja +quillajas +quillback +quillbacks +quilled +quillet +quillets +quilling +quillings +quills +quillwork +quillworks +quilt +quilted +quilter +quilters +quilting +quiltings +quilts +quin +quinacrine +quinacrines +quinaries +quinary +quinate +quince +quincentenaries +quincentenary +quincentennial +quincentennials +quinces +quincuncial +quincunx +quincunxes +quincunxial +quindecillion +quindecillions +quinela +quinelas +quinella +quinellas +quinic +quinidine +quinidines +quiniela +quinielas +quinin +quinina +quininas +quinine +quinines +quinins +quinnat +quinnats +quinoa +quinoas +quinoid +quinoids +quinol +quinolin +quinoline +quinolines +quinolins +quinols +quinone +quinones +quinonoid +quinquennia +quinquennial +quinquennially +quinquennials +quinquennium +quinquenniums +quins +quinsies +quinsy +quint +quinta +quintain +quintains +quintal +quintals +quintan +quintans +quintar +quintars +quintas +quinte +quintes +quintessence +quintessences +quintessential +quintessentially +quintet +quintets +quintette +quintettes +quintic +quintics +quintile +quintiles +quintillion +quintillions +quintillionth +quintillionths +quintin +quintins +quints +quintuple +quintupled +quintuples +quintuplet +quintuplets +quintuplicate +quintuplicated +quintuplicates +quintuplicating +quintupling +quip +quipped +quipper +quippers +quipping +quippish +quippu +quippus +quips +quipster +quipsters +quipu +quipus +quire +quired +quires +quiring +quirk +quirked +quirkier +quirkiest +quirkily +quirkiness +quirkinesses +quirking +quirkish +quirks +quirky +quirt +quirted +quirting +quirts +quisling +quislingism +quislingisms +quislings +quit +quitch +quitches +quitclaim +quitclaimed +quitclaiming +quitclaims +quite +quitrent +quitrents +quits +quittance +quittances +quitted +quitter +quitters +quitting +quittor +quittors +quiver +quivered +quiverer +quiverers +quivering +quiveringly +quivers +quivery +quixote +quixotes +quixotic +quixotical +quixotically +quixotism +quixotisms +quixotries +quixotry +quiz +quizmaster +quizmasters +quizzed +quizzer +quizzers +quizzes +quizzical +quizzicalities +quizzicality +quizzically +quizzing +quod +quodlibet +quodlibets +quods +quohog +quohogs +quoin +quoined +quoining +quoins +quoit +quoited +quoiting +quoits +quokka +quokkas +quomodo +quomodos +quondam +quorum +quorums +quota +quotabilities +quotability +quotable +quotably +quotas +quotation +quotations +quote +quoted +quoter +quoters +quotes +quoth +quotha +quotidian +quotidians +quotient +quotients +quoting +qursh +qurshes +qurush +qurushes +qwerty +qwertys +rabat +rabato +rabatos +rabats +rabbet +rabbeted +rabbeting +rabbets +rabbi +rabbies +rabbin +rabbinate +rabbinates +rabbinic +rabbinical +rabbinically +rabbinism +rabbinisms +rabbins +rabbis +rabbit +rabbitbrush +rabbitbrushes +rabbited +rabbiter +rabbiters +rabbiting +rabbitries +rabbitry +rabbits +rabbity +rabble +rabbled +rabblement +rabblements +rabbler +rabblers +rabbles +rabbling +rabboni +rabbonis +rabic +rabid +rabidities +rabidity +rabidly +rabidness +rabidnesses +rabies +rabietic +raccoon +raccoons +race +racecourse +racecourses +raced +racehorse +racehorses +racemate +racemates +raceme +racemed +racemes +racemic +racemism +racemisms +racemization +racemizations +racemize +racemized +racemizes +racemizing +racemoid +racemose +racemous +racer +racers +races +racetrack +racetracker +racetrackers +racetracks +racewalker +racewalkers +racewalking +racewalkings +raceway +raceways +rachet +rachets +rachial +rachides +rachilla +rachillae +rachis +rachises +rachitic +rachitides +rachitis +racial +racialism +racialisms +racialist +racialistic +racialists +racially +racier +raciest +racily +raciness +racinesses +racing +racings +racism +racisms +racist +racists +rack +racked +racker +rackers +racket +racketed +racketeer +racketeered +racketeering +racketeers +racketier +racketiest +racketing +rackets +rackety +rackful +rackfuls +racking +rackingly +rackle +racks +rackwork +rackworks +raclette +raclettes +racon +racons +raconteur +raconteurs +racoon +racoons +racquet +racquetball +racquetballs +racquets +racy +rad +radar +radars +radarscope +radarscopes +radded +radding +raddle +raddled +raddles +raddling +radiable +radial +radiale +radialia +radially +radials +radian +radiance +radiances +radiancies +radiancy +radians +radiant +radiantly +radiants +radiate +radiated +radiately +radiates +radiating +radiation +radiational +radiationless +radiations +radiative +radiator +radiators +radical +radicalise +radicalised +radicalises +radicalising +radicalism +radicalisms +radicalization +radicalizations +radicalize +radicalized +radicalizes +radicalizing +radically +radicalness +radicalnesses +radicals +radicand +radicands +radicate +radicated +radicates +radicating +radicchio +radicchios +radicel +radicels +radices +radicle +radicles +radicular +radii +radio +radioactive +radioactively +radioactivities +radioactivity +radioallergosorbent +radioautograph +radioautographic +radioautographies +radioautographs +radioautography +radiobiologic +radiobiological +radiobiologically +radiobiologies +radiobiologist +radiobiologists +radiobiology +radiocarbon +radiocarbons +radiochemical +radiochemically +radiochemist +radiochemistries +radiochemistry +radiochemists +radiochromatogram +radiochromatograms +radioecologies +radioecology +radioed +radioelement +radioelements +radiogenic +radiogram +radiograms +radiograph +radiographed +radiographic +radiographically +radiographies +radiographing +radiographs +radiography +radioimmunoassay +radioimmunoassayable +radioimmunoassays +radioing +radioisotope +radioisotopes +radioisotopic +radioisotopically +radiolabel +radiolabeled +radiolabeling +radiolabelled +radiolabelling +radiolabels +radiolarian +radiolarians +radiologic +radiological +radiologically +radiologies +radiologist +radiologists +radiology +radiolucencies +radiolucency +radiolucent +radiolyses +radiolysis +radiolytic +radioman +radiomen +radiometer +radiometers +radiometric +radiometrically +radiometries +radiometry +radiomimetic +radionuclide +radionuclides +radiopaque +radiopharmaceutical +radiopharmaceuticals +radiophone +radiophones +radiophoto +radiophotos +radioprotection +radioprotections +radioprotective +radios +radiosensitive +radiosensitivities +radiosensitivity +radiosonde +radiosondes +radiostrontium +radiostrontiums +radiotelegraph +radiotelegraphies +radiotelegraphs +radiotelegraphy +radiotelemetric +radiotelemetries +radiotelemetry +radiotelephone +radiotelephones +radiotelephonies +radiotelephony +radiotherapies +radiotherapist +radiotherapists +radiotherapy +radiothorium +radiothoriums +radiotracer +radiotracers +radish +radishes +radium +radiums +radius +radiuses +radix +radixes +radome +radomes +radon +radons +rads +radula +radulae +radular +radulas +radwaste +radwastes +raff +raffia +raffias +raffinose +raffinoses +raffish +raffishly +raffishness +raffishnesses +raffle +raffled +raffler +rafflers +raffles +rafflesia +rafflesias +raffling +raffs +raft +rafted +rafter +raftered +rafters +rafting +rafts +raftsman +raftsmen +rag +raga +ragamuffin +ragamuffins +ragas +ragbag +ragbags +rage +raged +ragee +ragees +rages +ragged +raggeder +raggedest +raggedly +raggedness +raggednesses +raggedy +raggee +raggees +raggies +ragging +raggle +raggles +raggy +ragi +raging +ragingly +ragis +raglan +raglans +ragman +ragmen +ragout +ragouted +ragouting +ragouts +ragpicker +ragpickers +rags +ragtag +ragtags +ragtime +ragtimes +ragtop +ragtops +ragweed +ragweeds +ragwort +ragworts +rah +raia +raias +raid +raided +raider +raiders +raiding +raids +rail +railbird +railbirds +railbus +railbuses +railbusses +railcar +railcars +railed +railer +railers +railhead +railheads +railing +railings +railleries +raillery +railroad +railroaded +railroader +railroaders +railroading +railroadings +railroads +rails +railway +railways +raiment +raiments +rain +rainband +rainbands +rainbird +rainbirds +rainbow +rainbowlike +rainbows +raincoat +raincoats +raindrop +raindrops +rained +rainfall +rainfalls +rainier +rainiest +rainily +raining +rainless +rainmaker +rainmakers +rainmaking +rainmakings +rainout +rainouts +rainproof +rains +rainspout +rainspouts +rainsquall +rainsqualls +rainstorm +rainstorms +rainwash +rainwashed +rainwashes +rainwashing +rainwater +rainwaters +rainwear +rainy +raisable +raise +raised +raiser +raisers +raises +raisin +raising +raisings +raisins +raisiny +raisonne +raj +raja +rajah +rajahs +rajas +rajes +rake +raked +rakee +rakees +rakehell +rakehells +rakehelly +rakeoff +rakeoffs +raker +rakers +rakes +raki +raking +rakis +rakish +rakishly +rakishness +rakishnesses +rale +rales +rallentando +rallied +rallier +ralliers +rallies +ralline +rally +rallye +rallyes +rallying +rallyings +rallyist +rallyists +ralph +ralphed +ralphing +ralphs +ram +ramate +ramble +rambled +rambler +ramblers +rambles +rambling +ramblingly +rambouillet +rambouillets +rambunctious +rambunctiously +rambunctiousness +rambunctiousnesses +rambutan +rambutans +ramee +ramees +ramekin +ramekins +ramenta +ramentum +ramequin +ramequins +ramet +ramets +rami +ramie +ramies +ramification +ramifications +ramified +ramifies +ramiform +ramify +ramifying +ramilie +ramilies +ramillie +ramillies +ramjet +ramjets +rammed +rammer +rammers +rammier +rammiest +ramming +rammish +rammy +ramose +ramosely +ramosities +ramosity +ramous +ramp +rampage +rampaged +rampageous +rampageously +rampageousness +rampageousnesses +rampager +rampagers +rampages +rampaging +rampancies +rampancy +rampant +rampantly +rampart +ramparted +ramparting +ramparts +ramped +rampike +rampikes +ramping +rampion +rampions +rampole +rampoles +ramps +ramrod +ramrodded +ramrodding +ramrods +rams +ramshackle +ramshorn +ramshorns +ramson +ramsons +ramtil +ramtils +ramulose +ramulous +ramus +ran +rance +rances +ranch +ranched +rancher +ranchero +rancheros +ranchers +ranches +ranching +ranchman +ranchmen +rancho +ranchos +rancid +rancidities +rancidity +rancidly +rancidness +rancidnesses +rancor +rancored +rancorous +rancorously +rancors +rancour +rancours +rand +randan +randans +randier +randies +randiest +random +randomization +randomizations +randomize +randomized +randomizer +randomizers +randomizes +randomizing +randomly +randomness +randomnesses +randoms +rands +randy +ranee +ranees +rang +range +ranged +rangeland +rangelands +ranger +rangers +ranges +rangier +rangiest +ranginess +ranginesses +ranging +rangy +rani +ranid +ranids +ranis +rank +ranked +ranker +rankers +rankest +ranking +rankings +rankish +rankle +rankled +rankles +rankling +rankly +rankness +ranknesses +ranks +ranpike +ranpikes +ransack +ransacked +ransacker +ransackers +ransacking +ransacks +ransom +ransomed +ransomer +ransomers +ransoming +ransoms +rant +ranted +ranter +ranters +ranting +rantingly +rants +ranula +ranulas +ranunculi +ranunculus +ranunculuses +rap +rapacious +rapaciously +rapaciousness +rapaciousnesses +rapacities +rapacity +rape +raped +raper +rapers +rapes +rapeseed +rapeseeds +raphae +raphe +raphes +raphia +raphias +raphide +raphides +raphis +rapid +rapider +rapidest +rapidities +rapidity +rapidly +rapidness +rapidnesses +rapids +rapier +rapiered +rapiers +rapine +rapines +raping +rapini +rapist +rapists +rapparee +rapparees +rapped +rappee +rappees +rappel +rappeled +rappeling +rappelled +rappelling +rappels +rappen +rapper +rappers +rapping +rappini +rapport +rapporteur +rapporteurs +rapports +rapprochement +rapprochements +raps +rapscallion +rapscallions +rapt +raptly +raptness +raptnesses +raptor +raptorial +raptors +rapture +raptured +raptures +rapturing +rapturous +rapturously +rapturousness +rapturousnesses +rare +rarebit +rarebits +rared +rarefaction +rarefactional +rarefactions +rarefied +rarefier +rarefiers +rarefies +rarefy +rarefying +rarely +rareness +rarenesses +rarer +rareripe +rareripes +rares +rarest +rarified +rarifies +rarify +rarifying +raring +rarities +rarity +ras +rasbora +rasboras +rascal +rascalities +rascality +rascally +rascals +rase +rased +raser +rasers +rases +rash +rasher +rashers +rashes +rashest +rashlike +rashly +rashness +rashnesses +rasing +rasorial +rasp +raspberries +raspberry +rasped +rasper +raspers +raspier +raspiest +rasping +raspingly +raspish +rasps +raspy +rassle +rassled +rassles +rassling +raster +rasters +rasure +rasures +rat +ratable +ratably +ratafee +ratafees +ratafia +ratafias +ratal +ratals +ratan +ratanies +ratans +ratany +rataplan +rataplanned +rataplanning +rataplans +ratatat +ratatats +ratatouille +ratatouilles +ratbag +ratbags +ratch +ratches +ratchet +ratcheted +ratcheting +ratchets +rate +rateable +rateably +rated +ratel +ratels +ratemeter +ratemeters +ratepayer +ratepayers +rater +raters +rates +ratfink +ratfinks +ratfish +ratfishes +rath +rathe +rather +rathole +ratholes +rathskeller +rathskellers +raticide +raticides +ratification +ratifications +ratified +ratifier +ratifiers +ratifies +ratify +ratifying +ratine +ratines +rating +ratings +ratio +ratiocinate +ratiocinated +ratiocinates +ratiocinating +ratiocination +ratiocinations +ratiocinative +ratiocinator +ratiocinators +ration +rational +rationale +rationales +rationalise +rationalised +rationalises +rationalising +rationalism +rationalisms +rationalist +rationalistic +rationalistically +rationalists +rationalities +rationality +rationalizable +rationalization +rationalizations +rationalize +rationalized +rationalizer +rationalizers +rationalizes +rationalizing +rationally +rationalness +rationalnesses +rationals +rationed +rationing +rations +ratios +ratite +ratites +ratlike +ratlin +ratline +ratlines +ratlins +rato +ratoon +ratooned +ratooner +ratooners +ratooning +ratoons +ratos +rats +ratsbane +ratsbanes +rattail +rattails +rattan +rattans +ratted +ratteen +ratteens +ratten +rattened +rattener +ratteners +rattening +rattens +ratter +ratters +rattier +rattiest +ratting +rattish +rattle +rattlebrain +rattlebrained +rattlebrains +rattled +rattler +rattlers +rattles +rattlesnake +rattlesnakes +rattletrap +rattletraps +rattling +rattlingly +rattlings +rattly +ratton +rattons +rattoon +rattooned +rattooning +rattoons +rattrap +rattraps +ratty +raucities +raucity +raucous +raucously +raucousness +raucousnesses +raunch +raunches +raunchier +raunchiest +raunchily +raunchiness +raunchinesses +raunchy +rauwolfia +rauwolfias +ravage +ravaged +ravagement +ravagements +ravager +ravagers +ravages +ravaging +rave +raved +ravel +raveled +raveler +ravelers +ravelin +raveling +ravelings +ravelins +ravelled +raveller +ravellers +ravelling +ravellings +ravelly +ravelment +ravelments +ravels +raven +ravened +ravener +raveners +ravening +ravenings +ravenous +ravenously +ravenousness +ravenousnesses +ravens +raver +ravers +raves +ravigote +ravigotes +ravin +ravine +ravined +ravines +raving +ravingly +ravings +ravining +ravins +ravioli +raviolis +ravish +ravished +ravisher +ravishers +ravishes +ravishing +ravishingly +ravishment +ravishments +raw +rawboned +rawer +rawest +rawhide +rawhided +rawhides +rawhiding +rawin +rawins +rawinsonde +rawinsondes +rawish +rawly +rawness +rawnesses +raws +rax +raxed +raxes +raxing +ray +raya +rayah +rayahs +rayas +rayed +raygrass +raygrasses +raying +rayless +raylessness +raylessnesses +raylike +rayon +rayons +rays +raze +razed +razee +razeed +razeeing +razees +razer +razers +razes +razing +razor +razorback +razorbacks +razorbill +razorbills +razored +razoring +razors +razz +razzamatazz +razzamatazzes +razzed +razzes +razzing +re +reabsorb +reabsorbed +reabsorbing +reabsorbs +reaccede +reacceded +reaccedes +reacceding +reaccelerate +reaccelerated +reaccelerates +reaccelerating +reaccent +reaccented +reaccenting +reaccents +reaccept +reaccepted +reaccepting +reaccepts +reaccession +reaccessions +reacclimatize +reacclimatized +reacclimatizes +reacclimatizing +reaccredit +reaccreditation +reaccreditations +reaccredited +reaccrediting +reaccredits +reaccuse +reaccused +reaccuses +reaccusing +reach +reachable +reached +reacher +reachers +reaches +reaching +reacquaint +reacquainted +reacquainting +reacquaints +reacquire +reacquired +reacquires +reacquiring +reacquisition +reacquisitions +react +reactance +reactances +reactant +reactants +reacted +reacting +reaction +reactionaries +reactionary +reactionaryism +reactionaryisms +reactions +reactivate +reactivated +reactivates +reactivating +reactivation +reactivations +reactive +reactively +reactiveness +reactivenesses +reactivities +reactivity +reactor +reactors +reacts +read +readabilities +readability +readable +readableness +readablenesses +readably +readapt +readapted +readapting +readapts +readd +readded +readdict +readdicted +readdicting +readdicts +readding +readdress +readdressed +readdresses +readdressing +readds +reader +readerly +readers +readership +readerships +readied +readier +readies +readiest +readily +readiness +readinesses +reading +readings +readjust +readjustable +readjusted +readjusting +readjustment +readjustments +readjusts +readmission +readmissions +readmit +readmits +readmitted +readmitting +readopt +readopted +readopting +readopts +readorn +readorned +readorning +readorns +readout +readouts +reads +ready +readying +readymade +readymades +reaffirm +reaffirmation +reaffirmations +reaffirmed +reaffirming +reaffirms +reaffix +reaffixed +reaffixes +reaffixing +reafforest +reafforestation +reafforestations +reafforested +reafforesting +reafforests +reagent +reagents +reaggregate +reaggregated +reaggregates +reaggregating +reaggregation +reaggregations +reagin +reaginic +reagins +real +realer +reales +realest +realgar +realgars +realia +realign +realigned +realigning +realignment +realignments +realigns +realise +realised +realiser +realisers +realises +realising +realism +realisms +realist +realistic +realistically +realists +realities +reality +realizable +realization +realizations +realize +realized +realizer +realizers +realizes +realizing +reallocate +reallocated +reallocates +reallocating +reallocation +reallocations +reallot +reallots +reallotted +reallotting +really +realm +realms +realness +realnesses +realpolitik +realpolitiks +reals +realter +realtered +realtering +realters +realties +realty +ream +reamed +reamer +reamers +reaming +reams +reanalyses +reanalysis +reanalyze +reanalyzed +reanalyzes +reanalyzing +reanimate +reanimated +reanimates +reanimating +reanimation +reanimations +reannex +reannexation +reannexations +reannexed +reannexes +reannexing +reanoint +reanointed +reanointing +reanoints +reap +reapable +reaped +reaper +reapers +reaphook +reaphooks +reaping +reappear +reappearance +reappearances +reappeared +reappearing +reappears +reapplication +reapplications +reapplied +reapplies +reapply +reapplying +reappoint +reappointed +reappointing +reappointment +reappointments +reappoints +reapportion +reapportioned +reapportioning +reapportionment +reapportionments +reapportions +reappraisal +reappraisals +reappraise +reappraised +reappraises +reappraising +reappropriate +reappropriated +reappropriates +reappropriating +reapprove +reapproved +reapproves +reapproving +reaps +rear +reared +rearer +rearers +rearguard +reargue +reargued +reargues +rearguing +reargument +rearguments +rearing +rearm +rearmament +rearmaments +rearmed +rearmice +rearming +rearmost +rearmouse +rearms +rearousal +rearousals +rearouse +rearoused +rearouses +rearousing +rearrange +rearranged +rearrangement +rearrangements +rearranges +rearranging +rearrest +rearrested +rearresting +rearrests +rears +rearticulate +rearticulated +rearticulates +rearticulating +rearward +rearwards +reascend +reascended +reascending +reascends +reascent +reascents +reason +reasonabilities +reasonability +reasonable +reasonableness +reasonablenesses +reasonably +reasoned +reasoner +reasoners +reasoning +reasonings +reasonless +reasonlessly +reasons +reassail +reassailed +reassailing +reassails +reassemblage +reassemblages +reassemble +reassembled +reassembles +reassemblies +reassembling +reassembly +reassert +reasserted +reasserting +reassertion +reassertions +reasserts +reassess +reassessed +reassesses +reassessing +reassessment +reassessments +reassign +reassigned +reassigning +reassignment +reassignments +reassigns +reassort +reassorted +reassorting +reassorts +reassume +reassumed +reassumes +reassuming +reassumption +reassumptions +reassurance +reassurances +reassure +reassured +reassures +reassuring +reassuringly +reata +reatas +reattach +reattached +reattaches +reattaching +reattachment +reattachments +reattack +reattacked +reattacking +reattacks +reattain +reattained +reattaining +reattains +reattempt +reattempted +reattempting +reattempts +reattribute +reattributed +reattributes +reattributing +reattribution +reattributions +reauthorization +reauthorizations +reauthorize +reauthorized +reauthorizes +reauthorizing +reavail +reavailed +reavailing +reavails +reave +reaved +reaver +reavers +reaves +reaving +reavow +reavowed +reavowing +reavows +reawake +reawaked +reawaken +reawakened +reawakening +reawakens +reawakes +reawaking +reawoke +reawoken +reb +rebait +rebaited +rebaiting +rebaits +rebalance +rebalanced +rebalances +rebalancing +rebaptism +rebaptisms +rebaptize +rebaptized +rebaptizes +rebaptizing +rebar +rebarbative +rebarbatively +rebars +rebate +rebated +rebater +rebaters +rebates +rebating +rebato +rebatos +rebbe +rebbes +rebec +rebeck +rebecks +rebecs +rebegan +rebegin +rebeginning +rebegins +rebegun +rebel +rebeldom +rebeldoms +rebelled +rebelling +rebellion +rebellions +rebellious +rebelliously +rebelliousness +rebelliousnesses +rebels +rebid +rebidden +rebidding +rebids +rebill +rebilled +rebilling +rebills +rebind +rebinding +rebinds +rebirth +rebirths +reblend +reblended +reblending +reblends +rebloom +rebloomed +reblooming +reblooms +reboant +reboard +reboarded +reboarding +reboards +rebodied +rebodies +rebody +rebodying +reboil +reboiled +reboiling +reboils +rebook +rebooked +rebooking +rebooks +reboot +rebooted +rebooting +reboots +rebop +rebops +rebore +rebored +rebores +reboring +reborn +rebottle +rebottled +rebottles +rebottling +rebought +rebound +rebounded +rebounder +rebounders +rebounding +rebounds +rebozo +rebozos +rebranch +rebranched +rebranches +rebranching +rebred +rebreed +rebreeding +rebreeds +rebroadcast +rebroadcasting +rebroadcasts +rebs +rebuff +rebuffed +rebuffing +rebuffs +rebuild +rebuilded +rebuilding +rebuilds +rebuilt +rebuke +rebuked +rebuker +rebukers +rebukes +rebuking +reburial +reburials +reburied +reburies +rebury +reburying +rebus +rebuses +rebut +rebuts +rebuttable +rebuttal +rebuttals +rebutted +rebutter +rebutters +rebutting +rebutton +rebuttoned +rebuttoning +rebuttons +rebuy +rebuying +rebuys +rec +recalcitrance +recalcitrances +recalcitrancies +recalcitrancy +recalcitrant +recalcitrants +recalculate +recalculated +recalculates +recalculating +recalculation +recalculations +recalibrate +recalibrated +recalibrates +recalibrating +recalibration +recalibrations +recall +recallabilities +recallability +recallable +recalled +recaller +recallers +recalling +recalls +recamier +recamiers +recanalization +recanalizations +recanalize +recanalized +recanalizes +recanalizing +recane +recaned +recanes +recaning +recant +recantation +recantations +recanted +recanter +recanters +recanting +recants +recap +recapitalization +recapitalizations +recapitalize +recapitalized +recapitalizes +recapitalizing +recapitulate +recapitulated +recapitulates +recapitulating +recapitulation +recapitulations +recappable +recapped +recapping +recaps +recapture +recaptured +recaptures +recapturing +recarried +recarries +recarry +recarrying +recast +recasting +recasts +recce +recces +recede +receded +recedes +receding +receipt +receipted +receipting +receipts +receivable +receivables +receive +received +receiver +receivers +receivership +receiverships +receives +receiving +recencies +recency +recension +recensions +recent +recenter +recentest +recently +recentness +recentnesses +recentralization +recentralizations +recentrifuge +recentrifuged +recentrifuges +recentrifuging +recept +receptacle +receptacles +reception +receptionist +receptionists +receptions +receptive +receptively +receptiveness +receptivenesses +receptivities +receptivity +receptor +receptors +recepts +recertification +recertifications +recertified +recertifies +recertify +recertifying +recess +recessed +recesses +recessing +recession +recessional +recessionals +recessionary +recessions +recessive +recessively +recessiveness +recessivenesses +recessives +rechallenge +rechallenged +rechallenges +rechallenging +rechange +rechanged +rechanges +rechanging +rechannel +rechanneled +rechanneling +rechannelled +rechannelling +rechannels +recharge +rechargeable +recharged +recharger +rechargers +recharges +recharging +rechart +recharted +recharter +rechartered +rechartering +recharters +recharting +recharts +rechauffe +rechauffes +recheat +recheats +recheck +rechecked +rechecking +rechecks +recherche +rechew +rechewed +rechewing +rechews +rechoose +rechooses +rechoosing +rechoreograph +rechoreographed +rechoreographing +rechoreographs +rechose +rechosen +rechristen +rechristened +rechristening +rechristens +rechromatograph +rechromatographed +rechromatographies +rechromatographing +rechromatographs +rechromatography +recidivism +recidivisms +recidivist +recidivistic +recidivists +recipe +recipes +recipient +recipients +reciprocal +reciprocally +reciprocals +reciprocate +reciprocated +reciprocates +reciprocating +reciprocation +reciprocations +reciprocative +reciprocator +reciprocators +reciprocities +reciprocity +recircle +recircled +recircles +recircling +recirculate +recirculated +recirculates +recirculating +recirculation +recirculations +recision +recisions +recital +recitalist +recitalists +recitals +recitation +recitations +recitative +recitatives +recitativi +recitativo +recitativos +recite +recited +reciter +reciters +recites +reciting +reck +recked +recking +reckless +recklessly +recklessness +recklessnesses +reckon +reckoned +reckoner +reckoners +reckoning +reckonings +reckons +recks +reclad +reclaim +reclaimable +reclaimed +reclaiming +reclaims +reclamation +reclamations +reclame +reclames +reclasp +reclasped +reclasping +reclasps +reclassification +reclassifications +reclassified +reclassifies +reclassify +reclassifying +reclean +recleaned +recleaning +recleans +recline +reclined +recliner +recliners +reclines +reclining +reclosable +reclothe +reclothed +reclothes +reclothing +recluse +recluses +reclusion +reclusions +reclusive +reclusively +reclusiveness +reclusivenesses +recoal +recoaled +recoaling +recoals +recock +recocked +recocking +recocks +recode +recoded +recodes +recodification +recodifications +recodified +recodifies +recodify +recodifying +recoding +recognise +recognised +recognises +recognising +recognition +recognitions +recognizabilities +recognizability +recognizable +recognizably +recognizance +recognizances +recognize +recognized +recognizer +recognizers +recognizes +recognizing +recoil +recoiled +recoiler +recoilers +recoiling +recoilless +recoils +recoin +recoinage +recoinages +recoined +recoining +recoins +recollect +recollected +recollecting +recollection +recollections +recollects +recolonization +recolonizations +recolonize +recolonized +recolonizes +recolonizing +recolor +recolored +recoloring +recolors +recomb +recombed +recombinant +recombinants +recombination +recombinational +recombinations +recombine +recombined +recombines +recombing +recombining +recombs +recommence +recommenced +recommencement +recommencements +recommences +recommencing +recommend +recommendable +recommendation +recommendations +recommendatory +recommended +recommending +recommends +recommission +recommissioned +recommissioning +recommissions +recommit +recommitment +recommitments +recommits +recommittal +recommittals +recommitted +recommitting +recompense +recompensed +recompenses +recompensing +recompilation +recompilations +recompile +recompiled +recompiles +recompiling +recompose +recomposed +recomposes +recomposing +recomposition +recompositions +recomputation +recomputations +recompute +recomputed +recomputes +recomputing +recon +reconceive +reconceived +reconceives +reconceiving +reconcentrate +reconcentrated +reconcentrates +reconcentrating +reconcentration +reconcentrations +reconception +reconceptions +reconceptualization +reconceptualizations +reconceptualize +reconceptualized +reconceptualizes +reconceptualizing +reconcilabilities +reconcilability +reconcilable +reconcile +reconciled +reconcilement +reconcilements +reconciler +reconcilers +reconciles +reconciliation +reconciliations +reconciliatory +reconciling +recondense +recondensed +recondenses +recondensing +recondite +reconditely +reconditeness +reconditenesses +recondition +reconditioned +reconditioning +reconditions +reconfigurable +reconfiguration +reconfigurations +reconfigure +reconfigured +reconfigures +reconfiguring +reconfirm +reconfirmation +reconfirmations +reconfirmed +reconfirming +reconfirms +reconnaissance +reconnaissances +reconnect +reconnected +reconnecting +reconnection +reconnections +reconnects +reconnoiter +reconnoitered +reconnoitering +reconnoiters +reconnoitre +reconnoitred +reconnoitres +reconnoitring +reconquer +reconquered +reconquering +reconquers +reconquest +reconquests +recons +reconsecrate +reconsecrated +reconsecrates +reconsecrating +reconsecration +reconsecrations +reconsider +reconsideration +reconsiderations +reconsidered +reconsidering +reconsiders +reconsolidate +reconsolidated +reconsolidates +reconsolidating +reconstitute +reconstituted +reconstitutes +reconstituting +reconstitution +reconstitutions +reconstruct +reconstructed +reconstructible +reconstructing +reconstruction +reconstructionism +reconstructionisms +reconstructionist +reconstructionists +reconstructions +reconstructive +reconstructor +reconstructors +reconstructs +recontact +recontacted +recontacting +recontacts +recontaminate +recontaminated +recontaminates +recontaminating +recontamination +recontaminations +recontextualize +recontextualized +recontextualizes +recontextualizing +recontour +recontoured +recontouring +recontours +reconvene +reconvened +reconvenes +reconvening +reconversion +reconversions +reconvert +reconverted +reconverting +reconverts +reconvey +reconveyance +reconveyances +reconveyed +reconveying +reconveys +reconvict +reconvicted +reconvicting +reconviction +reconvictions +reconvicts +reconvince +reconvinced +reconvinces +reconvincing +recook +recooked +recooking +recooks +recopied +recopies +recopy +recopying +record +recordable +recordation +recordations +recorded +recorder +recorders +recording +recordings +recordist +recordists +records +recork +recorked +recorking +recorks +recount +recounted +recounter +recounters +recounting +recounts +recoup +recoupable +recoupe +recouped +recouping +recouple +recoupled +recouples +recoupling +recoupment +recoupments +recoups +recourse +recourses +recover +recoverabilities +recoverability +recoverable +recovered +recoverer +recoverers +recoveries +recovering +recovers +recovery +recrate +recrated +recrates +recrating +recreant +recreants +recreate +recreated +recreates +recreating +recreation +recreational +recreationist +recreationists +recreations +recreative +recriminate +recriminated +recriminates +recriminating +recrimination +recriminations +recriminative +recriminatory +recross +recrossed +recrosses +recrossing +recrown +recrowned +recrowning +recrowns +recrudesce +recrudesced +recrudescence +recrudescences +recrudescent +recrudesces +recrudescing +recruit +recruited +recruiter +recruiters +recruiting +recruitment +recruitments +recruits +recrystallization +recrystallizations +recrystallize +recrystallized +recrystallizes +recrystallizing +recs +recta +rectal +rectally +rectangle +rectangles +rectangular +rectangularities +rectangularity +rectangularly +recti +rectifiabilities +rectifiability +rectifiable +rectification +rectifications +rectified +rectifier +rectifiers +rectifies +rectify +rectifying +rectilinear +rectilinearly +rectitude +rectitudes +rectitudinous +recto +rector +rectorate +rectorates +rectorial +rectories +rectors +rectorship +rectorships +rectory +rectos +rectrices +rectrix +rectum +rectums +rectus +recultivate +recultivated +recultivates +recultivating +recumbencies +recumbency +recumbent +recuperate +recuperated +recuperates +recuperating +recuperation +recuperations +recuperative +recur +recurred +recurrence +recurrences +recurrent +recurrently +recurring +recurs +recursion +recursions +recursive +recursively +recursiveness +recursivenesses +recurve +recurved +recurves +recurving +recusal +recusals +recusancies +recusancy +recusant +recusants +recuse +recused +recuses +recusing +recut +recuts +recutting +recyclable +recyclables +recycle +recycled +recycler +recyclers +recycles +recycling +red +redact +redacted +redacting +redaction +redactional +redactions +redactor +redactors +redacts +redamage +redamaged +redamages +redamaging +redan +redans +redargue +redargued +redargues +redarguing +redate +redated +redates +redating +redbait +redbaited +redbaiting +redbaits +redbay +redbays +redbird +redbirds +redbone +redbones +redbreast +redbreasts +redbrick +redbricks +redbud +redbuds +redbug +redbugs +redcap +redcaps +redcoat +redcoats +redd +redded +redden +reddened +reddening +reddens +redder +redders +reddest +redding +reddish +reddishness +reddishnesses +reddle +reddled +reddles +reddling +redds +rede +redear +redears +redecide +redecided +redecides +redeciding +redecorate +redecorated +redecorates +redecorating +redecoration +redecorations +redecorator +redecorators +reded +rededicate +rededicated +rededicates +rededicating +rededication +rededications +redeem +redeemable +redeemed +redeemer +redeemers +redeeming +redeems +redefeat +redefeated +redefeating +redefeats +redefect +redefected +redefecting +redefects +redefied +redefies +redefine +redefined +redefines +redefining +redefinition +redefinitions +redefy +redefying +redeliver +redelivered +redeliveries +redelivering +redelivers +redelivery +redemand +redemanded +redemanding +redemands +redemption +redemptioner +redemptioners +redemptions +redemptive +redemptory +redenied +redenies +redeny +redenying +redeploy +redeployed +redeploying +redeployment +redeployments +redeploys +redeposit +redeposited +redepositing +redeposits +redes +redescribe +redescribed +redescribes +redescribing +redescription +redescriptions +redesign +redesigned +redesigning +redesigns +redetermination +redeterminations +redetermine +redetermined +redetermines +redetermining +redevelop +redeveloped +redeveloper +redevelopers +redeveloping +redevelopment +redevelopments +redevelops +redeye +redeyes +redfin +redfins +redfish +redfishes +redhead +redheaded +redheads +redhorse +redhorses +redia +rediae +redial +redialed +redialing +redialled +redialling +redials +redias +redid +redigest +redigested +redigesting +redigestion +redigestions +redigests +reding +redingote +redingotes +redintegrate +redintegrated +redintegrates +redintegrating +redintegration +redintegrations +redintegrative +redip +redipped +redipping +redips +redipt +redirect +redirected +redirecting +redirection +redirections +redirects +rediscount +rediscountable +rediscounted +rediscounting +rediscounts +rediscover +rediscovered +rediscoveries +rediscovering +rediscovers +rediscovery +rediscuss +rediscussed +rediscusses +rediscussing +redisplay +redisplayed +redisplaying +redisplays +redispose +redisposed +redisposes +redisposing +redisposition +redispositions +redissolve +redissolved +redissolves +redissolving +redistill +redistillation +redistillations +redistilled +redistilling +redistills +redistribute +redistributed +redistributes +redistributing +redistribution +redistributional +redistributionist +redistributionists +redistributions +redistributive +redistrict +redistricted +redistricting +redistricts +redivide +redivided +redivides +redividing +redivision +redivisions +redivivus +redleg +redlegs +redline +redlined +redlines +redlining +redly +redneck +rednecked +rednecks +redness +rednesses +redo +redock +redocked +redocking +redocks +redoes +redoing +redolence +redolences +redolent +redolently +redon +redone +redonned +redonning +redons +redos +redouble +redoubled +redoubles +redoubling +redoubt +redoubtable +redoubtably +redoubts +redound +redounded +redounding +redounds +redout +redouts +redowa +redowas +redox +redoxes +redpoll +redpolls +redraft +redrafted +redrafting +redrafts +redraw +redrawer +redrawers +redrawing +redrawn +redraws +redream +redreamed +redreaming +redreams +redreamt +redress +redressed +redresser +redressers +redresses +redressing +redrew +redried +redries +redrill +redrilled +redrilling +redrills +redrive +redriven +redrives +redriving +redroot +redroots +redrove +redry +redrying +reds +redshank +redshanks +redshift +redshifted +redshifts +redshirt +redshirted +redshirting +redshirts +redskin +redskins +redstart +redstarts +redtail +redtails +redtop +redtops +redub +redubbed +redubbing +redubs +reduce +reduced +reducer +reducers +reduces +reducibilities +reducibility +reducible +reducibly +reducing +reductant +reductants +reductase +reductases +reduction +reductional +reductionism +reductionisms +reductionist +reductionistic +reductionists +reductions +reductive +reductively +reductiveness +reductivenesses +reductor +reductors +redundancies +redundancy +redundant +redundantly +reduplicate +reduplicated +reduplicates +reduplicating +reduplication +reduplications +reduplicative +reduplicatively +reduviid +reduviids +redux +redware +redwares +redwing +redwings +redwood +redwoods +redye +redyed +redyeing +redyes +ree +reearn +reearned +reearning +reearns +reechier +reechiest +reecho +reechoed +reechoes +reechoing +reechy +reed +reedbird +reedbirds +reedbuck +reedbucks +reeded +reedier +reediest +reedified +reedifies +reedify +reedifying +reedily +reediness +reedinesses +reeding +reedings +reedit +reedited +reediting +reedition +reeditions +reedits +reedlike +reedling +reedlings +reedman +reedmen +reeds +reeducate +reeducated +reeducates +reeducating +reeducation +reeducations +reeducative +reedy +reef +reefable +reefed +reefer +reefers +reefier +reefiest +reefing +reefs +reefy +reeject +reejected +reejecting +reejects +reek +reeked +reeker +reekers +reekier +reekiest +reeking +reeks +reeky +reel +reelable +reelect +reelected +reelecting +reelection +reelections +reelects +reeled +reeler +reelers +reeligibilities +reeligibility +reeligible +reeling +reels +reembark +reembarked +reembarking +reembarks +reembodied +reembodies +reembody +reembodying +reembroider +reembroidered +reembroidering +reembroiders +reemerge +reemerged +reemergence +reemergences +reemerges +reemerging +reemission +reemissions +reemit +reemits +reemitted +reemitting +reemphases +reemphasis +reemphasize +reemphasized +reemphasizes +reemphasizing +reemploy +reemployed +reemploying +reemployment +reemployments +reemploys +reenact +reenacted +reenacting +reenactment +reenactments +reenacts +reencounter +reencountered +reencountering +reencounters +reendow +reendowed +reendowing +reendows +reenergize +reenergized +reenergizes +reenergizing +reenforce +reenforced +reenforces +reenforcing +reengage +reengaged +reengagement +reengagements +reengages +reengaging +reengineer +reengineered +reengineering +reengineers +reengrave +reengraved +reengraves +reengraving +reenjoy +reenjoyed +reenjoying +reenjoys +reenlist +reenlisted +reenlisting +reenlistment +reenlistments +reenlists +reenroll +reenrolled +reenrolling +reenrolls +reenter +reentered +reentering +reenters +reenthrone +reenthroned +reenthrones +reenthroning +reentrance +reentrances +reentrant +reentrants +reentries +reentry +reequip +reequipment +reequipments +reequipped +reequipping +reequips +reerect +reerected +reerecting +reerects +rees +reescalate +reescalated +reescalates +reescalating +reescalation +reescalations +reest +reestablish +reestablished +reestablishes +reestablishing +reestablishment +reestablishments +reested +reestimate +reestimated +reestimates +reestimating +reesting +reests +reevaluate +reevaluated +reevaluates +reevaluating +reevaluation +reevaluations +reeve +reeved +reeves +reeving +reevoke +reevoked +reevokes +reevoking +reexamination +reexaminations +reexamine +reexamined +reexamines +reexamining +reexpel +reexpelled +reexpelling +reexpels +reexperience +reexperienced +reexperiences +reexperiencing +reexplore +reexplored +reexplores +reexploring +reexport +reexportation +reexportations +reexported +reexporting +reexports +reexpose +reexposed +reexposes +reexposing +reexposure +reexposures +reexpress +reexpressed +reexpresses +reexpressing +ref +reface +refaced +refaces +refacing +refall +refallen +refalling +refalls +refashion +refashioned +refashioning +refashions +refasten +refastened +refastening +refastens +refect +refected +refecting +refection +refections +refectories +refectory +refects +refed +refeed +refeeding +refeeds +refeel +refeeling +refeels +refel +refell +refelled +refelling +refels +refelt +refence +refenced +refences +refencing +refer +referable +referee +refereed +refereeing +referees +reference +referenced +references +referencing +referenda +referendum +referendums +referent +referential +referentialities +referentiality +referentially +referents +referral +referrals +referred +referrer +referrers +referring +refers +reffed +reffing +refight +refighting +refights +refigure +refigured +refigures +refiguring +refile +refiled +refiles +refiling +refill +refillable +refilled +refilling +refills +refilm +refilmed +refilming +refilms +refilter +refiltered +refiltering +refilters +refinance +refinanced +refinances +refinancing +refind +refinding +refinds +refine +refined +refinement +refinements +refiner +refineries +refiners +refinery +refines +refining +refinish +refinished +refinisher +refinishers +refinishes +refinishing +refire +refired +refires +refiring +refit +refits +refitted +refitting +refix +refixed +refixes +refixing +reflate +reflated +reflates +reflating +reflation +reflationary +reflations +reflect +reflectance +reflectances +reflected +reflecting +reflection +reflectional +reflections +reflective +reflectively +reflectiveness +reflectivenesses +reflectivities +reflectivity +reflectometer +reflectometers +reflectometries +reflectometry +reflector +reflectorize +reflectorized +reflectorizes +reflectorizing +reflectors +reflects +reflet +reflets +reflew +reflex +reflexed +reflexes +reflexing +reflexion +reflexions +reflexive +reflexively +reflexiveness +reflexivenesses +reflexives +reflexivities +reflexivity +reflexly +reflexologies +reflexology +reflies +refloat +refloated +refloating +refloats +reflood +reflooded +reflooding +refloods +reflow +reflowed +reflower +reflowered +reflowering +reflowers +reflowing +reflown +reflows +refluence +refluences +refluent +reflux +refluxed +refluxes +refluxing +refly +reflying +refocus +refocused +refocuses +refocusing +refocussed +refocusses +refocussing +refold +refolded +refolding +refolds +reforest +reforestation +reforestations +reforested +reforesting +reforests +reforge +reforged +reforges +reforging +reform +reformabilities +reformability +reformable +reformat +reformate +reformates +reformation +reformational +reformations +reformative +reformatories +reformatory +reformats +reformatted +reformatting +reformed +reformer +reformers +reforming +reformism +reformisms +reformist +reformists +reforms +reformulate +reformulated +reformulates +reformulating +reformulation +reformulations +refortification +refortifications +refortified +refortifies +refortify +refortifying +refought +refound +refoundation +refoundations +refounded +refounding +refounds +refract +refracted +refractile +refracting +refraction +refractions +refractive +refractively +refractiveness +refractivenesses +refractivities +refractivity +refractometer +refractometers +refractometric +refractometries +refractometry +refractor +refractories +refractorily +refractoriness +refractorinesses +refractors +refractory +refracts +refrain +refrained +refraining +refrainment +refrainments +refrains +reframe +reframed +reframes +reframing +refrangibilities +refrangibility +refrangible +refrangibleness +refrangiblenesses +refreeze +refreezes +refreezing +refresh +refreshed +refreshen +refreshened +refreshening +refreshens +refresher +refreshers +refreshes +refreshing +refreshingly +refreshment +refreshments +refried +refries +refrigerant +refrigerants +refrigerate +refrigerated +refrigerates +refrigerating +refrigeration +refrigerations +refrigerator +refrigerators +refront +refronted +refronting +refronts +refroze +refrozen +refry +refrying +refs +reft +refuel +refueled +refueling +refuelled +refuelling +refuels +refuge +refuged +refugee +refugeeism +refugeeisms +refugees +refuges +refugia +refuging +refugium +refulgence +refulgences +refulgent +refund +refundabilities +refundability +refundable +refunded +refunder +refunders +refunding +refunds +refurbish +refurbished +refurbisher +refurbishers +refurbishes +refurbishing +refurbishment +refurbishments +refurnish +refurnished +refurnishes +refurnishing +refusal +refusals +refuse +refused +refusenik +refuseniks +refuser +refusers +refuses +refusing +refusnik +refusniks +refutable +refutably +refutal +refutals +refutation +refutations +refute +refuted +refuter +refuters +refutes +refuting +reg +regain +regained +regainer +regainers +regaining +regains +regal +regale +regaled +regaler +regalers +regales +regalia +regaling +regalities +regality +regally +regard +regardant +regarded +regardful +regardfully +regardfulness +regardfulnesses +regarding +regardless +regardlessly +regardlessness +regardlessnesses +regards +regather +regathered +regathering +regathers +regatta +regattas +regauge +regauged +regauges +regauging +regave +regear +regeared +regearing +regears +regelate +regelated +regelates +regelating +regencies +regency +regenerable +regeneracies +regeneracy +regenerate +regenerated +regenerately +regenerateness +regeneratenesses +regenerates +regenerating +regeneration +regenerations +regenerative +regenerator +regenerators +regent +regental +regents +reges +reggae +reggaes +regicidal +regicide +regicides +regild +regilded +regilding +regilds +regilt +regime +regimen +regimens +regiment +regimental +regimentals +regimentation +regimentations +regimented +regimenting +regiments +regimes +regina +reginae +reginal +reginas +region +regional +regionalism +regionalisms +regionalist +regionalistic +regionalists +regionalization +regionalizations +regionalize +regionalized +regionalizes +regionalizing +regionally +regionals +regions +regisseur +regisseurs +register +registerable +registered +registering +registers +registrable +registrant +registrants +registrar +registrars +registration +registrations +registries +registry +regius +regive +regiven +regives +regiving +reglaze +reglazed +reglazes +reglazing +reglet +reglets +regloss +reglossed +reglosses +reglossing +reglow +reglowed +reglowing +reglows +reglue +reglued +reglues +regluing +regma +regmata +regna +regnal +regnancies +regnancy +regnant +regnum +regolith +regoliths +regorge +regorged +regorges +regorging +regosol +regosols +regrade +regraded +regrades +regrading +regraft +regrafted +regrafting +regrafts +regrant +regranted +regranting +regrants +regrate +regrated +regrates +regrating +regreen +regreened +regreening +regreens +regreet +regreeted +regreeting +regreets +regress +regressed +regresses +regressing +regression +regressions +regressive +regressively +regressiveness +regressivenesses +regressivities +regressivity +regressor +regressors +regret +regretful +regretfully +regretfulness +regretfulnesses +regrets +regrettable +regrettably +regretted +regretter +regretters +regretting +regrew +regrind +regrinding +regrinds +regroom +regroomed +regrooming +regrooms +regroove +regrooved +regrooves +regrooving +reground +regroup +regrouped +regrouping +regroups +regrow +regrowing +regrown +regrows +regrowth +regrowths +regs +regular +regularities +regularity +regularization +regularizations +regularize +regularized +regularizes +regularizing +regularly +regulars +regulate +regulated +regulates +regulating +regulation +regulations +regulative +regulator +regulators +regulatory +reguli +reguline +regulus +reguluses +regurgitate +regurgitated +regurgitates +regurgitating +regurgitation +regurgitations +rehab +rehabbed +rehabber +rehabbers +rehabbing +rehabilitant +rehabilitants +rehabilitate +rehabilitated +rehabilitates +rehabilitating +rehabilitation +rehabilitations +rehabilitative +rehabilitator +rehabilitators +rehabs +rehammer +rehammered +rehammering +rehammers +rehandle +rehandled +rehandles +rehandling +rehang +rehanged +rehanging +rehangs +reharden +rehardened +rehardening +rehardens +rehash +rehashed +rehashes +rehashing +rehear +reheard +rehearing +rehearings +rehears +rehearsal +rehearsals +rehearse +rehearsed +rehearser +rehearsers +rehearses +rehearsing +reheat +reheated +reheater +reheaters +reheating +reheats +reheel +reheeled +reheeling +reheels +rehem +rehemmed +rehemming +rehems +rehinge +rehinged +rehinges +rehinging +rehire +rehired +rehires +rehiring +rehoboam +rehoboams +rehospitalization +rehospitalizations +rehospitalize +rehospitalized +rehospitalizes +rehospitalizing +rehouse +rehoused +rehouses +rehousing +rehumanize +rehumanized +rehumanizes +rehumanizing +rehung +rehydratable +rehydrate +rehydrated +rehydrates +rehydrating +rehydration +rehydrations +rehypnotize +rehypnotized +rehypnotizes +rehypnotizing +rei +reichsmark +reichsmarks +reidentified +reidentifies +reidentify +reidentifying +reif +reification +reifications +reified +reifier +reifiers +reifies +reifs +reify +reifying +reign +reigned +reigning +reignite +reignited +reignites +reigniting +reignition +reignitions +reigns +reimage +reimaged +reimages +reimagine +reimagined +reimagines +reimaging +reimagining +reimbursable +reimburse +reimbursed +reimbursement +reimbursements +reimburses +reimbursing +reimmerse +reimmersed +reimmerses +reimmersing +reimplant +reimplantation +reimplantations +reimplanted +reimplanting +reimplants +reimport +reimportation +reimportations +reimported +reimporting +reimports +reimpose +reimposed +reimposes +reimposing +reimposition +reimpositions +reimpression +reimpressions +rein +reincarnate +reincarnated +reincarnates +reincarnating +reincarnation +reincarnations +reincite +reincited +reincites +reinciting +reincorporate +reincorporated +reincorporates +reincorporating +reincorporation +reincorporations +reincur +reincurred +reincurring +reincurs +reindeer +reindeers +reindex +reindexed +reindexes +reindexing +reindict +reindicted +reindicting +reindictment +reindictments +reindicts +reinduce +reinduced +reinduces +reinducing +reinduct +reinducted +reinducting +reinducts +reindustrialization +reindustrializations +reindustrialize +reindustrialized +reindustrializes +reindustrializing +reined +reinfect +reinfected +reinfecting +reinfection +reinfections +reinfects +reinfestation +reinfestations +reinflate +reinflated +reinflates +reinflating +reinflation +reinflations +reinforce +reinforceable +reinforced +reinforcement +reinforcements +reinforcer +reinforcers +reinforces +reinforcing +reinform +reinformed +reinforming +reinforms +reinfuse +reinfused +reinfuses +reinfusing +reinhabit +reinhabited +reinhabiting +reinhabits +reining +reinitiate +reinitiated +reinitiates +reinitiating +reinject +reinjected +reinjecting +reinjection +reinjections +reinjects +reinjure +reinjured +reinjures +reinjuries +reinjuring +reinjury +reink +reinked +reinking +reinks +reinless +reinnervate +reinnervated +reinnervates +reinnervating +reinnervation +reinnervations +reinoculate +reinoculated +reinoculates +reinoculating +reinoculation +reinoculations +reins +reinsert +reinserted +reinserting +reinsertion +reinsertions +reinserts +reinsman +reinsmen +reinspect +reinspected +reinspecting +reinspection +reinspections +reinspects +reinspire +reinspired +reinspires +reinspiring +reinstall +reinstallation +reinstallations +reinstalled +reinstalling +reinstalls +reinstate +reinstated +reinstatement +reinstatements +reinstates +reinstating +reinstitute +reinstituted +reinstitutes +reinstituting +reinstitutionalization +reinstitutionalizations +reinstitutionalize +reinstitutionalized +reinstitutionalizes +reinstitutionalizing +reinsurance +reinsurances +reinsure +reinsured +reinsurer +reinsurers +reinsures +reinsuring +reintegrate +reintegrated +reintegrates +reintegrating +reintegration +reintegrations +reintegrative +reinter +reinterpret +reinterpretation +reinterpretations +reinterpreted +reinterpreting +reinterprets +reinterred +reinterring +reinters +reinterview +reinterviewed +reinterviewing +reinterviews +reintroduce +reintroduced +reintroduces +reintroducing +reintroduction +reintroductions +reinvade +reinvaded +reinvades +reinvading +reinvasion +reinvasions +reinvent +reinvented +reinventing +reinvention +reinventions +reinvents +reinvest +reinvested +reinvestigate +reinvestigated +reinvestigates +reinvestigating +reinvestigation +reinvestigations +reinvesting +reinvestment +reinvestments +reinvests +reinvigorate +reinvigorated +reinvigorates +reinvigorating +reinvigoration +reinvigorations +reinvigorator +reinvigorators +reinvite +reinvited +reinvites +reinviting +reinvoke +reinvoked +reinvokes +reinvoking +reis +reissue +reissued +reissuer +reissuers +reissues +reissuing +reitbok +reitboks +reiterate +reiterated +reiterates +reiterating +reiteration +reiterations +reiterative +reiteratively +reive +reived +reiver +reivers +reives +reiving +rejacket +rejacketed +rejacketing +rejackets +reject +rejected +rejectee +rejectees +rejecter +rejecters +rejecting +rejectingly +rejection +rejections +rejective +rejector +rejectors +rejects +rejigger +rejiggered +rejiggering +rejiggers +rejoice +rejoiced +rejoicer +rejoicers +rejoices +rejoicing +rejoicingly +rejoicings +rejoin +rejoinder +rejoinders +rejoined +rejoining +rejoins +rejudge +rejudged +rejudges +rejudging +rejuggle +rejuggled +rejuggles +rejuggling +rejuvenate +rejuvenated +rejuvenates +rejuvenating +rejuvenation +rejuvenations +rejuvenator +rejuvenators +rejuvenescence +rejuvenescences +rejuvenescent +rekey +rekeyboard +rekeyboarded +rekeyboarding +rekeyboards +rekeyed +rekeying +rekeys +rekindle +rekindled +rekindles +rekindling +reknit +reknits +reknitted +reknitting +relabel +relabeled +relabeling +relabelled +relabelling +relabels +relace +relaced +relaces +relacing +relacquer +relacquered +relacquering +relacquers +relaid +relandscape +relandscaped +relandscapes +relandscaping +relapse +relapsed +relapser +relapsers +relapses +relapsing +relatable +relate +related +relatedly +relatedness +relatednesses +relater +relaters +relates +relating +relation +relational +relationally +relations +relationship +relationships +relative +relatively +relatives +relativism +relativisms +relativist +relativistic +relativistically +relativists +relativities +relativity +relativize +relativized +relativizes +relativizing +relator +relators +relaunch +relaunched +relaunches +relaunching +relax +relaxant +relaxants +relaxation +relaxations +relaxed +relaxedly +relaxedness +relaxednesses +relaxer +relaxers +relaxes +relaxin +relaxing +relaxins +relay +relayed +relaying +relays +relearn +relearned +relearning +relearns +relearnt +releasable +release +released +releaser +releasers +releases +releasing +relegate +relegated +relegates +relegating +relegation +relegations +relend +relending +relends +relent +relented +relenting +relentless +relentlessly +relentlessness +relentlessnesses +relents +relet +relets +reletter +relettered +relettering +reletters +reletting +relevance +relevances +relevancies +relevancy +relevant +relevantly +releve +releves +reliabilities +reliability +reliable +reliableness +reliablenesses +reliables +reliably +reliance +reliances +reliant +reliantly +relic +relicense +relicensed +relicenses +relicensing +relicensure +relicensures +relics +relict +reliction +relictions +relicts +relied +relief +reliefs +relier +reliers +relies +relievable +relieve +relieved +relievedly +reliever +relievers +relieves +relieving +relievo +relievos +relight +relighted +relighting +relights +religion +religionist +religionists +religionless +religions +religiose +religiosities +religiosity +religious +religiously +religiousness +religiousnesses +reline +relined +relines +relining +relink +relinked +relinking +relinks +relinquish +relinquished +relinquishes +relinquishing +relinquishment +relinquishments +reliquaries +reliquary +relique +reliquefied +reliquefies +reliquefy +reliquefying +reliques +reliquiae +relish +relishable +relished +relishes +relishing +relist +relisted +relisting +relists +relit +relive +relived +relives +reliving +reload +reloaded +reloader +reloaders +reloading +reloads +reloan +reloaned +reloaning +reloans +relocatable +relocate +relocated +relocatee +relocatees +relocates +relocating +relocation +relocations +relock +relocked +relocking +relocks +relook +relooked +relooking +relooks +relubricate +relubricated +relubricates +relubricating +relubrication +relubrications +relucent +reluct +reluctance +reluctances +reluctancies +reluctancy +reluctant +reluctantly +reluctate +reluctated +reluctates +reluctating +reluctation +reluctations +relucted +relucting +relucts +relume +relumed +relumes +relumine +relumined +relumines +reluming +relumining +rely +relying +rem +remade +remail +remailed +remailing +remails +remain +remainder +remaindered +remaindering +remainders +remained +remaining +remains +remake +remaker +remakers +remakes +remaking +reman +remand +remanded +remanding +remands +remanence +remanences +remanent +remanned +remanning +remans +remanufacture +remanufactured +remanufacturer +remanufacturers +remanufactures +remanufacturing +remap +remapped +remapping +remaps +remark +remarkable +remarkableness +remarkablenesses +remarkably +remarked +remarker +remarkers +remarket +remarketed +remarketing +remarkets +remarking +remarks +remarque +remarques +remarriage +remarriages +remarried +remarries +remarry +remarrying +remaster +remastered +remastering +remasters +rematch +rematched +rematches +rematching +remate +remated +rematerialize +rematerialized +rematerializes +rematerializing +remates +remating +remeasure +remeasured +remeasurement +remeasurements +remeasures +remeasuring +remediabilities +remediability +remediable +remedial +remedially +remediate +remediated +remediates +remediating +remediation +remediations +remedied +remedies +remediless +remedy +remedying +remeet +remeeting +remeets +remelt +remelted +remelting +remelts +remember +rememberabilities +rememberability +rememberable +remembered +rememberer +rememberers +remembering +remembers +remembrance +remembrancer +remembrancers +remembrances +remend +remended +remending +remends +remerge +remerged +remerges +remerging +remet +remex +remiges +remigial +remigration +remigrations +remilitarization +remilitarizations +remilitarize +remilitarized +remilitarizes +remilitarizing +remind +reminded +reminder +reminders +remindful +reminding +reminds +reminisce +reminisced +reminiscence +reminiscences +reminiscent +reminiscential +reminiscently +reminiscer +reminiscers +reminisces +reminiscing +remint +reminted +reminting +remints +remise +remised +remises +remising +remiss +remissible +remissibly +remission +remissions +remissly +remissness +remissnesses +remit +remitment +remitments +remits +remittable +remittal +remittals +remittance +remittances +remitted +remittent +remitter +remitters +remitting +remittor +remittors +remix +remixed +remixes +remixing +remixt +remnant +remnants +remobilization +remobilizations +remobilize +remobilized +remobilizes +remobilizing +remodel +remodeled +remodeling +remodelled +remodelling +remodels +remodified +remodifies +remodify +remodifying +remoisten +remoistened +remoistening +remoistens +remolade +remolades +remold +remolded +remolding +remolds +remonetization +remonetizations +remonetize +remonetized +remonetizes +remonetizing +remonstrance +remonstrances +remonstrant +remonstrantly +remonstrants +remonstrate +remonstrated +remonstrates +remonstrating +remonstration +remonstrations +remonstrative +remonstratively +remonstrator +remonstrators +remora +remoras +remorid +remorse +remorseful +remorsefully +remorsefulness +remorsefulnesses +remorseless +remorselessly +remorselessness +remorselessnesses +remorses +remortgage +remortgaged +remortgages +remortgaging +remote +remotely +remoteness +remotenesses +remoter +remotes +remotest +remotion +remotions +remotivate +remotivated +remotivates +remotivating +remotivation +remotivations +remount +remounted +remounting +remounts +removabilities +removability +removable +removableness +removablenesses +removably +removal +removals +remove +removeable +removed +remover +removers +removes +removing +rems +remuda +remudas +remunerate +remunerated +remunerates +remunerating +remuneration +remunerations +remunerative +remuneratively +remunerativeness +remunerativenesses +remunerator +remunerators +remuneratory +remythologize +remythologized +remythologizes +remythologizing +renail +renailed +renailing +renails +renaissance +renaissances +renal +rename +renamed +renames +renaming +renascence +renascences +renascent +renationalization +renationalizations +renationalize +renationalized +renationalizes +renationalizing +renaturation +renaturations +renature +renatured +renatures +renaturing +rencontre +rencontres +rencounter +rencountered +rencountering +rencounters +rend +rended +render +renderable +rendered +renderer +renderers +rendering +renders +rendezvous +rendezvoused +rendezvouses +rendezvousing +rendible +rending +rendition +renditions +rends +rendzina +rendzinas +renegade +renegaded +renegades +renegading +renegado +renegadoes +renegados +renege +reneged +reneger +renegers +reneges +reneging +renegotiable +renegotiate +renegotiated +renegotiates +renegotiating +renegotiation +renegotiations +renest +renested +renesting +renests +renew +renewabilities +renewability +renewable +renewably +renewal +renewals +renewed +renewer +renewers +renewing +renews +reniform +renig +renigged +renigging +renigs +renin +renins +renitencies +renitency +renitent +renminbi +rennase +rennases +rennet +rennets +rennin +rennins +renogram +renograms +renographic +renographies +renography +renominate +renominated +renominates +renominating +renomination +renominations +renormalization +renormalizations +renormalize +renormalized +renormalizes +renormalizing +renotified +renotifies +renotify +renotifying +renounce +renounced +renouncement +renouncements +renouncer +renouncers +renounces +renouncing +renovascular +renovate +renovated +renovates +renovating +renovation +renovations +renovative +renovator +renovators +renown +renowned +renowning +renowns +rent +rentabilities +rentability +rentable +rental +rentals +rente +rented +renter +renters +rentes +rentier +rentiers +renting +rents +renumber +renumbered +renumbering +renumbers +renunciate +renunciates +renunciation +renunciations +renunciative +renunciatory +renvoi +renvois +reobject +reobjected +reobjecting +reobjects +reobserve +reobserved +reobserves +reobserving +reobtain +reobtained +reobtaining +reobtains +reoccupation +reoccupations +reoccupied +reoccupies +reoccupy +reoccupying +reoccur +reoccurred +reoccurrence +reoccurrences +reoccurring +reoccurs +reoffer +reoffered +reoffering +reoffers +reoil +reoiled +reoiling +reoils +reopen +reopened +reopening +reopenings +reopens +reoperate +reoperated +reoperates +reoperating +reoperation +reoperations +reoppose +reopposed +reopposes +reopposing +reorchestrate +reorchestrated +reorchestrates +reorchestrating +reorchestration +reorchestrations +reordain +reordained +reordaining +reordains +reorder +reordered +reordering +reorders +reorganization +reorganizational +reorganizations +reorganize +reorganized +reorganizer +reorganizers +reorganizes +reorganizing +reorient +reorientate +reorientated +reorientates +reorientating +reorientation +reorientations +reoriented +reorienting +reorients +reoutfit +reoutfits +reoutfitted +reoutfitting +reovirus +reoviruses +reoxidation +reoxidations +reoxidize +reoxidized +reoxidizes +reoxidizing +rep +repacified +repacifies +repacify +repacifying +repack +repackage +repackaged +repackager +repackagers +repackages +repackaging +repacked +repacking +repacks +repaid +repaint +repainted +repainting +repaints +repair +repairabilities +repairability +repairable +repaired +repairer +repairers +repairing +repairman +repairmen +repairs +repand +repandly +repanel +repaneled +repaneling +repanelled +repanelling +repanels +repaper +repapered +repapering +repapers +reparable +reparation +reparations +reparative +repark +reparked +reparking +reparks +repartee +repartees +repartition +repartitions +repass +repassage +repassages +repassed +repasses +repassing +repast +repasted +repasting +repasts +repatch +repatched +repatches +repatching +repatriate +repatriated +repatriates +repatriating +repatriation +repatriations +repattern +repatterned +repatterning +repatterns +repave +repaved +repaves +repaving +repay +repayable +repaying +repayment +repayments +repays +repeal +repealable +repealed +repealer +repealers +repealing +repeals +repeat +repeatabilities +repeatability +repeatable +repeated +repeatedly +repeater +repeaters +repeating +repeats +repechage +repechages +repeg +repegged +repegging +repegs +repel +repellant +repellants +repelled +repellencies +repellency +repellent +repellently +repellents +repeller +repellers +repelling +repels +repent +repentance +repentances +repentant +repentantly +repented +repenter +repenters +repenting +repents +repeople +repeopled +repeoples +repeopling +repercussion +repercussions +repercussive +reperk +reperked +reperking +reperks +repertoire +repertoires +repertories +repertory +repetend +repetends +repetition +repetitional +repetitions +repetitious +repetitiously +repetitiousness +repetitiousnesses +repetitive +repetitively +repetitiveness +repetitivenesses +rephotograph +rephotographed +rephotographing +rephotographs +rephrase +rephrased +rephrases +rephrasing +repin +repine +repined +repiner +repiners +repines +repining +repinned +repinning +repins +replace +replaceable +replaced +replacement +replacements +replacer +replacers +replaces +replacing +replan +replanned +replanning +replans +replant +replantation +replantations +replanted +replanting +replants +replaster +replastered +replastering +replasters +replate +replated +replates +replating +replay +replayed +replaying +replays +replead +repleaded +repleader +repleaders +repleading +repleads +repled +repledge +repledged +repledges +repledging +replenish +replenishable +replenished +replenisher +replenishers +replenishes +replenishing +replenishment +replenishments +replete +repleteness +repletenesses +repletion +repletions +repleviable +replevied +replevies +replevin +replevined +replevining +replevins +replevy +replevying +replica +replicabilities +replicability +replicable +replicas +replicase +replicases +replicate +replicated +replicates +replicating +replication +replications +replicative +replicon +replicons +replied +replier +repliers +replies +replot +replots +replotted +replotting +replumb +replumbed +replumbing +replumbs +replunge +replunged +replunges +replunging +reply +replying +repo +repolarization +repolarizations +repolarize +repolarized +repolarizes +repolarizing +repolish +repolished +repolishes +repolishing +repoll +repolled +repolling +repolls +repopularize +repopularized +repopularizes +repopularizing +repopulate +repopulated +repopulates +repopulating +repopulation +repopulations +report +reportable +reportage +reportages +reported +reportedly +reporter +reporters +reporting +reportorial +reportorially +reports +repos +reposal +reposals +repose +reposed +reposeful +reposefully +reposefulness +reposefulnesses +reposer +reposers +reposes +reposing +reposit +reposited +repositing +reposition +repositioned +repositioning +repositions +repositories +repository +reposits +repossess +repossessed +repossesses +repossessing +repossession +repossessions +repossessor +repossessors +repot +repots +repotted +repotting +repour +repoured +repouring +repours +repousse +repousses +repower +repowered +repowering +repowers +repp +repped +repps +reprehend +reprehended +reprehending +reprehends +reprehensibilities +reprehensibility +reprehensible +reprehensibleness +reprehensiblenesses +reprehensibly +reprehension +reprehensions +reprehensive +represent +representable +representation +representational +representationalism +representationalisms +representationalist +representationalists +representationally +representations +representative +representatively +representativeness +representativenesses +representatives +representativities +representativity +represented +representer +representers +representing +represents +repress +repressed +represses +repressibilities +repressibility +repressible +repressing +repression +repressionist +repressions +repressive +repressively +repressiveness +repressivenesses +repressor +repressors +repressurize +repressurized +repressurizes +repressurizing +reprice +repriced +reprices +repricing +reprieval +reprievals +reprieve +reprieved +reprieves +reprieving +reprimand +reprimanded +reprimanding +reprimands +reprint +reprinted +reprinter +reprinters +reprinting +reprints +reprisal +reprisals +reprise +reprised +reprises +reprising +repristinate +repristinated +repristinates +repristinating +repristination +repristinations +reprivatization +reprivatizations +reprivatize +reprivatized +reprivatizes +reprivatizing +repro +reproach +reproachable +reproached +reproacher +reproachers +reproaches +reproachful +reproachfully +reproachfulness +reproachfulnesses +reproaching +reproachingly +reprobance +reprobances +reprobate +reprobated +reprobates +reprobating +reprobation +reprobations +reprobative +reprobatory +reprobe +reprobed +reprobes +reprobing +reprocess +reprocessed +reprocesses +reprocessing +reproduce +reproduced +reproducer +reproducers +reproduces +reproducibilities +reproducibility +reproducible +reproducibles +reproducibly +reproducing +reproduction +reproductions +reproductive +reproductively +reproductives +reprogram +reprogramed +reprograming +reprogrammable +reprogrammed +reprogramming +reprograms +reprographer +reprographers +reprographic +reprographics +reprographies +reprography +reproof +reproofs +repros +reproval +reprovals +reprove +reproved +reprover +reprovers +reproves +reproving +reprovingly +reprovision +reprovisioned +reprovisioning +reprovisions +reps +reptant +reptile +reptiles +reptilia +reptilian +reptilians +reptilium +republic +republican +republicanism +republicanisms +republicanize +republicanized +republicanizes +republicanizing +republicans +republication +republications +republics +republish +republished +republisher +republishers +republishes +republishing +repudiate +repudiated +repudiates +repudiating +repudiation +repudiationist +repudiationists +repudiations +repudiator +repudiators +repugn +repugnance +repugnances +repugnancies +repugnancy +repugnant +repugnantly +repugned +repugning +repugns +repulse +repulsed +repulser +repulsers +repulses +repulsing +repulsion +repulsions +repulsive +repulsively +repulsiveness +repulsivenesses +repump +repumped +repumping +repumps +repunctuation +repunctuations +repurchase +repurchased +repurchases +repurchasing +repurified +repurifies +repurify +repurifying +repursue +repursued +repursues +repursuing +reputabilities +reputability +reputable +reputably +reputation +reputational +reputations +repute +reputed +reputedly +reputes +reputing +requalification +requalifications +requalified +requalifies +requalify +requalifying +request +requested +requester +requesters +requesting +requestor +requestors +requests +requiem +requiems +requiescat +requiescats +requin +requins +require +required +requirement +requirements +requirer +requirers +requires +requiring +requisite +requisiteness +requisitenesses +requisites +requisition +requisitioned +requisitioning +requisitions +requital +requitals +requite +requited +requiter +requiters +requites +requiting +rerack +reracked +reracking +reracks +reradiate +reradiated +reradiates +reradiating +reradiation +reradiations +reraise +reraised +reraises +reraising +reran +reread +rereading +rereadings +rereads +rerecord +rerecorded +rerecording +rerecords +reredos +reredoses +reregister +reregistered +reregistering +reregisters +reregistration +reregistrations +reregulate +reregulated +reregulates +reregulating +reregulation +reregulations +rerelease +rereleased +rereleases +rereleasing +reremice +reremind +rereminded +rereminding +rereminds +reremouse +rerepeat +rerepeated +rerepeating +rerepeats +rereview +rereviewed +rereviewing +rereviews +rereward +rerewards +rerig +rerigged +rerigging +rerigs +rerise +rerisen +rerises +rerising +reroll +rerolled +reroller +rerollers +rerolling +rerolls +reroof +reroofed +reroofing +reroofs +rerose +reroute +rerouted +reroutes +rerouting +rerun +rerunning +reruns +res +resaddle +resaddled +resaddles +resaddling +resaid +resail +resailed +resailing +resails +resalable +resale +resales +resalute +resaluted +resalutes +resaluting +resample +resampled +resamples +resampling +resaw +resawed +resawing +resawn +resaws +resay +resaying +resays +rescale +rescaled +rescales +rescaling +reschedule +rescheduled +reschedules +rescheduling +reschool +reschooled +reschooling +reschools +rescind +rescinded +rescinder +rescinders +rescinding +rescindment +rescindments +rescinds +rescission +rescissions +rescissory +rescore +rescored +rescores +rescoring +rescreen +rescreened +rescreening +rescreens +rescript +rescripts +rescuable +rescue +rescued +rescuer +rescuers +rescues +rescuing +resculpt +resculpted +resculpting +resculpts +reseal +resealable +resealed +resealing +reseals +research +researchable +researched +researcher +researchers +researches +researching +researchist +researchists +reseason +reseasoned +reseasoning +reseasons +reseat +reseated +reseating +reseats +reseau +reseaus +reseaux +resect +resectabilities +resectability +resectable +resected +resecting +resection +resections +resects +resecure +resecured +resecures +resecuring +reseda +resedas +resee +reseed +reseeded +reseeding +reseeds +reseeing +reseek +reseeking +reseeks +reseen +resees +resegregate +resegregated +resegregates +resegregating +resegregation +resegregations +reseize +reseized +reseizes +reseizing +resell +reseller +resellers +reselling +resells +resemblance +resemblances +resemblant +resemble +resembled +resembles +resembling +resend +resending +resends +resensitize +resensitized +resensitizes +resensitizing +resent +resented +resentence +resentenced +resentences +resentencing +resentful +resentfully +resentfulness +resentfulnesses +resenting +resentment +resentments +resents +reserpine +reserpines +reservable +reservation +reservationist +reservationists +reservations +reserve +reserved +reservedly +reservedness +reservednesses +reserver +reservers +reserves +reservice +reserviced +reservices +reservicing +reserving +reservist +reservists +reservoir +reservoirs +reset +resets +resettable +resetter +resetters +resetting +resettle +resettled +resettlement +resettlements +resettles +resettling +resew +resewed +resewing +resewn +resews +resh +reshape +reshaped +reshaper +reshapers +reshapes +reshaping +reshave +reshaved +reshaven +reshaves +reshaving +reshes +reshine +reshined +reshines +reshingle +reshingled +reshingles +reshingling +reshining +reship +reshipped +reshipping +reships +reshod +reshoe +reshoeing +reshoes +reshone +reshoot +reshooting +reshoots +reshot +reshow +reshowed +reshowing +reshown +reshows +reshuffle +reshuffled +reshuffles +reshuffling +resid +reside +resided +residence +residences +residencies +residency +resident +residential +residentially +residents +resider +residers +resides +residing +resids +residua +residual +residually +residuals +residuary +residue +residues +residuum +residuums +resift +resifted +resifting +resifts +resight +resighted +resighting +resights +resign +resignation +resignations +resigned +resignedly +resignedness +resignednesses +resigner +resigners +resigning +resigns +resile +resiled +resiles +resilience +resiliences +resiliencies +resiliency +resilient +resiliently +resiling +resilver +resilvered +resilvering +resilvers +resin +resinate +resinated +resinates +resinating +resined +resinified +resinifies +resinify +resinifying +resining +resinoid +resinoids +resinous +resins +resiny +resist +resistance +resistances +resistant +resistants +resisted +resister +resisters +resistibilities +resistibility +resistible +resisting +resistive +resistively +resistiveness +resistivenesses +resistivities +resistivity +resistless +resistlessly +resistlessness +resistlessnesses +resistor +resistors +resists +resite +resited +resites +resiting +resitting +resittings +resize +resized +resizes +resizing +resketch +resketched +resketches +resketching +reslate +reslated +reslates +reslating +resmelt +resmelted +resmelting +resmelts +resmooth +resmoothed +resmoothing +resmooths +resoak +resoaked +resoaking +resoaks +resocialization +resocializations +resocialize +resocialized +resocializes +resocializing +resod +resodded +resodding +resods +resojet +resojets +resold +resolder +resoldered +resoldering +resolders +resole +resoled +resoles +resolidification +resolidifications +resolidified +resolidifies +resolidify +resolidifying +resoling +resoluble +resolute +resolutely +resoluteness +resolutenesses +resoluter +resolutes +resolutest +resolution +resolutions +resolvable +resolve +resolved +resolvent +resolvents +resolver +resolvers +resolves +resolving +resonance +resonances +resonant +resonantly +resonants +resonate +resonated +resonates +resonating +resonator +resonators +resorb +resorbed +resorbing +resorbs +resorcin +resorcinol +resorcinols +resorcins +resorption +resorptions +resorptive +resort +resorted +resorter +resorters +resorting +resorts +resought +resound +resounded +resounding +resoundingly +resounds +resource +resourceful +resourcefully +resourcefulness +resourcefulnesses +resources +resow +resowed +resowing +resown +resows +respace +respaced +respaces +respacing +respade +respaded +respades +respading +respeak +respeaking +respeaks +respect +respectabilities +respectability +respectable +respectableness +respectablenesses +respectables +respectably +respected +respecter +respecters +respectful +respectfully +respectfulness +respectfulnesses +respecting +respective +respectively +respectiveness +respectivenesses +respects +respell +respelled +respelling +respellings +respells +respelt +respirable +respiration +respirations +respirator +respirators +respiratory +respire +respired +respires +respiring +respiritualize +respiritualized +respiritualizes +respiritualizing +respirometer +respirometers +respirometric +respirometries +respirometry +respite +respited +respites +respiting +resplendence +resplendences +resplendencies +resplendency +resplendent +resplendently +resplice +respliced +resplices +resplicing +resplit +resplits +resplitting +respoke +respoken +respond +responded +respondent +respondents +responder +responders +responding +responds +responsa +response +responses +responsibilities +responsibility +responsible +responsibleness +responsiblenesses +responsibly +responsions +responsive +responsively +responsiveness +responsivenesses +responsories +responsory +responsum +respot +respots +respotted +respotting +resprang +respray +resprayed +respraying +resprays +respread +respreading +respreads +respring +respringing +resprings +resprout +resprouted +resprouting +resprouts +resprung +ressentiment +ressentiments +rest +restabilize +restabilized +restabilizes +restabilizing +restack +restacked +restacking +restacks +restaff +restaffed +restaffing +restaffs +restage +restaged +restages +restaging +restamp +restamped +restamping +restamps +restart +restartable +restarted +restarting +restarts +restate +restated +restatement +restatements +restates +restating +restaurant +restauranteur +restauranteurs +restaurants +restaurateur +restaurateurs +rested +rester +resters +restful +restfuller +restfullest +restfully +restfulness +restfulnesses +restimulate +restimulated +restimulates +restimulating +restimulation +restimulations +resting +restitch +restitched +restitches +restitching +restitute +restituted +restitutes +restituting +restitution +restitutions +restive +restively +restiveness +restivenesses +restless +restlessly +restlessness +restlessnesses +restock +restocked +restocking +restocks +restoke +restoked +restokes +restoking +restorable +restoral +restorals +restoration +restorations +restorative +restoratives +restore +restored +restorer +restorers +restores +restoring +restrain +restrainable +restrained +restrainedly +restrainer +restrainers +restraining +restrains +restraint +restraints +restrengthen +restrengthened +restrengthening +restrengthens +restress +restressed +restresses +restressing +restricken +restrict +restricted +restrictedly +restricting +restriction +restrictionism +restrictionisms +restrictionist +restrictionists +restrictions +restrictive +restrictively +restrictiveness +restrictivenesses +restrictives +restricts +restrike +restrikes +restriking +restring +restringing +restrings +restrive +restriven +restrives +restriving +restroom +restrooms +restrove +restruck +restructure +restructured +restructures +restructuring +restrung +rests +restudied +restudies +restudy +restudying +restuff +restuffed +restuffing +restuffs +restyle +restyled +restyles +restyling +resubmission +resubmissions +resubmit +resubmits +resubmitted +resubmitting +result +resultant +resultantly +resultants +resulted +resultful +resulting +resultless +results +resume +resumed +resumer +resumers +resumes +resuming +resummon +resummoned +resummoning +resummons +resumption +resumptions +resupinate +resupine +resupplied +resupplies +resupply +resupplying +resurface +resurfaced +resurfacer +resurfacers +resurfaces +resurfacing +resurge +resurged +resurgence +resurgences +resurgent +resurges +resurging +resurrect +resurrected +resurrecting +resurrection +resurrectional +resurrectionist +resurrectionists +resurrections +resurrects +resurvey +resurveyed +resurveying +resurveys +resuscitate +resuscitated +resuscitates +resuscitating +resuscitation +resuscitations +resuscitative +resuscitator +resuscitators +resyntheses +resynthesis +resynthesize +resynthesized +resynthesizes +resynthesizing +resystematize +resystematized +resystematizes +resystematizing +ret +retable +retables +retack +retacked +retacking +retackle +retackled +retackles +retackling +retacks +retag +retagged +retagging +retags +retail +retailed +retailer +retailers +retailing +retailings +retailor +retailored +retailoring +retailors +retails +retain +retained +retainer +retainers +retaining +retains +retake +retaken +retaker +retakers +retakes +retaking +retaliate +retaliated +retaliates +retaliating +retaliation +retaliations +retaliative +retaliatory +retape +retaped +retapes +retaping +retard +retardant +retardants +retardate +retardates +retardation +retardations +retarded +retarder +retarders +retarding +retards +retarget +retargeted +retargeting +retargets +retaste +retasted +retastes +retasting +retaught +retax +retaxed +retaxes +retaxing +retch +retched +retches +retching +rete +reteach +reteaches +reteaching +reteam +reteamed +reteaming +reteams +retear +retearing +retears +retell +retelling +retellings +retells +retem +retemper +retempered +retempering +retempers +retems +retene +retenes +retention +retentions +retentive +retentively +retentiveness +retentivenesses +retentivities +retentivity +retest +retested +retesting +retests +retexture +retextured +retextures +retexturing +rethink +rethinker +rethinkers +rethinking +rethinks +rethought +rethread +rethreaded +rethreading +rethreads +retia +retial +retiarii +retiarius +retiary +reticence +reticences +reticencies +reticency +reticent +reticently +reticle +reticles +reticula +reticular +reticulate +reticulated +reticulately +reticulates +reticulating +reticulation +reticulations +reticule +reticules +reticulocyte +reticulocytes +reticuloendothelial +reticulum +retie +retied +reties +retiform +retighten +retightened +retightening +retightens +retile +retiled +retiles +retiling +retime +retimed +retimes +retiming +retina +retinacula +retinaculum +retinae +retinal +retinals +retinas +retine +retinene +retinenes +retines +retinite +retinites +retinitides +retinitis +retinoblastoma +retinoblastomas +retinoblastomata +retinoid +retinoids +retinol +retinols +retinopathies +retinopathy +retinoscopies +retinoscopy +retinotectal +retint +retinted +retinting +retints +retinue +retinued +retinues +retinula +retinulae +retinular +retinulas +retirant +retirants +retire +retired +retiredly +retiredness +retirednesses +retiree +retirees +retirement +retirements +retirer +retirers +retires +retiring +retiringly +retiringness +retiringnesses +retitle +retitled +retitles +retitling +retold +retook +retool +retooled +retooling +retools +retore +retorn +retort +retorted +retorter +retorters +retorting +retorts +retouch +retouched +retoucher +retouchers +retouches +retouching +retrace +retraced +retraces +retracing +retrack +retracked +retracking +retracks +retract +retractable +retracted +retractile +retractilities +retractility +retracting +retraction +retractions +retractor +retractors +retracts +retrain +retrainable +retrained +retraining +retrains +retral +retrally +retransfer +retransferred +retransferring +retransfers +retransform +retransformation +retransformations +retransformed +retransforming +retransforms +retranslate +retranslated +retranslates +retranslating +retranslation +retranslations +retransmission +retransmissions +retransmit +retransmits +retransmitted +retransmitting +retread +retreaded +retreading +retreads +retreat +retreatant +retreatants +retreated +retreater +retreaters +retreating +retreats +retrench +retrenched +retrenches +retrenching +retrenchment +retrenchments +retrial +retrials +retribution +retributions +retributive +retributively +retributory +retried +retries +retrievabilities +retrievability +retrievable +retrieval +retrievals +retrieve +retrieved +retriever +retrievers +retrieves +retrieving +retrim +retrimmed +retrimming +retrims +retro +retroact +retroacted +retroacting +retroaction +retroactions +retroactive +retroactively +retroactivities +retroactivity +retroacts +retrocede +retroceded +retrocedes +retroceding +retrocession +retrocessions +retrodict +retrodicted +retrodicting +retrodiction +retrodictions +retrodictive +retrodicts +retrofire +retrofired +retrofires +retrofiring +retrofit +retrofits +retrofitted +retrofitting +retroflection +retroflections +retroflex +retroflexion +retroflexions +retrogradation +retrogradations +retrograde +retrograded +retrogradely +retrogrades +retrograding +retrogress +retrogressed +retrogresses +retrogressing +retrogression +retrogressions +retrogressive +retrogressively +retropack +retropacks +retroperitoneal +retroperitoneally +retroreflection +retroreflections +retroreflective +retroreflector +retroreflectors +retrorse +retros +retrospect +retrospected +retrospecting +retrospection +retrospections +retrospective +retrospectively +retrospectives +retrospects +retrousse +retroversion +retroversions +retroviral +retrovirus +retroviruses +retry +retrying +rets +retsina +retsinas +retted +retting +retune +retuned +retunes +retuning +return +returnable +returnables +returned +returnee +returnees +returner +returners +returning +returns +retuse +retwist +retwisted +retwisting +retwists +retying +retype +retyped +retypes +retyping +reunification +reunifications +reunified +reunifies +reunify +reunifying +reunion +reunionist +reunionistic +reunionists +reunions +reunite +reunited +reuniter +reuniters +reunites +reuniting +reupholster +reupholstered +reupholstering +reupholsters +reusabilities +reusability +reusable +reuse +reused +reuses +reusing +reutilization +reutilizations +reutilize +reutilized +reutilizes +reutilizing +reutter +reuttered +reuttering +reutters +rev +revaccinate +revaccinated +revaccinates +revaccinating +revaccination +revaccinations +revalidate +revalidated +revalidates +revalidating +revalidation +revalidations +revalorization +revalorizations +revalorize +revalorized +revalorizes +revalorizing +revaluate +revaluated +revaluates +revaluating +revaluation +revaluations +revalue +revalued +revalues +revaluing +revamp +revamped +revamper +revampers +revamping +revamps +revanche +revanches +revanchism +revanchisms +revanchist +revanchists +revascularization +revascularizations +reveal +revealable +revealed +revealer +revealers +revealing +revealingly +revealment +revealments +reveals +revegetate +revegetated +revegetates +revegetating +revegetation +revegetations +revehent +reveille +reveilles +revel +revelation +revelations +revelator +revelators +revelatory +reveled +reveler +revelers +reveling +revelled +reveller +revellers +revelling +revelries +revelry +revels +revenant +revenants +revenge +revenged +revengeful +revengefully +revengefulness +revengefulnesses +revenger +revengers +revenges +revenging +revenual +revenue +revenued +revenuer +revenuers +revenues +reverb +reverbed +reverberant +reverberantly +reverberate +reverberated +reverberates +reverberating +reverberation +reverberations +reverberative +reverberatory +reverbing +reverbs +revere +revered +reverence +reverenced +reverencer +reverencers +reverences +reverencing +reverend +reverends +reverent +reverential +reverentially +reverently +reverer +reverers +reveres +reverie +reveries +reverified +reverifies +reverify +reverifying +revering +revers +reversal +reversals +reverse +reversed +reversely +reverser +reversers +reverses +reversibilities +reversibility +reversible +reversibles +reversibly +reversing +reversion +reversional +reversionary +reversioner +reversioners +reversions +reverso +reversos +revert +revertant +revertants +reverted +reverter +reverters +revertible +reverting +reverts +revery +revest +revested +revesting +revests +revet +revetment +revetments +revets +revetted +revetting +revictual +revictualed +revictualing +revictualled +revictualling +revictuals +review +reviewable +reviewal +reviewals +reviewed +reviewer +reviewers +reviewing +reviews +revile +reviled +revilement +revilements +reviler +revilers +reviles +reviling +revisable +revisal +revisals +revise +revised +reviser +revisers +revises +revising +revision +revisionary +revisionism +revisionisms +revisionist +revisionists +revisions +revisit +revisited +revisiting +revisits +revisor +revisors +revisory +revisualization +revisualizations +revitalise +revitalised +revitalises +revitalising +revitalization +revitalizations +revitalize +revitalized +revitalizes +revitalizing +revivable +revival +revivalism +revivalisms +revivalist +revivalistic +revivalists +revivals +revive +revived +reviver +revivers +revives +revivification +revivifications +revivified +revivifies +revivify +revivifying +reviving +reviviscence +reviviscences +reviviscent +revocable +revocation +revocations +revoice +revoiced +revoices +revoicing +revokable +revoke +revoked +revoker +revokers +revokes +revoking +revolt +revolted +revolter +revolters +revolting +revoltingly +revolts +revolute +revolution +revolutionaries +revolutionarily +revolutionariness +revolutionarinesses +revolutionary +revolutionise +revolutionised +revolutionises +revolutionising +revolutionist +revolutionists +revolutionize +revolutionized +revolutionizer +revolutionizers +revolutionizes +revolutionizing +revolutions +revolvable +revolve +revolved +revolver +revolvers +revolves +revolving +revote +revoted +revotes +revoting +revs +revue +revues +revuist +revuists +revulsed +revulsion +revulsions +revulsive +revved +revving +rewake +rewaked +rewaken +rewakened +rewakening +rewakens +rewakes +rewaking +rewan +reward +rewardable +rewarded +rewarder +rewarders +rewarding +rewardingly +rewards +rewarm +rewarmed +rewarming +rewarms +rewash +rewashed +rewashes +rewashing +rewax +rewaxed +rewaxes +rewaxing +reweave +reweaved +reweaves +reweaving +rewed +rewedded +rewedding +reweds +reweigh +reweighed +reweighing +reweighs +reweld +rewelded +rewelding +rewelds +rewet +rewets +rewetted +rewetting +rewiden +rewidened +rewidening +rewidens +rewin +rewind +rewinded +rewinder +rewinders +rewinding +rewinds +rewinning +rewins +rewire +rewired +rewires +rewiring +rewoke +rewoken +rewon +reword +reworded +rewording +rewords +rework +reworked +reworking +reworks +rewound +rewove +rewoven +rewrap +rewrapped +rewrapping +rewraps +rewrapt +rewrite +rewriter +rewriters +rewrites +rewriting +rewritten +rewrote +rewrought +rex +rexes +reynard +reynards +rezone +rezoned +rezones +rezoning +rhabdocoele +rhabdocoeles +rhabdom +rhabdomancer +rhabdomancers +rhabdomancies +rhabdomancy +rhabdome +rhabdomere +rhabdomeres +rhabdomes +rhabdoms +rhabdomyosarcoma +rhabdomyosarcomas +rhabdomyosarcomata +rhabdovirus +rhabdoviruses +rhachides +rhachis +rhachises +rhadamanthine +rhamnose +rhamnoses +rhamnus +rhamnuses +rhaphae +rhaphe +rhaphes +rhapsode +rhapsodes +rhapsodic +rhapsodical +rhapsodically +rhapsodies +rhapsodist +rhapsodists +rhapsodize +rhapsodized +rhapsodizes +rhapsodizing +rhapsody +rhatanies +rhatany +rhea +rheas +rhebok +rheboks +rhematic +rhenium +rheniums +rheobase +rheobases +rheological +rheologically +rheologies +rheologist +rheologists +rheology +rheometer +rheometers +rheophil +rheostat +rheostatic +rheostats +rhesus +rhesuses +rhetor +rhetoric +rhetorical +rhetorically +rhetorician +rhetoricians +rhetorics +rhetors +rheum +rheumatic +rheumatically +rheumatics +rheumatism +rheumatisms +rheumatiz +rheumatizes +rheumatoid +rheumatologies +rheumatologist +rheumatologists +rheumatology +rheumic +rheumier +rheumiest +rheums +rheumy +rhinal +rhinencephala +rhinencephalic +rhinencephalon +rhinestone +rhinestoned +rhinestones +rhinitides +rhinitis +rhino +rhinoceri +rhinoceros +rhinoceroses +rhinoplasties +rhinoplasty +rhinos +rhinoscopies +rhinoscopy +rhinovirus +rhinoviruses +rhizobia +rhizobial +rhizobium +rhizoctonia +rhizoctonias +rhizoid +rhizoidal +rhizoids +rhizoma +rhizomata +rhizomatous +rhizome +rhizomes +rhizomic +rhizopi +rhizoplane +rhizoplanes +rhizopod +rhizopods +rhizopus +rhizopuses +rhizosphere +rhizospheres +rhizotomies +rhizotomy +rho +rhodamin +rhodamine +rhodamines +rhodamins +rhodic +rhodium +rhodiums +rhodochrosite +rhodochrosites +rhododendron +rhododendrons +rhodolite +rhodolites +rhodomontade +rhodomontades +rhodonite +rhodonites +rhodopsin +rhodopsins +rhodora +rhodoras +rhomb +rhombencephala +rhombencephalon +rhombi +rhombic +rhombohedra +rhombohedral +rhombohedron +rhombohedrons +rhomboid +rhomboidal +rhomboidei +rhomboideus +rhomboids +rhombs +rhombus +rhombuses +rhonchal +rhonchi +rhonchus +rhos +rhubarb +rhubarbs +rhumb +rhumba +rhumbaed +rhumbaing +rhumbas +rhumbs +rhus +rhuses +rhyme +rhymed +rhymeless +rhymer +rhymers +rhymes +rhymester +rhymesters +rhyming +rhynchocephalian +rhynchocephalians +rhyolite +rhyolites +rhyolitic +rhyta +rhythm +rhythmic +rhythmical +rhythmically +rhythmicities +rhythmicity +rhythmics +rhythmist +rhythmists +rhythmization +rhythmizations +rhythmize +rhythmized +rhythmizes +rhythmizing +rhythms +rhytidome +rhytidomes +rhyton +rhytons +ria +rial +rials +rialto +rialtos +riant +riantly +rias +riata +riatas +rib +ribald +ribaldly +ribaldries +ribaldry +ribalds +riband +ribands +ribavirin +ribavirins +ribband +ribbands +ribbed +ribber +ribbers +ribbier +ribbiest +ribbing +ribbings +ribbon +ribboned +ribbonfish +ribbonfishes +ribboning +ribbonlike +ribbons +ribbony +ribby +ribes +ribgrass +ribgrasses +ribier +ribiers +ribless +riblet +riblets +riblike +riboflavin +riboflavins +ribonuclease +ribonucleases +ribonucleoprotein +ribonucleoproteins +ribonucleoside +ribonucleosides +ribonucleotide +ribonucleotides +ribose +riboses +ribosomal +ribosome +ribosomes +ribs +ribwort +ribworts +rice +ricebird +ricebirds +riced +ricer +ricercar +ricercare +ricercari +ricercars +ricers +rices +rich +richen +richened +richening +richens +richer +riches +richest +richly +richness +richnesses +richweed +richweeds +ricin +ricing +ricins +ricinus +ricinuses +rick +ricked +ricketier +ricketiest +rickets +rickettsia +rickettsiae +rickettsial +rickettsias +rickety +rickey +rickeys +ricking +rickrack +rickracks +ricks +ricksha +rickshas +rickshaw +rickshaws +ricochet +ricocheted +ricocheting +ricochets +ricochetted +ricochetting +ricotta +ricottas +ricrac +ricracs +rictal +rictus +rictuses +rid +ridable +riddance +riddances +ridded +ridden +ridder +ridders +ridding +riddle +riddled +riddler +riddlers +riddles +riddling +ride +rideable +rident +rider +riderless +riders +ridership +riderships +rides +ridge +ridged +ridgel +ridgeline +ridgelines +ridgeling +ridgelings +ridgels +ridgepole +ridgepoles +ridges +ridgier +ridgiest +ridgil +ridgils +ridging +ridgling +ridglings +ridgy +ridicule +ridiculed +ridiculer +ridiculers +ridicules +ridiculing +ridiculous +ridiculously +ridiculousness +ridiculousnesses +riding +ridings +ridley +ridleys +ridotto +ridottos +rids +riel +riels +riesling +rieslings +riever +rievers +rif +rifampicin +rifampicins +rifampin +rifampins +rife +rifely +rifeness +rifenesses +rifer +rifest +riff +riffed +riffing +riffle +riffled +riffler +rifflers +riffles +riffling +riffraff +riffraffs +riffs +rifle +riflebird +riflebirds +rifled +rifleman +riflemen +rifler +rifleries +riflers +riflery +rifles +rifling +riflings +rifs +rift +rifted +rifting +riftless +rifts +rig +rigadoon +rigadoons +rigamarole +rigamaroles +rigatoni +rigatonis +rigaudon +rigaudons +rigged +rigger +riggers +rigging +riggings +right +righted +righteous +righteously +righteousness +righteousnesses +righter +righters +rightest +rightful +rightfully +rightfulness +rightfulnesses +righties +righting +rightism +rightisms +rightist +rightists +rightly +rightmost +rightness +rightnesses +righto +rights +rightward +righty +rigid +rigidification +rigidifications +rigidified +rigidifies +rigidify +rigidifying +rigidities +rigidity +rigidly +rigidness +rigidnesses +rigmarole +rigmaroles +rigor +rigorism +rigorisms +rigorist +rigoristic +rigorists +rigorous +rigorously +rigorousness +rigorousnesses +rigors +rigour +rigours +rigs +rijsttafel +rijsttafels +rikisha +rikishas +rikshaw +rikshaws +rile +riled +riles +riley +rilievi +rilievo +riling +rill +rille +rilled +rilles +rillet +rillets +rillettes +rilling +rills +rim +rime +rimed +rimer +rimers +rimes +rimester +rimesters +rimfire +rimfires +rimier +rimiest +riminess +riminesses +riming +rimland +rimlands +rimless +rimmed +rimmer +rimmers +rimming +rimose +rimosely +rimosities +rimosity +rimous +rimple +rimpled +rimples +rimpling +rimrock +rimrocks +rims +rimy +rin +rind +rinded +rinderpest +rinderpests +rinds +ring +ringbark +ringbarked +ringbarking +ringbarks +ringbolt +ringbolts +ringbone +ringbones +ringdove +ringdoves +ringed +ringent +ringer +ringers +ringgit +ringgits +ringhals +ringhalses +ringing +ringingly +ringleader +ringleaders +ringlet +ringlets +ringlike +ringmaster +ringmasters +ringneck +ringnecks +rings +ringside +ringsides +ringstraked +ringtail +ringtails +ringtaw +ringtaws +ringtoss +ringtosses +ringworm +ringworms +rink +rinks +rinning +rins +rinsable +rinse +rinsed +rinser +rinsers +rinses +rinsible +rinsing +rinsings +rioja +riojas +riot +rioted +rioter +rioters +rioting +riotous +riotously +riotousness +riotousnesses +riots +rip +riparian +ripcord +ripcords +ripe +riped +ripely +ripen +ripened +ripener +ripeners +ripeness +ripenesses +ripening +ripens +riper +ripes +ripest +ripieni +ripieno +ripienos +riping +ripoff +ripoffs +ripost +riposte +riposted +ripostes +riposting +riposts +rippable +ripped +ripper +rippers +ripping +ripple +rippled +rippler +ripplers +ripples +ripplet +ripplets +ripplier +rippliest +rippling +ripply +riprap +riprapped +riprapping +ripraps +rips +ripsaw +ripsaws +ripsnorter +ripsnorters +ripsnorting +ripstop +ripstops +riptide +riptides +rise +risen +riser +risers +rises +rishi +rishis +risibilities +risibility +risible +risibles +risibly +rising +risings +risk +risked +risker +riskers +riskier +riskiest +riskily +riskiness +riskinesses +risking +riskless +risks +risky +risorgimento +risorgimentos +risotto +risottos +risque +rissole +rissoles +risus +risuses +ritard +ritardando +ritardandos +ritards +rite +rites +ritornelli +ritornello +ritornellos +ritter +ritters +ritual +ritualism +ritualisms +ritualist +ritualistic +ritualistically +ritualists +ritualization +ritualizations +ritualize +ritualized +ritualizes +ritualizing +ritually +rituals +ritz +ritzes +ritzier +ritziest +ritzily +ritziness +ritzinesses +ritzy +rivage +rivages +rival +rivaled +rivaling +rivalled +rivalling +rivalries +rivalrous +rivalry +rivals +rive +rived +riven +river +riverbank +riverbanks +riverbed +riverbeds +riverboat +riverboats +riverfront +riverfronts +riverine +rivers +riverside +riversides +riverward +riverwards +rives +rivet +riveted +riveter +riveters +riveting +rivetingly +rivets +rivetted +rivetting +riviera +rivieras +riviere +rivieres +riving +rivulet +rivulets +rivulose +riyal +riyals +roach +roached +roaches +roaching +road +roadabilities +roadability +roadbed +roadbeds +roadblock +roadblocked +roadblocking +roadblocks +roadeo +roadeos +roadholding +roadholdings +roadhouse +roadhouses +roadie +roadies +roadkill +roadkills +roadless +roadrunner +roadrunners +roads +roadshow +roadshows +roadside +roadsides +roadstead +roadsteads +roadster +roadsters +roadway +roadways +roadwork +roadworks +roadworthiness +roadworthinesses +roadworthy +roam +roamed +roamer +roamers +roaming +roams +roan +roans +roar +roared +roarer +roarers +roaring +roaringly +roarings +roars +roast +roasted +roaster +roasters +roasting +roasts +rob +robalo +robalos +roband +robands +robbed +robber +robberies +robbers +robbery +robbin +robbing +robbins +robe +robed +robes +robin +robing +robins +roble +robles +roborant +roborants +robot +robotic +robotically +robotics +robotism +robotisms +robotization +robotizations +robotize +robotized +robotizes +robotizing +robotries +robotry +robots +robs +robust +robusta +robustas +robuster +robustest +robustious +robustiously +robustiousness +robustiousnesses +robustly +robustness +robustnesses +roc +rocaille +rocailles +rochet +rochets +rock +rockabies +rockabillies +rockabilly +rockaby +rockabye +rockabyes +rockaway +rockaways +rockbound +rocked +rocker +rockeries +rockers +rockery +rocket +rocketed +rocketeer +rocketeers +rocketer +rocketers +rocketing +rocketries +rocketry +rockets +rockfall +rockfalls +rockfish +rockfishes +rockhopper +rockhoppers +rockhound +rockhounding +rockhoundings +rockhounds +rockier +rockiest +rockiness +rockinesses +rocking +rockless +rocklike +rockling +rocklings +rockoon +rockoons +rockrose +rockroses +rocks +rockshaft +rockshafts +rockweed +rockweeds +rockwork +rockworks +rocky +rococo +rococos +rocs +rod +rodded +rodding +rode +rodent +rodenticide +rodenticides +rodents +rodeo +rodeoed +rodeoing +rodeos +rodless +rodlike +rodman +rodmen +rodomontade +rodomontades +rods +rodsman +rodsmen +roe +roebuck +roebucks +roentgen +roentgenogram +roentgenograms +roentgenographic +roentgenographically +roentgenographies +roentgenography +roentgenologic +roentgenological +roentgenologically +roentgenologies +roentgenologist +roentgenologists +roentgenology +roentgens +roes +rogation +rogations +rogatory +roger +rogers +rogue +rogued +rogueing +rogueries +roguery +rogues +roguing +roguish +roguishly +roguishness +roguishnesses +roil +roiled +roilier +roiliest +roiling +roils +roily +roister +roistered +roisterer +roisterers +roistering +roisterous +roisterously +roisters +rolamite +rolamites +role +roles +rolf +rolfed +rolfer +rolfers +rolfing +rolfs +roll +rollaway +rollback +rollbacks +rolled +roller +rollers +rollick +rollicked +rollicking +rollicks +rollicky +rolling +rollings +rollmop +rollmops +rollout +rollouts +rollover +rollovers +rolls +rolltop +rollway +rollways +rom +romaine +romaines +roman +romance +romanced +romancer +romancers +romances +romancing +romanise +romanised +romanises +romanising +romanization +romanizations +romanize +romanized +romanizes +romanizing +romano +romanos +romans +romantic +romantically +romanticise +romanticised +romanticises +romanticising +romanticism +romanticisms +romanticist +romanticists +romanticization +romanticizations +romanticize +romanticized +romanticizes +romanticizing +romantics +romaunt +romaunts +romeldale +romeldales +romeo +romeos +romp +romped +romper +rompers +romping +rompish +romps +roms +rondeau +rondeaux +rondel +rondelet +rondelets +rondelle +rondelles +rondels +rondo +rondos +rondure +rondures +ronion +ronions +ronnel +ronnels +rontgen +rontgens +ronyon +ronyons +rood +roods +roof +roofed +roofer +roofers +roofing +roofings +roofless +rooflike +roofline +rooflines +roofs +rooftop +rooftops +rooftree +rooftrees +rook +rooked +rookeries +rookery +rookie +rookier +rookies +rookiest +rooking +rooks +rooky +room +roomed +roomer +roomers +roomette +roomettes +roomful +roomfuls +roomie +roomier +roomies +roomiest +roomily +roominess +roominesses +rooming +roommate +roommates +rooms +roomy +roorbach +roorbachs +roorback +roorbacks +roose +roosed +rooser +roosers +rooses +roosing +roost +roosted +rooster +roosters +roosting +roosts +root +rootage +rootages +rooted +rootedness +rootednesses +rooter +rooters +roothold +rootholds +rootier +rootiest +rooting +rootless +rootlessness +rootlessnesses +rootlet +rootlets +rootlike +roots +rootstock +rootstocks +rooty +ropable +rope +roped +ropedancer +ropedancers +ropedancing +ropedancings +ropelike +roper +roperies +ropers +ropery +ropes +ropewalk +ropewalker +ropewalkers +ropewalks +ropeway +ropeways +ropey +ropier +ropiest +ropily +ropiness +ropinesses +roping +ropy +roque +roquelaure +roquelaures +roques +roquet +roqueted +roqueting +roquets +rorqual +rorquals +rosaceous +rosaria +rosarian +rosarians +rosaries +rosarium +rosariums +rosary +roscoe +roscoes +rose +roseate +roseately +rosebay +rosebays +rosebud +rosebuds +rosebush +rosebushes +rosed +rosefish +rosefishes +roselike +roselle +roselles +rosemaling +rosemalings +rosemaries +rosemary +roseola +roseolar +roseolas +roseries +roseroot +roseroots +rosery +roses +roseslug +roseslugs +roset +rosets +rosette +rosettes +rosewater +rosewood +rosewoods +rosier +rosiest +rosily +rosin +rosined +rosiness +rosinesses +rosing +rosining +rosinol +rosinols +rosinous +rosins +rosinweed +rosinweeds +rosiny +rosolio +rosolios +rostella +rostellar +rostellum +rostellums +roster +rosters +rostra +rostral +rostrally +rostrate +rostrum +rostrums +rosulate +rosy +rot +rota +rotameter +rotameters +rotaries +rotary +rotas +rotatable +rotate +rotated +rotates +rotating +rotation +rotational +rotations +rotative +rotatively +rotator +rotatores +rotators +rotatory +rotavirus +rotaviruses +rotch +rotche +rotches +rote +rotenone +rotenones +rotes +rotgut +rotguts +roti +rotifer +rotifers +rotiform +rotis +rotisserie +rotisseries +rotl +rotls +roto +rotogravure +rotogravures +rotor +rotorcraft +rotors +rotos +rototill +rototilled +rototiller +rototillers +rototilling +rototills +rots +rotte +rotted +rotten +rottener +rottenest +rottenly +rottenness +rottennesses +rottenstone +rottenstones +rotter +rotters +rottes +rotting +rottweiler +rottweilers +rotund +rotunda +rotundas +rotundities +rotundity +rotundly +rotundness +rotundnesses +roturier +roturiers +rouble +roubles +rouche +rouches +roue +rouen +rouens +roues +rouge +rouged +rouges +rough +roughage +roughages +roughcast +roughcasting +roughcasts +roughdried +roughdries +roughdry +roughdrying +roughed +roughen +roughened +roughening +roughens +rougher +roughers +roughest +roughhew +roughhewed +roughhewing +roughhewn +roughhews +roughhouse +roughhoused +roughhouses +roughhousing +roughing +roughish +roughleg +roughlegs +roughly +roughneck +roughnecks +roughness +roughnesses +roughrider +roughriders +roughs +roughshod +rouging +rouille +rouilles +roulade +roulades +rouleau +rouleaus +rouleaux +roulette +rouletted +roulettes +rouletting +round +roundabout +roundaboutness +roundaboutnesses +roundabouts +rounded +roundedness +roundednesses +roundel +roundelay +roundelays +roundels +rounder +rounders +roundest +roundheaded +roundheadedness +roundheadednesses +roundhouse +roundhouses +rounding +roundish +roundlet +roundlets +roundly +roundness +roundnesses +rounds +roundsman +roundsmen +roundtable +roundtables +roundup +roundups +roundwood +roundwoods +roundworm +roundworms +roup +rouped +roupet +roupier +roupiest +roupily +rouping +roups +roupy +rouse +rouseabout +rouseabouts +roused +rousement +rousements +rouser +rousers +rouses +rousing +rousingly +rousseau +rousseaus +roust +roustabout +roustabouts +rousted +rouster +rousters +rousting +rousts +rout +route +routed +routeman +routemen +router +routers +routes +routeway +routeways +routh +rouths +routine +routinely +routines +routing +routinization +routinizations +routinize +routinized +routinizes +routinizing +routs +roux +rove +roved +roven +rover +rovers +roves +roving +rovingly +rovings +row +rowable +rowan +rowanberries +rowanberry +rowans +rowboat +rowboats +rowdier +rowdies +rowdiest +rowdily +rowdiness +rowdinesses +rowdy +rowdyish +rowdyism +rowdyisms +rowed +rowel +roweled +roweling +rowelled +rowelling +rowels +rowen +rowens +rower +rowers +rowing +rowings +rowlock +rowlocks +rows +rowth +rowths +royal +royalism +royalisms +royalist +royalists +royally +royals +royalties +royalty +royster +roystered +roystering +roysters +rozzer +rozzers +ruana +ruanas +rub +rubaboo +rubaboos +rubace +rubaces +rubaiyat +rubasse +rubasses +rubato +rubatos +rubbaboo +rubbaboos +rubbed +rubber +rubbered +rubbering +rubberized +rubberlike +rubberneck +rubbernecked +rubbernecker +rubberneckers +rubbernecking +rubbernecks +rubbers +rubbery +rubbing +rubbings +rubbish +rubbishes +rubbishy +rubble +rubbled +rubbles +rubblier +rubbliest +rubbling +rubbly +rubdown +rubdowns +rube +rubefacient +rubefacients +rubella +rubellas +rubellite +rubellites +rubeola +rubeolar +rubeolas +rubes +rubicund +rubicundities +rubicundity +rubidic +rubidium +rubidiums +rubied +rubier +rubies +rubiest +rubigo +rubigos +rubious +ruble +rubles +ruboff +ruboffs +rubout +rubouts +rubric +rubrical +rubrically +rubricate +rubricated +rubricates +rubricating +rubrication +rubrications +rubricator +rubricators +rubrics +rubs +rubus +ruby +rubying +rubylike +rubythroat +rubythroats +ruche +ruched +ruches +ruching +ruchings +ruck +rucked +rucking +ruckle +ruckled +ruckles +ruckling +rucks +rucksack +rucksacks +ruckus +ruckuses +ruction +ructions +ructious +rudbeckia +rudbeckias +rudd +rudder +rudderless +rudderpost +rudderposts +rudders +ruddier +ruddiest +ruddily +ruddiness +ruddinesses +ruddle +ruddled +ruddles +ruddling +ruddock +ruddocks +rudds +ruddy +rude +rudely +rudeness +rudenesses +ruder +ruderal +ruderals +rudesbies +rudesby +rudest +rudiment +rudimental +rudimentarily +rudimentariness +rudimentarinesses +rudimentary +rudiments +rue +rued +rueful +ruefully +ruefulness +ruefulnesses +ruer +ruers +rues +rufescent +ruff +ruffe +ruffed +ruffes +ruffian +ruffianism +ruffianisms +ruffianly +ruffians +ruffing +ruffle +ruffled +ruffler +rufflers +ruffles +rufflier +ruffliest +rufflike +ruffling +ruffly +ruffs +rufiyaa +rufous +rug +ruga +rugae +rugal +rugate +rugbies +rugby +rugged +ruggeder +ruggedest +ruggedization +ruggedizations +ruggedize +ruggedized +ruggedizes +ruggedizing +ruggedly +ruggedness +ruggednesses +rugger +ruggers +rugging +ruglike +rugola +rugolas +rugosa +rugosas +rugose +rugosely +rugosities +rugosity +rugous +rugs +rugulose +ruin +ruinable +ruinate +ruinated +ruinates +ruinating +ruination +ruinations +ruined +ruiner +ruiners +ruing +ruining +ruinous +ruinously +ruinousness +ruinousnesses +ruins +rulable +rule +ruled +ruleless +ruler +rulers +rulership +rulerships +rules +rulier +ruliest +ruling +rulings +ruly +rum +rumaki +rumakis +rumba +rumbaed +rumbaing +rumbas +rumble +rumbled +rumbler +rumblers +rumbles +rumbling +rumblings +rumbly +rumbustious +rumbustiously +rumbustiousness +rumbustiousnesses +rumen +rumens +rumina +ruminal +ruminant +ruminantly +ruminants +ruminate +ruminated +ruminates +ruminating +rumination +ruminations +ruminative +ruminatively +ruminator +ruminators +rummage +rummaged +rummager +rummagers +rummages +rummaging +rummer +rummers +rummest +rummier +rummies +rummiest +rummy +rumor +rumored +rumoring +rumormonger +rumormongering +rumormongerings +rumormongers +rumors +rumour +rumoured +rumouring +rumours +rump +rumple +rumpled +rumples +rumpless +rumplier +rumpliest +rumpling +rumply +rumps +rumpus +rumpuses +rumrunner +rumrunners +rums +run +runabout +runabouts +runagate +runagates +runaround +runarounds +runaway +runaways +runback +runbacks +runcinate +rundle +rundles +rundlet +rundlets +rundown +rundowns +rune +runelike +runes +rung +rungless +rungs +runic +runkle +runkled +runkles +runkling +runless +runlet +runlets +runnel +runnels +runner +runners +runnier +runniest +running +runnings +runny +runoff +runoffs +runout +runouts +runover +runovers +runround +runrounds +runs +runt +runtier +runtiest +runtiness +runtinesses +runtish +runts +runty +runway +runways +rupee +rupees +rupiah +rupiahs +rupture +ruptured +ruptures +rupturing +rural +ruralise +ruralised +ruralises +ruralising +ruralism +ruralisms +ruralist +ruralists +ruralite +ruralites +ruralities +rurality +ruralize +ruralized +ruralizes +ruralizing +rurally +rurban +ruse +ruses +rush +rushed +rushee +rushees +rusher +rushers +rushes +rushier +rushiest +rushing +rushings +rushlight +rushlights +rushlike +rushy +rusine +rusk +rusks +russet +russeting +russetings +russets +russetting +russettings +russety +russified +russifies +russify +russifying +rust +rustable +rusted +rustic +rustical +rustically +rusticals +rusticate +rusticated +rusticates +rusticating +rustication +rustications +rusticator +rusticators +rusticities +rusticity +rusticly +rustics +rustier +rustiest +rustily +rustiness +rustinesses +rusting +rustle +rustled +rustler +rustlers +rustles +rustless +rustling +rustproof +rustproofed +rustproofing +rustproofs +rusts +rusty +rut +rutabaga +rutabagas +ruth +ruthenic +ruthenium +rutheniums +rutherfordium +rutherfordiums +ruthful +ruthfully +ruthfulness +ruthfulnesses +ruthless +ruthlessly +ruthlessness +ruthlessnesses +ruths +rutilant +rutile +rutiles +rutin +rutins +ruts +rutted +ruttier +ruttiest +ruttily +rutting +ruttish +ruttishly +ruttishness +ruttishnesses +rutty +rya +ryas +rye +ryegrass +ryegrasses +ryes +ryke +ryked +rykes +ryking +rynd +rynds +ryokan +ryokans +ryot +ryots +sab +sabadilla +sabadillas +sabaton +sabatons +sabayon +sabayons +sabbat +sabbath +sabbaths +sabbatic +sabbatical +sabbaticals +sabbatics +sabbats +sabbed +sabbing +sabe +sabed +sabeing +saber +sabered +sabering +sabermetrician +sabermetricians +sabermetrics +sabers +sabes +sabin +sabine +sabines +sabins +sabir +sabirs +sable +sablefish +sablefishes +sables +sabot +sabotage +sabotaged +sabotages +sabotaging +saboteur +saboteurs +sabots +sabra +sabras +sabre +sabred +sabres +sabring +sabs +sabulose +sabulous +sac +sacahuista +sacahuistas +sacahuiste +sacahuistes +sacaton +sacatons +sacbut +sacbuts +saccade +saccades +saccadic +saccate +saccharase +saccharases +saccharide +saccharides +saccharification +saccharifications +saccharified +saccharifies +saccharify +saccharifying +saccharimeter +saccharimeters +saccharin +saccharine +saccharinities +saccharinity +saccharins +saccharoidal +saccharometer +saccharometers +saccharomyces +saccular +sacculate +sacculated +sacculation +sacculations +saccule +saccules +sacculi +sacculus +sacerdotal +sacerdotalism +sacerdotalisms +sacerdotalist +sacerdotalists +sacerdotally +sachem +sachemic +sachems +sachet +sacheted +sachets +sack +sackbut +sackbuts +sackcloth +sackcloths +sacked +sacker +sackers +sackful +sackfuls +sacking +sackings +sacklike +sacks +sacksful +saclike +sacque +sacques +sacra +sacral +sacrals +sacrament +sacramental +sacramentalism +sacramentalisms +sacramentalist +sacramentalists +sacramentally +sacramentals +sacraments +sacraria +sacrarium +sacred +sacredly +sacredness +sacrednesses +sacrifice +sacrificed +sacrificer +sacrificers +sacrifices +sacrificial +sacrificially +sacrificing +sacrilege +sacrileges +sacrilegious +sacrilegiously +sacrilegiousness +sacrilegiousnesses +sacring +sacrings +sacrist +sacristan +sacristans +sacristies +sacrists +sacristy +sacroiliac +sacroiliacs +sacrosanct +sacrosanctities +sacrosanctity +sacrum +sacrums +sacs +sad +sadden +saddened +saddening +saddens +sadder +saddest +saddhu +saddhus +saddle +saddlebag +saddlebags +saddlebow +saddlebows +saddlebred +saddlebreds +saddlecloth +saddlecloths +saddled +saddleless +saddler +saddleries +saddlers +saddlery +saddles +saddletree +saddletrees +saddling +sade +sades +sadhe +sadhes +sadhu +sadhus +sadi +sadiron +sadirons +sadis +sadism +sadisms +sadist +sadistic +sadistically +sadists +sadly +sadness +sadnesses +sadomasochism +sadomasochisms +sadomasochist +sadomasochistic +sadomasochists +sae +safari +safaried +safariing +safaris +safe +safecracker +safecrackers +safecracking +safecrackings +safeguard +safeguarded +safeguarding +safeguards +safekeeping +safekeepings +safelight +safelights +safely +safeness +safenesses +safer +safes +safest +safetied +safeties +safety +safetying +safetyman +safetymen +safflower +safflowers +saffron +saffrons +safranin +safranine +safranines +safranins +safrol +safrole +safroles +safrols +sag +saga +sagacious +sagaciously +sagaciousness +sagaciousnesses +sagacities +sagacity +sagaman +sagamen +sagamore +sagamores +saganash +saganashes +sagas +sagbut +sagbuts +sage +sagebrush +sagebrushes +sagely +sageness +sagenesses +sager +sages +sagest +saggar +saggard +saggards +saggared +saggaring +saggars +sagged +sagger +saggered +saggering +saggers +saggier +saggiest +sagging +saggy +sagier +sagiest +sagittal +sagittally +sagittate +sago +sagos +sags +saguaro +saguaros +sagum +sagy +sahib +sahibs +sahiwal +sahiwals +sahuaro +sahuaros +saice +saices +said +saids +saiga +saigas +sail +sailable +sailboard +sailboarding +sailboardings +sailboards +sailboat +sailboater +sailboaters +sailboating +sailboatings +sailboats +sailcloth +sailcloths +sailed +sailer +sailers +sailfish +sailfishes +sailing +sailings +sailor +sailorly +sailors +sailplane +sailplaned +sailplaner +sailplaners +sailplanes +sailplaning +sails +saimin +saimins +sain +sained +sainfoin +sainfoins +saining +sains +saint +saintdom +saintdoms +sainted +sainthood +sainthoods +sainting +saintlier +saintliest +saintlike +saintliness +saintlinesses +saintly +saints +saintship +saintships +saith +saithe +saiyid +saiyids +sajou +sajous +sake +saker +sakers +sakes +saki +sakis +sal +salaam +salaamed +salaaming +salaams +salabilities +salability +salable +salably +salacious +salaciously +salaciousness +salaciousnesses +salacities +salacity +salad +saladang +saladangs +salads +salal +salals +salamander +salamanders +salamandrine +salami +salamis +salariat +salariats +salaried +salaries +salary +salarying +salaryman +salarymen +salchow +salchows +sale +saleable +saleably +salep +saleps +saleratus +saleratuses +saleroom +salerooms +sales +salesclerk +salesclerks +salesgirl +salesgirls +salesladies +saleslady +salesman +salesmanship +salesmanships +salesmen +salespeople +salesperson +salespersons +salesroom +salesrooms +saleswoman +saleswomen +salic +salicin +salicine +salicines +salicins +salicylate +salicylates +salience +saliences +saliencies +saliency +salient +saliently +salients +salified +salifies +salify +salifying +salina +salinas +saline +salines +salinities +salinity +salinization +salinizations +salinize +salinized +salinizes +salinizing +salinometer +salinometers +saliva +salivary +salivas +salivate +salivated +salivates +salivating +salivation +salivations +salivator +salivators +sall +sallet +sallets +sallied +sallier +salliers +sallies +sallow +sallowed +sallower +sallowest +sallowing +sallowish +sallowly +sallowness +sallownesses +sallows +sallowy +sally +sallying +salmagundi +salmagundis +salmi +salmis +salmon +salmonberries +salmonberry +salmonella +salmonellae +salmonellas +salmonelloses +salmonellosis +salmonid +salmonids +salmonoid +salmonoids +salmons +salol +salols +salometer +salometers +salon +salons +saloon +saloons +saloop +saloops +salp +salpa +salpae +salpas +salpian +salpians +salpid +salpids +salpiglosses +salpiglossis +salpiglossises +salpinges +salpingites +salpingitides +salpingitis +salpingitises +salpinx +salps +sals +salsa +salsas +salsifies +salsify +salsilla +salsillas +salt +saltant +saltarello +saltarellos +saltation +saltations +saltatorial +saltatory +saltbox +saltboxes +saltbush +saltbushes +saltcellar +saltcellars +salted +salter +saltern +salterns +salters +saltest +saltie +saltier +saltiers +salties +saltiest +saltily +saltimbocca +saltimboccas +saltine +saltines +saltiness +saltinesses +salting +saltings +saltire +saltires +saltish +saltless +saltlike +saltness +saltnesses +saltpan +saltpans +saltpeter +saltpeters +salts +saltshaker +saltshakers +saltwater +saltwork +saltworks +saltwort +saltworts +salty +salubrious +salubriously +salubriousness +salubriousnesses +salubrities +salubrity +saluki +salukis +salutarily +salutariness +salutarinesses +salutary +salutation +salutational +salutations +salutatorian +salutatorians +salutatories +salutatory +salute +saluted +saluter +saluters +salutes +salutiferous +saluting +salvable +salvably +salvage +salvageabilities +salvageability +salvageable +salvaged +salvagee +salvagees +salvager +salvagers +salvages +salvaging +salvarsan +salvarsans +salvation +salvational +salvationism +salvationisms +salvationist +salvations +salve +salved +salver +salverform +salvers +salves +salvia +salvias +salvific +salving +salvo +salvoed +salvoes +salvoing +salvor +salvors +salvos +samara +samaras +samaritan +samaritans +samarium +samariums +samarskite +samarskites +samba +sambaed +sambaing +sambar +sambars +sambas +sambhar +sambhars +sambhur +sambhurs +sambo +sambos +sambuca +sambucas +sambuke +sambukes +sambur +samburs +same +samech +samechs +samek +samekh +samekhs +sameks +sameness +samenesses +samiel +samiels +samisen +samisens +samite +samites +samizdat +samizdats +samlet +samlets +samosa +samosas +samovar +samovars +samp +sampan +sampans +samphire +samphires +sample +sampled +sampler +samplers +samples +sampling +samplings +samps +samsara +samsaras +samshu +samshus +samurai +samurais +sanative +sanatoria +sanatorium +sanatoriums +sanbenito +sanbenitos +sancta +sanctification +sanctifications +sanctified +sanctifier +sanctifiers +sanctifies +sanctify +sanctifying +sanctimonies +sanctimonious +sanctimoniously +sanctimoniousness +sanctimoniousnesses +sanctimony +sanction +sanctionable +sanctioned +sanctioning +sanctions +sanctities +sanctity +sanctuaries +sanctuary +sanctum +sanctums +sand +sandal +sandaled +sandaling +sandalled +sandalling +sandals +sandalwood +sandalwoods +sandarac +sandaracs +sandbag +sandbagged +sandbagger +sandbaggers +sandbagging +sandbags +sandbank +sandbanks +sandbar +sandbars +sandblast +sandblasted +sandblaster +sandblasters +sandblasting +sandblasts +sandbox +sandboxes +sandbur +sandburr +sandburrs +sandburs +sanddab +sanddabs +sanded +sander +sanderling +sanderlings +sanders +sandfish +sandfishes +sandflies +sandfly +sandglass +sandglasses +sandgrouse +sandgrouses +sandhi +sandhis +sandhog +sandhogs +sandier +sandiest +sandiness +sandinesses +sanding +sandlike +sandling +sandlings +sandlot +sandlots +sandlotter +sandlotters +sandman +sandmen +sandpainting +sandpaintings +sandpaper +sandpapered +sandpapering +sandpapers +sandpapery +sandpeep +sandpeeps +sandpile +sandpiles +sandpiper +sandpipers +sandpit +sandpits +sands +sandshoe +sandshoes +sandsoap +sandsoaps +sandspur +sandspurs +sandstone +sandstones +sandstorm +sandstorms +sandwich +sandwiched +sandwiches +sandwiching +sandworm +sandworms +sandwort +sandworts +sandy +sane +saned +sanely +saneness +sanenesses +saner +sanes +sanest +sang +sanga +sangar +sangaree +sangarees +sangars +sangas +sanger +sangers +sangfroid +sangfroids +sangh +sanghs +sangria +sangrias +sanguinaria +sanguinarias +sanguinarily +sanguinary +sanguine +sanguinely +sanguineness +sanguinenesses +sanguineous +sanguines +sanguinities +sanguinity +sanicle +sanicles +sanies +saning +sanious +sanitaria +sanitarian +sanitarians +sanitaries +sanitarily +sanitarium +sanitariums +sanitary +sanitate +sanitated +sanitates +sanitating +sanitation +sanitations +sanities +sanitise +sanitised +sanitises +sanitising +sanitization +sanitizations +sanitize +sanitized +sanitizes +sanitizing +sanitoria +sanitorium +sanitoriums +sanity +sanjak +sanjaks +sank +sannop +sannops +sannup +sannups +sannyasi +sannyasin +sannyasins +sannyasis +sans +sansar +sansars +sansculotte +sansculottes +sansculottic +sansculottish +sansculottism +sansculottisms +sansei +sanseis +sanserif +sanserifs +sansevieria +sansevierias +santalic +santalol +santalols +santimi +santims +santir +santirs +santo +santol +santolina +santolinas +santols +santonin +santonins +santos +santour +santours +santur +santurs +sap +sapajou +sapajous +saphead +sapheaded +sapheads +saphena +saphenae +saphenous +sapid +sapidities +sapidity +sapience +sapiences +sapiencies +sapiency +sapiens +sapient +sapiently +sapless +saplessness +saplessnesses +sapling +saplings +sapodilla +sapodillas +sapogenin +sapogenins +saponaceous +saponaceousness +saponaceousnesses +saponifiable +saponification +saponifications +saponified +saponifier +saponifiers +saponifies +saponify +saponifying +saponin +saponine +saponines +saponins +saponite +saponites +sapor +saporous +sapors +sapota +sapotas +sapote +sapotes +sapour +sapours +sapped +sapper +sappers +sapphic +sapphics +sapphire +sapphires +sapphirine +sapphism +sapphisms +sapphist +sapphists +sappier +sappiest +sappily +sappiness +sappinesses +sapping +sappy +sapremia +sapremias +sapremic +saprobe +saprobes +saprobic +saprogenic +saprogenicities +saprogenicity +saprolite +saprolites +sapropel +sapropels +saprophagous +saprophyte +saprophytes +saprophytic +saprophytically +saprozoic +saps +sapsago +sapsagos +sapsucker +sapsuckers +sapwood +sapwoods +saraband +sarabande +sarabandes +sarabands +saran +sarans +sarape +sarapes +sarcasm +sarcasms +sarcastic +sarcastically +sarcenet +sarcenets +sarcoid +sarcoidoses +sarcoidosis +sarcoids +sarcolemma +sarcolemmal +sarcolemmas +sarcoma +sarcomas +sarcomata +sarcomatoses +sarcomatosis +sarcomatous +sarcomere +sarcomeres +sarcophagi +sarcophagus +sarcophaguses +sarcoplasm +sarcoplasmic +sarcoplasms +sarcosomal +sarcosome +sarcosomes +sarcous +sard +sardana +sardanas +sardar +sardars +sardine +sardines +sardius +sardiuses +sardonic +sardonically +sardonicism +sardonicisms +sardonyx +sardonyxes +sards +saree +sarees +sargasso +sargassos +sargassum +sargassums +sarge +sarges +sari +sarin +sarins +saris +sark +sarkier +sarkiest +sarks +sarky +sarment +sarmenta +sarments +sarmentum +sarod +sarode +sarodes +sarodist +sarodists +sarods +sarong +sarongs +saros +saroses +sarracenia +sarracenias +sarsaparilla +sarsaparillas +sarsar +sarsars +sarsen +sarsenet +sarsenets +sarsens +sartor +sartorial +sartorially +sartorii +sartorius +sartors +sash +sashay +sashayed +sashaying +sashays +sashed +sashes +sashimi +sashimis +sashing +sasin +sasins +saskatoon +saskatoons +sass +sassabies +sassaby +sassafras +sassafrases +sassed +sasses +sassier +sassies +sassiest +sassily +sassing +sasswood +sasswoods +sassy +sastruga +sastrugi +sat +satang +satangs +satanic +satanically +satanism +satanisms +satanist +satanists +satara +sataras +satay +satays +satchel +satchelful +satchelfuls +satchels +satchelsful +sate +sated +sateen +sateens +satellite +satellites +satem +sates +sati +satiable +satiably +satiate +satiated +satiates +satiating +satiation +satiations +satieties +satiety +satin +satinet +satinets +sating +satinpod +satinpods +satins +satinwood +satinwoods +satiny +satire +satires +satiric +satirical +satirically +satirise +satirised +satirises +satirising +satirist +satirists +satirizable +satirize +satirized +satirizes +satirizing +satis +satisfaction +satisfactions +satisfactorily +satisfactoriness +satisfactorinesses +satisfactory +satisfiable +satisfied +satisfies +satisfy +satisfying +satisfyingly +satori +satoris +satrap +satrapies +satraps +satrapy +satsuma +satsumas +saturable +saturant +saturants +saturate +saturated +saturates +saturating +saturation +saturations +saturator +saturators +saturnalia +saturnalian +saturnalianly +saturnalias +saturniid +saturniids +saturnine +saturnism +saturnisms +satyagraha +satyagrahas +satyr +satyriases +satyriasis +satyric +satyrid +satyrids +satyrs +sau +sauce +sauceboat +sauceboats +saucebox +sauceboxes +sauced +saucepan +saucepans +saucer +saucerlike +saucers +sauces +sauch +sauchs +saucier +sauciest +saucily +sauciness +saucinesses +saucing +saucy +sauerbraten +sauerbratens +sauerkraut +sauerkrauts +sauger +saugers +saugh +saughs +saughy +saul +sauls +sault +saults +sauna +saunas +saunter +sauntered +saunterer +saunterers +sauntering +saunters +saurel +saurels +saurian +saurians +sauries +saurischian +saurischians +sauropod +sauropods +saury +sausage +sausages +saute +sauted +sauteed +sauteing +sauterne +sauternes +sautes +sautoir +sautoire +sautoires +sautoirs +savable +savage +savaged +savagely +savageness +savagenesses +savager +savageries +savagery +savages +savagest +savaging +savagism +savagisms +savanna +savannah +savannahs +savannas +savant +savants +savarin +savarins +savate +savates +save +saveable +saved +saveloy +saveloys +saver +savers +saves +savin +savine +savines +saving +savingly +savings +savins +savior +saviors +saviour +saviours +savor +savored +savorer +savorers +savorier +savories +savoriest +savorily +savoriness +savorinesses +savoring +savorless +savorous +savors +savory +savour +savoured +savourer +savourers +savourier +savouries +savouriest +savouring +savours +savoury +savoy +savoys +savvied +savvier +savvies +savviest +savvy +savvying +saw +sawbill +sawbills +sawbones +sawboneses +sawbuck +sawbucks +sawdust +sawdusts +sawed +sawer +sawers +sawfish +sawfishes +sawflies +sawfly +sawhorse +sawhorses +sawing +sawlike +sawlog +sawlogs +sawmill +sawmills +sawn +sawney +sawneys +saws +sawteeth +sawtimber +sawtimbers +sawtooth +sawyer +sawyers +sax +saxatile +saxes +saxhorn +saxhorns +saxicolous +saxifrage +saxifrages +saxitoxin +saxitoxins +saxonies +saxony +saxophone +saxophones +saxophonic +saxophonist +saxophonists +saxtuba +saxtubas +say +sayable +sayer +sayers +sayest +sayid +sayids +saying +sayings +sayonara +sayonaras +says +sayst +sayyid +sayyids +scab +scabbard +scabbarded +scabbarding +scabbards +scabbed +scabbier +scabbiest +scabbily +scabbing +scabble +scabbled +scabbles +scabbling +scabby +scabies +scabietic +scabiosa +scabiosas +scabious +scabiouses +scabland +scablands +scablike +scabrous +scabrously +scabrousness +scabrousnesses +scabs +scad +scads +scaffold +scaffolded +scaffolding +scaffoldings +scaffolds +scag +scagliola +scagliolas +scags +scalable +scalably +scalade +scalades +scalado +scalados +scalage +scalages +scalar +scalare +scalares +scalariform +scalariformly +scalars +scalawag +scalawags +scald +scalded +scaldic +scalding +scalds +scale +scaled +scaleless +scalelike +scalene +scaleni +scalenus +scalepan +scalepans +scaler +scalers +scales +scaleup +scaleups +scalier +scaliest +scaliness +scalinesses +scaling +scall +scallion +scallions +scallop +scalloped +scalloper +scallopers +scalloping +scallopini +scallopinis +scallops +scalls +scallywag +scallywags +scalogram +scalograms +scaloppine +scaloppines +scalp +scalped +scalpel +scalpels +scalper +scalpers +scalping +scalps +scaly +scam +scammed +scamming +scammonies +scammony +scamp +scamped +scamper +scampered +scampering +scampers +scampi +scampies +scamping +scampish +scamps +scams +scan +scandal +scandaled +scandaling +scandalise +scandalised +scandalises +scandalising +scandalize +scandalized +scandalizes +scandalizing +scandalled +scandalling +scandalmonger +scandalmongering +scandalmongerings +scandalmongers +scandalous +scandalously +scandalousness +scandalousnesses +scandals +scandent +scandia +scandias +scandic +scandium +scandiums +scannable +scanned +scanner +scanners +scanning +scannings +scans +scansion +scansions +scant +scanted +scanter +scantest +scantier +scanties +scantiest +scantily +scantiness +scantinesses +scanting +scantling +scantlings +scantly +scantness +scantnesses +scants +scanty +scape +scaped +scapegoat +scapegoated +scapegoating +scapegoatings +scapegoatism +scapegoatisms +scapegoats +scapegrace +scapegraces +scapes +scaphoid +scaphoids +scaping +scapolite +scapolites +scapose +scapula +scapulae +scapular +scapulars +scapulas +scar +scarab +scarabaei +scarabaeus +scarabaeuses +scarabs +scaramouch +scaramouche +scaramouches +scarce +scarcely +scarceness +scarcenesses +scarcer +scarcest +scarcities +scarcity +scare +scarecrow +scarecrows +scared +scarehead +scareheads +scaremonger +scaremongers +scarer +scarers +scares +scarey +scarf +scarfed +scarfing +scarfpin +scarfpins +scarfs +scarfskin +scarfskins +scarier +scariest +scarification +scarifications +scarified +scarifier +scarifiers +scarifies +scarify +scarifying +scarifyingly +scarily +scaring +scariose +scarious +scarlatina +scarlatinal +scarlatinas +scarless +scarlet +scarlets +scarp +scarped +scarper +scarpered +scarpering +scarpers +scarph +scarphed +scarphing +scarphs +scarping +scarps +scarred +scarrier +scarriest +scarring +scarry +scars +scart +scarted +scarting +scarts +scarves +scary +scat +scatback +scatbacks +scathe +scathed +scatheless +scathes +scathing +scathingly +scatological +scatologies +scatology +scats +scatt +scatted +scatter +scatteration +scatterations +scatterbrain +scatterbrained +scatterbrains +scattered +scatterer +scatterers +scattergood +scattergoods +scattergram +scattergrams +scattergun +scatterguns +scattering +scatteringly +scatterings +scatters +scattershot +scattier +scattiest +scatting +scatts +scatty +scaup +scauper +scaupers +scaups +scaur +scaurs +scavenge +scavenged +scavenger +scavengers +scavenges +scavenging +scena +scenario +scenarios +scenarist +scenarists +scenas +scend +scended +scending +scends +scene +sceneries +scenery +scenes +sceneshifter +sceneshifters +scenic +scenical +scenically +scenographer +scenographers +scenographic +scenographies +scenography +scent +scented +scenting +scentless +scents +scepter +sceptered +sceptering +scepters +sceptic +sceptical +scepticism +scepticisms +sceptics +sceptral +sceptre +sceptred +sceptres +sceptring +schadenfreude +schadenfreudes +schappe +schappes +schav +schavs +schedule +scheduled +scheduler +schedulers +schedules +scheduling +scheelite +scheelites +schema +schemas +schemata +schematic +schematically +schematics +schematism +schematisms +schematization +schematizations +schematize +schematized +schematizes +schematizing +scheme +schemed +schemer +schemers +schemes +scheming +scherzando +scherzandos +scherzi +scherzo +scherzos +schiller +schillers +schilling +schillings +schipperke +schipperkes +schism +schismatic +schismatical +schismatically +schismatics +schismatize +schismatized +schismatizes +schismatizing +schisms +schist +schistose +schistosities +schistosity +schistosomal +schistosome +schistosomes +schistosomiases +schistosomiasis +schists +schizier +schiziest +schizo +schizocarp +schizocarps +schizogonic +schizogonies +schizogonous +schizogony +schizoid +schizoids +schizont +schizonts +schizophrene +schizophrenes +schizophrenia +schizophrenias +schizophrenic +schizophrenically +schizophrenics +schizos +schizy +schizzier +schizziest +schizzy +schlemiel +schlemiels +schlep +schlepp +schlepped +schlepping +schlepps +schleps +schliere +schlieren +schlieric +schlock +schlockmeister +schlockmeisters +schlocks +schlocky +schlump +schlumped +schlumping +schlumps +schmaltz +schmaltzes +schmaltzier +schmaltziest +schmaltzy +schmalz +schmalzes +schmalzier +schmalziest +schmalzy +schmear +schmears +schmeer +schmeered +schmeering +schmeers +schmelze +schmelzes +schmo +schmoe +schmoes +schmoos +schmoose +schmoosed +schmooses +schmoosing +schmooze +schmoozed +schmoozes +schmoozing +schmos +schmuck +schmucks +schnapps +schnaps +schnauzer +schnauzers +schnecke +schnecken +schnitzel +schnitzels +schnook +schnooks +schnorkel +schnorkeled +schnorkeling +schnorkels +schnorrer +schnorrers +schnoz +schnozz +schnozzes +schnozzle +schnozzles +scholar +scholarly +scholars +scholarship +scholarships +scholastic +scholastically +scholasticate +scholasticates +scholasticism +scholasticisms +scholastics +scholia +scholiast +scholiastic +scholiasts +scholium +scholiums +school +schoolbag +schoolbags +schoolbook +schoolbooks +schoolboy +schoolboyish +schoolboys +schoolchild +schoolchildren +schooled +schoolfellow +schoolfellows +schoolgirl +schoolgirls +schoolhouse +schoolhouses +schooling +schoolings +schoolkid +schoolkids +schoolman +schoolmarm +schoolmarmish +schoolmarms +schoolmaster +schoolmasterish +schoolmasterly +schoolmasters +schoolmate +schoolmates +schoolmen +schoolmistress +schoolmistresses +schoolroom +schoolrooms +schools +schoolteacher +schoolteachers +schooltime +schooltimes +schoolwork +schoolworks +schooner +schooners +schorl +schorls +schottische +schottisches +schrik +schriks +schrod +schrods +schtick +schticks +schtik +schtiks +schuit +schuits +schul +schuln +schuss +schussboomer +schussboomers +schussed +schusser +schussers +schusses +schussing +schwa +schwarmerei +schwarmereis +schwas +sciaenid +sciaenids +sciatic +sciatica +sciaticas +sciatics +science +sciences +sciential +scientific +scientifically +scientism +scientisms +scientist +scientists +scientize +scientized +scientizes +scientizing +scilicet +scilla +scillas +scimetar +scimetars +scimitar +scimitars +scimiter +scimiters +scincoid +scincoids +scintigraphic +scintigraphies +scintigraphy +scintilla +scintillae +scintillant +scintillantly +scintillas +scintillate +scintillated +scintillates +scintillating +scintillation +scintillations +scintillator +scintillators +scintillometer +scintillometers +sciolism +sciolisms +sciolist +sciolistic +sciolists +scion +scions +scirocco +sciroccos +scirrhi +scirrhous +scirrhus +scirrhuses +scissile +scission +scissions +scissor +scissored +scissoring +scissors +scissortail +scissortails +scissure +scissures +sciurid +sciurids +sciurine +sciurines +sciuroid +sclaff +sclaffed +sclaffer +sclaffers +sclaffing +sclaffs +sclera +sclerae +scleral +scleras +sclereid +sclereids +sclerenchyma +sclerenchymas +sclerenchymata +sclerenchymatous +sclerite +sclerites +scleroderma +sclerodermas +sclerodermata +scleroid +scleroma +scleromata +sclerometer +sclerometers +scleroprotein +scleroproteins +sclerose +sclerosed +scleroses +sclerosing +sclerosis +sclerotia +sclerotial +sclerotic +sclerotics +sclerotin +sclerotins +sclerotium +sclerotization +sclerotizations +sclerotized +sclerous +scoff +scoffed +scoffer +scoffers +scoffing +scofflaw +scofflaws +scoffs +scold +scolded +scolder +scolders +scolding +scoldings +scolds +scoleces +scolecite +scolecites +scolex +scolices +scolioma +scoliomas +scolioses +scoliosis +scoliotic +scollop +scolloped +scolloping +scollops +scolopendra +scolopendras +scombroid +scombroids +sconce +sconced +sconces +sconcing +scone +scones +scoop +scooped +scooper +scoopers +scoopful +scoopfuls +scooping +scoops +scoopsful +scoot +scooted +scooter +scooters +scooting +scoots +scop +scope +scoped +scopes +scoping +scopolamine +scopolamines +scops +scopula +scopulae +scopulas +scorbutic +scorch +scorched +scorcher +scorchers +scorches +scorching +scorchingly +score +scoreboard +scoreboards +scorecard +scorecards +scored +scorekeeper +scorekeepers +scoreless +scorepad +scorepads +scorer +scorers +scores +scoria +scoriaceous +scoriae +scorified +scorifies +scorify +scorifying +scoring +scorn +scorned +scorner +scorners +scornful +scornfully +scornfulness +scornfulnesses +scorning +scorns +scorpaenid +scorpaenids +scorpion +scorpions +scot +scotch +scotched +scotches +scotching +scoter +scoters +scotia +scotias +scotoma +scotomas +scotomata +scotopia +scotopias +scotopic +scots +scottie +scotties +scoundrel +scoundrelly +scoundrels +scour +scoured +scourer +scourers +scourge +scourged +scourger +scourgers +scourges +scourging +scouring +scourings +scours +scouse +scouses +scout +scoutcraft +scoutcrafts +scouted +scouter +scouters +scouth +scouther +scouthered +scouthering +scouthers +scouths +scouting +scoutings +scoutmaster +scoutmasters +scouts +scow +scowder +scowdered +scowdering +scowders +scowed +scowing +scowl +scowled +scowler +scowlers +scowling +scowlingly +scowls +scows +scrabble +scrabbled +scrabbler +scrabblers +scrabbles +scrabblier +scrabbliest +scrabbling +scrabbly +scrag +scragged +scraggier +scraggiest +scragging +scragglier +scraggliest +scraggly +scraggy +scrags +scraich +scraiched +scraiching +scraichs +scraigh +scraighed +scraighing +scraighs +scram +scramble +scrambled +scrambler +scramblers +scrambles +scrambling +scramjet +scramjets +scrammed +scramming +scrams +scrannel +scrannels +scrap +scrapbook +scrapbooks +scrape +scraped +scraper +scrapers +scrapes +scrapheap +scrapheaps +scrapie +scrapies +scraping +scrapings +scrappage +scrappages +scrapped +scrapper +scrappers +scrappier +scrappiest +scrappily +scrappiness +scrappinesses +scrapping +scrapple +scrapples +scrappy +scraps +scratch +scratchboard +scratchboards +scratched +scratcher +scratchers +scratches +scratchier +scratchiest +scratchily +scratchiness +scratchinesses +scratching +scratchy +scrawl +scrawled +scrawler +scrawlers +scrawlier +scrawliest +scrawling +scrawls +scrawly +scrawnier +scrawniest +scrawniness +scrawninesses +scrawny +screak +screaked +screaking +screaks +screaky +scream +screamed +screamer +screamers +screaming +screamingly +screams +scree +screech +screeched +screecher +screechers +screeches +screechier +screechiest +screeching +screechy +screed +screeded +screeding +screeds +screen +screenable +screened +screener +screeners +screening +screenings +screenland +screenlands +screenplay +screenplays +screens +screenwriter +screenwriters +screes +screw +screwball +screwballs +screwbean +screwbeans +screwdriver +screwdrivers +screwed +screwer +screwers +screwier +screwiest +screwiness +screwinesses +screwing +screwlike +screws +screwup +screwups +screwworm +screwworms +screwy +scribal +scribble +scribbled +scribbler +scribblers +scribbles +scribbling +scribblings +scribe +scribed +scriber +scribers +scribes +scribing +scried +scries +scrieve +scrieved +scrieves +scrieving +scrim +scrimmage +scrimmaged +scrimmager +scrimmagers +scrimmages +scrimmaging +scrimp +scrimped +scrimper +scrimpers +scrimpier +scrimpiest +scrimping +scrimpit +scrimps +scrimpy +scrims +scrimshander +scrimshanders +scrimshaw +scrimshawed +scrimshawing +scrimshaws +scrip +scrips +script +scripted +scripter +scripters +scripting +scriptoria +scriptorium +scripts +scriptural +scripturally +scripture +scriptures +scriptwriter +scriptwriters +scrive +scrived +scrivener +scriveners +scrives +scriving +scrod +scrods +scrofula +scrofulas +scrofulous +scroggier +scroggiest +scroggy +scroll +scrolled +scrolling +scrolls +scrollwork +scrollworks +scrooch +scrooched +scrooches +scrooching +scrooge +scrooges +scroop +scrooped +scrooping +scroops +scrootch +scrootched +scrootches +scrootching +scrota +scrotal +scrotum +scrotums +scrouge +scrouged +scrouges +scrouging +scrounge +scrounged +scrounger +scroungers +scrounges +scroungier +scroungiest +scrounging +scroungy +scrub +scrubbable +scrubbed +scrubber +scrubbers +scrubbier +scrubbiest +scrubbing +scrubby +scrubland +scrublands +scrubs +scrubwoman +scrubwomen +scruff +scruffier +scruffiest +scruffily +scruffiness +scruffinesses +scruffs +scruffy +scrum +scrummage +scrummaged +scrummages +scrummaging +scrummed +scrumming +scrumptious +scrumptiously +scrums +scrunch +scrunched +scrunches +scrunching +scruple +scrupled +scruples +scrupling +scrupulosities +scrupulosity +scrupulous +scrupulously +scrupulousness +scrupulousnesses +scrutable +scrutineer +scrutineers +scrutinies +scrutinise +scrutinised +scrutinises +scrutinising +scrutinize +scrutinized +scrutinizer +scrutinizers +scrutinizes +scrutinizing +scrutiny +scry +scrying +scuba +scubas +scud +scudded +scudding +scudi +scudo +scuds +scuff +scuffed +scuffing +scuffle +scuffled +scuffler +scufflers +scuffles +scuffling +scuffs +sculk +sculked +sculker +sculkers +sculking +sculks +scull +sculled +sculler +sculleries +scullers +scullery +sculling +scullion +scullions +sculls +sculp +sculped +sculpin +sculping +sculpins +sculps +sculpt +sculpted +sculpting +sculptor +sculptors +sculptress +sculptresses +sculpts +sculptural +sculpturally +sculpture +sculptured +sculptures +sculpturesque +sculpturesquely +sculpturing +scum +scumbag +scumbags +scumble +scumbled +scumbles +scumbling +scumlike +scummed +scummer +scummers +scummier +scummiest +scumming +scummy +scums +scungilli +scungillis +scunner +scunnered +scunnering +scunners +scup +scuppaug +scuppaugs +scupper +scuppered +scuppering +scuppernong +scuppernongs +scuppers +scups +scurf +scurfier +scurfiest +scurfs +scurfy +scurried +scurries +scurril +scurrile +scurrilities +scurrility +scurrilous +scurrilously +scurrilousness +scurrilousnesses +scurry +scurrying +scurvier +scurvies +scurviest +scurvily +scurviness +scurvinesses +scurvy +scut +scuta +scutage +scutages +scutate +scutch +scutched +scutcheon +scutcheons +scutcher +scutchers +scutches +scutching +scute +scutella +scutellar +scutellate +scutellated +scutellum +scutes +scuts +scutter +scuttered +scuttering +scutters +scuttle +scuttlebutt +scuttlebutts +scuttled +scuttles +scuttling +scutum +scuzzier +scuzziest +scuzzy +scyphate +scyphi +scyphistoma +scyphistomae +scyphistomas +scyphozoan +scyphozoans +scyphus +scythe +scythed +scythes +scything +sea +seabag +seabags +seabeach +seabeaches +seabed +seabeds +seabird +seabirds +seaboard +seaboards +seaboot +seaboots +seaborgium +seaborgiums +seaborne +seacoast +seacoasts +seacock +seacocks +seacraft +seacrafts +seadog +seadogs +seadrome +seadromes +seafarer +seafarers +seafaring +seafarings +seafloor +seafloors +seafood +seafoods +seafowl +seafowls +seafront +seafronts +seagirt +seagoing +seagull +seagulls +seal +sealable +sealant +sealants +sealed +sealer +sealeries +sealers +sealery +sealing +seallike +seals +sealskin +sealskins +seam +seaman +seamanlike +seamanly +seamanship +seamanships +seamark +seamarks +seamed +seamen +seamer +seamers +seamier +seamiest +seaminess +seaminesses +seaming +seamless +seamlessly +seamlessness +seamlessnesses +seamlike +seamount +seamounts +seams +seamster +seamsters +seamstress +seamstresses +seamy +seance +seances +seapiece +seapieces +seaplane +seaplanes +seaport +seaports +seaquake +seaquakes +sear +search +searchable +searched +searcher +searchers +searches +searching +searchingly +searchless +searchlight +searchlights +seared +searer +searest +searing +searingly +searobin +searobins +sears +seas +seascape +seascapes +seascout +seascouts +seashell +seashells +seashore +seashores +seasick +seasickness +seasicknesses +seaside +seasides +season +seasonable +seasonableness +seasonablenesses +seasonably +seasonal +seasonalities +seasonality +seasonally +seasoned +seasoner +seasoners +seasoning +seasonings +seasonless +seasons +seastrand +seastrands +seat +seated +seater +seaters +seating +seatings +seatless +seatmate +seatmates +seatrain +seatrains +seats +seatwork +seatworks +seawall +seawalls +seawan +seawans +seawant +seawants +seaward +seawards +seaware +seawares +seawater +seawaters +seaway +seaways +seaweed +seaweeds +seaworthiness +seaworthinesses +seaworthy +sebaceous +sebacic +sebasic +seborrhea +seborrheas +seborrheic +sebum +sebums +sec +secalose +secaloses +secant +secantly +secants +secateur +secateurs +secco +seccos +secede +seceded +seceder +seceders +secedes +seceding +secern +secerned +secerning +secerns +secession +secessionism +secessionisms +secessionist +secessionists +secessions +seclude +secluded +secludedly +secludedness +secludednesses +secludes +secluding +seclusion +seclusions +seclusive +seclusively +seclusiveness +seclusivenesses +secobarbital +secobarbitals +second +secondaries +secondarily +secondariness +secondarinesses +secondary +seconde +seconded +seconder +seconders +secondes +secondhand +secondi +seconding +secondly +secondo +seconds +secpar +secpars +secrecies +secrecy +secret +secretagogue +secretagogues +secretarial +secretariat +secretariats +secretaries +secretary +secretaryship +secretaryships +secrete +secreted +secreter +secretes +secretest +secretin +secreting +secretins +secretion +secretionary +secretions +secretive +secretively +secretiveness +secretivenesses +secretly +secretor +secretors +secretory +secrets +secs +sect +sectarian +sectarianism +sectarianisms +sectarianize +sectarianized +sectarianizes +sectarianizing +sectarians +sectaries +sectary +sectile +sectilities +sectility +section +sectional +sectionalism +sectionalisms +sectionally +sectionals +sectioned +sectioning +sections +sector +sectoral +sectored +sectorial +sectoring +sectors +sects +secular +secularise +secularised +secularises +secularising +secularism +secularisms +secularist +secularistic +secularists +secularities +secularity +secularization +secularizations +secularize +secularized +secularizer +secularizers +secularizes +secularizing +secularly +seculars +secund +secundly +secundum +secure +secured +securely +securement +securements +secureness +securenesses +securer +securers +secures +securest +securing +securities +securitization +securitizations +securitize +securitized +securitizes +securitizing +security +sedan +sedans +sedarim +sedate +sedated +sedately +sedateness +sedatenesses +sedater +sedates +sedatest +sedating +sedation +sedations +sedative +sedatives +sedentary +seder +seders +sederunt +sederunts +sedge +sedges +sedgier +sedgiest +sedgy +sedile +sedilia +sedilium +sediment +sedimentable +sedimentary +sedimentation +sedimentations +sedimented +sedimenting +sedimentologic +sedimentological +sedimentologically +sedimentologies +sedimentologist +sedimentologists +sedimentology +sediments +sedition +seditions +seditious +seditiously +seditiousness +seditiousnesses +seduce +seduced +seducement +seducements +seducer +seducers +seduces +seducing +seducive +seduction +seductions +seductive +seductively +seductiveness +seductivenesses +seductress +seductresses +sedulities +sedulity +sedulous +sedulously +sedulousness +sedulousnesses +sedum +sedums +see +seeable +seecatch +seecatchie +seed +seedbed +seedbeds +seedcake +seedcakes +seedcase +seedcases +seedeater +seedeaters +seeded +seeder +seeders +seedier +seediest +seedily +seediness +seedinesses +seeding +seedless +seedlike +seedling +seedlings +seedman +seedmen +seedpod +seedpods +seeds +seedsman +seedsmen +seedtime +seedtimes +seedy +seeing +seeings +seek +seeker +seekers +seeking +seeks +seel +seeled +seeling +seels +seely +seem +seemed +seemer +seemers +seeming +seemingly +seemings +seemlier +seemliest +seemliness +seemlinesses +seemly +seems +seen +seep +seepage +seepages +seeped +seepier +seepiest +seeping +seeps +seepy +seer +seeress +seeresses +seers +seersucker +seersuckers +sees +seesaw +seesawed +seesawing +seesaws +seethe +seethed +seethes +seething +seg +segetal +seggar +seggars +segment +segmental +segmentally +segmentary +segmentation +segmentations +segmented +segmenting +segments +segni +segno +segnos +sego +segos +segregant +segregants +segregate +segregated +segregates +segregating +segregation +segregationist +segregationists +segregations +segregative +segs +segue +segued +segueing +segues +seguidilla +seguidillas +sei +seicento +seicentos +seiche +seiches +seidel +seidels +seif +seifs +seigneur +seigneurial +seigneuries +seigneurs +seigneury +seignior +seigniorage +seigniorages +seigniories +seigniors +seigniory +seignorage +seignorages +seignorial +seignories +seignory +seine +seined +seiner +seiners +seines +seining +seis +seisable +seise +seised +seiser +seisers +seises +seisin +seising +seisings +seisins +seism +seismal +seismic +seismically +seismicities +seismicity +seismism +seismisms +seismogram +seismograms +seismograph +seismographer +seismographers +seismographic +seismographies +seismographs +seismography +seismological +seismologies +seismologist +seismologists +seismology +seismometer +seismometers +seismometric +seismometries +seismometry +seisms +seisor +seisors +seisure +seisures +seizable +seize +seized +seizer +seizers +seizes +seizin +seizing +seizings +seizins +seizor +seizors +seizure +seizures +sejant +sejeant +sel +selachian +selachians +seladang +seladangs +selaginella +selaginellas +selah +selahs +selamlik +selamliks +selcouth +seldom +seldomly +select +selectable +selected +selectee +selectees +selecting +selection +selectionist +selectionists +selections +selective +selectively +selectiveness +selectivenesses +selectivities +selectivity +selectly +selectman +selectmen +selectness +selectnesses +selector +selectors +selects +selenate +selenates +selenic +selenide +selenides +seleniferous +selenite +selenites +selenium +seleniums +selenocentric +selenological +selenologies +selenologist +selenologists +selenology +selenous +self +selfdom +selfdoms +selfed +selfheal +selfheals +selfhood +selfhoods +selfing +selfish +selfishly +selfishness +selfishnesses +selfless +selflessly +selflessness +selflessnesses +selfness +selfnesses +selfs +selfsame +selfsameness +selfsamenesses +selfward +sell +sellable +selle +seller +sellers +selles +selling +sellout +sellouts +sells +sels +selsyn +selsyns +seltzer +seltzers +selva +selvage +selvaged +selvages +selvas +selvedge +selvedged +selvedges +selves +semantic +semantical +semantically +semanticist +semanticists +semantics +semaphore +semaphored +semaphores +semaphoring +semasiological +semasiologies +semasiology +sematic +semblable +semblables +semblably +semblance +semblances +seme +semeiologies +semeiology +semeiotic +semeiotics +sememe +sememes +sememic +semen +semens +semes +semester +semesters +semestral +semestrial +semi +semiabstract +semiabstraction +semiabstractions +semiannual +semiannually +semiaquatic +semiarboreal +semiarid +semiaridities +semiaridity +semiautobiographical +semiautomatic +semiautomatically +semiautomatics +semiautonomous +semibald +semibreve +semibreves +semicentennial +semicentennials +semicircle +semicircles +semicircular +semicivilized +semiclassic +semiclassical +semiclassics +semicolon +semicolonial +semicolonialism +semicolonialisms +semicolonies +semicolons +semicolony +semicoma +semicomas +semicommercial +semiconducting +semiconductor +semiconductors +semiconscious +semiconsciousness +semiconsciousnesses +semiconservative +semiconservatively +semicrystalline +semicylindrical +semidarkness +semidarknesses +semideaf +semideified +semideifies +semideify +semideifying +semidesert +semideserts +semidetached +semidiameter +semidiameters +semidiurnal +semidivine +semidocumentaries +semidocumentary +semidome +semidomed +semidomes +semidomesticated +semidomestication +semidomestications +semidominant +semidry +semidrying +semidwarf +semidwarfs +semidwarves +semiempirical +semierect +semievergreen +semifeudal +semifinal +semifinalist +semifinalists +semifinals +semifinished +semifit +semifitted +semiflexible +semifluid +semifluids +semiformal +semigala +semigloss +semigovernmental +semigroup +semigroups +semihard +semihigh +semihobo +semihoboes +semihobos +semilegendary +semilethal +semilethals +semiliquid +semiliquids +semiliterate +semiliterates +semilog +semilogarithmic +semilunar +semilustrous +semimat +semimatt +semimatte +semimetal +semimetallic +semimetals +semimicro +semimoist +semimonastic +semimonthlies +semimonthly +semimute +semimystical +semina +seminal +seminally +seminar +seminarian +seminarians +seminaries +seminarist +seminarists +seminars +seminary +seminatural +seminiferous +seminomad +seminomadic +seminomads +seminude +seminudities +seminudity +semiofficial +semiofficially +semiological +semiologically +semiologies +semiologist +semiologists +semiology +semiopaque +semioses +semiosis +semiotic +semiotician +semioticians +semioticist +semioticists +semiotics +semipalmated +semiparasite +semiparasites +semiparasitic +semipermanent +semipermeabilities +semipermeability +semipermeable +semipolitical +semipopular +semiporcelain +semiporcelains +semipornographic +semipornographies +semipornography +semipostal +semipostals +semiprecious +semiprivate +semipro +semiprofessional +semiprofessionally +semiprofessionals +semipros +semipublic +semiquantitative +semiquantitatively +semiquaver +semiquavers +semiraw +semireligious +semiretired +semiretirement +semiretirements +semirigid +semirural +semis +semisacred +semisecret +semisedentary +semises +semishrubby +semiskilled +semisoft +semisolid +semisolids +semisubmersible +semisubmersibles +semisweet +semisynthetic +semiterrestrial +semitist +semitists +semitonal +semitonally +semitone +semitones +semitonic +semitonically +semitrailer +semitrailers +semitranslucent +semitransparent +semitropic +semitropical +semitropics +semivowel +semivowels +semiweeklies +semiweekly +semiwild +semiworks +semiyearly +semolina +semolinas +sempervivum +sempervivums +sempiternal +sempiternally +sempiternities +sempiternity +semple +semplice +sempre +sempstress +sempstresses +sen +senarii +senarius +senary +senate +senates +senator +senatorial +senatorian +senators +senatorship +senatorships +send +sendable +sendal +sendals +sended +sender +senders +sending +sendoff +sendoffs +sends +sendup +sendups +sene +seneca +senecas +senecio +senecios +senectitude +senectitudes +senega +senegas +senescence +senescences +senescent +seneschal +seneschals +sengi +senhor +senhora +senhoras +senhores +senhorita +senhoritas +senhors +senile +senilely +seniles +senilities +senility +senior +seniorities +seniority +seniors +seniti +senna +sennas +sennet +sennets +sennight +sennights +sennit +sennits +senopia +senopias +senor +senora +senoras +senores +senorita +senoritas +senors +senryu +sensa +sensate +sensated +sensately +sensates +sensating +sensation +sensational +sensationalise +sensationalised +sensationalises +sensationalising +sensationalism +sensationalisms +sensationalist +sensationalistic +sensationalists +sensationalize +sensationalized +sensationalizes +sensationalizing +sensationally +sensations +sense +sensed +senseful +senseless +senselessly +senselessness +senselessnesses +senses +sensibilia +sensibilities +sensibility +sensible +sensibleness +sensiblenesses +sensibler +sensibles +sensiblest +sensibly +sensilla +sensillae +sensillum +sensing +sensitisation +sensitisations +sensitise +sensitised +sensitises +sensitising +sensitive +sensitively +sensitiveness +sensitivenesses +sensitives +sensitivities +sensitivity +sensitization +sensitizations +sensitize +sensitized +sensitizer +sensitizers +sensitizes +sensitizing +sensitometer +sensitometers +sensitometric +sensitometries +sensitometry +sensor +sensoria +sensorial +sensorially +sensorimotor +sensorineural +sensorium +sensoriums +sensors +sensory +sensual +sensualism +sensualisms +sensualist +sensualistic +sensualists +sensualities +sensuality +sensualization +sensualizations +sensualize +sensualized +sensualizes +sensualizing +sensually +sensum +sensuosities +sensuosity +sensuous +sensuously +sensuousness +sensuousnesses +sent +sente +sentence +sentenced +sentences +sentencing +sententia +sententiae +sentential +sententious +sententiously +sententiousness +sententiousnesses +senti +sentience +sentiences +sentient +sentiently +sentients +sentiment +sentimental +sentimentalise +sentimentalised +sentimentalises +sentimentalising +sentimentalism +sentimentalisms +sentimentalist +sentimentalists +sentimentalities +sentimentality +sentimentalization +sentimentalizations +sentimentalize +sentimentalized +sentimentalizes +sentimentalizing +sentimentally +sentiments +sentimo +sentimos +sentinel +sentineled +sentineling +sentinelled +sentinelling +sentinels +sentries +sentry +sepal +sepaled +sepaline +sepalled +sepaloid +sepalous +sepals +separabilities +separability +separable +separableness +separablenesses +separate +separated +separately +separateness +separatenesses +separates +separating +separation +separationist +separationists +separations +separatism +separatisms +separatist +separatistic +separatists +separative +separator +separators +sepia +sepias +sepic +sepiolite +sepiolites +sepoy +sepoys +seppuku +seppukus +sepses +sepsis +sept +septa +septal +septaria +septarium +septate +septenarii +septenarius +septendecillion +septendecillions +septennial +septennially +septentrion +septentrional +septentrions +septet +septets +septette +septettes +septic +septical +septicemia +septicemias +septicemic +septicidal +septics +septillion +septillions +septime +septimes +septs +septuagenarian +septuagenarians +septum +septums +septuple +septupled +septuples +septupling +sepulcher +sepulchered +sepulchering +sepulchers +sepulchral +sepulchrally +sepulchre +sepulchred +sepulchres +sepulchring +sepulture +sepultures +sequacious +sequaciously +sequacities +sequacity +sequel +sequela +sequelae +sequels +sequence +sequenced +sequencer +sequencers +sequences +sequencies +sequencing +sequency +sequent +sequential +sequentially +sequents +sequester +sequestered +sequestering +sequesters +sequestra +sequestrate +sequestrated +sequestrates +sequestrating +sequestration +sequestrations +sequestrum +sequestrums +sequin +sequined +sequinned +sequins +sequitur +sequiturs +sequoia +sequoias +ser +sera +serac +seracs +seraglio +seraglios +serai +serail +serails +serais +seral +serape +serapes +seraph +seraphic +seraphically +seraphim +seraphims +seraphin +seraphs +serdab +serdabs +sere +sered +serein +sereins +serenade +serenaded +serenader +serenaders +serenades +serenading +serenata +serenatas +serenate +serendipities +serendipitous +serendipitously +serendipity +serene +serenely +sereneness +serenenesses +serener +serenes +serenest +serenities +serenity +serer +seres +serest +serf +serfage +serfages +serfdom +serfdoms +serfhood +serfhoods +serfish +serflike +serfs +serge +sergeancies +sergeancy +sergeant +sergeanties +sergeants +sergeanty +serges +serging +sergings +serial +serialise +serialised +serialises +serialising +serialism +serialisms +serialist +serialists +serialization +serializations +serialize +serialized +serializes +serializing +serially +serials +seriate +seriated +seriately +seriates +seriatim +seriating +sericeous +sericin +sericins +sericultural +sericulture +sericultures +sericulturist +sericulturists +seriema +seriemas +series +serif +serifed +seriffed +serifs +serigraph +serigrapher +serigraphers +serigraphies +serigraphs +serigraphy +serin +serine +serines +sering +seringa +seringas +serins +seriocomic +seriocomically +serious +seriously +seriousness +seriousnesses +serjeant +serjeanties +serjeants +serjeanty +sermon +sermonette +sermonettes +sermonic +sermonize +sermonized +sermonizer +sermonizers +sermonizes +sermonizing +sermons +seroconversion +seroconversions +serodiagnoses +serodiagnosis +serodiagnostic +serologic +serological +serologically +serologies +serologist +serologists +serology +seronegative +seronegativities +seronegativity +seropositive +seropositivities +seropositivity +seropurulent +serosa +serosae +serosal +serosas +serosities +serosity +serotinal +serotine +serotines +serotinous +serotonergic +serotonin +serotoninergic +serotonins +serotype +serotypes +serous +serow +serows +serpent +serpentine +serpentinely +serpentines +serpents +serpigines +serpiginous +serpiginously +serpigo +serpigoes +serranid +serranids +serrano +serranos +serrate +serrated +serrates +serrating +serration +serrations +serried +serriedly +serriedness +serriednesses +serries +serry +serrying +sers +serum +serumal +serums +servable +serval +servals +servant +servanthood +servanthoods +servantless +servants +serve +served +server +servers +serves +service +serviceabilities +serviceability +serviceable +serviceableness +serviceablenesses +serviceably +serviceberries +serviceberry +serviced +serviceman +servicemen +servicer +servicers +services +servicewoman +servicewomen +servicing +serviette +serviettes +servile +servilely +servileness +servilenesses +servilities +servility +serving +servings +servitor +servitors +servitude +servitudes +servo +servomechanism +servomechanisms +servomotor +servomotors +servos +sesame +sesames +sesamoid +sesamoids +sesquicarbonate +sesquicarbonates +sesquicentenaries +sesquicentenary +sesquicentennial +sesquicentennials +sesquipedalian +sesquiterpene +sesquiterpenes +sessile +session +sessional +sessions +sesspool +sesspools +sesterce +sesterces +sestertia +sestertium +sestet +sestets +sestina +sestinas +sestine +sestines +set +seta +setaceous +setae +setal +setback +setbacks +setenant +setenants +setiform +setline +setlines +setoff +setoffs +seton +setons +setose +setous +setout +setouts +sets +setscrew +setscrews +sett +settee +settees +setter +setters +setting +settings +settle +settleable +settled +settlement +settlements +settler +settlers +settles +settling +settlings +settlor +settlors +setts +setulose +setulous +setup +setups +seven +sevenfold +sevens +seventeen +seventeens +seventeenth +seventeenths +seventh +sevenths +seventies +seventieth +seventieths +seventy +sever +severabilities +severability +severable +several +severalfold +severally +severals +severalties +severalty +severance +severances +severe +severed +severely +severeness +severenesses +severer +severest +severing +severities +severity +severs +seviche +seviches +sevruga +sevrugas +sew +sewabilities +sewability +sewable +sewage +sewages +sewan +sewans +sewar +sewars +sewed +sewer +sewerage +sewerages +sewered +sewering +sewers +sewing +sewings +sewn +sews +sex +sexagenarian +sexagenarians +sexagesimal +sexagesimals +sexdecillion +sexdecillions +sexed +sexes +sexier +sexiest +sexily +sexiness +sexinesses +sexing +sexism +sexisms +sexist +sexists +sexless +sexlessly +sexlessness +sexlessnesses +sexologies +sexologist +sexologists +sexology +sexploitation +sexploitations +sexpot +sexpots +sext +sextain +sextains +sextan +sextans +sextant +sextants +sextarii +sextarius +sextet +sextets +sextette +sextettes +sextile +sextiles +sextillion +sextillions +sexto +sextodecimo +sextodecimos +sexton +sextons +sextos +sexts +sextuple +sextupled +sextuples +sextuplet +sextuplets +sextuplicate +sextuplicated +sextuplicates +sextuplicating +sextupling +sextuply +sexual +sexualities +sexuality +sexualization +sexualizations +sexualize +sexualized +sexualizes +sexualizing +sexually +sexy +sferics +sforzandi +sforzando +sforzandos +sforzato +sforzatos +sfumato +sfumatos +sgraffiti +sgraffito +sh +sha +shabbier +shabbiest +shabbily +shabbiness +shabbinesses +shabby +shack +shackle +shacklebone +shacklebones +shackled +shackler +shacklers +shackles +shackling +shacko +shackoes +shackos +shacks +shad +shadberries +shadberry +shadblow +shadblows +shadbush +shadbushes +shadchan +shadchanim +shadchans +shaddock +shaddocks +shade +shaded +shadeless +shader +shaders +shades +shadflies +shadfly +shadier +shadiest +shadily +shadiness +shadinesses +shading +shadings +shadoof +shadoofs +shadow +shadowbox +shadowboxed +shadowboxes +shadowboxing +shadowed +shadower +shadowers +shadowgraph +shadowgraphies +shadowgraphs +shadowgraphy +shadowier +shadowiest +shadowily +shadowiness +shadowinesses +shadowing +shadowless +shadowlike +shadows +shadowy +shadrach +shadrachs +shads +shaduf +shadufs +shady +shaft +shafted +shafting +shaftings +shafts +shag +shagbark +shagbarks +shagged +shaggier +shaggiest +shaggily +shagginess +shagginesses +shagging +shaggy +shaggymane +shaggymanes +shagreen +shagreens +shags +shah +shahdom +shahdoms +shahs +shaird +shairds +shairn +shairns +shaitan +shaitans +shakable +shake +shakeable +shakedown +shakedowns +shaken +shakeout +shakeouts +shaker +shakers +shakes +shakeup +shakeups +shakier +shakiest +shakily +shakiness +shakinesses +shaking +shako +shakoes +shakos +shaky +shale +shaled +shales +shaley +shalier +shaliest +shall +shalloon +shalloons +shallop +shallops +shallot +shallots +shallow +shallowed +shallower +shallowest +shallowing +shallowly +shallowness +shallownesses +shallows +shalom +shaloms +shalt +shaly +sham +shamable +shaman +shamanic +shamanism +shamanisms +shamanist +shamanistic +shamanists +shamans +shamas +shamble +shambled +shambles +shambling +shambolic +shame +shamed +shamefaced +shamefacedly +shamefacedness +shamefacednesses +shamefast +shameful +shamefully +shamefulness +shamefulnesses +shameless +shamelessly +shamelessness +shamelessnesses +shames +shaming +shammas +shammash +shammashim +shammasim +shammed +shammer +shammers +shammes +shammied +shammies +shamming +shammos +shammosim +shammy +shammying +shamois +shamos +shamosim +shamoy +shamoyed +shamoying +shamoys +shampoo +shampooed +shampooer +shampooers +shampooing +shampoos +shamrock +shamrocks +shams +shamus +shamuses +shandies +shandy +shandygaff +shandygaffs +shanghai +shanghaied +shanghaier +shanghaiers +shanghaiing +shanghais +shank +shanked +shanking +shankpiece +shankpieces +shanks +shannies +shanny +shantey +shanteys +shanti +shanties +shantih +shantihs +shantis +shantung +shantungs +shanty +shantyman +shantymen +shantytown +shantytowns +shapable +shape +shapeable +shaped +shapeless +shapelessly +shapelessness +shapelessnesses +shapelier +shapeliest +shapeliness +shapelinesses +shapely +shapen +shaper +shapers +shapes +shapeup +shapeups +shaping +sharable +shard +shards +share +shareabilities +shareability +shareable +sharecrop +sharecropped +sharecropper +sharecroppers +sharecropping +sharecrops +shared +shareholder +shareholders +sharer +sharers +shares +shareware +sharewares +sharif +sharifian +sharifs +sharing +shark +sharked +sharker +sharkers +sharking +sharklike +sharks +sharkskin +sharkskins +sharn +sharns +sharny +sharp +sharped +sharpen +sharpened +sharpener +sharpeners +sharpening +sharpens +sharper +sharpers +sharpest +sharpie +sharpies +sharping +sharply +sharpness +sharpnesses +sharps +sharpshooter +sharpshooters +sharpshooting +sharpshootings +sharpy +shashlick +shashlicks +shashlik +shashliks +shaslik +shasliks +shat +shatter +shattered +shattering +shatteringly +shatterproof +shatters +shaugh +shaughs +shaul +shauled +shauling +shauls +shavable +shave +shaved +shaveling +shavelings +shaven +shaver +shavers +shaves +shavetail +shavetails +shavie +shavies +shaving +shavings +shaw +shawed +shawing +shawl +shawled +shawling +shawls +shawm +shawms +shawn +shaws +shay +shays +she +shea +sheaf +sheafed +sheafing +sheaflike +sheafs +sheal +shealing +shealings +sheals +shear +sheared +shearer +shearers +shearing +shearings +shearling +shearlings +shears +shearwater +shearwaters +sheas +sheath +sheathbill +sheathbills +sheathe +sheathed +sheather +sheathers +sheathes +sheathing +sheathings +sheaths +sheave +sheaved +sheaves +sheaving +shebang +shebangs +shebean +shebeans +shebeen +shebeens +shed +shedable +shedded +shedder +shedders +shedding +shedlike +sheds +sheen +sheened +sheeney +sheeneys +sheenful +sheenie +sheenier +sheenies +sheeniest +sheening +sheens +sheeny +sheep +sheepberries +sheepberry +sheepcot +sheepcote +sheepcotes +sheepcots +sheepdog +sheepdogs +sheepfold +sheepfolds +sheepherder +sheepherders +sheepherding +sheepherdings +sheepish +sheepishly +sheepishness +sheepishnesses +sheepman +sheepmen +sheepshank +sheepshanks +sheepshead +sheepsheads +sheepshearer +sheepshearers +sheepshearing +sheepshearings +sheepskin +sheepskins +sheer +sheered +sheerer +sheerest +sheering +sheerlegs +sheerly +sheerness +sheernesses +sheers +sheet +sheeted +sheeter +sheeters +sheetfed +sheeting +sheetings +sheetlike +sheets +sheeve +sheeves +shegetz +sheik +sheikdom +sheikdoms +sheikh +sheikhdom +sheikhdoms +sheikhs +sheiks +sheila +sheilas +sheitan +sheitans +shekel +shekels +sheldrake +sheldrakes +shelduck +shelducks +shelf +shelfful +shelffuls +shelflike +shell +shellac +shellack +shellacked +shellacking +shellackings +shellacks +shellacs +shellback +shellbacks +shellcracker +shellcrackers +shelled +sheller +shellers +shellfire +shellfires +shellfish +shellfisheries +shellfishery +shellfishes +shellier +shelliest +shelling +shellproof +shells +shellshocked +shellwork +shellworks +shelly +shelta +sheltas +shelter +shelterbelt +shelterbelts +sheltered +shelterer +shelterers +sheltering +shelterless +shelters +sheltie +shelties +shelty +shelve +shelved +shelver +shelvers +shelves +shelvier +shelviest +shelving +shelvings +shelvy +shenanigan +shenanigans +shend +shending +shends +shent +sheol +sheols +shepherd +shepherded +shepherdess +shepherdesses +shepherding +shepherds +sheqalim +sheqel +sherbert +sherberts +sherbet +sherbets +sherd +sherds +shereef +shereefs +shergottite +shergottites +sherif +sheriff +sheriffdom +sheriffdoms +sheriffs +sherifs +sherlock +sherlocks +sheroot +sheroots +sherpa +sherpas +sherries +sherris +sherrises +sherry +shes +shetland +shetlands +sheuch +sheuchs +sheugh +sheughs +shew +shewbread +shewbreads +shewed +shewer +shewers +shewing +shewn +shews +shh +shiatsu +shiatsus +shiatzu +shiatzus +shibah +shibahs +shibboleth +shibboleths +shicker +shickers +shicksa +shicksas +shied +shiel +shield +shielded +shielder +shielders +shielding +shields +shieling +shielings +shiels +shier +shiers +shies +shiest +shift +shiftable +shifted +shifter +shifters +shiftier +shiftiest +shiftily +shiftiness +shiftinesses +shifting +shiftless +shiftlessly +shiftlessness +shiftlessnesses +shifts +shifty +shigella +shigellae +shigellas +shigelloses +shigellosis +shiitake +shiitakes +shikar +shikaree +shikarees +shikari +shikaris +shikarred +shikarring +shikars +shikker +shikkers +shiksa +shiksas +shikse +shikses +shilingi +shill +shillala +shillalah +shillalahs +shillalas +shilled +shillelagh +shillelaghs +shilling +shillings +shills +shilpit +shily +shim +shimmed +shimmer +shimmered +shimmering +shimmers +shimmery +shimmied +shimmies +shimming +shimmy +shimmying +shims +shin +shinbone +shinbones +shindies +shindig +shindigs +shindy +shindys +shine +shined +shiner +shiners +shines +shingle +shingled +shingler +shinglers +shingles +shingling +shingly +shinier +shiniest +shinily +shininess +shininesses +shining +shinleaf +shinleafs +shinleaves +shinned +shinneries +shinnery +shinney +shinneyed +shinneying +shinneys +shinnied +shinnies +shinning +shinny +shinnying +shinplaster +shinplasters +shins +shinsplints +shiny +ship +shipboard +shipboards +shipborne +shipbuilder +shipbuilders +shipbuilding +shipbuildings +shipfitter +shipfitters +shiplap +shiplaps +shipload +shiploads +shipman +shipmaster +shipmasters +shipmate +shipmates +shipmen +shipment +shipments +shipowner +shipowners +shippable +shipped +shippen +shippens +shipper +shippers +shipping +shippings +shippon +shippons +ships +shipshape +shipside +shipsides +shipway +shipways +shipworm +shipworms +shipwreck +shipwrecked +shipwrecking +shipwrecks +shipwright +shipwrights +shipyard +shipyards +shire +shires +shirk +shirked +shirker +shirkers +shirking +shirks +shirr +shirred +shirring +shirrings +shirrs +shirt +shirtdress +shirtdresses +shirtfront +shirtfronts +shirtier +shirtiest +shirting +shirtings +shirtless +shirtmaker +shirtmakers +shirts +shirtsleeve +shirtsleeved +shirtsleeves +shirttail +shirttails +shirtwaist +shirtwaists +shirty +shist +shists +shit +shitake +shitakes +shithead +shitheads +shits +shittah +shittahs +shitted +shittier +shittiest +shittim +shittims +shittimwood +shittimwoods +shitting +shitty +shiv +shiva +shivah +shivahs +shivaree +shivareed +shivareeing +shivarees +shivas +shive +shiver +shivered +shiverer +shiverers +shivering +shivers +shivery +shives +shivs +shkotzim +shlemiehl +shlemiehls +shlemiel +shlemiels +shlep +shlepp +shlepped +shlepping +shlepps +shleps +shlock +shlocks +shlump +shlumped +shlumping +shlumps +shlumpy +shmaltz +shmaltzes +shmaltzier +shmaltziest +shmaltzy +shmear +shmears +shmo +shmoes +shmooze +shmoozed +shmoozes +shmoozing +shmuck +shmucks +shnaps +shnook +shnooks +shoal +shoaled +shoaler +shoalest +shoalier +shoaliest +shoaling +shoals +shoaly +shoat +shoats +shock +shockable +shocked +shocker +shockers +shocking +shockingly +shockproof +shocks +shod +shodden +shoddier +shoddies +shoddiest +shoddily +shoddiness +shoddinesses +shoddy +shoe +shoebill +shoebills +shoeblack +shoeblacks +shoed +shoehorn +shoehorned +shoehorning +shoehorns +shoeing +shoelace +shoelaces +shoeless +shoemaker +shoemakers +shoepac +shoepack +shoepacks +shoepacs +shoer +shoers +shoes +shoeshine +shoeshines +shoestring +shoestrings +shoetree +shoetrees +shofar +shofars +shofroth +shog +shogged +shogging +shogs +shogun +shogunal +shogunate +shogunates +shoguns +shoji +shojis +sholom +sholoms +shone +shoo +shooed +shooflies +shoofly +shooing +shook +shooks +shool +shooled +shooling +shools +shoon +shoos +shoot +shooter +shooters +shooting +shootings +shootout +shootouts +shoots +shop +shopboy +shopboys +shopgirl +shopgirls +shophar +shophars +shophroth +shopkeeper +shopkeepers +shoplift +shoplifted +shoplifter +shoplifters +shoplifting +shoplifts +shopman +shopmen +shoppe +shopped +shopper +shoppers +shoppes +shopping +shoppings +shops +shoptalk +shoptalks +shopwindow +shopwindows +shopworn +shoran +shorans +shore +shorebird +shorebirds +shored +shorefront +shorefronts +shoreline +shorelines +shores +shoreside +shoreward +shorewards +shoring +shorings +shorl +shorls +shorn +short +shortage +shortages +shortbread +shortbreads +shortcake +shortcakes +shortchange +shortchanged +shortchanger +shortchangers +shortchanges +shortchanging +shortcoming +shortcomings +shortcut +shortcuts +shortcutting +shorted +shorten +shortened +shortener +shorteners +shortening +shortenings +shortens +shorter +shortest +shortfall +shortfalls +shorthair +shorthaired +shorthairs +shorthand +shorthanded +shorthands +shorthorn +shorthorns +shortia +shortias +shortie +shorties +shorting +shortish +shortlist +shortlists +shortly +shortness +shortnesses +shorts +shortsighted +shortsightedly +shortsightedness +shortsightednesses +shortstop +shortstops +shortwave +shortwaves +shorty +shot +shote +shotes +shotgun +shotgunned +shotgunner +shotgunners +shotgunning +shotguns +shots +shott +shotted +shotten +shotting +shotts +should +shoulder +shouldered +shouldering +shoulders +shouldest +shouldst +shout +shouted +shouter +shouters +shouting +shouts +shove +shoved +shovel +shoveled +shoveler +shovelers +shovelful +shovelfuls +shoveling +shovelled +shoveller +shovellers +shovelling +shovelnose +shovelnoses +shovels +shovelsful +shover +shovers +shoves +shoving +show +showable +showbiz +showbizzes +showbizzy +showboat +showboated +showboating +showboats +showbread +showbreads +showcase +showcased +showcases +showcasing +showdown +showdowns +showed +shower +showered +showerer +showerers +showerhead +showerheads +showering +showerless +showers +showery +showgirl +showgirls +showier +showiest +showily +showiness +showinesses +showing +showings +showman +showmanship +showmanships +showmen +shown +showoff +showoffs +showpiece +showpieces +showplace +showplaces +showring +showrings +showroom +showrooms +shows +showstopper +showstoppers +showstopping +showy +shoyu +shoyus +shrank +shrapnel +shred +shredded +shredder +shredders +shredding +shreds +shrew +shrewd +shrewder +shrewdest +shrewdie +shrewdies +shrewdly +shrewdness +shrewdnesses +shrewed +shrewing +shrewish +shrewishly +shrewishness +shrewishnesses +shrewlike +shrews +shri +shriek +shrieked +shrieker +shriekers +shriekier +shriekiest +shrieking +shrieks +shrieky +shrieval +shrievalties +shrievalty +shrieve +shrieved +shrieves +shrieving +shrift +shrifts +shrike +shrikes +shrill +shrilled +shriller +shrillest +shrilling +shrillness +shrillnesses +shrills +shrilly +shrimp +shrimped +shrimper +shrimpers +shrimpier +shrimpiest +shrimping +shrimplike +shrimps +shrimpy +shrine +shrined +shrines +shrining +shrink +shrinkable +shrinkage +shrinkages +shrinker +shrinkers +shrinking +shrinks +shris +shrive +shrived +shrivel +shriveled +shriveling +shrivelled +shrivelling +shrivels +shriven +shriver +shrivers +shrives +shriving +shroff +shroffed +shroffing +shroffs +shroud +shrouded +shrouding +shrouds +shrove +shrub +shrubberies +shrubbery +shrubbier +shrubbiest +shrubby +shrubs +shrug +shrugged +shrugging +shrugs +shrunk +shrunken +shtetel +shtetels +shtetl +shtetlach +shtetls +shtick +shticks +shtik +shtiks +shuck +shucked +shucker +shuckers +shucking +shuckings +shucks +shudder +shuddered +shuddering +shudders +shuddery +shuffle +shuffleboard +shuffleboards +shuffled +shuffler +shufflers +shuffles +shuffling +shul +shuln +shuls +shun +shunned +shunner +shunners +shunning +shunpike +shunpiked +shunpiker +shunpikers +shunpikes +shunpiking +shunpikings +shuns +shunt +shunted +shunter +shunters +shunting +shunts +shush +shushed +shushes +shushing +shut +shutdown +shutdowns +shute +shuted +shutes +shuteye +shuteyes +shuting +shutoff +shutoffs +shutout +shutouts +shuts +shutter +shutterbug +shutterbugs +shuttered +shuttering +shutterless +shutters +shutting +shuttle +shuttlecock +shuttlecocked +shuttlecocking +shuttlecocks +shuttled +shuttleless +shuttles +shuttling +shwanpan +shwanpans +shy +shyer +shyers +shyest +shying +shylock +shylocked +shylocking +shylocks +shyly +shyness +shynesses +shyster +shysters +si +sial +sialagogue +sialagogues +sialic +sialid +sialidan +sialidans +sialids +sialoid +sials +siamang +siamangs +siamese +siameses +sib +sibb +sibbs +sibilance +sibilances +sibilant +sibilantly +sibilants +sibilate +sibilated +sibilates +sibilating +sibilation +sibilations +sibling +siblings +sibs +sibyl +sibylic +sibyllic +sibylline +sibyls +sic +siccan +sicced +siccing +sice +sices +sick +sickbay +sickbays +sickbed +sickbeds +sicked +sickee +sickees +sicken +sickened +sickener +sickeners +sickening +sickeningly +sickens +sicker +sickerly +sickest +sickie +sickies +sicking +sickish +sickishly +sickishness +sickishnesses +sickle +sickled +sicklemia +sicklemias +sickles +sicklied +sicklier +sicklies +sickliest +sicklily +sickliness +sicklinesses +sickling +sickly +sicklying +sickness +sicknesses +sicko +sickos +sickout +sickouts +sickroom +sickrooms +sicks +sics +siddur +siddurim +siddurs +side +sidearm +sideband +sidebands +sidebar +sidebars +sideboard +sideboards +sideburned +sideburns +sidecar +sidecars +sided +sidedness +sidednesses +sidedress +sidedresses +sidehill +sidehills +sidekick +sidekicks +sidelight +sidelights +sideline +sidelined +sideliner +sideliners +sidelines +sideling +sidelining +sidelong +sideman +sidemen +sidepiece +sidepieces +sidereal +siderite +siderites +siderolite +siderolites +sides +sidesaddle +sidesaddles +sideshow +sideshows +sideslip +sideslipped +sideslipping +sideslips +sidespin +sidespins +sidesplitting +sidesplittingly +sidestep +sidestepped +sidestepper +sidesteppers +sidestepping +sidesteps +sidestream +sidestroke +sidestrokes +sideswipe +sideswiped +sideswipes +sideswiping +sidetrack +sidetracked +sidetracking +sidetracks +sidewalk +sidewalks +sidewall +sidewalls +sideward +sidewards +sideway +sideways +sidewinder +sidewinders +sidewise +siding +sidings +sidle +sidled +sidler +sidlers +sidles +sidling +siege +sieged +sieges +sieging +siemens +sienite +sienites +sienna +siennas +sierozem +sierozems +sierra +sierran +sierras +siesta +siestas +sieur +sieurs +sieve +sieved +sieves +sieving +sifaka +sifakas +siffleur +siffleurs +sift +sifted +sifter +sifters +sifting +siftings +sifts +siganid +siganids +sigh +sighed +sigher +sighers +sighing +sighless +sighlike +sighs +sight +sighted +sighter +sighters +sighting +sightings +sightless +sightlessly +sightlessness +sightlessnesses +sightlier +sightliest +sightliness +sightlinesses +sightly +sights +sightsaw +sightsee +sightseeing +sightseen +sightseer +sightseers +sightsees +sigil +sigils +sigloi +siglos +sigma +sigmas +sigmate +sigmoid +sigmoidal +sigmoidally +sigmoidoscopies +sigmoidoscopy +sigmoids +sign +signage +signages +signal +signaled +signaler +signalers +signaling +signalise +signalised +signalises +signalising +signalization +signalizations +signalize +signalized +signalizes +signalizing +signalled +signaller +signallers +signalling +signally +signalman +signalmen +signalment +signalments +signals +signatories +signatory +signature +signatures +signboard +signboards +signed +signee +signees +signer +signers +signet +signeted +signeting +signets +significance +significances +significancies +significancy +significant +significantly +signification +significations +significative +significs +signified +signifieds +signifier +signifiers +signifies +signify +signifying +signifyings +signing +signior +signiori +signiories +signiors +signiory +signor +signora +signoras +signore +signori +signories +signorina +signorinas +signorine +signors +signory +signpost +signposted +signposting +signposts +signs +sike +siker +sikes +silage +silages +silane +silanes +sild +silds +silence +silenced +silencer +silencers +silences +silencing +sileni +silent +silenter +silentest +silently +silentness +silentnesses +silents +silenus +silesia +silesias +silex +silexes +silhouette +silhouetted +silhouettes +silhouetting +silhouettist +silhouettists +silica +silicas +silicate +silicates +siliceous +silicic +silicide +silicides +silicification +silicifications +silicified +silicifies +silicify +silicifying +silicious +silicium +siliciums +silicle +silicles +silicon +silicone +silicones +siliconized +silicons +silicoses +silicosis +silicotic +silicotics +silicula +siliculae +siliqua +siliquae +silique +siliques +silk +silkaline +silkalines +silked +silken +silkier +silkies +silkiest +silkily +silkiness +silkinesses +silking +silklike +silkoline +silkolines +silks +silkweed +silkweeds +silkworm +silkworms +silky +sill +sillabub +sillabubs +siller +sillers +sillibub +sillibubs +sillier +sillies +silliest +sillily +sillimanite +sillimanites +silliness +sillinesses +sills +silly +silo +siloed +siloing +silos +siloxane +siloxanes +silt +siltation +siltations +silted +siltier +siltiest +silting +silts +siltstone +siltstones +silty +silurid +silurids +siluroid +siluroids +silva +silvae +silvan +silvans +silvas +silver +silverback +silverbacks +silverberries +silverberry +silvered +silverer +silverers +silverfish +silverfishes +silveriness +silverinesses +silvering +silverly +silvern +silverpoint +silverpoints +silvers +silverside +silversides +silversmith +silversmithing +silversmithings +silversmiths +silverware +silverwares +silverweed +silverweeds +silvery +silvex +silvexes +silvical +silvics +silvicultural +silviculturally +silviculture +silvicultures +silviculturist +silviculturists +sim +sima +simar +simars +simaruba +simarubas +simas +simazine +simazines +simian +simians +similar +similarities +similarity +similarly +simile +similes +similitude +similitudes +simioid +simious +simitar +simitars +simlin +simlins +simmer +simmered +simmering +simmers +simnel +simnels +simoleon +simoleons +simoniac +simoniacal +simoniacally +simoniacs +simonies +simonist +simonists +simonize +simonized +simonizes +simonizing +simony +simoom +simooms +simoon +simoons +simp +simpatico +simper +simpered +simperer +simperers +simpering +simpers +simple +simpleminded +simplemindedly +simplemindedness +simplemindednesses +simpleness +simplenesses +simpler +simples +simplest +simpleton +simpletons +simplex +simplexes +simplices +simplicia +simplicial +simplicially +simplicities +simplicity +simplification +simplifications +simplified +simplifier +simplifiers +simplifies +simplify +simplifying +simplism +simplisms +simplist +simplistic +simplistically +simplists +simply +simps +sims +simulacra +simulacre +simulacres +simulacrum +simulacrums +simulant +simulants +simular +simulars +simulate +simulated +simulates +simulating +simulation +simulations +simulative +simulator +simulators +simulcast +simulcasted +simulcasting +simulcasts +simultaneities +simultaneity +simultaneous +simultaneously +simultaneousness +simultaneousnesses +sin +sinapism +sinapisms +since +sincere +sincerely +sincereness +sincerenesses +sincerer +sincerest +sincerities +sincerity +sincipita +sincipital +sinciput +sinciputs +sine +sinecure +sinecures +sines +sinew +sinewed +sinewing +sinews +sinewy +sinfonia +sinfonie +sinfonietta +sinfoniettas +sinful +sinfully +sinfulness +sinfulnesses +sing +singable +singe +singed +singeing +singer +singers +singes +singing +single +singled +singleness +singlenesses +singles +singlestick +singlesticks +singlet +singleton +singletons +singletree +singletrees +singlets +singling +singly +sings +singsong +singsongs +singsongy +singspiel +singspiels +singular +singularities +singularity +singularize +singularized +singularizes +singularizing +singularly +singulars +sinh +sinhs +sinicize +sinicized +sinicizes +sinicizing +sinister +sinisterly +sinisterness +sinisternesses +sinistral +sinistrous +sink +sinkable +sinkage +sinkages +sinker +sinkers +sinkhole +sinkholes +sinking +sinks +sinless +sinlessly +sinlessness +sinlessnesses +sinned +sinner +sinners +sinning +sinoatrial +sinological +sinologies +sinologist +sinologists +sinologue +sinologues +sinology +sinopia +sinopias +sinopie +sins +sinsemilla +sinsemillas +sinsyne +sinter +sinterabilities +sinterability +sintered +sintering +sinters +sinuate +sinuated +sinuates +sinuating +sinuosities +sinuosity +sinuous +sinuously +sinuousness +sinuousnesses +sinus +sinuses +sinusitis +sinusitises +sinusoid +sinusoidal +sinusoidally +sinusoids +sip +sipe +siped +sipes +siphon +siphonal +siphoned +siphonic +siphoning +siphonophore +siphonophores +siphonostele +siphonosteles +siphons +siping +sipped +sipper +sippers +sippet +sippets +sipping +sips +sir +sirdar +sirdars +sire +sired +siree +sirees +siren +sirenian +sirenians +sirens +sires +siring +sirloin +sirloins +sirocco +siroccos +sirra +sirrah +sirrahs +sirras +sirree +sirrees +sirs +sirup +sirups +sirupy +sirvente +sirventes +sis +sisal +sisals +sises +siskin +siskins +sissier +sissies +sissiest +sissified +sissy +sissyish +sister +sistered +sisterhood +sisterhoods +sistering +sisterly +sisters +sistra +sistroid +sistrum +sistrums +sit +sitar +sitarist +sitarists +sitars +sitcom +sitcoms +site +sited +sites +sith +sithence +sithens +siting +sitologies +sitology +sitosterol +sitosterols +sits +sitten +sitter +sitters +sitting +sittings +situate +situated +situates +situating +situation +situational +situationally +situations +situp +situps +situs +situses +sitzmark +sitzmarks +siver +sivers +six +sixes +sixfold +sixmo +sixmos +sixpence +sixpences +sixpenny +sixte +sixteen +sixteenmo +sixteenmos +sixteens +sixteenth +sixteenths +sixtes +sixth +sixthly +sixths +sixties +sixtieth +sixtieths +sixty +sixtyish +sizable +sizableness +sizablenesses +sizably +sizar +sizars +size +sizeable +sizeably +sized +sizer +sizers +sizes +sizier +siziest +siziness +sizinesses +sizing +sizings +sizy +sizzle +sizzled +sizzler +sizzlers +sizzles +sizzling +sjambok +sjamboked +sjamboking +sjamboks +ska +skag +skags +skald +skaldic +skalds +skas +skat +skate +skateboard +skateboarder +skateboarders +skateboarding +skateboardings +skateboards +skated +skater +skaters +skates +skating +skatings +skatol +skatole +skatoles +skatols +skats +skean +skeane +skeanes +skeans +skedaddle +skedaddled +skedaddler +skedaddlers +skedaddles +skedaddling +skee +skeed +skeeing +skeen +skeens +skees +skeet +skeeter +skeeters +skeets +skeg +skegs +skeigh +skein +skeined +skeining +skeins +skeletal +skeletally +skeleton +skeletonic +skeletonise +skeletonised +skeletonises +skeletonising +skeletonize +skeletonized +skeletonizer +skeletonizers +skeletonizes +skeletonizing +skeletons +skellum +skellums +skelm +skelms +skelp +skelped +skelping +skelpit +skelps +skelter +skeltered +skeltering +skelters +skene +skenes +skep +skeps +skepsis +skepsises +skeptic +skeptical +skeptically +skepticism +skepticisms +skeptics +skerries +skerry +sketch +sketchbook +sketchbooks +sketched +sketcher +sketchers +sketches +sketchier +sketchiest +sketchily +sketchiness +sketchinesses +sketching +sketchy +skew +skewback +skewbacks +skewbald +skewbalds +skewed +skewer +skewered +skewering +skewers +skewing +skewness +skewnesses +skews +ski +skiable +skiagram +skiagrams +skibob +skibobber +skibobbers +skibobbing +skibobbings +skibobs +skid +skidded +skidder +skidders +skiddier +skiddiest +skidding +skiddoo +skiddooed +skiddooing +skiddoos +skiddy +skidoo +skidooed +skidooing +skidoos +skidproof +skids +skidway +skidways +skied +skier +skiers +skies +skiey +skiff +skiffle +skiffled +skiffles +skiffling +skiffs +skiing +skiings +skijorer +skijorers +skijoring +skijorings +skilful +skill +skilled +skilless +skillessness +skillessnesses +skillet +skillets +skillful +skillfully +skillfulness +skillfulnesses +skilling +skillings +skills +skim +skimmed +skimmer +skimmers +skimming +skimmings +skimo +skimobile +skimobiles +skimos +skimp +skimped +skimpier +skimpiest +skimpily +skimpiness +skimpinesses +skimping +skimps +skimpy +skims +skin +skinflint +skinflints +skinful +skinfuls +skinhead +skinheads +skink +skinked +skinker +skinkers +skinking +skinks +skinless +skinlike +skinned +skinner +skinners +skinnier +skinniest +skinniness +skinninesses +skinning +skinny +skins +skint +skintight +skioring +skiorings +skip +skipjack +skipjacks +skiplane +skiplanes +skippable +skipped +skipper +skippered +skippering +skippers +skippet +skippets +skipping +skips +skirl +skirled +skirling +skirls +skirmish +skirmished +skirmisher +skirmishers +skirmishes +skirmishing +skirr +skirred +skirret +skirrets +skirring +skirrs +skirt +skirted +skirter +skirters +skirting +skirtings +skirts +skis +skit +skite +skited +skites +skiting +skits +skitter +skittered +skitterier +skitteriest +skittering +skitters +skittery +skittish +skittishly +skittishness +skittishnesses +skittle +skittles +skive +skived +skiver +skivers +skives +skiving +skivvied +skivvies +skivvy +skivvying +skiwear +sklent +sklented +sklenting +sklents +skoal +skoaled +skoaling +skoals +skookum +skosh +skoshes +skreegh +skreeghed +skreeghing +skreeghs +skreigh +skreighed +skreighing +skreighs +skua +skuas +skulduggeries +skulduggery +skulk +skulked +skulker +skulkers +skulking +skulks +skull +skullcap +skullcaps +skullduggeries +skullduggery +skulled +skulls +skunk +skunked +skunking +skunks +sky +skyborne +skybox +skyboxes +skycap +skycaps +skydive +skydived +skydiver +skydivers +skydives +skydiving +skydivings +skydove +skyed +skyey +skyhook +skyhooks +skying +skyjack +skyjacked +skyjacker +skyjackers +skyjacking +skyjackings +skyjacks +skylark +skylarked +skylarker +skylarkers +skylarking +skylarks +skylight +skylighted +skylights +skyline +skylines +skylit +skyman +skymen +skyphoi +skyphos +skyrocket +skyrocketed +skyrocketing +skyrockets +skysail +skysails +skyscraper +skyscrapers +skywalk +skywalks +skyward +skywards +skyway +skyways +skywrite +skywriter +skywriters +skywrites +skywriting +skywritings +skywritten +skywrote +slab +slabbed +slabber +slabbered +slabbering +slabbers +slabbery +slabbing +slablike +slabs +slack +slacked +slacken +slackened +slackening +slackens +slacker +slackers +slackest +slacking +slackly +slackness +slacknesses +slacks +slag +slagged +slaggier +slaggiest +slagging +slaggy +slags +slain +slainte +slakable +slake +slaked +slaker +slakers +slakes +slaking +slalom +slalomed +slaloming +slaloms +slam +slammed +slammer +slammers +slamming +slams +slander +slandered +slanderer +slanderers +slandering +slanderous +slanderously +slanderousness +slanderousnesses +slanders +slang +slanged +slangier +slangiest +slangily +slanginess +slanginesses +slanging +slangs +slanguage +slanguages +slangy +slank +slant +slanted +slanting +slantingly +slants +slantways +slantwise +slanty +slap +slapdash +slapdashes +slaphappier +slaphappiest +slaphappy +slapjack +slapjacks +slapped +slapper +slappers +slapping +slaps +slapstick +slapsticks +slash +slashed +slasher +slashers +slashes +slashing +slashingly +slashings +slat +slatch +slatches +slate +slated +slatelike +slater +slaters +slates +slatey +slather +slathered +slathering +slathers +slatier +slatiest +slating +slatings +slats +slatted +slattern +slatternliness +slatternlinesses +slatternly +slatterns +slatting +slattings +slaty +slaughter +slaughtered +slaughterer +slaughterers +slaughterhouse +slaughterhouses +slaughtering +slaughterous +slaughterously +slaughters +slave +slaved +slaveholder +slaveholders +slaveholding +slaveholdings +slaver +slavered +slaverer +slaverers +slaveries +slavering +slavers +slavery +slaves +slavey +slaveys +slaving +slavish +slavishly +slavishness +slavishnesses +slavocracies +slavocracy +slaw +slaws +slay +slayed +slayer +slayers +slaying +slays +sleave +sleaved +sleaves +sleaving +sleaze +sleazebag +sleazebags +sleazeball +sleazeballs +sleazes +sleazier +sleaziest +sleazily +sleaziness +sleazinesses +sleazo +sleazy +sled +sledded +sledder +sledders +sledding +sleddings +sledge +sledged +sledgehammer +sledgehammered +sledgehammering +sledgehammers +sledges +sledging +sleds +sleek +sleeked +sleeken +sleekened +sleekening +sleekens +sleeker +sleekest +sleekier +sleekiest +sleeking +sleekit +sleekly +sleekness +sleeknesses +sleeks +sleeky +sleep +sleeper +sleepers +sleepier +sleepiest +sleepily +sleepiness +sleepinesses +sleeping +sleepings +sleepless +sleeplessly +sleeplessness +sleeplessnesses +sleeplike +sleepover +sleepovers +sleeps +sleepwalk +sleepwalked +sleepwalker +sleepwalkers +sleepwalking +sleepwalks +sleepwear +sleepy +sleepyhead +sleepyheads +sleet +sleeted +sleetier +sleetiest +sleeting +sleets +sleety +sleeve +sleeved +sleeveless +sleevelet +sleevelets +sleeves +sleeving +sleigh +sleighed +sleigher +sleighers +sleighing +sleighs +sleight +sleights +slender +slenderer +slenderest +slenderize +slenderized +slenderizes +slenderizing +slenderly +slenderness +slendernesses +slept +sleuth +sleuthed +sleuthhound +sleuthhounds +sleuthing +sleuths +slew +slewed +slewing +slews +slice +sliceable +sliced +slicer +slicers +slices +slicing +slick +slicked +slickenside +slickensides +slicker +slickers +slickest +slicking +slickly +slickness +slicknesses +slickrock +slickrocks +slicks +slid +slidable +slidden +slide +slider +sliders +slides +slideway +slideways +sliding +slier +sliest +slight +slighted +slighter +slightest +slighting +slightingly +slightly +slightness +slightnesses +slights +slily +slim +slime +slimeball +slimeballs +slimed +slimes +slimier +slimiest +slimily +sliminess +sliminesses +sliming +slimly +slimmed +slimmer +slimmers +slimmest +slimming +slimnastics +slimness +slimnesses +slimpsier +slimpsiest +slimpsy +slims +slimsier +slimsiest +slimsy +slimy +sling +slinger +slingers +slinging +slings +slingshot +slingshots +slink +slinked +slinkier +slinkiest +slinkily +slinkiness +slinkinesses +slinking +slinks +slinky +slip +slipcase +slipcased +slipcases +slipcover +slipcovers +slipe +sliped +slipes +slipform +slipformed +slipforming +slipforms +sliping +slipknot +slipknots +slipless +slipout +slipouts +slipover +slipovers +slippage +slippages +slipped +slipper +slippered +slipperier +slipperiest +slipperiness +slipperinesses +slippers +slippery +slippier +slippiest +slipping +slippy +slips +slipshod +slipslop +slipslops +slipsole +slipsoles +slipstream +slipstreamed +slipstreaming +slipstreams +slipt +slipup +slipups +slipware +slipwares +slipway +slipways +slit +slither +slithered +slithering +slithers +slithery +slitless +slits +slitted +slitter +slitters +slitting +sliver +slivered +sliverer +sliverers +slivering +slivers +slivovic +slivovices +slivovitz +slivovitzes +slob +slobber +slobbered +slobberer +slobberers +slobbering +slobbers +slobbery +slobbier +slobbiest +slobbish +slobby +slobs +sloe +sloes +slog +slogan +sloganeer +sloganeered +sloganeering +sloganeers +sloganize +sloganized +sloganizes +sloganizing +slogans +slogged +slogger +sloggers +slogging +slogs +sloid +sloids +slojd +slojds +sloop +sloops +slop +slope +sloped +sloper +slopers +slopes +sloping +slopped +sloppier +sloppiest +sloppily +sloppiness +sloppinesses +slopping +sloppy +slops +slopwork +slopworks +slosh +sloshed +sloshes +sloshier +sloshiest +sloshing +sloshy +slot +slotback +slotbacks +sloth +slothful +slothfully +slothfulness +slothfulnesses +sloths +slots +slotted +slotting +slouch +slouched +sloucher +slouchers +slouches +slouchier +slouchiest +slouchily +slouchiness +slouchinesses +slouching +slouchy +slough +sloughed +sloughier +sloughiest +sloughing +sloughs +sloughy +sloven +slovenlier +slovenliest +slovenliness +slovenlinesses +slovenly +slovens +slow +slowdown +slowdowns +slowed +slower +slowest +slowing +slowish +slowly +slowness +slownesses +slowpoke +slowpokes +slows +slowworm +slowworms +sloyd +sloyds +slub +slubbed +slubber +slubbered +slubbering +slubbers +slubbing +slubbings +slubs +sludge +sludges +sludgier +sludgiest +sludgy +slue +slued +slues +sluff +sluffed +sluffing +sluffs +slug +slugabed +slugabeds +slugfest +slugfests +sluggard +sluggardly +sluggardness +sluggardnesses +sluggards +slugged +slugger +sluggers +slugging +sluggish +sluggishly +sluggishness +sluggishnesses +slugs +sluice +sluiced +sluices +sluiceway +sluiceways +sluicing +sluicy +sluing +slum +slumber +slumbered +slumberer +slumberers +slumbering +slumberous +slumbers +slumbery +slumbrous +slumgullion +slumgullions +slumgum +slumgums +slumism +slumisms +slumlord +slumlords +slummed +slummer +slummers +slummier +slummiest +slumming +slummy +slump +slumped +slumpflation +slumpflations +slumping +slumps +slums +slung +slungshot +slungshots +slunk +slur +slurb +slurban +slurbs +slurp +slurped +slurping +slurps +slurred +slurried +slurries +slurring +slurry +slurrying +slurs +slush +slushed +slushes +slushier +slushiest +slushily +slushiness +slushinesses +slushing +slushy +slut +sluts +sluttier +sluttiest +sluttish +sluttishly +sluttishness +sluttishnesses +slutty +sly +slyboots +slyer +slyest +slyly +slyness +slynesses +slype +slypes +smack +smacked +smacker +smackers +smacking +smacks +small +smallage +smallages +smallclothes +smaller +smallest +smallholder +smallholders +smallholding +smallholdings +smallish +smallmouth +smallmouths +smallness +smallnesses +smallpox +smallpoxes +smalls +smallsword +smallswords +smalt +smalti +smaltine +smaltines +smaltite +smaltites +smalto +smaltos +smalts +smaragd +smaragde +smaragdes +smaragdine +smaragdite +smaragdites +smaragds +smarm +smarmier +smarmiest +smarmily +smarminess +smarminesses +smarms +smarmy +smart +smartass +smartasses +smarted +smarten +smartened +smartening +smartens +smarter +smartest +smartie +smarties +smarting +smartly +smartness +smartnesses +smarts +smartweed +smartweeds +smarty +smash +smashed +smasher +smashers +smashes +smashing +smashingly +smashup +smashups +smatter +smattered +smatterer +smatterers +smattering +smatterings +smatters +smaze +smazes +smear +smearcase +smearcases +smeared +smearer +smearers +smearier +smeariest +smearing +smears +smeary +smectic +smectite +smectites +smectitic +smeddum +smeddums +smeek +smeeked +smeeking +smeeks +smegma +smegmas +smell +smelled +smeller +smellers +smellier +smelliest +smelling +smells +smelly +smelt +smelted +smelter +smelteries +smelters +smeltery +smelting +smelts +smerk +smerked +smerking +smerks +smew +smews +smidge +smidgen +smidgens +smidgeon +smidgeons +smidges +smidgin +smidgins +smiercase +smiercases +smilax +smilaxes +smile +smiled +smileless +smiler +smilers +smiles +smiley +smiling +smilingly +smirch +smirched +smirches +smirching +smirk +smirked +smirker +smirkers +smirkier +smirkiest +smirking +smirks +smirky +smit +smite +smiter +smiters +smites +smith +smithereens +smitheries +smithers +smithery +smithies +smiths +smithsonite +smithsonites +smithy +smiting +smitten +smock +smocked +smocking +smockings +smocks +smog +smoggier +smoggiest +smoggy +smogless +smogs +smokable +smoke +smokeable +smoked +smokehouse +smokehouses +smokejack +smokejacks +smokeless +smokelike +smokepot +smokepots +smoker +smokers +smokes +smokestack +smokestacks +smokey +smokier +smokiest +smokily +smokiness +smokinesses +smoking +smoky +smolder +smoldered +smoldering +smolders +smolt +smolts +smooch +smooched +smooches +smooching +smoochy +smooth +smoothbore +smoothbores +smoothed +smoothen +smoothened +smoothening +smoothens +smoother +smoothers +smoothes +smoothest +smoothie +smoothies +smoothing +smoothly +smoothness +smoothnesses +smooths +smoothy +smorgasbord +smorgasbords +smote +smother +smothered +smothering +smothers +smothery +smoulder +smouldered +smouldering +smoulders +smudge +smudged +smudges +smudgier +smudgiest +smudgily +smudginess +smudginesses +smudging +smudgy +smug +smugger +smuggest +smuggle +smuggled +smuggler +smugglers +smuggles +smuggling +smugly +smugness +smugnesses +smut +smutch +smutched +smutches +smutchier +smutchiest +smutching +smutchy +smuts +smutted +smuttier +smuttiest +smuttily +smuttiness +smuttinesses +smutting +smutty +snack +snacked +snacking +snacks +snaffle +snaffled +snaffles +snaffling +snafu +snafued +snafuing +snafus +snag +snagged +snaggier +snaggiest +snagging +snaggleteeth +snaggletooth +snaggletoothed +snaggy +snaglike +snags +snail +snailed +snailing +snaillike +snails +snake +snakebird +snakebirds +snakebit +snakebite +snakebites +snakebitten +snaked +snakelike +snakeroot +snakeroots +snakes +snakeskin +snakeskins +snakeweed +snakeweeds +snakey +snakier +snakiest +snakily +snaking +snaky +snap +snapback +snapbacks +snapdragon +snapdragons +snapless +snapped +snapper +snappers +snappier +snappiest +snappily +snappiness +snappinesses +snapping +snappish +snappishly +snappishness +snappishnesses +snappy +snaps +snapshooter +snapshooters +snapshot +snapshots +snapshotted +snapshotting +snapweed +snapweeds +snare +snared +snarer +snarers +snares +snaring +snark +snarkier +snarkiest +snarks +snarky +snarl +snarled +snarler +snarlers +snarlier +snarliest +snarling +snarls +snarly +snash +snashes +snatch +snatched +snatcher +snatchers +snatches +snatchier +snatchiest +snatching +snatchy +snath +snathe +snathes +snaths +snaw +snawed +snawing +snaws +snazzier +snazziest +snazzy +sneak +sneaked +sneaker +sneakered +sneakers +sneakier +sneakiest +sneakily +sneakiness +sneakinesses +sneaking +sneakingly +sneaks +sneaky +sneap +sneaped +sneaping +sneaps +sneck +snecks +sned +snedded +snedding +sneds +sneer +sneered +sneerer +sneerers +sneerful +sneering +sneers +sneesh +sneeshes +sneeze +sneezed +sneezer +sneezers +sneezes +sneezeweed +sneezeweeds +sneezier +sneeziest +sneezing +sneezy +snell +snelled +sneller +snellest +snelling +snells +snib +snibbed +snibbing +snibs +snick +snicked +snicker +snickered +snickerer +snickerers +snickering +snickers +snickersnee +snickersnees +snickery +snicking +snicks +snide +snidely +snideness +snidenesses +snider +snidest +sniff +sniffed +sniffer +sniffers +sniffier +sniffiest +sniffily +sniffiness +sniffinesses +sniffing +sniffish +sniffishly +sniffishness +sniffishnesses +sniffle +sniffled +sniffler +snifflers +sniffles +sniffling +sniffs +sniffy +snifter +snifters +snigger +sniggered +sniggerer +sniggerers +sniggering +sniggers +sniggle +sniggled +sniggler +snigglers +sniggles +sniggling +snip +snipe +sniped +sniper +snipers +sniperscope +sniperscopes +snipes +sniping +snipped +snipper +snippers +snippersnapper +snippersnappers +snippet +snippetier +snippetiest +snippets +snippety +snippier +snippiest +snippily +snipping +snippy +snips +snit +snitch +snitched +snitcher +snitchers +snitches +snitching +snits +snivel +sniveled +sniveler +snivelers +sniveling +snivelled +snivelling +snivels +snob +snobberies +snobbery +snobbier +snobbiest +snobbily +snobbish +snobbishly +snobbishness +snobbishnesses +snobbism +snobbisms +snobby +snobs +snog +snogged +snogging +snogs +snollygoster +snollygosters +snood +snooded +snooding +snoods +snook +snooked +snooker +snookered +snookering +snookers +snooking +snooks +snool +snooled +snooling +snools +snoop +snooped +snooper +snoopers +snoopier +snoopiest +snoopily +snooping +snoops +snoopy +snoot +snooted +snootier +snootiest +snootily +snootiness +snootinesses +snooting +snoots +snooty +snooze +snoozed +snoozer +snoozers +snoozes +snoozier +snooziest +snoozing +snoozle +snoozled +snoozles +snoozling +snoozy +snore +snored +snorer +snorers +snores +snoring +snorkel +snorkeled +snorkeler +snorkelers +snorkeling +snorkels +snort +snorted +snorter +snorters +snorting +snorts +snot +snots +snottier +snottiest +snottily +snottiness +snottinesses +snotty +snout +snouted +snoutier +snoutiest +snouting +snoutish +snouts +snouty +snow +snowball +snowballed +snowballing +snowballs +snowbank +snowbanks +snowbell +snowbells +snowbelt +snowbelts +snowberries +snowberry +snowbird +snowbirds +snowblower +snowblowers +snowboard +snowboarder +snowboarders +snowboarding +snowboardings +snowboards +snowbound +snowbrush +snowbrushes +snowbush +snowbushes +snowcap +snowcapped +snowcaps +snowdrift +snowdrifts +snowdrop +snowdrops +snowed +snowfall +snowfalls +snowfield +snowfields +snowflake +snowflakes +snowier +snowiest +snowily +snowiness +snowinesses +snowing +snowland +snowlands +snowless +snowlike +snowmaker +snowmakers +snowmaking +snowman +snowmelt +snowmelts +snowmen +snowmobile +snowmobiler +snowmobilers +snowmobiles +snowmobiling +snowmobilings +snowmobilist +snowmobilists +snowmold +snowmolds +snowpack +snowpacks +snowplow +snowplowed +snowplowing +snowplows +snows +snowscape +snowscapes +snowshed +snowsheds +snowshoe +snowshoed +snowshoeing +snowshoer +snowshoers +snowshoes +snowslide +snowslides +snowstorm +snowstorms +snowsuit +snowsuits +snowy +snub +snubbed +snubber +snubbers +snubbier +snubbiest +snubbiness +snubbinesses +snubbing +snubby +snubness +snubnesses +snubs +snuck +snuff +snuffbox +snuffboxes +snuffed +snuffer +snuffers +snuffier +snuffiest +snuffily +snuffing +snuffle +snuffled +snuffler +snufflers +snuffles +snufflier +snuffliest +snuffling +snuffly +snuffs +snuffy +snug +snugged +snugger +snuggeries +snuggery +snuggest +snuggies +snugging +snuggle +snuggled +snuggles +snuggling +snugly +snugness +snugnesses +snugs +snye +snyes +so +soak +soakage +soakages +soaked +soaker +soakers +soaking +soaks +soap +soapbark +soapbarks +soapberries +soapberry +soapbox +soapboxes +soaped +soaper +soapers +soapier +soapiest +soapily +soapiness +soapinesses +soaping +soapless +soaplike +soaps +soapstone +soapstones +soapsuds +soapwort +soapworts +soapy +soar +soared +soarer +soarers +soaring +soarings +soars +soave +soaves +sob +sobbed +sobber +sobbers +sobbing +sobeit +sober +sobered +soberer +soberest +sobering +soberize +soberized +soberizes +soberizing +soberly +soberness +sobernesses +sobers +sobersided +sobersidedness +sobersidednesses +sobersides +sobful +sobrieties +sobriety +sobriquet +sobriquets +sobs +socage +socager +socagers +socages +soccage +soccages +soccer +soccers +sociabilities +sociability +sociable +sociableness +sociablenesses +sociables +sociably +social +socialise +socialised +socialises +socialising +socialism +socialisms +socialist +socialistic +socialistically +socialists +socialite +socialites +socialities +sociality +socialization +socializations +socialize +socialized +socializer +socializers +socializes +socializing +socially +socials +societal +societally +societies +society +sociobiological +sociobiologies +sociobiologist +sociobiologists +sociobiology +sociocultural +socioculturally +socioeconomic +socioeconomically +sociogram +sociograms +sociohistorical +sociolinguist +sociolinguistic +sociolinguistics +sociolinguists +sociologese +sociologeses +sociologic +sociological +sociologically +sociologies +sociologist +sociologists +sociology +sociometric +sociometries +sociometry +sociopath +sociopathic +sociopaths +sociopolitical +sociopsychological +socioreligious +sociosexual +sock +sockdolager +sockdolagers +sockdologer +sockdologers +socked +socket +socketed +socketing +sockets +sockeye +sockeyes +socking +sockless +sockman +sockmen +socko +socks +socle +socles +socman +socmen +sod +soda +sodaless +sodalist +sodalists +sodalite +sodalites +sodalities +sodality +sodamide +sodamides +sodas +sodbuster +sodbusters +sodded +sodden +soddened +soddening +soddenly +soddenness +soddennesses +soddens +soddies +sodding +soddy +sodic +sodium +sodiums +sodom +sodomies +sodomist +sodomists +sodomite +sodomites +sodomitic +sodomitical +sodomize +sodomized +sodomizes +sodomizing +sodoms +sodomy +sods +soever +sofa +sofar +sofars +sofas +soffit +soffits +soft +softa +softas +softback +softbacks +softball +softballer +softballers +softballs +softbound +softcover +softcovers +soften +softened +softener +softeners +softening +softens +softer +softest +softhead +softheaded +softheadedly +softheadedness +softheadednesses +softheads +softhearted +softheartedly +softheartedness +softheartednesses +softie +softies +softish +softly +softness +softnesses +softs +softshell +softshells +software +softwares +softwood +softwoods +softy +sogged +soggier +soggiest +soggily +sogginess +sogginesses +soggy +soigne +soignee +soil +soilage +soilages +soilborne +soiled +soiling +soilless +soils +soilure +soilures +soiree +soirees +soja +sojas +sojourn +sojourned +sojourner +sojourners +sojourning +sojourns +soke +sokeman +sokemen +sokes +sokol +sokols +sol +sola +solace +solaced +solacement +solacements +solacer +solacers +solaces +solacing +solan +solanaceous +soland +solander +solanders +solands +solanin +solanine +solanines +solanins +solano +solanos +solans +solanum +solanums +solar +solaria +solarise +solarised +solarises +solarising +solarism +solarisms +solarium +solariums +solarization +solarizations +solarize +solarized +solarizes +solarizing +solate +solated +solates +solatia +solating +solation +solations +solatium +sold +soldan +soldans +solder +solderabilities +solderability +soldered +solderer +solderers +soldering +solders +soldi +soldier +soldiered +soldieries +soldiering +soldierings +soldierly +soldiers +soldiership +soldierships +soldiery +soldo +sole +solecise +solecised +solecises +solecising +solecism +solecisms +solecist +solecistic +solecists +solecize +solecized +solecizes +solecizing +soled +solei +soleless +solely +solemn +solemner +solemnest +solemnified +solemnifies +solemnify +solemnifying +solemnities +solemnity +solemnization +solemnizations +solemnize +solemnized +solemnizes +solemnizing +solemnly +solemnness +solemnnesses +soleness +solenesses +solenoid +solenoidal +solenoids +soleplate +soleplates +soleret +solerets +soles +soleus +solfatara +solfataras +solfege +solfeges +solfeggi +solfeggio +solfeggios +solgel +soli +solicit +solicitant +solicitants +solicitation +solicitations +solicited +soliciting +solicitor +solicitors +solicitorship +solicitorships +solicitous +solicitously +solicitousness +solicitousnesses +solicits +solicitude +solicitudes +solid +solidago +solidagos +solidarism +solidarisms +solidarist +solidaristic +solidarists +solidarities +solidarity +solidary +solider +solidest +solidi +solidification +solidifications +solidified +solidifies +solidify +solidifying +solidities +solidity +solidly +solidness +solidnesses +solids +solidus +solifluction +solifluctions +soliloquies +soliloquise +soliloquised +soliloquises +soliloquising +soliloquist +soliloquists +soliloquize +soliloquized +soliloquizer +soliloquizers +soliloquizes +soliloquizing +soliloquy +soling +solion +solions +solipsism +solipsisms +solipsist +solipsistic +solipsistically +solipsists +soliquid +soliquids +solitaire +solitaires +solitaries +solitarily +solitariness +solitarinesses +solitary +soliton +solitons +solitude +solitudes +solitudinarian +solitudinarians +solleret +sollerets +solmization +solmizations +solo +soloed +soloing +soloist +soloists +solon +solonchak +solonchaks +solonets +solonetses +solonetz +solonetzes +solonetzic +solons +solos +sols +solstice +solstices +solstitial +solubilise +solubilised +solubilises +solubilising +solubilities +solubility +solubilization +solubilizations +solubilize +solubilized +solubilizes +solubilizing +soluble +solubles +solubly +solum +solums +solus +solute +solutes +solution +solutions +solvabilities +solvability +solvable +solvate +solvated +solvates +solvating +solvation +solvations +solve +solved +solvencies +solvency +solvent +solventless +solvently +solvents +solver +solvers +solves +solving +solvolyses +solvolysis +solvolytic +soma +somas +somata +somatic +somatically +somatological +somatologies +somatology +somatomedin +somatomedins +somatopleure +somatopleures +somatosensory +somatostatin +somatostatins +somatotrophin +somatotrophins +somatotropin +somatotropins +somatotype +somatotypes +somber +somberly +somberness +sombernesses +sombre +sombrely +sombrero +sombreros +sombrous +some +somebodies +somebody +someday +somedeal +somehow +someone +someones +someplace +somersault +somersaulted +somersaulting +somersaults +somerset +somerseted +somerseting +somersets +somersetted +somersetting +something +sometime +sometimes +someway +someways +somewhat +somewhats +somewhen +somewhere +somewheres +somewhither +somewise +somital +somite +somites +somitic +sommelier +sommeliers +somnambulant +somnambulate +somnambulated +somnambulates +somnambulating +somnambulation +somnambulations +somnambulism +somnambulisms +somnambulist +somnambulistic +somnambulistically +somnambulists +somnifacient +somnifacients +somniferous +somnolence +somnolences +somnolent +somnolently +son +sonance +sonances +sonant +sonantal +sonantic +sonants +sonar +sonarman +sonarmen +sonars +sonata +sonatas +sonatina +sonatinas +sonatine +sonde +sonder +sonders +sondes +sone +sones +song +songbird +songbirds +songbook +songbooks +songfest +songfests +songful +songfully +songfulness +songfulnesses +songless +songlessly +songlike +songs +songsmith +songsmiths +songster +songsters +songstress +songstresses +songwriter +songwriters +songwriting +songwritings +sonhood +sonhoods +sonic +sonically +sonicate +sonicated +sonicates +sonicating +sonication +sonications +sonics +sonless +sonlike +sonly +sonnet +sonneted +sonneteer +sonneteering +sonneteerings +sonneteers +sonneting +sonnets +sonnetted +sonnetting +sonnies +sonny +sonobuoy +sonobuoys +sonogram +sonograms +sonographer +sonographers +sonographies +sonography +sonorant +sonorants +sonorities +sonority +sonorous +sonorously +sonorousness +sonorousnesses +sonovox +sonovoxes +sons +sonship +sonships +sonsie +sonsier +sonsiest +sonsy +soochong +soochongs +sooey +sook +sooks +soon +sooner +sooners +soonest +soot +sooted +sooth +soothe +soothed +soother +soothers +soothes +soothest +soothfast +soothing +soothingly +soothingness +soothingnesses +soothly +sooths +soothsaid +soothsay +soothsayer +soothsayers +soothsaying +soothsayings +soothsays +sootier +sootiest +sootily +sootiness +sootinesses +sooting +soots +sooty +sop +sopaipilla +sopaipillas +sopapilla +sopapillas +soph +sophies +sophism +sophisms +sophist +sophistic +sophistical +sophistically +sophisticate +sophisticated +sophisticatedly +sophisticates +sophisticating +sophistication +sophistications +sophistries +sophistry +sophists +sophomore +sophomores +sophomoric +sophs +sophy +sopite +sopited +sopites +sopiting +sopor +soporiferous +soporiferousness +soporiferousnesses +soporific +soporifics +sopors +sopped +soppier +soppiest +soppiness +soppinesses +sopping +soppy +soprani +sopranino +sopraninos +soprano +sopranos +sops +sora +soras +sorb +sorbabilities +sorbability +sorbable +sorbate +sorbates +sorbed +sorbent +sorbents +sorbet +sorbets +sorbic +sorbing +sorbitol +sorbitols +sorbose +sorboses +sorbs +sorcerer +sorcerers +sorceress +sorceresses +sorceries +sorcerous +sorcery +sord +sordid +sordidly +sordidness +sordidnesses +sordine +sordines +sordini +sordino +sordor +sordors +sords +sore +sorehead +soreheaded +soreheads +sorel +sorels +sorely +soreness +sorenesses +sorer +sores +sorest +sorgho +sorghos +sorghum +sorghums +sorgo +sorgos +sori +soricine +soring +sorings +sorites +soritic +sorn +sorned +sorner +sorners +sorning +sorns +soroche +soroches +sororal +sororate +sororates +sororities +sorority +soroses +sorosis +sorosises +sorption +sorptions +sorptive +sorrel +sorrels +sorrier +sorriest +sorrily +sorriness +sorrinesses +sorrow +sorrowed +sorrower +sorrowers +sorrowful +sorrowfully +sorrowfulness +sorrowfulnesses +sorrowing +sorrows +sorry +sort +sortable +sortably +sorted +sorter +sorters +sortie +sortied +sortieing +sorties +sortilege +sortileges +sorting +sortition +sortitions +sorts +sorus +sos +sostenuti +sostenuto +sostenutos +sot +soteriological +soteriologies +soteriology +soth +soths +sotol +sotols +sots +sotted +sottish +sottishly +sottishness +sottishnesses +sou +souari +souaris +soubise +soubises +soubrette +soubrettes +soubriquet +soubriquets +soucar +soucars +souchong +souchongs +soudan +soudans +souffle +souffled +souffleed +souffles +sough +soughed +soughing +soughs +sought +souk +souks +soul +souled +soulful +soulfully +soulfulness +soulfulnesses +soulless +soullessly +soullessness +soullessnesses +soullike +souls +sound +soundable +soundalike +soundalikes +soundboard +soundboards +soundbox +soundboxes +sounded +sounder +sounders +soundest +sounding +soundingly +soundings +soundless +soundlessly +soundly +soundman +soundmen +soundness +soundnesses +soundproof +soundproofed +soundproofing +soundproofs +sounds +soundstage +soundstages +soundtrack +soundtracks +soup +soupcon +soupcons +souped +soupier +soupiest +souping +soups +soupspoon +soupspoons +soupy +sour +sourball +sourballs +source +sourcebook +sourcebooks +sourced +sourceless +sources +sourcing +sourdine +sourdines +sourdough +sourdoughs +soured +sourer +sourest +souring +sourish +sourly +sourness +sournesses +sourpuss +sourpusses +sours +soursop +soursops +sourwood +sourwoods +sous +sousaphone +sousaphones +souse +soused +souses +sousing +soutache +soutaches +soutane +soutanes +souter +souters +south +southbound +southeast +southeaster +southeasterly +southeastern +southeasternmost +southeasters +southeasts +southeastward +southeastwards +southed +souther +southerlies +southerly +southern +southerner +southerners +southernmost +southernness +southernnesses +southerns +southernwood +southernwoods +southers +southing +southings +southland +southlands +southpaw +southpaws +southron +southrons +souths +southward +southwards +southwest +southwester +southwesterly +southwestern +southwesternmost +southwesters +southwests +southwestward +southwestwards +souvenir +souvenirs +souvlaki +souvlakia +souvlakias +souvlakis +sovereign +sovereignly +sovereigns +sovereignties +sovereignty +soviet +sovietism +sovietisms +sovietization +sovietizations +sovietize +sovietized +sovietizes +sovietizing +soviets +sovkhoz +sovkhozes +sovkhozy +sovran +sovranly +sovrans +sovranties +sovranty +sow +sowable +sowans +sowar +sowars +sowbellies +sowbelly +sowbread +sowbreads +sowcar +sowcars +sowed +sowens +sower +sowers +sowing +sown +sows +sox +soy +soya +soyas +soybean +soybeans +soymilk +soymilks +soys +soyuz +soyuzes +sozin +sozine +sozines +sozins +sozzled +spa +space +spaceband +spacebands +spacecraft +spacecrafts +spaced +spaceflight +spaceflights +spaceless +spaceman +spacemen +spaceport +spaceports +spacer +spacers +spaces +spaceship +spaceships +spacesuit +spacesuits +spacewalk +spacewalked +spacewalker +spacewalkers +spacewalking +spacewalks +spaceward +spacey +spacial +spacier +spaciest +spacing +spacings +spacious +spaciously +spaciousness +spaciousnesses +spackle +spackled +spackles +spackling +spacy +spade +spaded +spadefish +spadefishes +spadeful +spadefuls +spader +spaders +spades +spadework +spadeworks +spadices +spadille +spadilles +spading +spadix +spadixes +spado +spadones +spae +spaed +spaeing +spaeings +spaes +spaetzle +spaetzles +spaghetti +spaghettilike +spaghettini +spaghettinis +spaghettis +spagyric +spagyrics +spahee +spahees +spahi +spahis +spail +spails +spait +spaits +spake +spale +spales +spall +spallable +spallation +spallations +spalled +spaller +spallers +spalling +spalls +spalpeen +spalpeens +span +spanakopita +spanakopitas +spancel +spanceled +spanceling +spancelled +spancelling +spancels +spandex +spandexes +spandrel +spandrels +spandril +spandrils +spang +spangle +spangled +spangles +spanglier +spangliest +spangling +spangly +spaniel +spaniels +spank +spanked +spanker +spankers +spanking +spankings +spanks +spanless +spanned +spanner +spanners +spanning +spanokopita +spanokopitas +spans +spanworm +spanworms +spar +sparable +sparables +spare +spareable +spared +sparely +spareness +sparenesses +sparer +sparerib +spareribs +sparers +spares +sparest +sparge +sparged +sparger +spargers +sparges +sparging +sparid +sparids +sparing +sparingly +spark +sparked +sparker +sparkers +sparkier +sparkiest +sparkily +sparking +sparkish +sparkle +sparkled +sparkler +sparklers +sparkles +sparklier +sparkliest +sparkling +sparkly +sparkplug +sparkplugged +sparkplugging +sparkplugs +sparks +sparky +sparlike +sparling +sparlings +sparoid +sparoids +sparred +sparrier +sparriest +sparring +sparrow +sparrowlike +sparrows +sparry +spars +sparse +sparsely +sparseness +sparsenesses +sparser +sparsest +sparsities +sparsity +spartan +sparteine +sparteines +spas +spasm +spasmodic +spasmodically +spasmolytic +spasmolytics +spasms +spastic +spastically +spasticities +spasticity +spastics +spat +spate +spates +spathal +spathe +spathed +spathes +spathic +spathose +spathulate +spatial +spatialities +spatiality +spatially +spatiotemporal +spatiotemporally +spats +spatted +spatter +spatterdock +spatterdocks +spattered +spattering +spatters +spatting +spatula +spatular +spatulas +spatulate +spatzle +spavie +spavies +spaviet +spavin +spavined +spavins +spawn +spawned +spawner +spawners +spawning +spawns +spay +spayed +spaying +spays +spaz +spazzes +speak +speakable +speakeasies +speakeasy +speaker +speakerphone +speakerphones +speakers +speakership +speakerships +speaking +speakings +speaks +spean +speaned +speaning +speans +spear +speared +spearer +spearers +spearfish +spearfished +spearfishes +spearfishing +speargun +spearguns +spearhead +spearheaded +spearheading +spearheads +spearing +spearman +spearmen +spearmint +spearmints +spears +spearwort +spearworts +spec +specced +speccing +special +specialer +specialest +specialisation +specialisations +specialise +specialised +specialises +specialising +specialism +specialisms +specialist +specialistic +specialists +specialities +speciality +specialization +specializations +specialize +specialized +specializes +specializing +specially +specialness +specialnesses +specials +specialties +specialty +speciate +speciated +speciates +speciating +speciation +speciational +speciations +specie +species +speciesism +speciesisms +specifiable +specific +specifically +specification +specifications +specificities +specificity +specifics +specified +specifier +specifiers +specifies +specify +specifying +specimen +specimens +speciosities +speciosity +specious +speciously +speciousness +speciousnesses +speck +specked +specking +speckle +speckled +speckles +speckling +specks +specs +spectacle +spectacled +spectacles +spectacular +spectacularly +spectaculars +spectate +spectated +spectates +spectating +spectator +spectatorial +spectators +spectatorship +spectatorships +specter +specters +spectinomycin +spectinomycins +spectra +spectral +spectrally +spectre +spectres +spectrofluorimeter +spectrofluorimeters +spectrofluorometer +spectrofluorometers +spectrofluorometric +spectrofluorometries +spectrofluorometry +spectrogram +spectrograms +spectrograph +spectrographic +spectrographically +spectrographies +spectrographs +spectrography +spectroheliogram +spectroheliograms +spectroheliograph +spectroheliographies +spectroheliographs +spectroheliography +spectrohelioscope +spectrohelioscopes +spectrometer +spectrometers +spectrometric +spectrometries +spectrometry +spectrophotometer +spectrophotometers +spectrophotometric +spectrophotometrical +spectrophotometrically +spectrophotometries +spectrophotometry +spectroscope +spectroscopes +spectroscopic +spectroscopically +spectroscopies +spectroscopist +spectroscopists +spectroscopy +spectrum +spectrums +specula +specular +specularities +specularity +specularly +speculate +speculated +speculates +speculating +speculation +speculations +speculative +speculatively +speculator +speculators +speculum +speculums +sped +speech +speeches +speechified +speechifies +speechify +speechifying +speechless +speechlessly +speechlessness +speechlessnesses +speechwriter +speechwriters +speed +speedball +speedballed +speedballing +speedballs +speedboat +speedboating +speedboatings +speedboats +speeded +speeder +speeders +speedier +speediest +speedily +speediness +speedinesses +speeding +speedings +speedo +speedometer +speedometers +speedos +speeds +speedster +speedsters +speedup +speedups +speedway +speedways +speedwell +speedwells +speedy +speel +speeled +speeling +speels +speer +speered +speering +speerings +speers +speil +speiled +speiling +speils +speir +speired +speiring +speirs +speise +speises +speiss +speisses +spelaean +spelean +speleological +speleologies +speleologist +speleologists +speleology +spell +spellbind +spellbinder +spellbinders +spellbinding +spellbindingly +spellbinds +spellbound +spelled +speller +spellers +spelling +spellings +spells +spelt +spelter +spelters +spelts +speltz +speltzes +spelunk +spelunked +spelunker +spelunkers +spelunking +spelunkings +spelunks +spence +spencer +spencers +spences +spend +spendable +spender +spenders +spending +spends +spendthrift +spendthrifts +spense +spenses +spent +sperm +spermaceti +spermacetis +spermagonia +spermagonium +spermaries +spermary +spermatheca +spermathecae +spermathecas +spermatia +spermatial +spermatic +spermatid +spermatids +spermatium +spermatocyte +spermatocytes +spermatogeneses +spermatogenesis +spermatogenic +spermatogonia +spermatogonial +spermatogonium +spermatophore +spermatophores +spermatophyte +spermatophytes +spermatophytic +spermatozoa +spermatozoal +spermatozoan +spermatozoans +spermatozoid +spermatozoids +spermatozoon +spermic +spermicidal +spermicide +spermicides +spermine +spermines +spermiogeneses +spermiogenesis +spermophile +spermophiles +spermous +sperms +sperrylite +sperrylites +spessartine +spessartines +spessartite +spessartites +spew +spewed +spewer +spewers +spewing +spews +sphagnous +sphagnum +sphagnums +sphalerite +sphalerites +sphene +sphenes +sphenic +sphenodon +sphenodons +sphenodont +sphenoid +sphenoidal +sphenoids +sphenopsid +sphenopsids +spheral +sphere +sphered +spheres +spheric +spherical +spherically +sphericities +sphericity +spherics +spherier +spheriest +sphering +spheroid +spheroidal +spheroidally +spheroids +spherometer +spherometers +spheroplast +spheroplasts +spherule +spherules +spherulite +spherulites +spherulitic +sphery +sphincter +sphincteric +sphincters +sphinges +sphingid +sphingids +sphingosine +sphingosines +sphinx +sphinxes +sphinxlike +sphygmic +sphygmograph +sphygmographs +sphygmomanometer +sphygmomanometers +sphygmomanometries +sphygmomanometry +sphygmus +sphygmuses +spic +spica +spicae +spicas +spicate +spicated +spiccato +spiccatos +spice +spicebush +spicebushes +spiced +spiceless +spicer +spiceries +spicers +spicery +spices +spicey +spicier +spiciest +spicily +spiciness +spicinesses +spicing +spick +spicks +spics +spicula +spiculae +spicular +spiculation +spiculations +spicule +spicules +spiculum +spicy +spider +spiderier +spideriest +spiderish +spiderlike +spiders +spiderweb +spiderwebs +spiderwort +spiderworts +spidery +spied +spiegel +spiegeleisen +spiegeleisens +spiegels +spiel +spieled +spieler +spielers +spieling +spiels +spier +spiered +spiering +spiers +spies +spiff +spiffed +spiffier +spiffiest +spiffily +spiffiness +spiffinesses +spiffing +spiffs +spiffy +spigot +spigots +spik +spike +spiked +spikelet +spikelets +spikelike +spikenard +spikenards +spiker +spikers +spikes +spikey +spikier +spikiest +spikily +spikiness +spikinesses +spiking +spiks +spiky +spile +spiled +spiles +spilikin +spilikins +spiling +spilings +spill +spillable +spillage +spillages +spilled +spiller +spillers +spillikin +spillikins +spilling +spillover +spillovers +spills +spillway +spillways +spilt +spilth +spilths +spin +spinach +spinaches +spinachlike +spinachy +spinage +spinages +spinal +spinally +spinals +spinate +spindle +spindled +spindler +spindlers +spindles +spindlier +spindliest +spindling +spindly +spindrift +spindrifts +spine +spined +spinel +spineless +spinelessly +spinelessness +spinelessnesses +spinelike +spinelle +spinelles +spinels +spines +spinet +spinets +spinier +spiniest +spinifex +spinifexes +spininess +spininesses +spinless +spinnaker +spinnakers +spinner +spinneret +spinnerets +spinnerette +spinnerettes +spinneries +spinners +spinnery +spinney +spinneys +spinnies +spinning +spinnings +spinny +spinoff +spinoffs +spinor +spinors +spinose +spinosities +spinosity +spinous +spinout +spinouts +spins +spinster +spinsterhood +spinsterhoods +spinsterish +spinsterly +spinsters +spinthariscope +spinthariscopes +spinto +spintos +spinula +spinulae +spinule +spinules +spinulose +spiny +spiracle +spiracles +spiracular +spiraea +spiraeas +spiral +spiraled +spiraling +spiralled +spiralling +spirally +spirals +spirant +spirants +spire +spirea +spireas +spired +spirem +spireme +spiremes +spirems +spires +spirier +spiriest +spirilla +spirillum +spiring +spirit +spirited +spiritedly +spiritedness +spiritednesses +spiriting +spiritism +spiritisms +spiritist +spiritistic +spiritists +spiritless +spiritlessly +spiritlessness +spiritlessnesses +spiritoso +spiritous +spirits +spiritual +spiritualism +spiritualisms +spiritualist +spiritualistic +spiritualists +spiritualities +spirituality +spiritualization +spiritualizations +spiritualize +spiritualized +spiritualizes +spiritualizing +spiritually +spiritualness +spiritualnesses +spirituals +spiritualties +spiritualty +spirituel +spirituelle +spirituous +spirochaete +spirochaetes +spirochetal +spirochete +spirochetes +spirochetoses +spirochetosis +spirogyra +spirogyras +spiroid +spirometer +spirometers +spirometric +spirometries +spirometry +spirt +spirted +spirting +spirts +spirula +spirulae +spirulas +spiry +spit +spital +spitals +spitball +spitballs +spite +spited +spiteful +spitefuller +spitefullest +spitefully +spitefulness +spitefulnesses +spites +spitfire +spitfires +spiting +spits +spitted +spitter +spitters +spitting +spittle +spittlebug +spittlebugs +spittles +spittoon +spittoons +spitz +spitzes +spiv +spivs +splake +splakes +splanchnic +splash +splashboard +splashboards +splashdown +splashdowns +splashed +splasher +splashers +splashes +splashier +splashiest +splashily +splashiness +splashinesses +splashing +splashy +splat +splats +splatted +splatter +splattered +splattering +splatters +splatting +splay +splayed +splayfeet +splayfoot +splayfooted +splaying +splays +spleen +spleenful +spleenier +spleeniest +spleens +spleenwort +spleenworts +spleeny +splendent +splendid +splendider +splendidest +splendidly +splendidness +splendidnesses +splendiferous +splendiferously +splendiferousness +splendiferousnesses +splendor +splendorous +splendors +splendour +splendours +splendrous +splenectomies +splenectomize +splenectomized +splenectomizes +splenectomizing +splenectomy +splenetic +splenetically +splenetics +splenia +splenial +splenic +splenii +splenium +splenius +splenomegalies +splenomegaly +splent +splents +spleuchan +spleuchans +splice +spliced +splicer +splicers +splices +splicing +spliff +spliffs +spline +splined +splines +splining +splint +splinted +splinter +splintered +splintering +splinters +splintery +splinting +splints +split +splits +splitter +splitters +splitting +splodge +splodged +splodges +splodging +splore +splores +splosh +sploshed +sploshes +sploshing +splotch +splotched +splotches +splotchier +splotchiest +splotching +splotchy +splurge +splurged +splurger +splurgers +splurges +splurgier +splurgiest +splurging +splurgy +splutter +spluttered +splutterer +splutterers +spluttering +splutters +spluttery +spode +spodes +spodumene +spodumenes +spoil +spoilable +spoilage +spoilages +spoiled +spoiler +spoilers +spoiling +spoils +spoilsman +spoilsmen +spoilsport +spoilsports +spoilt +spoke +spoked +spoken +spokes +spokeshave +spokeshaves +spokesman +spokesmanship +spokesmanships +spokesmen +spokespeople +spokesperson +spokespersons +spokeswoman +spokeswomen +spoking +spoliate +spoliated +spoliates +spoliating +spoliation +spoliations +spoliator +spoliators +spondaic +spondaics +spondee +spondees +spondylites +spondylitides +spondylitis +spondylitises +sponge +sponged +sponger +spongers +sponges +spongeware +spongewares +spongier +spongiest +spongily +spongin +sponginess +sponginesses +sponging +spongins +spongy +sponsal +sponsion +sponsions +sponson +sponsons +sponsor +sponsored +sponsorial +sponsoring +sponsors +sponsorship +sponsorships +spontaneities +spontaneity +spontaneous +spontaneously +spontaneousness +spontaneousnesses +spontoon +spontoons +spoof +spoofed +spoofer +spooferies +spoofers +spoofery +spoofing +spoofs +spoofy +spook +spooked +spookeries +spookery +spookier +spookiest +spookily +spookiness +spookinesses +spooking +spookish +spooks +spooky +spool +spooled +spooling +spoolings +spools +spoon +spoonbill +spoonbills +spooned +spoonerism +spoonerisms +spooney +spooneys +spoonful +spoonfuls +spoonier +spoonies +spooniest +spoonily +spooning +spoons +spoonsful +spoony +spoor +spoored +spooring +spoors +sporadic +sporadically +sporal +sporangia +sporangial +sporangiophore +sporangiophores +sporangium +spore +spored +spores +sporicidal +sporicide +sporicides +sporing +sporocarp +sporocarps +sporocyst +sporocysts +sporogeneses +sporogenesis +sporogenic +sporogenous +sporogonia +sporogonic +sporogonies +sporogonium +sporogony +sporoid +sporophore +sporophores +sporophyll +sporophylls +sporophyte +sporophytes +sporophytic +sporopollenin +sporopollenins +sporotrichoses +sporotrichosis +sporotrichosises +sporozoa +sporozoan +sporozoans +sporozoite +sporozoites +sporozoon +sporran +sporrans +sport +sported +sporter +sporters +sportfisherman +sportfishermen +sportfishing +sportfishings +sportful +sportfully +sportfulness +sportfulnesses +sportier +sportiest +sportif +sportily +sportiness +sportinesses +sporting +sportingly +sportive +sportively +sportiveness +sportivenesses +sports +sportscast +sportscaster +sportscasters +sportscasting +sportscastings +sportscasts +sportsman +sportsmanlike +sportsmanly +sportsmanship +sportsmanships +sportsmen +sportswear +sportswoman +sportswomen +sportswriter +sportswriters +sportswriting +sportswritings +sporty +sporular +sporulate +sporulated +sporulates +sporulating +sporulation +sporulations +sporulative +sporule +sporules +spot +spotless +spotlessly +spotlessness +spotlessnesses +spotlight +spotlighted +spotlighting +spotlights +spotlit +spots +spottable +spotted +spotter +spotters +spottier +spottiest +spottily +spottiness +spottinesses +spotting +spotty +spousal +spousals +spouse +spoused +spouses +spousing +spout +spouted +spouter +spouters +spouting +spouts +sprachgefuhl +sprachgefuhls +spraddle +spraddled +spraddles +spraddling +sprag +sprags +sprain +sprained +spraining +sprains +sprang +sprangs +sprat +sprats +sprattle +sprattled +sprattles +sprattling +sprawl +sprawled +sprawler +sprawlers +sprawlier +sprawliest +sprawling +sprawls +sprawly +spray +sprayed +sprayer +sprayers +spraying +sprays +spread +spreadabilities +spreadability +spreadable +spreader +spreaders +spreading +spreads +spreadsheet +spreadsheets +spree +sprees +sprent +sprier +spriest +sprig +sprigged +sprigger +spriggers +spriggier +spriggiest +sprigging +spriggy +spright +sprightful +sprightfully +sprightfulness +sprightfulnesses +sprightlier +sprightliest +sprightliness +sprightlinesses +sprightly +sprights +sprigs +spring +springal +springald +springalds +springals +springboard +springboards +springbok +springboks +springe +springed +springeing +springer +springers +springes +springhead +springheads +springhouse +springhouses +springier +springiest +springily +springiness +springinesses +springing +springings +springlike +springs +springtail +springtails +springtide +springtides +springtime +springtimes +springwater +springwaters +springwood +springwoods +springy +sprinkle +sprinkled +sprinkler +sprinklered +sprinklers +sprinkles +sprinkling +sprinklings +sprint +sprinted +sprinter +sprinters +sprinting +sprints +sprit +sprite +sprites +sprits +spritsail +spritsails +spritz +spritzed +spritzer +spritzers +spritzes +spritzing +sprocket +sprockets +sprout +sprouted +sprouting +sprouts +spruce +spruced +sprucely +spruceness +sprucenesses +sprucer +spruces +sprucest +sprucier +spruciest +sprucing +sprucy +sprue +sprues +sprug +sprugs +sprung +spry +spryer +spryest +spryly +spryness +sprynesses +spud +spudded +spudder +spudders +spudding +spuds +spue +spued +spues +spuing +spume +spumed +spumes +spumier +spumiest +spuming +spumone +spumones +spumoni +spumonis +spumous +spumy +spun +spunbonded +spunk +spunked +spunkie +spunkier +spunkies +spunkiest +spunkily +spunkiness +spunkinesses +spunking +spunks +spunky +spur +spurgall +spurgalled +spurgalling +spurgalls +spurge +spurges +spurious +spuriously +spuriousness +spuriousnesses +spurn +spurned +spurner +spurners +spurning +spurns +spurred +spurrer +spurrers +spurrey +spurreys +spurrier +spurriers +spurries +spurring +spurry +spurs +spurt +spurted +spurting +spurtle +spurtles +spurts +sputa +sputnik +sputniks +sputter +sputtered +sputterer +sputterers +sputtering +sputters +sputum +spy +spyglass +spyglasses +spying +spymaster +spymasters +squab +squabbier +squabbiest +squabble +squabbled +squabbler +squabblers +squabbles +squabbling +squabby +squabs +squad +squadded +squadding +squadron +squadroned +squadroning +squadrons +squads +squalene +squalenes +squalid +squalider +squalidest +squalidly +squalidness +squalidnesses +squall +squalled +squaller +squallers +squallier +squalliest +squalling +squalls +squally +squalor +squalors +squama +squamae +squamate +squamation +squamations +squamosal +squamosals +squamose +squamous +squamulose +squander +squandered +squanderer +squanderers +squandering +squanders +square +squared +squarely +squareness +squarenesses +squarer +squarers +squares +squarest +squaring +squarish +squarishly +squarishness +squarishnesses +squash +squashed +squasher +squashers +squashes +squashier +squashiest +squashily +squashiness +squashinesses +squashing +squashy +squat +squatly +squatness +squatnesses +squats +squatted +squatter +squattered +squattering +squatters +squattest +squattier +squattiest +squatting +squatty +squaw +squawfish +squawfishes +squawk +squawked +squawker +squawkers +squawking +squawks +squawroot +squawroots +squaws +squeak +squeaked +squeaker +squeakers +squeakier +squeakiest +squeaking +squeaks +squeaky +squeal +squealed +squealer +squealers +squealing +squeals +squeamish +squeamishly +squeamishness +squeamishnesses +squeegee +squeegeed +squeegeeing +squeegees +squeezabilities +squeezability +squeezable +squeeze +squeezed +squeezer +squeezers +squeezes +squeezing +squeg +squegged +squegging +squegs +squelch +squelched +squelcher +squelchers +squelches +squelchier +squelchiest +squelching +squelchy +squeteague +squib +squibbed +squibbing +squibs +squid +squidded +squidding +squids +squiffed +squiffier +squiffiest +squiffy +squiggle +squiggled +squiggles +squigglier +squiggliest +squiggling +squiggly +squilgee +squilgeed +squilgeeing +squilgees +squill +squilla +squillae +squillas +squills +squinch +squinched +squinches +squinching +squinnied +squinnier +squinnies +squinniest +squinny +squinnying +squint +squinted +squinter +squinters +squintest +squintier +squintiest +squinting +squintingly +squints +squinty +squirarchies +squirarchy +squire +squirearchies +squirearchy +squired +squireen +squireens +squires +squiring +squirish +squirm +squirmed +squirmer +squirmers +squirmier +squirmiest +squirming +squirms +squirmy +squirrel +squirreled +squirreling +squirrelled +squirrelling +squirrelly +squirrels +squirt +squirted +squirter +squirters +squirting +squirts +squish +squished +squishes +squishier +squishiest +squishiness +squishinesses +squishing +squishy +squoosh +squooshed +squooshes +squooshier +squooshiest +squooshing +squooshy +squush +squushed +squushes +squushing +sraddha +sraddhas +sradha +sradhas +sri +sris +stab +stabbed +stabber +stabbers +stabbing +stabbings +stabile +stabiles +stabilities +stability +stabilization +stabilizations +stabilize +stabilized +stabilizer +stabilizers +stabilizes +stabilizing +stable +stabled +stableman +stablemate +stablemates +stablemen +stableness +stablenesses +stabler +stablers +stables +stablest +stabling +stablings +stablish +stablished +stablishes +stablishing +stablishment +stablishments +stably +stabs +staccati +staccato +staccatos +stack +stackable +stacked +stacker +stackers +stacking +stacks +stackup +stackups +stacte +stactes +staddle +staddles +stade +stades +stadia +stadias +stadium +stadiums +stadtholder +stadtholderate +stadtholderates +stadtholders +stadtholdership +stadtholderships +staff +staffed +staffer +staffers +staffing +staffs +stag +stage +stageable +stagecoach +stagecoaches +stagecraft +stagecrafts +staged +stageful +stagefuls +stagehand +stagehands +stagelike +stager +stagers +stages +stagestruck +stagey +stagflation +stagflationary +stagflations +staggard +staggards +staggart +staggarts +stagged +stagger +staggerbush +staggerbushes +staggered +staggerer +staggerers +staggering +staggeringly +staggers +staggery +staggie +staggier +staggies +staggiest +stagging +staggy +staghound +staghounds +stagier +stagiest +stagily +staginess +staginesses +staging +stagings +stagnancies +stagnancy +stagnant +stagnantly +stagnate +stagnated +stagnates +stagnating +stagnation +stagnations +stags +stagy +staid +staider +staidest +staidly +staidness +staidnesses +staig +staigs +stain +stainabilities +stainability +stainable +stained +stainer +stainers +staining +stainless +stainlesses +stainlessly +stainproof +stains +stair +staircase +staircases +stairs +stairway +stairways +stairwell +stairwells +staithe +staithes +stake +staked +stakeholder +stakeholders +stakeout +stakeouts +stakes +staking +stalactite +stalactites +stalactitic +stalag +stalagmite +stalagmites +stalagmitic +stalags +stale +staled +stalely +stalemate +stalemated +stalemates +stalemating +staleness +stalenesses +staler +stales +stalest +staling +stalk +stalked +stalker +stalkers +stalkier +stalkiest +stalkily +stalking +stalkless +stalks +stalky +stall +stalled +stallholder +stallholders +stalling +stallion +stallions +stalls +stalwart +stalwartly +stalwartness +stalwartnesses +stalwarts +stalworth +stalworths +stamen +stamens +stamina +staminal +staminas +staminate +staminodia +staminodium +stammel +stammels +stammer +stammered +stammerer +stammerers +stammering +stammers +stamp +stamped +stampede +stampeded +stampeder +stampeders +stampedes +stampeding +stamper +stampers +stamping +stampless +stamps +stance +stances +stanch +stanched +stancher +stanchers +stanches +stanchest +stanching +stanchion +stanchioned +stanchions +stanchly +stand +standard +standardbred +standardbreds +standardise +standardised +standardises +standardising +standardization +standardizations +standardize +standardized +standardizes +standardizing +standardless +standardly +standards +standaway +standby +standbys +standee +standees +stander +standers +standing +standings +standish +standishes +standoff +standoffish +standoffishly +standoffishness +standoffishnesses +standoffs +standout +standouts +standpat +standpatter +standpatters +standpattism +standpattisms +standpipe +standpipes +standpoint +standpoints +stands +standstill +standstills +standup +stane +staned +stanes +stang +stanged +stanging +stangs +stanhope +stanhopes +stanine +stanines +staning +stank +stanks +stannaries +stannary +stannic +stannite +stannites +stannous +stannum +stannums +stanza +stanzaed +stanzaic +stanzas +stapedectomies +stapedectomy +stapedes +stapedial +stapelia +stapelias +stapes +staph +staphs +staphylinid +staphylinids +staphylococcal +staphylococci +staphylococcic +staphylococcus +staple +stapled +stapler +staplers +staples +stapling +star +starboard +starboarded +starboarding +starboards +starch +starched +starches +starchier +starchiest +starchily +starchiness +starchinesses +starching +starchy +stardom +stardoms +stardust +stardusts +stare +stared +starer +starers +stares +starets +starfish +starfishes +starflower +starflowers +starfruit +starfruits +stargaze +stargazed +stargazer +stargazers +stargazes +stargazing +stargazings +staring +stark +starker +starkers +starkest +starkly +starkness +starknesses +starless +starlet +starlets +starlight +starlights +starlike +starling +starlings +starlit +starnose +starnoses +starred +starrier +starriest +starring +starry +stars +starship +starships +starstruck +start +started +starter +starters +starting +startle +startled +startlement +startlements +startler +startlers +startles +startling +startlingly +starts +startsy +startup +startups +starvation +starvations +starve +starved +starveling +starvelings +starver +starvers +starves +starving +starwort +starworts +stases +stash +stashed +stashes +stashing +stasima +stasimon +stasis +stat +statable +statal +statant +state +stateable +statecraft +statecrafts +stated +statedly +statehood +statehoods +statehouse +statehouses +stateless +statelessness +statelessnesses +statelier +stateliest +stateliness +statelinesses +stately +statement +statements +stater +stateroom +staterooms +staters +states +stateside +statesman +statesmanlike +statesmanly +statesmanship +statesmanships +statesmen +statewide +static +statical +statically +statice +statices +staticky +statics +stating +station +stational +stationary +stationed +stationer +stationeries +stationers +stationery +stationing +stationmaster +stationmasters +stations +statism +statisms +statist +statistic +statistical +statistically +statistician +statisticians +statistics +statists +stative +statives +statoblast +statoblasts +statocyst +statocysts +statolith +statoliths +stator +stators +statoscope +statoscopes +stats +statuaries +statuary +statue +statued +statues +statuesque +statuesquely +statuette +statuettes +stature +statures +status +statuses +statusy +statutable +statute +statutes +statutorily +statutory +staumrel +staumrels +staunch +staunched +stauncher +staunches +staunchest +staunching +staunchly +staunchness +staunchnesses +staurolite +staurolites +staurolitic +stave +staved +staves +stavesacre +stavesacres +staving +staw +stay +stayed +stayer +stayers +staying +stays +staysail +staysails +stead +steaded +steadfast +steadfastly +steadfastness +steadfastnesses +steadied +steadier +steadiers +steadies +steadiest +steadily +steadiness +steadinesses +steading +steadings +steads +steady +steadying +steak +steakhouse +steakhouses +steaks +steal +stealable +stealage +stealages +stealer +stealers +stealing +stealings +steals +stealth +stealthier +stealthiest +stealthily +stealthiness +stealthinesses +stealths +stealthy +steam +steamboat +steamboats +steamed +steamer +steamered +steamering +steamers +steamfitter +steamfitters +steamier +steamiest +steamily +steaminess +steaminesses +steaming +steamroll +steamrolled +steamroller +steamrollered +steamrollering +steamrollers +steamrolling +steamrolls +steams +steamship +steamships +steamy +steapsin +steapsins +stearate +stearates +stearic +stearin +stearine +stearines +stearins +steatite +steatites +steatitic +steatopygia +steatopygias +steatopygic +steatopygous +steatorrhea +steatorrheas +stedfast +steed +steeds +steek +steeked +steeking +steeks +steel +steeled +steelhead +steelheads +steelie +steelier +steelies +steeliest +steeliness +steelinesses +steeling +steelmaker +steelmakers +steelmaking +steelmakings +steels +steelwork +steelworker +steelworkers +steelworks +steely +steelyard +steelyards +steenbok +steenboks +steep +steeped +steepen +steepened +steepening +steepens +steeper +steepers +steepest +steeping +steepish +steeple +steeplebush +steeplebushes +steeplechase +steeplechaser +steeplechasers +steeplechases +steeplechasing +steeplechasings +steepled +steeplejack +steeplejacks +steeples +steeply +steepness +steepnesses +steeps +steer +steerable +steerage +steerages +steerageway +steerageways +steered +steerer +steerers +steering +steers +steersman +steersmen +steeve +steeved +steeves +steeving +steevings +stegodon +stegodons +stegosaur +stegosaurs +stegosaurus +stegosauruses +stein +steinbok +steinboks +steins +stela +stelae +stelai +stelar +stele +stelene +steles +stelic +stella +stellar +stellas +stellate +stellified +stellifies +stellify +stellifying +stem +stemless +stemlike +stemma +stemmas +stemmata +stemmatic +stemmed +stemmer +stemmeries +stemmers +stemmery +stemmier +stemmiest +stemming +stemmy +stems +stemson +stemsons +stemware +stemwares +stench +stenches +stenchful +stenchier +stenchiest +stenchy +stencil +stenciled +stenciler +stencilers +stenciling +stencilled +stenciller +stencillers +stencilling +stencils +stengah +stengahs +steno +stenobathic +stenographer +stenographers +stenographic +stenographically +stenographies +stenography +stenohaline +stenokies +stenoky +stenos +stenosed +stenoses +stenosis +stenotherm +stenothermal +stenotherms +stenotic +stenotopic +stenotype +stenotyped +stenotypes +stenotypies +stenotyping +stenotypist +stenotypists +stenotypy +stentor +stentorian +stentors +step +stepbrother +stepbrothers +stepchild +stepchildren +stepdame +stepdames +stepdaughter +stepdaughters +stepfamilies +stepfamily +stepfather +stepfathers +stephanotis +stephanotises +stepladder +stepladders +steplike +stepmother +stepmothers +stepparent +stepparenting +stepparentings +stepparents +steppe +stepped +stepper +steppers +steppes +stepping +steps +stepsister +stepsisters +stepson +stepsons +stepwise +stercoraceous +stere +stereo +stereochemical +stereochemistries +stereochemistry +stereoed +stereogram +stereograms +stereograph +stereographed +stereographic +stereographies +stereographing +stereographs +stereography +stereoing +stereoisomer +stereoisomeric +stereoisomerism +stereoisomerisms +stereoisomers +stereological +stereologically +stereologies +stereology +stereomicroscope +stereomicroscopes +stereomicroscopic +stereomicroscopically +stereophonic +stereophonically +stereophonies +stereophony +stereophotographic +stereophotographies +stereophotography +stereopses +stereopsides +stereopsis +stereopticon +stereopticons +stereoregular +stereoregularities +stereoregularity +stereos +stereoscope +stereoscopes +stereoscopic +stereoscopically +stereoscopies +stereoscopy +stereospecific +stereospecifically +stereospecificities +stereospecificity +stereotactic +stereotaxic +stereotaxically +stereotype +stereotyped +stereotyper +stereotypers +stereotypes +stereotypic +stereotypical +stereotypically +stereotypies +stereotyping +stereotypy +steres +steric +sterical +sterically +sterigma +sterigmas +sterigmata +sterilant +sterilants +sterile +sterilely +sterilities +sterility +sterilization +sterilizations +sterilize +sterilized +sterilizer +sterilizers +sterilizes +sterilizing +sterlet +sterlets +sterling +sterlingly +sterlingness +sterlingnesses +sterlings +stern +sterna +sternal +sterner +sternest +sternforemost +sternite +sternites +sternly +sternmost +sternness +sternnesses +sternocostal +sternpost +sternposts +sterns +sternson +sternsons +sternum +sternums +sternutation +sternutations +sternutator +sternutators +sternward +sternwards +sternway +sternways +steroid +steroidal +steroidogeneses +steroidogenesis +steroidogenic +steroids +sterol +sterols +stertor +stertorous +stertorously +stertors +stet +stethoscope +stethoscopes +stethoscopic +stets +stetted +stetting +stevedore +stevedored +stevedores +stevedoring +stew +steward +stewarded +stewardess +stewardesses +stewarding +stewards +stewardship +stewardships +stewbum +stewbums +stewed +stewing +stewpan +stewpans +stews +stey +sthenia +sthenias +sthenic +stibial +stibine +stibines +stibium +stibiums +stibnite +stibnites +stich +stichic +stichomythia +stichomythias +stichomythic +stichomythies +stichomythy +stichs +stick +stickball +stickballs +sticked +sticker +stickers +stickful +stickfuls +stickhandle +stickhandled +stickhandler +stickhandlers +stickhandles +stickhandling +stickier +stickiest +stickily +stickiness +stickinesses +sticking +stickit +stickle +stickleback +sticklebacks +stickled +stickler +sticklers +stickles +sticklike +stickling +stickman +stickmen +stickout +stickouts +stickpin +stickpins +sticks +stickseed +stickseeds +sticktight +sticktights +stickum +stickums +stickup +stickups +stickweed +stickweeds +stickwork +stickworks +sticky +stiction +stictions +stied +sties +stiff +stiffed +stiffen +stiffened +stiffener +stiffeners +stiffening +stiffens +stiffer +stiffest +stiffing +stiffish +stiffly +stiffness +stiffnesses +stiffs +stifle +stifled +stifler +stiflers +stifles +stifling +stiflingly +stigma +stigmal +stigmas +stigmasterol +stigmasterols +stigmata +stigmatic +stigmatically +stigmatics +stigmatist +stigmatists +stigmatization +stigmatizations +stigmatize +stigmatized +stigmatizes +stigmatizing +stilbene +stilbenes +stilbestrol +stilbestrols +stilbite +stilbites +stile +stiles +stiletto +stilettoed +stilettoes +stilettoing +stilettos +still +stillbirth +stillbirths +stillborn +stillborns +stilled +stiller +stillest +stillier +stilliest +stilling +stillman +stillmen +stillness +stillnesses +stillroom +stillrooms +stills +stilly +stilt +stilted +stiltedly +stiltedness +stiltednesses +stilting +stilts +stime +stimes +stimied +stimies +stimulant +stimulants +stimulate +stimulated +stimulates +stimulating +stimulation +stimulations +stimulative +stimulator +stimulators +stimulatory +stimuli +stimulus +stimy +stimying +sting +stingaree +stingarees +stinger +stingers +stingier +stingiest +stingily +stinginess +stinginesses +stinging +stingingly +stingless +stingo +stingos +stingray +stingrays +stings +stingy +stink +stinkard +stinkards +stinkbug +stinkbugs +stinker +stinkers +stinkhorn +stinkhorns +stinkier +stinkiest +stinking +stinkingly +stinko +stinkpot +stinkpots +stinks +stinkweed +stinkweeds +stinkwood +stinkwoods +stinky +stint +stinted +stinter +stinters +stinting +stints +stipe +stiped +stipel +stipels +stipend +stipendiaries +stipendiary +stipends +stipes +stipites +stipple +stippled +stippler +stipplers +stipples +stippling +stipular +stipulate +stipulated +stipulates +stipulating +stipulation +stipulations +stipulator +stipulators +stipulatory +stipule +stipuled +stipules +stir +stirabout +stirabouts +stirk +stirks +stirp +stirpes +stirps +stirred +stirrer +stirrers +stirring +stirringly +stirrup +stirrups +stirs +stitch +stitched +stitcher +stitcheries +stitchers +stitchery +stitches +stitching +stitchwort +stitchworts +stithied +stithies +stithy +stithying +stiver +stivers +stoa +stoae +stoai +stoas +stoat +stoats +stob +stobbed +stobbing +stobs +stoccado +stoccados +stoccata +stoccatas +stochastic +stochastically +stock +stockade +stockaded +stockades +stockading +stockbreeder +stockbreeders +stockbroker +stockbrokerage +stockbrokerages +stockbrokers +stockbroking +stockbrokings +stockcar +stockcars +stocked +stocker +stockers +stockfish +stockfishes +stockholder +stockholders +stockier +stockiest +stockily +stockiness +stockinesses +stockinet +stockinets +stockinette +stockinettes +stocking +stockinged +stockings +stockish +stockist +stockists +stockjobber +stockjobbers +stockjobbing +stockjobbings +stockkeeper +stockkeepers +stockman +stockmen +stockpile +stockpiled +stockpiler +stockpilers +stockpiles +stockpiling +stockpot +stockpots +stockroom +stockrooms +stocks +stocktaking +stocktakings +stocky +stockyard +stockyards +stodge +stodged +stodges +stodgier +stodgiest +stodgily +stodginess +stodginesses +stodging +stodgy +stogey +stogeys +stogie +stogies +stogy +stoic +stoical +stoically +stoichiometric +stoichiometrically +stoichiometries +stoichiometry +stoicism +stoicisms +stoics +stoke +stoked +stokehold +stokeholds +stoker +stokers +stokes +stokesia +stokesias +stoking +stole +stoled +stolen +stoles +stolid +stolider +stolidest +stolidities +stolidity +stolidly +stollen +stollens +stolon +stolonic +stoloniferous +stolons +stolport +stolports +stoma +stomach +stomachache +stomachaches +stomached +stomacher +stomachers +stomachic +stomachics +stomaching +stomachs +stomachy +stomal +stomas +stomata +stomatal +stomate +stomates +stomatic +stomatitides +stomatitis +stomatitises +stomatopod +stomatopods +stomodaea +stomodaeal +stomodaeum +stomodaeums +stomodea +stomodeal +stomodeum +stomodeums +stomp +stomped +stomper +stompers +stomping +stomps +stonable +stone +stoneboat +stoneboats +stonechat +stonechats +stonecrop +stonecrops +stonecutter +stonecutters +stonecutting +stonecuttings +stoned +stonefish +stonefishes +stoneflies +stonefly +stonemason +stonemasonries +stonemasonry +stonemasons +stoner +stoners +stones +stonewall +stonewalled +stonewaller +stonewallers +stonewalling +stonewalls +stoneware +stonewares +stonewashed +stonework +stoneworks +stonewort +stoneworts +stoney +stonier +stoniest +stonily +stoniness +stoninesses +stoning +stonish +stonished +stonishes +stonishing +stony +stonyhearted +stood +stooge +stooged +stooges +stooging +stook +stooked +stooker +stookers +stooking +stooks +stool +stooled +stoolie +stoolies +stooling +stools +stoop +stoopball +stoopballs +stooped +stooper +stoopers +stooping +stoops +stop +stopbank +stopbanks +stopcock +stopcocks +stope +stoped +stoper +stopers +stopes +stopgap +stopgaps +stoping +stoplight +stoplights +stopover +stopovers +stoppable +stoppage +stoppages +stopped +stopper +stoppered +stoppering +stoppers +stopping +stopple +stoppled +stopples +stoppling +stops +stopt +stopwatch +stopwatches +storable +storables +storage +storages +storax +storaxes +store +stored +storefront +storefronts +storehouse +storehouses +storekeeper +storekeepers +storeroom +storerooms +stores +storeship +storeships +storewide +storey +storeyed +storeys +storied +stories +storing +stork +storks +storksbill +storksbills +storm +stormbound +stormed +stormier +stormiest +stormily +storminess +storminesses +storming +storms +stormy +story +storyboard +storyboarded +storyboarding +storyboards +storybook +storybooks +storying +storyteller +storytellers +storytelling +storytellings +stoss +stotinka +stotinki +stound +stounded +stounding +stounds +stoup +stoups +stour +stoure +stoures +stourie +stours +stoury +stout +stouten +stoutened +stoutening +stoutens +stouter +stoutest +stouthearted +stoutheartedly +stoutheartedness +stoutheartednesses +stoutish +stoutly +stoutness +stoutnesses +stouts +stove +stovepipe +stovepipes +stover +stovers +stoves +stow +stowable +stowage +stowages +stowaway +stowaways +stowed +stowing +stowp +stowps +stows +strabismic +strabismus +strabismuses +straddle +straddled +straddler +straddlers +straddles +straddling +strafe +strafed +strafer +strafers +strafes +strafing +straggle +straggled +straggler +stragglers +straggles +stragglier +straggliest +straggling +straggly +straight +straightaway +straightaways +straightbred +straightbreds +straighted +straightedge +straightedges +straighten +straightened +straightener +straighteners +straightening +straightens +straighter +straightest +straightforward +straightforwardly +straightforwardness +straightforwardnesses +straightforwards +straighting +straightish +straightjacket +straightjacketed +straightjacketing +straightjackets +straightlaced +straightly +straightness +straightnesses +straights +straightway +strain +strained +strainer +strainers +straining +strains +strait +straiten +straitened +straitening +straitens +straiter +straitest +straitjacket +straitjacketed +straitjacketing +straitjackets +straitlaced +straitlacedly +straitlacedness +straitlacednesses +straitly +straitness +straitnesses +straits +strake +straked +strakes +stramash +stramashes +stramonies +stramonium +stramoniums +stramony +strand +stranded +strandedness +strandednesses +strander +stranders +stranding +strandline +strandlines +strands +strang +strange +strangely +strangeness +strangenesses +stranger +strangered +strangering +strangers +strangest +strangle +strangled +stranglehold +strangleholds +strangler +stranglers +strangles +strangling +strangulate +strangulated +strangulates +strangulating +strangulation +strangulations +stranguries +strangury +strap +straphang +straphanger +straphangers +straphanging +straphangs +straphung +strapless +straplesses +strappado +strappadoes +strappados +strapped +strapper +strappers +strapping +strappings +straps +strass +strasses +strata +stratagem +stratagems +stratal +stratas +strategic +strategical +strategically +strategies +strategist +strategists +strategize +strategized +strategizes +strategizing +strategy +strath +straths +strathspey +strathspeys +strati +stratification +stratifications +stratified +stratifies +stratiform +stratify +stratifying +stratigraphic +stratigraphies +stratigraphy +stratocracies +stratocracy +stratocumuli +stratocumulus +stratosphere +stratospheres +stratospheric +stratous +stratovolcano +stratovolcanoes +stratovolcanos +stratum +stratums +stratus +stravage +stravaged +stravages +stravaging +stravaig +stravaiged +stravaiging +stravaigs +straw +strawberries +strawberry +strawed +strawflower +strawflowers +strawhat +strawier +strawiest +strawing +straws +strawy +stray +strayed +strayer +strayers +straying +strays +streak +streaked +streaker +streakers +streakier +streakiest +streakiness +streakinesses +streaking +streakings +streaks +streaky +stream +streambed +streambeds +streamed +streamer +streamers +streamier +streamiest +streaming +streamings +streamlet +streamlets +streamline +streamlined +streamliner +streamliners +streamlines +streamlining +streams +streamside +streamsides +streamy +streek +streeked +streeker +streekers +streeking +streeks +streel +streeled +streeling +streels +street +streetcar +streetcars +streetlamp +streetlamps +streetlight +streetlights +streets +streetscape +streetscapes +streetwalker +streetwalkers +streetwalking +streetwalkings +streetwise +strength +strengthen +strengthened +strengthener +strengtheners +strengthening +strengthens +strengths +strenuosities +strenuosity +strenuous +strenuously +strenuousness +strenuousnesses +strep +streps +streptobacilli +streptobacillus +streptococcal +streptococci +streptococcic +streptococcus +streptokinase +streptokinases +streptolysin +streptolysins +streptomyces +streptomycete +streptomycetes +streptomycin +streptomycins +streptothricin +streptothricins +stress +stressed +stresses +stressful +stressfully +stressing +stressless +stresslessness +stresslessnesses +stressor +stressors +stretch +stretchabilities +stretchability +stretchable +stretched +stretcher +stretchers +stretches +stretchier +stretchiest +stretching +stretchy +stretta +strettas +strette +stretti +stretto +strettos +streusel +streusels +strew +strewed +strewer +strewers +strewing +strewment +strewments +strewn +strews +stria +striae +striate +striated +striates +striating +striation +striations +strick +stricken +strickle +strickled +strickles +strickling +stricks +strict +stricter +strictest +strictly +strictness +strictnesses +stricture +strictures +stridden +stride +stridence +stridences +stridencies +stridency +strident +stridently +strider +striders +strides +striding +stridor +stridors +stridulate +stridulated +stridulates +stridulating +stridulation +stridulations +stridulatory +stridulous +stridulously +strife +strifeless +strifes +strigil +strigils +strigose +strike +strikebound +strikebreaker +strikebreakers +strikebreaking +strikebreakings +strikeout +strikeouts +strikeover +strikeovers +striker +strikers +strikes +striking +strikingly +string +stringcourse +stringcourses +stringed +stringencies +stringency +stringendo +stringent +stringently +stringer +stringers +stringhalt +stringhalted +stringhalts +stringier +stringiest +stringiness +stringinesses +stringing +stringings +stringless +stringpiece +stringpieces +strings +stringy +stringybark +stringybarks +strip +stripe +striped +stripeless +striper +stripers +stripes +stripier +stripiest +striping +stripings +stripling +striplings +strippable +stripped +stripper +strippers +stripping +strips +stript +striptease +stripteaser +stripteasers +stripteases +stripy +strive +strived +striven +striver +strivers +strives +striving +strobe +strobes +strobic +strobil +strobila +strobilae +strobilation +strobilations +strobile +strobiles +strobili +strobils +strobilus +stroboscope +stroboscopes +stroboscopic +stroboscopically +strobotron +strobotrons +strode +stroganoff +stroke +stroked +stroker +strokers +strokes +stroking +stroll +strolled +stroller +strollers +strolling +strolls +stroma +stromal +stromata +stromatolite +stromatolites +stromatolitic +strong +strongbox +strongboxes +stronger +strongest +stronghold +strongholds +strongish +strongly +strongman +strongmen +strongyl +strongyle +strongyles +strongyloidiases +strongyloidiasis +strongyloidoses +strongyloidosis +strongyloidosises +strongyls +strontia +strontianite +strontianites +strontias +strontic +strontium +strontiums +strook +strop +strophanthin +strophanthins +strophe +strophes +strophic +stropped +stropper +stroppers +stroppier +stroppiest +stropping +stroppy +strops +stroud +strouding +stroudings +strouds +strove +strow +strowed +strowing +strown +strows +stroy +stroyed +stroyer +stroyers +stroying +stroys +struck +strucken +structural +structuralism +structuralisms +structuralist +structuralists +structuralization +structuralizations +structuralize +structuralized +structuralizes +structuralizing +structurally +structuration +structurations +structure +structured +structureless +structurelessness +structurelessnesses +structures +structuring +strudel +strudels +struggle +struggled +struggler +strugglers +struggles +struggling +strum +struma +strumae +strumas +strummed +strummer +strummers +strumming +strumose +strumous +strumpet +strumpets +strums +strung +strunt +strunted +strunting +strunts +strut +struthious +struts +strutted +strutter +strutters +strutting +strychnine +strychnines +stub +stubbed +stubbier +stubbiest +stubbily +stubbing +stubble +stubbled +stubbles +stubblier +stubbliest +stubbly +stubborn +stubborner +stubbornest +stubbornly +stubbornness +stubbornnesses +stubby +stubs +stucco +stuccoed +stuccoer +stuccoers +stuccoes +stuccoing +stuccos +stuccowork +stuccoworks +stuck +stud +studbook +studbooks +studded +studdie +studdies +studding +studdings +student +students +studentship +studentships +studfish +studfishes +studhorse +studhorses +studied +studiedly +studiedness +studiednesses +studier +studiers +studies +studio +studios +studious +studiously +studiousness +studiousnesses +studlier +studliest +studly +studs +studwork +studworks +study +studying +stuff +stuffed +stuffer +stuffers +stuffier +stuffiest +stuffily +stuffiness +stuffinesses +stuffing +stuffings +stuffless +stuffs +stuffy +stuiver +stuivers +stull +stulls +stultification +stultifications +stultified +stultifies +stultify +stultifying +stum +stumble +stumblebum +stumblebums +stumbled +stumbler +stumblers +stumbles +stumbling +stumblingly +stummed +stumming +stump +stumpage +stumpages +stumped +stumper +stumpers +stumpier +stumpiest +stumping +stumps +stumpy +stums +stun +stung +stunk +stunned +stunner +stunners +stunning +stunningly +stuns +stunsail +stunsails +stunt +stunted +stuntedness +stuntednesses +stunting +stuntman +stuntmen +stunts +stuntwoman +stuntwomen +stupa +stupas +stupe +stupefaction +stupefactions +stupefied +stupefies +stupefy +stupefying +stupefyingly +stupendous +stupendously +stupendousness +stupendousnesses +stupes +stupid +stupider +stupidest +stupidities +stupidity +stupidly +stupidness +stupidnesses +stupids +stupor +stuporous +stupors +sturdied +sturdier +sturdies +sturdiest +sturdily +sturdiness +sturdinesses +sturdy +sturgeon +sturgeons +sturt +sturts +stutter +stuttered +stutterer +stutterers +stuttering +stutters +sty +stye +styed +styes +stygian +stying +stylar +stylate +style +stylebook +stylebooks +styled +styleless +stylelessness +stylelessnesses +styler +stylers +styles +stylet +stylets +styli +styliform +styling +stylings +stylise +stylised +styliser +stylisers +stylises +stylish +stylishly +stylishness +stylishnesses +stylising +stylist +stylistic +stylistically +stylistics +stylists +stylite +stylites +stylitic +stylization +stylizations +stylize +stylized +stylizer +stylizers +stylizes +stylizing +stylobate +stylobates +stylographies +stylography +styloid +stylopodia +stylopodium +stylus +styluses +stymie +stymied +stymieing +stymies +stymy +stymying +stypsis +stypsises +styptic +styptics +styrax +styraxes +styrene +styrenes +suabilities +suability +suable +suably +suasion +suasions +suasive +suasively +suasiveness +suasivenesses +suasory +suave +suavely +suaveness +suavenesses +suaver +suavest +suavities +suavity +sub +suba +subabbot +subabbots +subacid +subacidly +subacidness +subacidnesses +subacrid +subacute +subacutely +subadar +subadars +subadolescent +subadolescents +subadult +subadults +subaerial +subaerially +subagencies +subagency +subagent +subagents +subah +subahdar +subahdars +subahs +subalar +suballocation +suballocations +subalpine +subaltern +subalterns +subantarctic +subapical +subaquatic +subaqueous +subarachnoid +subarachnoidal +subarctic +subarctics +subarea +subareas +subarid +subas +subassemblies +subassembly +subatmospheric +subatom +subatomic +subatoms +subaudible +subaudition +subauditions +subaverage +subaxial +subbase +subbasement +subbasements +subbases +subbasin +subbasins +subbass +subbasses +subbed +subbing +subbings +subbituminous +subblock +subblocks +subbranch +subbranches +subbreed +subbreeds +subcabinet +subcapsular +subcaste +subcastes +subcategories +subcategorization +subcategorizations +subcategorize +subcategorized +subcategorizes +subcategorizing +subcategory +subcause +subcauses +subceiling +subceilings +subcell +subcellar +subcellars +subcells +subcellular +subcenter +subcenters +subcentral +subcentrally +subchapter +subchapters +subchaser +subchasers +subchief +subchiefs +subclan +subclans +subclass +subclassed +subclasses +subclassification +subclassifications +subclassified +subclassifies +subclassify +subclassifying +subclassing +subclavian +subclavians +subclerk +subclerks +subclimax +subclimaxes +subclinical +subclinically +subcluster +subclusters +subcode +subcodes +subcollection +subcollections +subcollege +subcolleges +subcollegiate +subcolonies +subcolony +subcommission +subcommissions +subcommittee +subcommittees +subcommunities +subcommunity +subcompact +subcompacts +subcomponent +subcomponents +subconscious +subconsciouses +subconsciously +subconsciousness +subconsciousnesses +subcontinent +subcontinental +subcontinents +subcontract +subcontracted +subcontracting +subcontractor +subcontractors +subcontracts +subcontraoctave +subcontraoctaves +subcontraries +subcontrary +subcool +subcooled +subcooling +subcools +subcordate +subcoriaceous +subcortical +subcounties +subcounty +subcritical +subcrustal +subcult +subcults +subcultural +subculturally +subculture +subcultured +subcultures +subculturing +subcurative +subcuratives +subcutaneous +subcutaneously +subcutes +subcutis +subcutises +subdeacon +subdeacons +subdean +subdeans +subdeb +subdebs +subdebutante +subdebutantes +subdecision +subdecisions +subdepartment +subdepartments +subdepot +subdepots +subdermal +subdermally +subdevelopment +subdevelopments +subdialect +subdialects +subdirector +subdirectors +subdiscipline +subdisciplines +subdistrict +subdistricted +subdistricting +subdistricts +subdividable +subdivide +subdivided +subdivider +subdividers +subdivides +subdividing +subdivision +subdivisions +subdominant +subdominants +subdual +subduals +subduce +subduced +subduces +subducing +subduct +subducted +subducting +subduction +subductions +subducts +subdue +subdued +subduedly +subduer +subduers +subdues +subduing +subdural +subecho +subechoes +subeconomies +subeconomy +subedit +subedited +subediting +subeditor +subeditorial +subeditors +subedits +subemployed +subemployment +subemployments +subentries +subentry +subepidermal +subepoch +subepochs +suber +suberect +suberic +suberin +suberins +suberise +suberised +suberises +suberising +suberization +suberizations +suberize +suberized +suberizes +suberizing +suberose +suberous +subers +subfamilies +subfamily +subfield +subfields +subfile +subfiles +subfix +subfixes +subfloor +subfloors +subfluid +subfossil +subfossils +subframe +subframes +subfreezing +subfusc +subgenera +subgeneration +subgenerations +subgenre +subgenres +subgenus +subgenuses +subglacial +subglacially +subgoal +subgoals +subgovernment +subgovernments +subgrade +subgrades +subgraph +subgraphs +subgroup +subgroups +subgum +subgums +subhead +subheading +subheadings +subheads +subhuman +subhumans +subhumid +subidea +subideas +subindex +subindexes +subindices +subindustries +subindustry +subinfeudate +subinfeudated +subinfeudates +subinfeudating +subinfeudation +subinfeudations +subinhibitory +subinterval +subintervals +subirrigate +subirrigated +subirrigates +subirrigating +subirrigation +subirrigations +subitem +subitems +subito +subjacencies +subjacency +subjacent +subjacently +subject +subjected +subjecting +subjection +subjections +subjective +subjectively +subjectiveness +subjectivenesses +subjectives +subjectivise +subjectivised +subjectivises +subjectivising +subjectivism +subjectivisms +subjectivist +subjectivistic +subjectivists +subjectivities +subjectivity +subjectivization +subjectivizations +subjectivize +subjectivized +subjectivizes +subjectivizing +subjectless +subjects +subjoin +subjoined +subjoining +subjoins +subjugate +subjugated +subjugates +subjugating +subjugation +subjugations +subjugator +subjugators +subjunction +subjunctions +subjunctive +subjunctives +subkingdom +subkingdoms +sublanguage +sublanguages +sublate +sublated +sublates +sublating +sublation +sublations +sublease +subleased +subleases +subleasing +sublet +sublethal +sublethally +sublets +subletting +sublevel +sublevels +sublibrarian +sublibrarians +sublicense +sublicensed +sublicenses +sublicensing +sublieutenant +sublieutenants +sublimable +sublimate +sublimated +sublimates +sublimating +sublimation +sublimations +sublime +sublimed +sublimely +sublimeness +sublimenesses +sublimer +sublimers +sublimes +sublimest +subliminal +subliminally +subliming +sublimities +sublimity +subline +sublines +sublingual +subliteracies +subliteracy +subliterary +subliterate +subliterature +subliteratures +sublittoral +sublittorals +sublot +sublots +sublunar +sublunary +subluxation +subluxations +submanager +submanagers +submandibular +submandibulars +submarginal +submarine +submarined +submariner +submariners +submarines +submarining +submarket +submarkets +submaxillaries +submaxillary +submaximal +submediant +submediants +submenu +submenus +submerge +submerged +submergence +submergences +submerges +submergible +submerging +submerse +submersed +submerses +submersible +submersibles +submersing +submersion +submersions +submetacentric +submetacentrics +submicrogram +submicron +submicroscopic +submicroscopically +submillimeter +subminiature +subminimal +subminister +subministers +submiss +submission +submissions +submissive +submissively +submissiveness +submissivenesses +submit +submitochondrial +submits +submittal +submittals +submitted +submitting +submucosa +submucosae +submucosal +submucosas +submultiple +submultiples +submunition +submunitions +subnasal +subnational +subnet +subnets +subnetwork +subnetworks +subniche +subniches +subnodal +subnormal +subnormalities +subnormality +subnormally +subnuclear +suboceanic +suboptic +suboptimal +suboptimization +suboptimizations +suboptimize +suboptimized +suboptimizes +suboptimizing +suboptimum +suboral +suborbicular +suborbital +suborder +suborders +subordinate +subordinated +subordinately +subordinateness +subordinatenesses +subordinates +subordinating +subordination +subordinations +subordinative +subordinator +subordinators +suborganization +suborganizations +suborn +subornation +subornations +suborned +suborner +suborners +suborning +suborns +suboval +subovate +suboxide +suboxides +subpanel +subpanels +subpar +subparagraph +subparagraphs +subparallel +subpart +subparts +subpena +subpenaed +subpenaing +subpenas +subperiod +subperiods +subphase +subphases +subphyla +subphylum +subplot +subplots +subpoena +subpoenaed +subpoenaing +subpoenas +subpolar +subpopulation +subpopulations +subpotencies +subpotency +subpotent +subprimate +subprimates +subprincipal +subprincipals +subproblem +subproblems +subprocess +subprocesses +subproduct +subproducts +subprofessional +subprofessionals +subprogram +subprograms +subproject +subprojects +subproletariat +subproletariats +subpubic +subrace +subraces +subrational +subregion +subregional +subregions +subrent +subrents +subreption +subreptions +subreptitious +subreptitiously +subring +subrings +subrogate +subrogated +subrogates +subrogating +subrogation +subrogations +subroutine +subroutines +subrule +subrules +subs +subsale +subsales +subsample +subsampled +subsamples +subsampling +subsatellite +subsatellites +subsaturated +subsaturation +subsaturations +subscale +subscales +subscience +subsciences +subscribe +subscribed +subscriber +subscribers +subscribes +subscribing +subscript +subscription +subscriptions +subscripts +subsea +subsecretaries +subsecretary +subsect +subsection +subsections +subsector +subsectors +subsects +subsegment +subsegments +subseizure +subseizures +subsense +subsenses +subsentence +subsentences +subsequence +subsequences +subsequent +subsequently +subsequents +subsere +subseres +subseries +subserve +subserved +subserves +subservience +subserviences +subserviencies +subserviency +subservient +subserviently +subserving +subset +subsets +subshaft +subshafts +subshell +subshells +subshrub +subshrubs +subside +subsided +subsidence +subsidences +subsider +subsiders +subsides +subsidiaries +subsidiarily +subsidiarities +subsidiarity +subsidiary +subsidies +subsiding +subsidise +subsidised +subsidises +subsidising +subsidization +subsidizations +subsidize +subsidized +subsidizer +subsidizers +subsidizes +subsidizing +subsidy +subsist +subsisted +subsistence +subsistences +subsistent +subsisting +subsists +subsite +subsites +subskill +subskills +subsocial +subsocieties +subsociety +subsoil +subsoiled +subsoiler +subsoilers +subsoiling +subsoils +subsolar +subsonic +subsonically +subspace +subspaces +subspecialist +subspecialists +subspecialize +subspecialized +subspecializes +subspecializing +subspecialties +subspecialty +subspecies +subspecific +substage +substages +substance +substanceless +substances +substandard +substantial +substantialities +substantiality +substantially +substantialness +substantialnesses +substantials +substantiate +substantiated +substantiates +substantiating +substantiation +substantiations +substantiative +substantival +substantivally +substantive +substantively +substantiveness +substantivenesses +substantives +substantivize +substantivized +substantivizes +substantivizing +substate +substates +substation +substations +substituent +substituents +substitutabilities +substitutability +substitutable +substitute +substituted +substitutes +substituting +substitution +substitutional +substitutionally +substitutionary +substitutions +substitutive +substitutively +substrata +substrate +substrates +substratum +substructural +substructure +substructures +subsumable +subsume +subsumed +subsumes +subsuming +subsumption +subsumptions +subsurface +subsurfaces +subsystem +subsystems +subtask +subtasks +subtaxa +subtaxon +subtaxons +subteen +subteens +subtemperate +subtenancies +subtenancy +subtenant +subtenants +subtend +subtended +subtending +subtends +subterfuge +subterfuges +subterminal +subterranean +subterraneanly +subterraneous +subterraneously +subtest +subtests +subtext +subtexts +subtextual +subtheme +subthemes +subtherapeutic +subthreshold +subtile +subtilely +subtileness +subtilenesses +subtiler +subtilest +subtilin +subtilins +subtilisin +subtilisins +subtilization +subtilizations +subtilize +subtilized +subtilizes +subtilizing +subtilties +subtilty +subtitle +subtitled +subtitles +subtitling +subtle +subtleness +subtlenesses +subtler +subtlest +subtleties +subtlety +subtly +subtone +subtones +subtonic +subtonics +subtopia +subtopias +subtopic +subtopics +subtotal +subtotaled +subtotaling +subtotalled +subtotalling +subtotally +subtotals +subtract +subtracted +subtracter +subtracters +subtracting +subtraction +subtractions +subtractive +subtracts +subtrahend +subtrahends +subtreasuries +subtreasury +subtrend +subtrends +subtribe +subtribes +subtropic +subtropical +subtropics +subtunic +subtunics +subtype +subtypes +subulate +subumbrella +subumbrellas +subunit +subunits +suburb +suburban +suburbanise +suburbanised +suburbanises +suburbanising +suburbanite +suburbanites +suburbanization +suburbanizations +suburbanize +suburbanized +suburbanizes +suburbanizing +suburbans +suburbed +suburbia +suburbias +suburbs +subvarieties +subvariety +subvassal +subvassals +subvene +subvened +subvenes +subvening +subvention +subventionary +subventions +subversion +subversionary +subversions +subversive +subversively +subversiveness +subversivenesses +subversives +subvert +subverted +subverter +subverters +subverting +subverts +subvicar +subvicars +subviral +subvisible +subvisual +subvocal +subvocalization +subvocalizations +subvocalize +subvocalized +subvocalizes +subvocalizing +subvocally +subway +subwayed +subwaying +subways +subworld +subworlds +subwriter +subwriters +subzero +subzone +subzones +succah +succahs +succedanea +succedaneous +succedaneum +succedaneums +succedent +succeed +succeeded +succeeder +succeeders +succeeding +succeeds +success +successes +successful +successfully +successfulness +successfulnesses +succession +successional +successionally +successions +successive +successively +successiveness +successivenesses +successor +successors +succinate +succinates +succinct +succincter +succinctest +succinctly +succinctness +succinctnesses +succinic +succinyl +succinylcholine +succinylcholines +succinyls +succor +succored +succorer +succorers +succories +succoring +succors +succory +succotash +succotashes +succoth +succour +succoured +succouring +succours +succuba +succubae +succubi +succubus +succubuses +succulence +succulences +succulent +succulently +succulents +succumb +succumbed +succumbing +succumbs +succuss +succussed +succusses +succussing +such +suchlike +suchness +suchnesses +suck +sucked +sucker +suckered +suckering +suckers +suckfish +suckfishes +sucking +suckle +suckled +suckler +sucklers +suckles +suckless +suckling +sucklings +sucks +sucrase +sucrases +sucre +sucres +sucrose +sucroses +suction +suctional +suctioned +suctioning +suctions +suctorial +suctorian +suctorians +sudaria +sudaries +sudarium +sudary +sudation +sudations +sudatoria +sudatories +sudatorium +sudatoriums +sudatory +sudd +sudden +suddenly +suddenness +suddennesses +suddens +sudds +sudor +sudoral +sudoriferous +sudorific +sudorifics +sudors +suds +sudsed +sudser +sudsers +sudses +sudsier +sudsiest +sudsing +sudsless +sudsy +sue +sued +suede +sueded +suedes +sueding +suer +suers +sues +suet +suets +suety +suffari +suffaris +suffer +sufferable +sufferableness +sufferablenesses +sufferably +sufferance +sufferances +suffered +sufferer +sufferers +suffering +sufferings +suffers +suffice +sufficed +sufficer +sufficers +suffices +sufficiencies +sufficiency +sufficient +sufficiently +sufficing +suffix +suffixal +suffixation +suffixations +suffixed +suffixes +suffixing +sufflate +sufflated +sufflates +sufflating +suffocate +suffocated +suffocates +suffocating +suffocatingly +suffocation +suffocations +suffocative +suffragan +suffragans +suffrage +suffrages +suffragette +suffragettes +suffragist +suffragists +suffuse +suffused +suffuses +suffusing +suffusion +suffusions +suffusive +sugar +sugarberries +sugarberry +sugarcane +sugarcanes +sugarcoat +sugarcoated +sugarcoating +sugarcoats +sugared +sugarhouse +sugarhouses +sugarier +sugariest +sugaring +sugarless +sugarloaf +sugarloaves +sugarplum +sugarplums +sugars +sugary +suggest +suggested +suggester +suggesters +suggestibilities +suggestibility +suggestible +suggesting +suggestion +suggestions +suggestive +suggestively +suggestiveness +suggestivenesses +suggests +sugh +sughed +sughing +sughs +suicidal +suicidally +suicide +suicided +suicides +suiciding +suing +suint +suints +suit +suitabilities +suitability +suitable +suitableness +suitablenesses +suitably +suitcase +suitcases +suite +suited +suiter +suiters +suites +suiting +suitings +suitlike +suitor +suitors +suits +sukiyaki +sukiyakis +sukkah +sukkahs +sukkot +sukkoth +sulcal +sulcate +sulcated +sulci +sulcus +suldan +suldans +sulfa +sulfadiazine +sulfadiazines +sulfanilamide +sulfanilamides +sulfas +sulfatase +sulfatases +sulfate +sulfated +sulfates +sulfating +sulfhydryl +sulfhydryls +sulfid +sulfide +sulfides +sulfids +sulfinpyrazone +sulfinpyrazones +sulfinyl +sulfinyls +sulfite +sulfites +sulfitic +sulfo +sulfonamide +sulfonamides +sulfonate +sulfonated +sulfonates +sulfonating +sulfonation +sulfonations +sulfone +sulfones +sulfonic +sulfonium +sulfoniums +sulfonyl +sulfonyls +sulfonylurea +sulfonylureas +sulfoxide +sulfoxides +sulfur +sulfured +sulfuret +sulfureted +sulfureting +sulfurets +sulfuretted +sulfuretting +sulfuric +sulfuring +sulfurize +sulfurized +sulfurizes +sulfurizing +sulfurous +sulfurously +sulfurousness +sulfurousnesses +sulfurs +sulfury +sulfuryl +sulfuryls +sulk +sulked +sulker +sulkers +sulkier +sulkies +sulkiest +sulkily +sulkiness +sulkinesses +sulking +sulks +sulky +sullage +sullages +sullen +sullener +sullenest +sullenly +sullenness +sullennesses +sullied +sullies +sully +sullying +sulpha +sulphas +sulphate +sulphated +sulphates +sulphating +sulphid +sulphide +sulphides +sulphids +sulphite +sulphites +sulphone +sulphones +sulphur +sulphured +sulphureous +sulphuring +sulphurise +sulphurised +sulphurises +sulphurising +sulphurous +sulphurs +sulphury +sultan +sultana +sultanas +sultanate +sultanates +sultaness +sultanesses +sultanic +sultans +sultrier +sultriest +sultrily +sultriness +sultrinesses +sultry +sulu +sulus +sum +sumac +sumach +sumachs +sumacs +sumless +summa +summabilities +summability +summable +summae +summand +summands +summaries +summarily +summarise +summarised +summarises +summarising +summarizable +summarization +summarizations +summarize +summarized +summarizer +summarizers +summarizes +summarizing +summary +summas +summate +summated +summates +summating +summation +summational +summations +summative +summed +summer +summered +summerhouse +summerhouses +summerier +summeriest +summering +summerlike +summerlong +summerly +summers +summersault +summersaulted +summersaulting +summersaults +summertime +summertimes +summerwood +summerwoods +summery +summing +summit +summital +summited +summiteer +summiteers +summiting +summitries +summitry +summits +summon +summonable +summoned +summoner +summoners +summoning +summons +summonsed +summonses +summonsing +sumo +sumos +sump +sumps +sumpter +sumpters +sumptuary +sumptuous +sumptuously +sumptuousness +sumptuousnesses +sumpweed +sumpweeds +sums +sun +sunback +sunbaked +sunbath +sunbathe +sunbathed +sunbather +sunbathers +sunbathes +sunbathing +sunbaths +sunbeam +sunbeams +sunbeamy +sunbelt +sunbelts +sunbird +sunbirds +sunblock +sunblocks +sunbonnet +sunbonnets +sunbow +sunbows +sunburn +sunburned +sunburning +sunburns +sunburnt +sunburst +sunbursts +sunchoke +sunchokes +sundae +sundaes +sundeck +sundecks +sunder +sundered +sunderer +sunderers +sundering +sunders +sundew +sundews +sundial +sundials +sundog +sundogs +sundown +sundowner +sundowners +sundowns +sundress +sundresses +sundries +sundrops +sundry +sunfast +sunfish +sunfishes +sunflower +sunflowers +sung +sunglass +sunglasses +sunglow +sunglows +sunk +sunken +sunket +sunkets +sunlamp +sunlamps +sunland +sunlands +sunless +sunlight +sunlights +sunlike +sunlit +sunn +sunna +sunnah +sunnahs +sunnas +sunned +sunnier +sunniest +sunnily +sunniness +sunninesses +sunning +sunns +sunny +sunporch +sunporches +sunproof +sunrise +sunrises +sunroof +sunroofs +sunroom +sunrooms +suns +sunscald +sunscalds +sunscreen +sunscreening +sunscreens +sunseeker +sunseekers +sunset +sunsets +sunshade +sunshades +sunshine +sunshines +sunshiny +sunspot +sunspots +sunstone +sunstones +sunstroke +sunstrokes +sunstruck +sunsuit +sunsuits +suntan +suntanned +suntans +sunup +sunups +sunward +sunwards +sunwise +sup +supe +super +superable +superableness +superablenesses +superably +superabound +superabounded +superabounding +superabounds +superabsorbent +superabsorbents +superabundance +superabundances +superabundant +superabundantly +superachiever +superachievers +superactivities +superactivity +superadd +superadded +superadding +superaddition +superadditions +superadds +superadministrator +superadministrators +superagencies +superagency +superagent +superagents +superalloy +superalloys +superaltern +superalterns +superambitious +superannuate +superannuated +superannuates +superannuating +superannuation +superannuations +superathlete +superathletes +superb +superbad +superbank +superbanks +superber +superbest +superbillionaire +superbillionaires +superbitch +superbitches +superblock +superblocks +superbly +superbness +superbnesses +superboard +superboards +superbomb +superbomber +superbombers +superbombs +superbright +superbureaucrat +superbureaucrats +supercabinet +supercabinets +supercalender +supercalendered +supercalendering +supercalenders +supercar +supercargo +supercargoes +supercargos +supercarrier +supercarriers +supercars +supercautious +supercede +superceded +supercedes +superceding +supercenter +supercenters +supercharge +supercharged +supercharger +superchargers +supercharges +supercharging +superchic +superchurch +superchurches +superciliary +supercilious +superciliously +superciliousness +superciliousnesses +supercities +supercity +supercivilization +supercivilizations +supercivilized +superclass +superclasses +superclean +superclub +superclubs +supercluster +superclusters +supercoil +supercoiled +supercoiling +supercoils +supercollider +supercolliders +supercolossal +supercomfortable +supercompetitive +supercomputer +supercomputers +superconduct +superconducted +superconducting +superconductive +superconductivities +superconductivity +superconductor +superconductors +superconducts +superconfident +superconglomerate +superconglomerates +superconservative +supercontinent +supercontinents +superconvenient +supercool +supercooled +supercooling +supercools +supercop +supercops +supercorporation +supercorporations +supercriminal +supercriminals +supercritical +supercurrent +supercurrents +supercute +superdeluxe +superdiplomat +superdiplomats +supered +supereffective +superefficiencies +superefficiency +superefficient +superego +superegoist +superegoists +superegos +superelevate +superelevated +superelevates +superelevating +superelevation +superelevations +superelite +superelites +supereminence +supereminences +supereminent +supereminently +superencipher +superenciphered +superenciphering +superenciphers +supererogation +supererogations +supererogatory +superette +superettes +superexpensive +superexpress +superexpresses +superfamilies +superfamily +superfan +superfans +superfarm +superfarms +superfast +superfatted +superfecundation +superfecundations +superfetation +superfetations +superficial +superficialities +superficiality +superficially +superficies +superfine +superfirm +superfirms +superfix +superfixes +superflack +superflacks +superfluid +superfluidities +superfluidity +superfluids +superfluities +superfluity +superfluous +superfluously +superfluousness +superfluousnesses +superfund +superfunds +supergene +supergenes +supergiant +supergiants +superglue +superglues +supergood +supergovernment +supergovernments +supergraphics +supergravities +supergravity +supergroup +supergroups +supergrowth +supergrowths +superharden +superhardened +superhardening +superhardens +superheat +superheated +superheater +superheaters +superheating +superheats +superheavy +superheavyweight +superheavyweights +superhelical +superhelices +superhelix +superhelixes +superhero +superheroes +superheroine +superheroines +superheterodyne +superheterodynes +superhighway +superhighways +superhit +superhits +superhot +superhuman +superhumanities +superhumanity +superhumanly +superhumanness +superhumannesses +superhype +superhyped +superhypes +superhyping +superimposable +superimpose +superimposed +superimposes +superimposing +superimposition +superimpositions +superincumbent +superincumbently +superindividual +superinduce +superinduced +superinduces +superinducing +superinduction +superinductions +superinfect +superinfected +superinfecting +superinfection +superinfections +superinfects +supering +superinsulated +superintellectual +superintellectuals +superintelligence +superintelligences +superintelligent +superintend +superintended +superintendence +superintendences +superintendencies +superintendency +superintendent +superintendents +superintending +superintends +superintensities +superintensity +superior +superiorities +superiority +superiorly +superiors +superjacent +superjet +superjets +superjock +superjocks +superjumbo +superlain +superlarge +superlative +superlatively +superlativeness +superlativenesses +superlatives +superlawyer +superlawyers +superlay +superlie +superlies +superlight +superliner +superliners +superlobbyist +superlobbyists +superloyalist +superloyalists +superlunar +superlunary +superluxuries +superluxurious +superluxury +superlying +supermacho +supermachos +supermajorities +supermajority +supermale +supermales +superman +supermarket +supermarkets +supermasculine +supermassive +supermen +supermicro +supermicros +supermilitant +supermillionaire +supermillionaires +supermind +superminds +supermini +superminicomputer +superminicomputers +superminis +superminister +superministers +supermodel +supermodels +supermodern +supermom +supermoms +supernal +supernally +supernatant +supernatants +supernation +supernational +supernations +supernatural +supernaturalism +supernaturalisms +supernaturalist +supernaturalistic +supernaturalists +supernaturally +supernaturalness +supernaturalnesses +supernaturals +supernature +supernatures +supernormal +supernormalities +supernormality +supernormally +supernova +supernovae +supernovas +supernumeraries +supernumerary +supernutrition +supernutritions +superorder +superorders +superordinate +superorganic +superorganism +superorganisms +superorgasm +superorgasms +superovulate +superovulated +superovulates +superovulating +superovulation +superovulations +superoxide +superoxides +superparasitism +superparasitisms +superpatriot +superpatriotic +superpatriotism +superpatriotisms +superpatriots +superperson +superpersonal +superpersons +superphenomena +superphenomenon +superphosphate +superphosphates +superphysical +superpimp +superpimps +superplane +superplanes +superplastic +superplasticities +superplasticity +superplayer +superplayers +superpolite +superport +superports +superposable +superpose +superposed +superposes +superposing +superposition +superpositions +superpower +superpowered +superpowerful +superpowers +superpremium +superpremiums +superpro +superprofit +superprofits +superpros +superqualities +superquality +superrace +superraces +superreal +superrealism +superrealisms +superregenerative +superregional +superrich +superroad +superroads +superromantic +superromanticism +superromanticisms +supers +supersafe +supersale +supersales +supersalesman +supersalesmen +supersaturate +supersaturated +supersaturates +supersaturating +supersaturation +supersaturations +superscale +superscales +superschool +superschools +superscout +superscouts +superscribe +superscribed +superscribes +superscribing +superscript +superscription +superscriptions +superscripts +supersecrecies +supersecrecy +supersecret +supersecrets +supersede +supersedeas +superseded +superseder +superseders +supersedes +superseding +supersedure +supersedures +supersell +superseller +supersellers +supersells +supersensible +supersensitive +supersensitively +supersensitivities +supersensitivity +supersensory +superserviceable +supersession +supersessions +supersex +supersexes +supersexualities +supersexuality +supersharp +supershow +supershows +supersinger +supersingers +supersize +supersized +supersleuth +supersleuths +superslick +supersmart +supersmooth +supersoft +supersonic +supersonically +supersonics +supersophisticated +superspecial +superspecialist +superspecialists +superspecialization +superspecializations +superspecialized +superspecials +superspectacle +superspectacles +superspectacular +superspectaculars +superspeculation +superspeculations +superspies +superspy +superstar +superstardom +superstardoms +superstars +superstate +superstates +superstation +superstations +superstimulate +superstimulated +superstimulates +superstimulating +superstition +superstitions +superstitious +superstitiously +superstock +superstocks +superstore +superstores +superstrata +superstratum +superstrength +superstrengths +superstrike +superstrikes +superstring +superstrings +superstrong +superstructural +superstructure +superstructures +superstud +superstuds +supersubstantial +supersubtle +supersubtleties +supersubtlety +supersurgeon +supersurgeons +supersweet +supersymmetric +supersymmetries +supersymmetry +supersystem +supersystems +supertanker +supertankers +supertax +supertaxes +superterrific +superthick +superthin +superthriller +superthrillers +supertight +supertonic +supertonics +supervene +supervened +supervenes +supervenient +supervening +supervention +superventions +supervirile +supervirtuosi +supervirtuoso +supervirtuosos +supervise +supervised +supervises +supervising +supervision +supervisions +supervisor +supervisors +supervisory +superwave +superwaves +superweapon +superweapons +superwide +superwife +superwives +superwoman +superwomen +supes +supinate +supinated +supinates +supinating +supination +supinations +supinator +supinators +supine +supinely +supineness +supinenesses +supines +supped +supper +suppers +suppertime +suppertimes +supping +supplant +supplantation +supplantations +supplanted +supplanter +supplanters +supplanting +supplants +supple +suppled +supplejack +supplejacks +supplely +supplement +supplemental +supplementals +supplementary +supplementation +supplementations +supplemented +supplementer +supplementers +supplementing +supplements +suppleness +supplenesses +suppler +supples +supplest +suppletion +suppletions +suppletive +suppletory +suppliance +suppliances +suppliant +suppliantly +suppliants +supplicant +supplicants +supplicate +supplicated +supplicates +supplicating +supplication +supplications +supplicatory +supplied +supplier +suppliers +supplies +suppling +supply +supplying +support +supportabilities +supportability +supportable +supported +supporter +supporters +supporting +supportive +supportiveness +supportivenesses +supports +supposable +supposably +supposal +supposals +suppose +supposed +supposedly +supposer +supposers +supposes +supposing +supposition +suppositional +suppositions +suppositious +supposititious +supposititiously +suppositories +suppository +suppress +suppressant +suppressants +suppressed +suppresses +suppressibilities +suppressibility +suppressible +suppressing +suppression +suppressions +suppressive +suppressiveness +suppressivenesses +suppressor +suppressors +suppurate +suppurated +suppurates +suppurating +suppuration +suppurations +suppurative +supra +supraliminal +supramolecular +supranational +supranationalism +supranationalisms +supranationalist +supranationalists +supranationalities +supranationality +supraoptic +supraorbital +suprarational +suprarenal +suprarenals +suprasegmental +supraventricular +supravital +supravitally +supremacies +supremacist +supremacists +supremacy +suprematism +suprematisms +suprematist +suprematists +supreme +supremely +supremeness +supremenesses +supremer +supremest +supremo +supremos +sups +suq +suqs +sura +surah +surahs +sural +suras +surbase +surbased +surbases +surcease +surceased +surceases +surceasing +surcharge +surcharged +surcharges +surcharging +surcingle +surcingles +surcoat +surcoats +surd +surds +sure +surefire +surefooted +surefootedly +surefootedness +surefootednesses +surely +sureness +surenesses +surer +surest +sureties +surety +suretyship +suretyships +surf +surfable +surface +surfaced +surfacer +surfacers +surfaces +surfacing +surfacings +surfactant +surfactants +surfbird +surfbirds +surfboard +surfboarded +surfboarder +surfboarders +surfboarding +surfboards +surfboat +surfboats +surfed +surfeit +surfeited +surfeiter +surfeiters +surfeiting +surfeits +surfer +surfers +surffish +surffishes +surficial +surfier +surfiest +surfing +surfings +surflike +surfperch +surfperches +surfs +surfy +surge +surged +surgeon +surgeonfish +surgeonfishes +surgeons +surger +surgeries +surgers +surgery +surges +surgical +surgically +surging +surgy +suricate +suricates +surimi +surjection +surjections +surjective +surlier +surliest +surlily +surliness +surlinesses +surly +surmise +surmised +surmiser +surmisers +surmises +surmising +surmount +surmountable +surmounted +surmounting +surmounts +surname +surnamed +surnamer +surnamers +surnames +surnaming +surpass +surpassable +surpassed +surpasses +surpassing +surpassingly +surplice +surplices +surplus +surplusage +surplusages +surpluses +surprint +surprinted +surprinting +surprints +surprisal +surprisals +surprise +surprised +surpriser +surprisers +surprises +surprising +surprisingly +surprize +surprized +surprizes +surprizing +surra +surras +surreal +surrealism +surrealisms +surrealist +surrealistic +surrealistically +surrealists +surreally +surrebutter +surrebutters +surrejoinder +surrejoinders +surrender +surrendered +surrendering +surrenders +surreptitious +surreptitiously +surrey +surreys +surrogacies +surrogacy +surrogate +surrogated +surrogates +surrogating +surround +surrounded +surrounding +surroundings +surrounds +surroyal +surroyals +surtax +surtaxed +surtaxes +surtaxing +surtout +surtouts +surveil +surveillance +surveillances +surveillant +surveillants +surveilled +surveilling +surveils +survey +surveyed +surveying +surveyings +surveyor +surveyors +surveys +survivabilities +survivability +survivable +survival +survivalist +survivalists +survivals +survivance +survivances +survive +survived +surviver +survivers +survives +surviving +survivor +survivors +survivorship +survivorships +susceptibilities +susceptibility +susceptible +susceptibleness +susceptiblenesses +susceptibly +susceptive +susceptiveness +susceptivenesses +susceptivities +susceptivity +sushi +sushis +suslik +susliks +suspect +suspected +suspecting +suspects +suspend +suspended +suspender +suspendered +suspenders +suspending +suspends +suspense +suspenseful +suspensefully +suspensefulness +suspensefulnesses +suspenseless +suspenser +suspensers +suspenses +suspension +suspensions +suspensive +suspensively +suspensor +suspensories +suspensors +suspensory +suspicion +suspicioned +suspicioning +suspicions +suspicious +suspiciously +suspiciousness +suspiciousnesses +suspiration +suspirations +suspire +suspired +suspires +suspiring +suss +sussed +susses +sussing +sustain +sustainabilities +sustainability +sustainable +sustained +sustainedly +sustainer +sustainers +sustaining +sustains +sustenance +sustenances +sustentation +sustentations +sustentative +susurrant +susurration +susurrations +susurrous +susurrus +susurruses +sutler +sutlers +sutra +sutras +sutta +suttas +suttee +suttees +sutural +suturally +suture +sutured +sutures +suturing +suzerain +suzerains +suzerainties +suzerainty +svaraj +svarajes +svedberg +svedbergs +svelte +sveltely +svelteness +sveltenesses +svelter +sveltest +swab +swabbed +swabber +swabbers +swabbie +swabbies +swabbing +swabby +swabs +swacked +swaddle +swaddled +swaddles +swaddling +swag +swage +swaged +swager +swagers +swages +swagged +swagger +swaggered +swaggerer +swaggerers +swaggering +swaggeringly +swaggers +swaggie +swaggies +swagging +swaging +swagman +swagmen +swags +swail +swails +swain +swainish +swainishness +swainishnesses +swains +swale +swales +swallow +swallowable +swallowed +swallower +swallowers +swallowing +swallows +swallowtail +swallowtails +swam +swami +swamies +swamis +swamp +swamped +swamper +swampers +swampier +swampiest +swampiness +swampinesses +swamping +swampish +swampland +swamplands +swamps +swampy +swamy +swan +swang +swanherd +swanherds +swank +swanked +swanker +swankest +swankier +swankiest +swankily +swankiness +swankinesses +swanking +swanks +swanky +swanlike +swanned +swanneries +swannery +swanning +swanpan +swanpans +swans +swansdown +swansdowns +swanskin +swanskins +swap +swapped +swapper +swappers +swapping +swaps +swaraj +swarajes +swarajist +swarajists +sward +swarded +swarding +swards +sware +swarf +swarfs +swarm +swarmed +swarmer +swarmers +swarming +swarms +swart +swarth +swarthier +swarthiest +swarthiness +swarthinesses +swarths +swarthy +swartness +swartnesses +swarty +swash +swashbuckle +swashbuckled +swashbuckler +swashbucklers +swashbuckles +swashbuckling +swashed +swasher +swashers +swashes +swashing +swastica +swasticas +swastika +swastikas +swat +swatch +swatches +swath +swathe +swathed +swather +swathers +swathes +swathing +swaths +swats +swatted +swatter +swatters +swatting +sway +swayable +swayback +swaybacked +swaybacks +swayed +swayer +swayers +swayful +swaying +sways +swear +swearer +swearers +swearing +swears +swearword +swearwords +sweat +sweatband +sweatbands +sweatbox +sweatboxes +sweated +sweater +sweaterdress +sweaterdresses +sweaters +sweatier +sweatiest +sweatily +sweatiness +sweatinesses +sweating +sweatpants +sweats +sweatshirt +sweatshirts +sweatshop +sweatshops +sweaty +swede +swedes +sweenies +sweeny +sweep +sweepback +sweepbacks +sweeper +sweepers +sweepier +sweepiest +sweeping +sweepingly +sweepingness +sweepingnesses +sweepings +sweeps +sweepstakes +sweepy +sweer +sweet +sweetbread +sweetbreads +sweetbriar +sweetbriars +sweetbrier +sweetbriers +sweeten +sweetened +sweetener +sweeteners +sweetening +sweetenings +sweetens +sweeter +sweetest +sweetheart +sweethearts +sweetie +sweeties +sweeting +sweetings +sweetish +sweetishly +sweetly +sweetmeat +sweetmeats +sweetness +sweetnesses +sweets +sweetshop +sweetshops +sweetsop +sweetsops +swell +swelled +sweller +swellest +swellfish +swellfishes +swellhead +swellheaded +swellheadedness +swellheadednesses +swellheads +swelling +swellings +swells +swelter +sweltered +sweltering +swelteringly +swelters +sweltrier +sweltriest +sweltry +swept +swerve +swerved +swerver +swervers +swerves +swerving +sweven +swevens +swidden +swiddens +swift +swifter +swifters +swiftest +swiftlet +swiftlets +swiftly +swiftness +swiftnesses +swifts +swig +swigged +swigger +swiggers +swigging +swigs +swill +swilled +swiller +swillers +swilling +swills +swim +swimmable +swimmer +swimmeret +swimmerets +swimmers +swimmier +swimmiest +swimmily +swimming +swimmingly +swimmings +swimmy +swims +swimsuit +swimsuits +swimwear +swindle +swindled +swindler +swindlers +swindles +swindling +swine +swineherd +swineherds +swinepox +swinepoxes +swing +swingby +swingbys +swinge +swinged +swingeing +swinger +swingers +swinges +swingier +swingiest +swinging +swingingest +swingingly +swingings +swingle +swingled +swingles +swingletree +swingletrees +swingling +swingman +swingmen +swings +swingy +swinish +swinishly +swinishness +swinishnesses +swink +swinked +swinking +swinks +swinney +swinneys +swipe +swiped +swipes +swiping +swiple +swiples +swipple +swipples +swirl +swirled +swirlier +swirliest +swirling +swirlingly +swirls +swirly +swish +swished +swisher +swishers +swishes +swishier +swishiest +swishing +swishingly +swishy +swiss +swisses +switch +switchable +switchback +switchbacked +switchbacking +switchbacks +switchblade +switchblades +switchboard +switchboards +switched +switcher +switcheroo +switcheroos +switchers +switches +switchgrass +switchgrasses +switching +switchman +switchmen +switchyard +switchyards +swith +swithe +swither +swithered +swithering +swithers +swithly +swive +swived +swivel +swiveled +swiveling +swivelled +swivelling +swivels +swives +swivet +swivets +swiving +swizzle +swizzled +swizzler +swizzlers +swizzles +swizzling +swob +swobbed +swobber +swobbers +swobbing +swobs +swollen +swoon +swooned +swooner +swooners +swooning +swooningly +swoons +swoop +swooped +swooper +swoopers +swooping +swoops +swoopstake +swoosh +swooshed +swooshes +swooshing +swop +swopped +swopping +swops +sword +swordfish +swordfishes +swordlike +swordman +swordmen +swordplay +swordplayer +swordplayers +swordplays +swords +swordsman +swordsmanship +swordsmanships +swordsmen +swordtail +swordtails +swore +sworn +swot +swots +swotted +swotter +swotters +swotting +swoun +swound +swounded +swounding +swounds +swouned +swouning +swouns +swum +swung +sybarite +sybarites +sybaritic +sybaritically +sybaritism +sybaritisms +sybo +syboes +sycamine +sycamines +sycamore +sycamores +syce +sycee +sycees +syces +sycomore +sycomores +syconia +syconium +sycophancies +sycophancy +sycophant +sycophantic +sycophantically +sycophantish +sycophantishly +sycophantism +sycophantisms +sycophantly +sycophants +sycoses +sycosis +syenite +syenites +syenitic +syke +sykes +syli +sylis +syllabaries +syllabary +syllabi +syllabic +syllabically +syllabicate +syllabicated +syllabicates +syllabicating +syllabication +syllabications +syllabicities +syllabicity +syllabics +syllabification +syllabifications +syllabified +syllabifies +syllabify +syllabifying +syllable +syllabled +syllables +syllabling +syllabub +syllabubs +syllabus +syllabuses +syllepses +syllepsis +sylleptic +syllogism +syllogisms +syllogist +syllogistic +syllogistically +syllogists +syllogize +syllogized +syllogizes +syllogizing +sylph +sylphic +sylphid +sylphids +sylphish +sylphlike +sylphs +sylphy +sylva +sylvae +sylvan +sylvanite +sylvanites +sylvans +sylvas +sylvatic +sylviculture +sylvicultures +sylvin +sylvine +sylvines +sylvins +sylvite +sylvites +symbion +symbions +symbiont +symbionts +symbioses +symbiosis +symbiot +symbiote +symbiotes +symbiotic +symbiotically +symbiots +symbol +symboled +symbolic +symbolical +symbolically +symboling +symbolise +symbolised +symbolises +symbolising +symbolism +symbolisms +symbolist +symbolistic +symbolists +symbolization +symbolizations +symbolize +symbolized +symbolizer +symbolizers +symbolizes +symbolizing +symbolled +symbolling +symbologies +symbology +symbols +symmetallism +symmetallisms +symmetric +symmetrical +symmetrically +symmetricalness +symmetricalnesses +symmetries +symmetrization +symmetrizations +symmetrize +symmetrized +symmetrizes +symmetrizing +symmetry +sympathectomies +sympathectomized +sympathectomy +sympathetic +sympathetically +sympathetics +sympathies +sympathin +sympathins +sympathise +sympathised +sympathises +sympathising +sympathize +sympathized +sympathizer +sympathizers +sympathizes +sympathizing +sympatholytic +sympatholytics +sympathomimetic +sympathomimetics +sympathy +sympatric +sympatrically +sympatries +sympatry +sympetalies +sympetalous +sympetaly +symphonic +symphonically +symphonies +symphonious +symphoniously +symphonist +symphonists +symphony +symphyseal +symphyses +symphysial +symphysis +sympodia +sympodial +sympodium +symposia +symposiarch +symposiarchs +symposiast +symposiasts +symposium +symposiums +symptom +symptomatic +symptomatically +symptomatologic +symptomatological +symptomatologically +symptomatologies +symptomatology +symptomless +symptoms +syn +synaereses +synaeresis +synaestheses +synaesthesia +synaesthesias +synaesthesis +synagog +synagogal +synagogs +synagogue +synagogues +synalepha +synalephas +synaloepha +synaloephas +synanon +synanons +synapse +synapsed +synapses +synapsid +synapsids +synapsing +synapsis +synaptic +synaptically +synaptosomal +synaptosome +synaptosomes +synarthrodial +synarthroses +synarthrosis +sync +syncarp +syncarpies +syncarpous +syncarps +syncarpy +syncategorematic +syncategorematically +synced +synch +synched +synching +synchro +synchrocyclotron +synchrocyclotrons +synchromesh +synchromeshes +synchronal +synchroneities +synchroneity +synchronic +synchronical +synchronically +synchronicities +synchronicity +synchronies +synchronisation +synchronisations +synchronise +synchronised +synchronises +synchronising +synchronism +synchronisms +synchronistic +synchronization +synchronizations +synchronize +synchronized +synchronizer +synchronizers +synchronizes +synchronizing +synchronous +synchronously +synchronousness +synchronousnesses +synchrony +synchros +synchroscope +synchroscopes +synchrotron +synchrotrons +synchs +syncing +synclinal +syncline +synclines +syncom +syncoms +syncopal +syncopate +syncopated +syncopates +syncopating +syncopation +syncopations +syncopative +syncopator +syncopators +syncope +syncopes +syncopic +syncretic +syncretise +syncretised +syncretises +syncretising +syncretism +syncretisms +syncretist +syncretistic +syncretists +syncretize +syncretized +syncretizes +syncretizing +syncs +syncytia +syncytial +syncytium +syndactylies +syndactylism +syndactylisms +syndactyly +syndeses +syndesis +syndesises +syndesmoses +syndesmosis +syndet +syndetic +syndetically +syndets +syndic +syndical +syndicalism +syndicalisms +syndicalist +syndicalists +syndicate +syndicated +syndicates +syndicating +syndication +syndications +syndicator +syndicators +syndics +syndrome +syndromes +syne +synecdoche +synecdoches +synecdochic +synecdochical +synecdochically +synecological +synecologies +synecology +synectic +synereses +syneresis +synergetic +synergia +synergias +synergic +synergically +synergid +synergids +synergies +synergism +synergisms +synergist +synergistic +synergistically +synergists +synergy +synesis +synesises +synesthesia +synesthesias +synesthetic +synfuel +synfuels +syngamic +syngamies +syngamy +syngas +syngases +syngasses +syngeneic +synizeses +synizesis +synkaryon +synkaryons +synod +synodal +synodic +synodical +synods +synonym +synonyme +synonymes +synonymic +synonymical +synonymies +synonymist +synonymists +synonymities +synonymity +synonymize +synonymized +synonymizes +synonymizing +synonymous +synonymously +synonyms +synonymy +synopses +synopsis +synopsize +synopsized +synopsizes +synopsizing +synoptic +synoptical +synoptically +synostoses +synostosis +synovia +synovial +synovias +synovitis +synovitises +syntactic +syntactical +syntactically +syntactics +syntagma +syntagmas +syntagmata +syntagmatic +syntax +syntaxes +synth +syntheses +synthesis +synthesist +synthesists +synthesize +synthesized +synthesizer +synthesizers +synthesizes +synthesizing +synthetase +synthetases +synthetic +synthetically +synthetics +synths +syntonic +syntonies +syntony +synura +synurae +syph +sypher +syphered +syphering +syphers +syphilis +syphilises +syphilitic +syphilitics +syphon +syphoned +syphoning +syphons +syphs +syren +syrens +syringa +syringas +syringe +syringed +syringes +syringing +syringomyelia +syringomyelias +syringomyelic +syrinx +syrinxes +syrphian +syrphians +syrphid +syrphids +syrup +syrups +syrupy +sysop +sysops +systaltic +system +systematic +systematically +systematicness +systematicnesses +systematics +systematise +systematised +systematises +systematising +systematism +systematisms +systematist +systematists +systematization +systematizations +systematize +systematized +systematizer +systematizers +systematizes +systematizing +systemic +systemically +systemics +systemization +systemizations +systemize +systemized +systemizes +systemizing +systemless +systems +systole +systoles +systolic +syzygal +syzygial +syzygies +syzygy +ta +tab +tabanid +tabanids +tabard +tabarded +tabards +tabaret +tabarets +tabbed +tabbied +tabbies +tabbing +tabbis +tabbises +tabbouleh +tabboulehs +tabby +tabbying +taber +tabered +tabering +tabernacle +tabernacled +tabernacles +tabernacling +tabernacular +tabers +tabes +tabetic +tabetics +tabid +tabla +tablas +tablature +tablatures +table +tableau +tableaus +tableaux +tablecloth +tablecloths +tabled +tableful +tablefuls +tableland +tablelands +tablemate +tablemates +tables +tablesful +tablespoon +tablespoonful +tablespoonfuls +tablespoons +tablespoonsful +tablet +tableted +tableting +tabletop +tabletops +tablets +tabletted +tabletting +tableware +tablewares +tabling +tabloid +tabloids +taboo +tabooed +tabooing +tabooley +tabooleys +taboos +tabor +tabored +taborer +taborers +taboret +taborets +taborin +taborine +taborines +taboring +taborins +tabors +tabouli +taboulis +tabour +taboured +tabourer +tabourers +tabouret +tabourets +tabouring +tabours +tabs +tabu +tabued +tabuing +tabular +tabulate +tabulated +tabulates +tabulating +tabulation +tabulations +tabulator +tabulators +tabuli +tabulis +tabun +tabuns +tabus +tacamahac +tacamahacs +tace +taces +tacet +tach +tache +taches +tachinid +tachinids +tachism +tachisme +tachismes +tachisms +tachist +tachiste +tachistes +tachistoscope +tachistoscopes +tachistoscopic +tachistoscopically +tachists +tachometer +tachometers +tachs +tachyarrhythmia +tachyarrhythmias +tachycardia +tachycardias +tachyon +tachyons +tacit +tacitly +tacitness +tacitnesses +taciturn +taciturnities +taciturnity +tack +tackboard +tackboards +tacked +tacker +tackers +tacket +tackets +tackey +tackier +tackiest +tackified +tackifier +tackifiers +tackifies +tackify +tackifying +tackily +tackiness +tackinesses +tacking +tackle +tackled +tackler +tacklers +tackles +tackless +tackling +tacklings +tacks +tacky +tacnode +tacnodes +taco +taconite +taconites +tacos +tact +tactful +tactfully +tactfulness +tactfulnesses +tactic +tactical +tactically +tactician +tacticians +tactics +tactile +tactilely +tactilities +tactility +taction +tactions +tactless +tactlessly +tactlessness +tactlessnesses +tacts +tactual +tactually +tad +tadpole +tadpoles +tads +tae +tael +taels +taenia +taeniae +taenias +taeniases +taeniasis +taffarel +taffarels +tafferel +tafferels +taffeta +taffetas +taffetized +taffia +taffias +taffies +taffrail +taffrails +taffy +tafia +tafias +tag +tagalong +tagalongs +tagboard +tagboards +tagged +tagger +taggers +tagging +tagliatelle +tagliatelles +taglike +tagmeme +tagmemes +tagmemic +tagrag +tagrags +tags +tahini +tahinis +tahr +tahrs +tahsil +tahsils +taiga +taigas +taiglach +tail +tailback +tailbacks +tailboard +tailboards +tailbone +tailbones +tailcoat +tailcoated +tailcoats +tailed +tailender +tailenders +tailer +tailers +tailfan +tailfans +tailgate +tailgated +tailgater +tailgaters +tailgates +tailgating +tailing +tailings +taillamp +taillamps +taille +tailles +tailless +tailleur +tailleurs +taillight +taillights +taillike +tailor +tailorbird +tailorbirds +tailored +tailoring +tailorings +tailors +tailpiece +tailpieces +tailpipe +tailpipes +tailplane +tailplanes +tailrace +tailraces +tails +tailskid +tailskids +tailslide +tailslides +tailspin +tailspins +tailwater +tailwaters +tailwind +tailwinds +tain +tains +taint +tainted +tainting +taintless +taints +taipan +taipans +taj +tajes +taka +takable +takahe +takahes +take +takeable +takeaway +takedown +takedowns +taken +takeoff +takeoffs +takeout +takeouts +takeover +takeovers +taker +takers +takes +takeup +takeups +takin +taking +takingly +takings +takins +tala +talapoin +talapoins +talar +talaria +talars +talas +talc +talced +talcing +talcked +talcking +talcky +talcose +talcous +talcs +talcum +talcums +tale +talebearer +talebearers +talebearing +talebearings +talent +talented +talentless +talents +taler +talers +tales +talesman +talesmen +taleysim +tali +talion +talions +taliped +talipeds +talipes +talipot +talipots +talisman +talismanic +talismanically +talismans +talk +talkable +talkathon +talkathons +talkative +talkatively +talkativeness +talkativenesses +talked +talker +talkers +talkfests +talkie +talkier +talkies +talkiest +talkiness +talkinesses +talking +talkings +talks +talky +tall +tallage +tallaged +tallages +tallaging +tallaisim +tallboy +tallboys +taller +tallest +tallied +tallier +talliers +tallies +tallis +tallish +tallisim +tallit +tallith +tallithes +tallithim +tallitim +tallitoth +tallness +tallnesses +tallol +tallols +tallow +tallowed +tallowing +tallows +tallowy +tally +tallyho +tallyhoed +tallyhoing +tallyhos +tallying +tallyman +tallymen +talmudic +talmudism +talmudisms +talon +taloned +talons +talooka +talookas +taluk +taluka +talukas +taluks +talus +taluses +tam +tamable +tamal +tamale +tamales +tamals +tamandu +tamandua +tamanduas +tamandus +tamarack +tamaracks +tamarao +tamaraos +tamarau +tamaraus +tamari +tamarillo +tamarillos +tamarin +tamarind +tamarinds +tamarins +tamaris +tamarisk +tamarisks +tamasha +tamashas +tambac +tambacs +tambak +tambaks +tambala +tambalas +tambour +tamboura +tambouras +tamboured +tambourer +tambourers +tambourine +tambourines +tambouring +tambours +tambur +tambura +tamburas +tamburs +tame +tameable +tamed +tamein +tameins +tameless +tamely +tameness +tamenesses +tamer +tamers +tames +tamest +taming +tamis +tamises +tammie +tammies +tammy +tamoxifen +tamoxifens +tamp +tampala +tampalas +tampan +tampans +tamped +tamper +tampered +tamperer +tamperers +tampering +tamperproof +tampers +tamping +tampion +tampions +tampon +tamponed +tamponing +tampons +tamps +tams +tan +tanager +tanagers +tanbark +tanbarks +tandem +tandems +tandoor +tandoori +tang +tanged +tangelo +tangelos +tangence +tangences +tangencies +tangency +tangent +tangential +tangentially +tangents +tangerine +tangerines +tangibilities +tangibility +tangible +tangibleness +tangiblenesses +tangibles +tangibly +tangier +tangiest +tanging +tangle +tangled +tanglement +tanglements +tangler +tanglers +tangles +tanglier +tangliest +tangling +tangly +tango +tangoed +tangoing +tangos +tangram +tangrams +tangs +tangy +tanist +tanistries +tanistry +tanists +tank +tanka +tankage +tankages +tankard +tankards +tankas +tanked +tanker +tankers +tankful +tankfuls +tanking +tanklike +tanks +tankship +tankships +tannable +tannage +tannages +tannate +tannates +tanned +tanner +tanneries +tanners +tannery +tannest +tannic +tannin +tanning +tannings +tannins +tannish +tanrec +tanrecs +tans +tansies +tansy +tantalate +tantalates +tantalic +tantalise +tantalised +tantalises +tantalising +tantalite +tantalites +tantalize +tantalized +tantalizer +tantalizers +tantalizes +tantalizing +tantalizingly +tantalum +tantalums +tantalus +tantaluses +tantamount +tantara +tantaras +tantivies +tantivy +tanto +tantra +tantras +tantric +tantrum +tantrums +tanuki +tanukis +tanyard +tanyards +tanzanite +tanzanites +tao +taos +tap +tapa +tapadera +tapaderas +tapadero +tapaderos +tapalo +tapalos +tapas +tape +taped +tapeless +tapelike +tapeline +tapelines +taper +tapered +taperer +taperers +tapering +tapers +taperstick +tapersticks +tapes +tapestried +tapestries +tapestry +tapestrying +tapeta +tapetal +tapetum +tapeworm +tapeworms +taphole +tapholes +taphonomic +taphonomies +taphonomist +taphonomists +taphonomy +taphouse +taphouses +taping +tapioca +tapiocas +tapir +tapirs +tapis +tapises +tapped +tapper +tappers +tappet +tappets +tapping +tappings +taproom +taprooms +taproot +taproots +taps +tapster +tapsters +tar +taradiddle +taradiddles +tarama +taramas +tarantas +tarantases +tarantella +tarantellas +tarantism +tarantisms +tarantula +tarantulae +tarantulas +tarboosh +tarbooshes +tarbush +tarbushes +tardier +tardies +tardiest +tardigrade +tardigrades +tardily +tardiness +tardinesses +tardo +tardy +tardyon +tardyons +tare +tared +tares +targe +targes +target +targetable +targeted +targeting +targets +tariff +tariffed +tariffing +tariffs +taring +tarlatan +tarlatans +tarletan +tarletans +tarmac +tarmacadam +tarmacadams +tarmacs +tarn +tarnal +tarnally +tarnation +tarnations +tarnish +tarnishable +tarnished +tarnishes +tarnishing +tarns +taro +taroc +tarocs +tarok +taroks +taros +tarot +tarots +tarp +tarpan +tarpans +tarpaper +tarpapers +tarpaulin +tarpaulins +tarpon +tarpons +tarps +tarradiddle +tarradiddles +tarragon +tarragons +tarre +tarred +tarres +tarriance +tarriances +tarried +tarrier +tarriers +tarries +tarriest +tarring +tarry +tarrying +tars +tarsal +tarsals +tarsi +tarsia +tarsias +tarsier +tarsiers +tarsometatarsi +tarsometatarsus +tarsus +tart +tartan +tartana +tartanas +tartans +tartar +tartaric +tartars +tarted +tarter +tartest +tarting +tartish +tartlet +tartlets +tartly +tartness +tartnesses +tartrate +tartrates +tarts +tartufe +tartufes +tartuffe +tartuffes +tarty +tarweed +tarweeds +tarzan +tarzans +tas +task +tasked +tasking +taskmaster +taskmasters +taskmistress +taskmistresses +tasks +taskwork +taskworks +tass +tasse +tassel +tasseled +tasseling +tasselled +tasselling +tassels +tasses +tasset +tassets +tassie +tassies +tastable +taste +tasted +tasteful +tastefully +tastefulness +tastefulnesses +tasteless +tastelessly +tastelessness +tastelessnesses +tastemaker +tastemakers +taster +tasters +tastes +tastier +tastiest +tastily +tastiness +tastinesses +tasting +tasty +tat +tatami +tatamis +tatar +tatars +tate +tater +taters +tates +tatouay +tatouays +tats +tatted +tatter +tatterdemalion +tatterdemalions +tattered +tattering +tatters +tattersall +tattersalls +tattie +tattier +tatties +tattiest +tattily +tattiness +tattinesses +tatting +tattings +tattle +tattled +tattler +tattlers +tattles +tattletale +tattletales +tattling +tattoo +tattooed +tattooer +tattooers +tattooing +tattooist +tattooists +tattoos +tatty +tau +taught +taunt +taunted +taunter +taunters +taunting +tauntingly +taunts +taupe +taupes +taurine +taurines +taus +taut +tautaug +tautaugs +tauted +tauten +tautened +tautening +tautens +tauter +tautest +tauting +tautly +tautness +tautnesses +tautog +tautogs +tautological +tautologically +tautologies +tautologous +tautologously +tautology +tautomer +tautomeric +tautomerism +tautomerisms +tautomers +tautonym +tautonymies +tautonyms +tautonymy +tauts +tav +tavern +taverna +tavernas +taverner +taverners +taverns +tavs +taw +tawdrier +tawdries +tawdriest +tawdrily +tawdriness +tawdrinesses +tawdry +tawed +tawer +tawers +tawie +tawing +tawney +tawneys +tawnier +tawnies +tawniest +tawnily +tawniness +tawninesses +tawny +tawpie +tawpies +taws +tawse +tawsed +tawses +tawsing +tax +taxa +taxable +taxables +taxably +taxation +taxations +taxed +taxeme +taxemes +taxemic +taxer +taxers +taxes +taxi +taxicab +taxicabs +taxidermic +taxidermies +taxidermist +taxidermists +taxidermy +taxied +taxies +taxiing +taximan +taximen +taximeter +taximeters +taxing +taxingly +taxis +taxite +taxites +taxitic +taxiway +taxiways +taxless +taxman +taxmen +taxon +taxonomic +taxonomically +taxonomies +taxonomist +taxonomists +taxonomy +taxons +taxpaid +taxpayer +taxpayers +taxpaying +taxus +taxwise +taxying +tazza +tazzas +tazze +tchotchke +tchotchkes +tea +teaberries +teaberry +teaboard +teaboards +teabowl +teabowls +teabox +teaboxes +teacake +teacakes +teacart +teacarts +teach +teachable +teachableness +teachablenesses +teachably +teacher +teacherly +teachers +teaches +teaching +teachings +teacup +teacupful +teacupfuls +teacups +teacupsful +teahouse +teahouses +teak +teakettle +teakettles +teaks +teakwood +teakwoods +teal +tealike +teals +team +teamaker +teamakers +teamed +teaming +teammate +teammates +teams +teamster +teamsters +teamwork +teamworks +teapot +teapots +teapoy +teapoys +tear +tearable +tearaway +tearaways +teardown +teardowns +teardrop +teardrops +teared +tearer +tearers +tearful +tearfully +tearfulness +tearfulnesses +teargas +teargases +teargassed +teargasses +teargassing +tearier +teariest +tearily +tearing +tearjerker +tearjerkers +tearless +tearoom +tearooms +tears +tearstain +tearstained +tearstains +teary +teas +tease +teased +teasel +teaseled +teaseler +teaselers +teaseling +teaselled +teaselling +teasels +teaser +teasers +teases +teashop +teashops +teasing +teasingly +teaspoon +teaspoonful +teaspoonfuls +teaspoons +teaspoonsful +teat +teated +teatime +teatimes +teats +teaware +teawares +teazel +teazeled +teazeling +teazelled +teazelling +teazels +teazle +teazled +teazles +teazling +teched +techie +techier +techies +techiest +techily +technetium +technetiums +technetronic +technic +technical +technicalities +technicality +technicalization +technicalizations +technicalize +technicalized +technicalizes +technicalizing +technically +technicals +technician +technicians +technics +technique +techniques +technobabble +technobabbles +technocracies +technocracy +technocrat +technocratic +technocrats +technologic +technological +technologically +technologies +technologist +technologists +technologize +technologized +technologizes +technologizing +technology +technophile +technophiles +technophobe +technophobes +technophobia +technophobias +technophobic +technostructure +technostructures +techy +tecta +tectal +tectite +tectites +tectonic +tectonically +tectonics +tectonism +tectonisms +tectrices +tectrix +tectum +ted +tedded +tedder +tedders +teddies +tedding +teddy +tedious +tediously +tediousness +tediousnesses +tedium +tediums +teds +tee +teed +teeing +teel +teels +teem +teemed +teemer +teemers +teeming +teemingly +teemingness +teemingnesses +teems +teen +teenage +teenaged +teenager +teenagers +teener +teeners +teenful +teenier +teeniest +teens +teensier +teensiest +teensy +teentsier +teentsiest +teentsy +teeny +teenybop +teenybopper +teenyboppers +teepee +teepees +tees +teeter +teeterboard +teeterboards +teetered +teetering +teeters +teeth +teethe +teethed +teether +teethers +teethes +teething +teethings +teethridge +teethridges +teetotal +teetotaled +teetotaler +teetotalers +teetotaling +teetotalism +teetotalisms +teetotalist +teetotalists +teetotalled +teetotaller +teetotallers +teetotalling +teetotally +teetotals +teetotum +teetotums +teff +teffs +tefillin +teg +tegmen +tegmenta +tegmental +tegmentum +tegmina +tegminal +tegs +tegua +teguas +tegular +tegumen +tegument +teguments +tegumina +teiglach +teiid +teiids +teind +teinds +tektite +tektites +tektitic +tel +tela +telae +telamon +telamones +telangiectases +telangiectasia +telangiectasias +telangiectasis +telangiectatic +tele +telecast +telecasted +telecaster +telecasters +telecasting +telecasts +telecommunication +telecommunications +telecommute +telecommuted +telecommuter +telecommuters +telecommutes +telecommuting +teleconference +teleconferenced +teleconferences +teleconferencing +teleconferencings +telecourse +telecourses +teledu +teledus +telefacsimile +telefacsimiles +telefilm +telefilms +telega +telegas +telegenic +telegonies +telegony +telegram +telegrammed +telegramming +telegrams +telegraph +telegraphed +telegrapher +telegraphers +telegraphese +telegrapheses +telegraphic +telegraphically +telegraphies +telegraphing +telegraphist +telegraphists +telegraphs +telegraphy +telekineses +telekinesis +telekinetic +telekinetically +teleman +telemark +telemarketer +telemarketers +telemarketing +telemarketings +telemarks +telemen +telemeter +telemetered +telemetering +telemeters +telemetric +telemetrically +telemetries +telemetry +telencephala +telencephalic +telencephalon +telencephalons +teleologic +teleological +teleologically +teleologies +teleologist +teleologists +teleology +teleonomic +teleonomies +teleonomy +teleost +teleostean +teleosts +telepath +telepathic +telepathically +telepathies +telepaths +telepathy +telephone +telephoned +telephoner +telephoners +telephones +telephonic +telephonically +telephonies +telephoning +telephonist +telephonists +telephony +telephoto +telephotographies +telephotography +telephotos +teleplay +teleplays +teleport +teleportation +teleportations +teleported +teleporting +teleports +teleprinter +teleprinters +teleprocessing +teleprocessings +teleran +telerans +teles +telescope +telescoped +telescopes +telescopic +telescopically +telescoping +teleses +telesis +telestic +telestics +teletext +teletexts +telethon +telethons +teletypewriter +teletypewriters +teleutospore +teleutospores +televangelism +televangelisms +televangelist +televangelists +teleview +televiewed +televiewer +televiewers +televiewing +televiews +televise +televised +televises +televising +television +televisions +televisual +telex +telexed +telexes +telexing +telfer +telfered +telfering +telfers +telford +telfords +telia +telial +telic +telically +teliospore +teliospores +telium +tell +tellable +teller +tellers +tellies +telling +tellingly +tells +telltale +telltales +telluric +telluride +tellurides +tellurium +telluriums +tellurometer +tellurometers +telly +tellys +telocentric +telocentrics +teloi +telome +telomere +telomeres +telomes +telomic +telophase +telophases +telos +telotaxes +telotaxis +telpher +telphered +telphering +telphers +tels +telson +telsonic +telsons +temblor +temblores +temblors +temerarious +temerariously +temerariousness +temerariousnesses +temerities +temerity +temp +temped +tempeh +tempehs +temper +tempera +temperable +temperament +temperamental +temperamentally +temperaments +temperance +temperances +temperas +temperate +temperately +temperateness +temperatenesses +temperature +temperatures +tempered +temperer +temperers +tempering +tempers +tempest +tempested +tempesting +tempests +tempestuous +tempestuously +tempestuousness +tempestuousnesses +tempi +temping +templar +templars +template +templates +temple +templed +temples +templet +templets +tempo +temporal +temporalities +temporality +temporalize +temporalized +temporalizes +temporalizing +temporally +temporals +temporaries +temporarily +temporariness +temporarinesses +temporary +temporise +temporised +temporises +temporising +temporization +temporizations +temporize +temporized +temporizer +temporizers +temporizes +temporizing +temporomandibular +tempos +temps +tempt +temptable +temptation +temptations +tempted +tempter +tempters +tempting +temptingly +temptress +temptresses +tempts +tempura +tempuras +ten +tenabilities +tenability +tenable +tenableness +tenablenesses +tenably +tenace +tenaces +tenacious +tenaciously +tenaciousness +tenaciousnesses +tenacities +tenacity +tenacula +tenaculum +tenaculums +tenail +tenaille +tenailles +tenails +tenancies +tenancy +tenant +tenantable +tenanted +tenanting +tenantless +tenantries +tenantry +tenants +tench +tenches +tend +tendance +tendances +tended +tendence +tendences +tendencies +tendencious +tendency +tendentious +tendentiously +tendentiousness +tendentiousnesses +tender +tendered +tenderer +tenderers +tenderest +tenderfeet +tenderfoot +tenderfoots +tenderhearted +tenderheartedly +tenderheartedness +tenderheartednesses +tendering +tenderization +tenderizations +tenderize +tenderized +tenderizer +tenderizers +tenderizes +tenderizing +tenderloin +tenderloins +tenderly +tenderness +tendernesses +tenderometer +tenderometers +tenders +tending +tendinites +tendinitides +tendinitis +tendinitises +tendinous +tendon +tendonites +tendonitides +tendonitis +tendonitises +tendons +tendresse +tendresses +tendril +tendriled +tendrilled +tendrilous +tendrils +tends +tenebrae +tenebrific +tenebrionid +tenebrionids +tenebrious +tenebrism +tenebrisms +tenebrist +tenebrists +tenebrous +tenement +tenements +tenesmic +tenesmus +tenesmuses +tenet +tenets +tenfold +tenfolds +tenia +teniae +tenias +teniases +teniasis +tenner +tenners +tennies +tennis +tennises +tennist +tennists +tenon +tenoned +tenoner +tenoners +tenoning +tenons +tenor +tenorist +tenorists +tenorite +tenorites +tenors +tenosynovitis +tenosynovitises +tenotomies +tenotomy +tenour +tenours +tenpence +tenpences +tenpenny +tenpin +tenpins +tenpounder +tenpounders +tenrec +tenrecs +tens +tense +tensed +tensely +tenseness +tensenesses +tenser +tenses +tensest +tensible +tensibly +tensile +tensilities +tensility +tensing +tensiometer +tensiometers +tensiometric +tensiometries +tensiometry +tension +tensional +tensioned +tensioner +tensioners +tensioning +tensionless +tensions +tensities +tensity +tensive +tensor +tensors +tent +tentacle +tentacled +tentacles +tentacular +tentage +tentages +tentative +tentatively +tentativeness +tentativenesses +tentatives +tented +tenter +tentered +tenterhook +tenterhooks +tentering +tenters +tenth +tenthly +tenths +tentie +tentier +tentiest +tenting +tentless +tentlike +tents +tenty +tenues +tenuis +tenuities +tenuity +tenuous +tenuously +tenuousness +tenuousnesses +tenurable +tenure +tenured +tenures +tenurial +tenurially +tenuti +tenuto +tenutos +teocalli +teocallis +teopan +teopans +teosinte +teosintes +tepa +tepal +tepals +tepas +tepee +tepees +tepefied +tepefies +tepefy +tepefying +tephra +tephras +tephrite +tephrites +tepid +tepidities +tepidity +tepidly +tepidness +tepidnesses +tepoy +tepoys +tequila +tequilas +terai +terais +teraohm +teraohms +teraph +teraphim +teratism +teratisms +teratocarcinoma +teratocarcinomas +teratocarcinomata +teratogen +teratogeneses +teratogenesis +teratogenic +teratogenicities +teratogenicity +teratogens +teratoid +teratologic +teratological +teratologies +teratologist +teratologists +teratology +teratoma +teratomas +teratomata +terawatt +terawatts +terbia +terbias +terbic +terbium +terbiums +terce +tercel +tercelet +tercelets +tercels +tercentenaries +tercentenary +tercentennial +tercentennials +terces +tercet +tercets +terebene +terebenes +terebic +terebinth +terebinths +teredines +teredo +teredos +terefah +terephthalate +terephthalates +terete +terga +tergal +tergite +tergites +tergiversate +tergiversated +tergiversates +tergiversating +tergiversation +tergiversations +tergiversator +tergiversators +tergum +teriyaki +teriyakis +term +termagant +termagants +termed +termer +termers +terminable +terminableness +terminablenesses +terminably +terminal +terminally +terminals +terminate +terminated +terminates +terminating +termination +terminational +terminations +terminative +terminatively +terminator +terminators +terming +termini +terminological +terminologically +terminologies +terminology +terminus +terminuses +termitaria +termitaries +termitarium +termitary +termite +termites +termitic +termless +termly +termor +termors +terms +termtime +termtimes +tern +ternaries +ternary +ternate +ternately +terne +terneplate +terneplates +ternes +ternion +ternions +terns +terpene +terpeneless +terpenes +terpenic +terpenoid +terpenoids +terpineol +terpineols +terpinol +terpinols +terpolymer +terpolymers +terpsichorean +terra +terrace +terraced +terraces +terracing +terrae +terraform +terraformed +terraforming +terraforms +terrain +terrains +terrane +terranes +terrapin +terrapins +terraqueous +terraria +terrarium +terrariums +terras +terrases +terrazzo +terrazzos +terreen +terreens +terrella +terrellas +terrene +terrenes +terreplein +terrepleins +terrestrial +terrestrially +terrestrials +terret +terrets +terrible +terribleness +terriblenesses +terribly +terricolous +terrier +terriers +terries +terrific +terrifically +terrified +terrifies +terrify +terrifying +terrifyingly +terrigenous +terrine +terrines +territ +territorial +territorialism +territorialisms +territorialist +territorialists +territorialities +territoriality +territorialization +territorializations +territorialize +territorialized +territorializes +territorializing +territorially +territorials +territories +territory +territs +terror +terrorise +terrorised +terrorises +terrorising +terrorism +terrorisms +terrorist +terroristic +terrorists +terrorization +terrorizations +terrorize +terrorized +terrorizes +terrorizing +terrorless +terrors +terry +terse +tersely +terseness +tersenesses +terser +tersest +tertial +tertials +tertian +tertians +tertiaries +tertiary +tervalent +tesla +teslas +tessellate +tessellated +tessellates +tessellating +tessellation +tessellations +tessera +tesseract +tesseracts +tesserae +tessitura +tessituras +test +testa +testabilities +testability +testable +testaceous +testacies +testacy +testae +testament +testamentary +testaments +testate +testates +testator +testators +testatrices +testatrix +testcross +testcrossed +testcrosses +testcrossing +tested +testee +testees +tester +testers +testes +testicle +testicles +testicular +testier +testiest +testified +testifier +testifiers +testifies +testify +testifying +testily +testimonial +testimonials +testimonies +testimony +testiness +testinesses +testing +testis +teston +testons +testoon +testoons +testosterone +testosterones +tests +testudines +testudo +testudos +testy +tet +tetanal +tetanic +tetanically +tetanics +tetanies +tetanise +tetanised +tetanises +tetanising +tetanization +tetanizations +tetanize +tetanized +tetanizes +tetanizing +tetanoid +tetanus +tetanuses +tetany +tetartohedral +tetched +tetchier +tetchiest +tetchily +tetchiness +tetchinesses +tetchy +teth +tether +tetherball +tetherballs +tethered +tethering +tethers +teths +tetotum +tetotums +tetra +tetracaine +tetracaines +tetrachloride +tetrachlorides +tetrachord +tetrachords +tetracid +tetracids +tetracycline +tetracyclines +tetrad +tetradic +tetradrachm +tetradrachms +tetrads +tetradynamous +tetrafluoride +tetrafluorides +tetragon +tetragonal +tetragonally +tetragons +tetragrammaton +tetragrammatons +tetrahedra +tetrahedral +tetrahedrally +tetrahedrite +tetrahedrites +tetrahedron +tetrahedrons +tetrahydrocannabinol +tetrahydrocannabinols +tetrahydrofuran +tetrahydrofurans +tetrahymena +tetrahymenas +tetralogies +tetralogy +tetramer +tetrameric +tetramerous +tetramers +tetrameter +tetrameters +tetramethyllead +tetramethylleads +tetraploid +tetraploidies +tetraploids +tetraploidy +tetrapod +tetrapods +tetrapyrrole +tetrapyrroles +tetrarch +tetrarchic +tetrarchies +tetrarchs +tetrarchy +tetras +tetraspore +tetraspores +tetrasporic +tetravalent +tetrazolium +tetrazoliums +tetrazzini +tetrode +tetrodes +tetrodotoxin +tetrodotoxins +tetroxid +tetroxide +tetroxides +tetroxids +tetryl +tetryls +tets +tetter +tetters +teuch +teugh +teughly +teutonize +teutonized +teutonizes +teutonizing +tew +tewed +tewing +tews +texas +texases +text +textbook +textbookish +textbooks +textile +textiles +textless +texts +textual +textually +textuaries +textuary +textural +texturally +texture +textured +textureless +textures +texturing +texturize +texturized +texturizes +texturizing +thack +thacked +thacking +thacks +thae +thairm +thairms +thalami +thalamic +thalamus +thalassaemia +thalassaemias +thalassemia +thalassemias +thalassemic +thalassemics +thalassic +thalassocracies +thalassocracy +thalassocrat +thalassocrats +thaler +thalers +thalidomide +thalidomides +thalli +thallic +thallium +thalliums +thalloid +thallophyte +thallophytes +thallophytic +thallous +thallus +thalluses +than +thanage +thanages +thanatological +thanatologies +thanatologist +thanatologists +thanatology +thanatos +thanatoses +thane +thanes +thaneship +thaneships +thank +thanked +thanker +thankers +thankful +thankfuller +thankfullest +thankfully +thankfulness +thankfulnesses +thanking +thankless +thanklessly +thanklessness +thanklessnesses +thanks +thanksgiving +thanksgivings +thankworthy +tharm +tharms +that +thataway +thatch +thatched +thatcher +thatchers +thatches +thatchier +thatchiest +thatching +thatchy +thaumaturge +thaumaturges +thaumaturgic +thaumaturgies +thaumaturgist +thaumaturgists +thaumaturgy +thaw +thawed +thawer +thawers +thawing +thawless +thaws +the +thearchies +thearchy +theater +theatergoer +theatergoers +theatergoing +theatergoings +theaters +theatre +theatres +theatric +theatrical +theatricalism +theatricalisms +theatricalities +theatricality +theatricalization +theatricalizations +theatricalize +theatricalized +theatricalizes +theatricalizing +theatrically +theatricals +theatrics +thebaine +thebaines +thebe +theca +thecae +thecal +thecate +thecodont +thecodonts +thee +theelin +theelins +theelol +theelols +theft +thefts +thegn +thegnly +thegns +thein +theine +theines +theins +their +theirs +theirselves +theism +theisms +theist +theistic +theistical +theistically +theists +thelitis +thelitises +them +thematic +thematically +thematics +theme +themed +themes +theming +themselves +then +thenage +thenages +thenal +thenar +thenars +thence +thenceforth +thenceforward +thenceforwards +thens +theobromine +theobromines +theocentric +theocentricities +theocentricity +theocentrism +theocentrisms +theocracies +theocracy +theocrat +theocratic +theocratical +theocratically +theocrats +theodicies +theodicy +theodolite +theodolites +theogonic +theogonies +theogony +theolog +theologian +theologians +theologic +theological +theologically +theologies +theologise +theologised +theologises +theologising +theologize +theologized +theologizer +theologizers +theologizes +theologizing +theologs +theologue +theologues +theology +theonomies +theonomous +theonomy +theophanic +theophanies +theophany +theophylline +theophyllines +theorbo +theorbos +theorem +theorematic +theorems +theoretic +theoretical +theoretically +theoretician +theoreticians +theories +theorise +theorised +theorises +theorising +theorist +theorists +theorization +theorizations +theorize +theorized +theorizer +theorizers +theorizes +theorizing +theory +theosophical +theosophically +theosophies +theosophist +theosophists +theosophy +therapeuses +therapeusis +therapeutic +therapeutically +therapeutics +therapies +therapist +therapists +therapsid +therapsids +therapy +there +thereabout +thereabouts +thereafter +thereat +thereby +therefor +therefore +therefrom +therein +thereinafter +thereinto +theremin +theremins +thereof +thereon +theres +thereto +theretofore +thereunder +thereunto +thereupon +therewith +therewithal +theriac +theriaca +theriacal +theriacas +theriacs +theriomorphic +therm +thermae +thermal +thermalization +thermalizations +thermalize +thermalized +thermalizes +thermalizing +thermally +thermals +therme +thermel +thermels +thermes +thermic +thermically +thermion +thermionic +thermionics +thermions +thermistor +thermistors +thermite +thermites +thermochemical +thermochemist +thermochemistries +thermochemistry +thermochemists +thermocline +thermoclines +thermocouple +thermocouples +thermoduric +thermodynamic +thermodynamical +thermodynamically +thermodynamicist +thermodynamicists +thermodynamics +thermoelectric +thermoelectricities +thermoelectricity +thermoelement +thermoelements +thermoform +thermoformable +thermoformed +thermoforming +thermoforms +thermogram +thermograms +thermograph +thermographic +thermographically +thermographies +thermographs +thermography +thermohaline +thermojunction +thermojunctions +thermolabile +thermolabilities +thermolability +thermoluminescence +thermoluminescences +thermoluminescent +thermomagnetic +thermometer +thermometers +thermometric +thermometrically +thermometries +thermometry +thermonuclear +thermoperiodicities +thermoperiodicity +thermoperiodism +thermoperiodisms +thermophile +thermophiles +thermophilic +thermophilous +thermopile +thermopiles +thermoplastic +thermoplasticities +thermoplasticity +thermoplastics +thermoreceptor +thermoreceptors +thermoregulate +thermoregulated +thermoregulates +thermoregulating +thermoregulation +thermoregulations +thermoregulator +thermoregulators +thermoregulatory +thermoremanence +thermoremanences +thermoremanent +thermos +thermoscope +thermoscopes +thermoses +thermoset +thermosets +thermosetting +thermosphere +thermospheres +thermospheric +thermostabilities +thermostability +thermostable +thermostat +thermostated +thermostatic +thermostatically +thermostating +thermostats +thermostatted +thermostatting +thermotactic +thermotaxes +thermotaxis +thermotropic +thermotropism +thermotropisms +therms +theroid +theropod +theropods +thesaural +thesauri +thesaurus +thesauruses +these +theses +thesis +thespian +thespians +theta +thetas +thetic +thetical +thetically +theurgic +theurgical +theurgies +theurgist +theurgists +theurgy +thew +thewier +thewiest +thewless +thews +thewy +they +thiabendazole +thiabendazoles +thiamin +thiaminase +thiaminases +thiamine +thiamines +thiamins +thiazide +thiazides +thiazin +thiazine +thiazines +thiazins +thiazol +thiazole +thiazoles +thiazols +thick +thicken +thickened +thickener +thickeners +thickening +thickenings +thickens +thicker +thickest +thicket +thicketed +thickets +thickety +thickhead +thickheaded +thickheads +thickish +thickly +thickness +thicknesses +thicks +thickset +thicksets +thief +thieve +thieved +thieveries +thievery +thieves +thieving +thievish +thievishly +thievishness +thievishnesses +thigh +thighbone +thighbones +thighed +thighs +thigmotaxes +thigmotaxis +thigmotropism +thigmotropisms +thill +thills +thimble +thimbleberries +thimbleberry +thimbleful +thimblefuls +thimblerig +thimblerigged +thimblerigger +thimbleriggers +thimblerigging +thimblerigs +thimbles +thimbleweed +thimbleweeds +thimerosal +thimerosals +thin +thinclad +thinclads +thindown +thindowns +thine +thing +thingamabob +thingamabobs +thingamajig +thingamajigs +thingness +thingnesses +things +thingumajig +thingumajigs +thingummies +thingummy +think +thinkable +thinkableness +thinkablenesses +thinkably +thinker +thinkers +thinking +thinkingly +thinkingness +thinkingnesses +thinkings +thinks +thinly +thinned +thinner +thinners +thinness +thinnesses +thinnest +thinning +thinnish +thins +thio +thiocyanate +thiocyanates +thiol +thiolic +thiols +thionate +thionates +thionic +thionin +thionine +thionines +thionins +thionyl +thionyls +thiopental +thiopentals +thiophen +thiophene +thiophenes +thiophens +thioridazine +thioridazines +thiosulfate +thiosulfates +thiotepa +thiotepas +thiouracil +thiouracils +thiourea +thioureas +thir +thiram +thirams +third +thirdhand +thirdly +thirds +thirl +thirlage +thirlages +thirled +thirling +thirls +thirst +thirsted +thirster +thirsters +thirstier +thirstiest +thirstily +thirstiness +thirstinesses +thirsting +thirsts +thirsty +thirteen +thirteens +thirteenth +thirteenths +thirties +thirtieth +thirtieths +thirty +thirtyish +this +thistle +thistledown +thistledowns +thistles +thistlier +thistliest +thistly +thither +thitherto +thitherward +thitherwards +thixotropic +thixotropies +thixotropy +tho +thole +tholed +tholeiite +tholeiites +tholeiitic +tholepin +tholepins +tholes +tholing +tholoi +tholos +thong +thonged +thongs +thoracal +thoraces +thoracic +thoracically +thoracotomies +thoracotomy +thorax +thoraxes +thoria +thorianite +thorianites +thorias +thoric +thorite +thorites +thorium +thoriums +thorn +thornback +thornbacks +thornbush +thornbushes +thorned +thornier +thorniest +thornily +thorniness +thorninesses +thorning +thornless +thornlike +thorns +thorny +thoro +thoron +thorons +thorough +thoroughbass +thoroughbasses +thoroughbrace +thoroughbraces +thoroughbred +thoroughbreds +thorougher +thoroughest +thoroughfare +thoroughfares +thoroughgoing +thoroughly +thoroughness +thoroughnesses +thoroughpin +thoroughpins +thoroughwort +thoroughworts +thorp +thorpe +thorpes +thorps +those +thou +thoued +though +thought +thoughtful +thoughtfully +thoughtfulness +thoughtfulnesses +thoughtless +thoughtlessly +thoughtlessness +thoughtlessnesses +thoughts +thoughtway +thoughtways +thouing +thous +thousand +thousandfold +thousands +thousandth +thousandths +thowless +thraldom +thraldoms +thrall +thralldom +thralldoms +thralled +thralling +thralls +thrash +thrashed +thrasher +thrashers +thrashes +thrashing +thrashings +thrasonical +thrasonically +thrave +thraves +thraw +thrawart +thrawed +thrawing +thrawn +thrawnly +thraws +thread +threadbare +threadbareness +threadbarenesses +threaded +threader +threaders +threadfin +threadfins +threadier +threadiest +threadiness +threadinesses +threading +threadless +threadlike +threads +threadworm +threadworms +thready +threap +threaped +threaper +threapers +threaping +threaps +threat +threated +threaten +threatened +threatener +threateners +threatening +threateningly +threatens +threating +threats +three +threefold +threep +threeped +threepence +threepences +threepenny +threeping +threeps +threes +threescore +threesome +threesomes +threnode +threnodes +threnodic +threnodies +threnodist +threnodists +threnody +threonine +threonines +thresh +threshed +thresher +threshers +threshes +threshing +threshold +thresholds +threw +thrice +thrift +thriftier +thriftiest +thriftily +thriftiness +thriftinesses +thriftless +thriftlessly +thriftlessness +thriftlessnesses +thrifts +thrifty +thrill +thrilled +thriller +thrillers +thrilling +thrillingly +thrills +thrip +thrips +thrive +thrived +thriven +thriver +thrivers +thrives +thriving +thrivingly +thro +throat +throated +throatier +throatiest +throatily +throatiness +throatinesses +throating +throatlatch +throatlatches +throats +throaty +throb +throbbed +throbber +throbbers +throbbing +throbs +throe +throes +thrombi +thrombin +thrombins +thrombocyte +thrombocytes +thrombocytic +thrombocytopenia +thrombocytopenias +thrombocytopenic +thromboembolic +thromboembolism +thromboembolisms +thrombokinase +thrombokinases +thrombolytic +thrombophlebitides +thrombophlebitis +thromboplastic +thromboplastin +thromboplastins +thromboses +thrombosis +thrombotic +thromboxane +thromboxanes +thrombus +throne +throned +thrones +throng +thronged +thronging +throngs +throning +throstle +throstles +throttle +throttleable +throttled +throttlehold +throttleholds +throttler +throttlers +throttles +throttling +through +throughither +throughly +throughother +throughout +throughput +throughputs +throughway +throughways +throve +throw +throwaway +throwaways +throwback +throwbacks +thrower +throwers +throwing +thrown +throws +throwster +throwsters +thru +thrum +thrummed +thrummer +thrummers +thrummier +thrummiest +thrumming +thrummy +thrums +thruput +thruputs +thrush +thrushes +thrust +thrusted +thruster +thrusters +thrustful +thrusting +thrustor +thrustors +thrusts +thruway +thruways +thud +thudded +thudding +thuds +thug +thuggee +thuggees +thuggeries +thuggery +thuggish +thugs +thuja +thujas +thulia +thulias +thulium +thuliums +thumb +thumbed +thumbhole +thumbholes +thumbing +thumbkin +thumbkins +thumbnail +thumbnails +thumbnut +thumbnuts +thumbprint +thumbprints +thumbs +thumbscrew +thumbscrews +thumbtack +thumbtacked +thumbtacking +thumbtacks +thumbwheel +thumbwheels +thump +thumped +thumper +thumpers +thumping +thumps +thunder +thunderbird +thunderbirds +thunderbolt +thunderbolts +thunderclap +thunderclaps +thundercloud +thunderclouds +thundered +thunderer +thunderers +thunderhead +thunderheads +thundering +thunderingly +thunderous +thunderously +thunders +thundershower +thundershowers +thunderstone +thunderstones +thunderstorm +thunderstorms +thunderstricken +thunderstrike +thunderstrikes +thunderstriking +thunderstroke +thunderstrokes +thunderstruck +thundery +thunk +thunked +thunking +thunks +thurible +thuribles +thurifer +thurifers +thurl +thurls +thus +thusly +thuya +thuyas +thwack +thwacked +thwacker +thwackers +thwacking +thwacks +thwart +thwarted +thwarter +thwarters +thwarting +thwartly +thwarts +thwartwise +thy +thylacine +thylacines +thylakoid +thylakoids +thyme +thymectomies +thymectomize +thymectomized +thymectomizes +thymectomizing +thymectomy +thymes +thymey +thymi +thymic +thymidine +thymidines +thymier +thymiest +thymine +thymines +thymocyte +thymocytes +thymol +thymols +thymosin +thymosins +thymus +thymuses +thymy +thyratron +thyratrons +thyreoid +thyristor +thyristors +thyrocalcitonin +thyrocalcitonins +thyroglobulin +thyroglobulins +thyroid +thyroidal +thyroidectomies +thyroidectomized +thyroidectomy +thyroidites +thyroiditides +thyroiditis +thyroiditises +thyroids +thyrotoxicoses +thyrotoxicosis +thyrotrophic +thyrotrophin +thyrotrophins +thyrotropic +thyrotropin +thyrotropins +thyroxin +thyroxine +thyroxines +thyroxins +thyrse +thyrses +thyrsi +thyrsoid +thyrsus +thysanuran +thysanurans +thyself +ti +tiara +tiaraed +tiaras +tibia +tibiae +tibial +tibias +tibiofibula +tibiofibulae +tibiofibulas +tic +tical +ticals +tick +ticked +ticker +tickers +ticket +ticketed +ticketing +ticketless +tickets +ticking +tickings +tickle +tickled +tickler +ticklers +tickles +tickling +ticklish +ticklishly +ticklishness +ticklishnesses +ticks +tickseed +tickseeds +ticktack +ticktacked +ticktacking +ticktacks +ticktacktoe +ticktacktoes +ticktock +ticktocked +ticktocking +ticktocks +tics +tictac +tictacked +tictacking +tictacs +tictoc +tictocked +tictocking +tictocs +tidal +tidally +tidbit +tidbits +tiddledywinks +tiddler +tiddlers +tiddly +tiddlywinks +tide +tided +tideland +tidelands +tideless +tidelike +tidemark +tidemarks +tiderip +tiderips +tides +tidewater +tidewaters +tideway +tideways +tidied +tidier +tidiers +tidies +tidiest +tidily +tidiness +tidinesses +tiding +tidings +tidy +tidying +tidytips +tie +tieback +tiebacks +tiebreaker +tiebreakers +tieclasp +tieclasps +tied +tieing +tieless +tiemannite +tiemannites +tiepin +tiepins +tier +tierce +tierced +tiercel +tiercels +tierces +tiered +tiering +tiers +ties +tiff +tiffanies +tiffany +tiffed +tiffin +tiffined +tiffing +tiffining +tiffins +tiffs +tiger +tigereye +tigereyes +tigerish +tigerishly +tigerishness +tigerishnesses +tigerlike +tigers +tight +tighten +tightened +tightener +tighteners +tightening +tightens +tighter +tightest +tightfisted +tightfistedness +tightfistednesses +tightly +tightness +tightnesses +tightrope +tightropes +tights +tightwad +tightwads +tightwire +tightwires +tiglon +tiglons +tigon +tigons +tigress +tigresses +tigrish +tike +tikes +tiki +tikis +til +tilak +tilaks +tilapia +tilapias +tilburies +tilbury +tilde +tildes +tile +tiled +tilefish +tilefishes +tilelike +tiler +tilers +tiles +tiling +tilings +till +tillable +tillage +tillages +tillandsia +tillandsias +tilled +tiller +tillered +tillering +tillerman +tillermen +tillers +tilling +tillite +tillites +tills +tils +tilt +tiltable +tilted +tilter +tilters +tilth +tilths +tilting +tiltmeter +tiltmeters +tilts +tiltyard +tiltyards +timarau +timaraus +timbal +timbale +timbales +timbals +timber +timberdoodle +timberdoodles +timbered +timberhead +timberheads +timbering +timberings +timberland +timberlands +timberline +timberlines +timberman +timbermen +timbers +timberwork +timberworks +timbral +timbre +timbrel +timbrelled +timbrels +timbres +time +timecard +timecards +timed +timekeeper +timekeepers +timekeeping +timekeepings +timeless +timelessly +timelessness +timelessnesses +timelier +timeliest +timeline +timelines +timeliness +timelinesses +timely +timeous +timeously +timeout +timeouts +timepiece +timepieces +timepleaser +timepleasers +timer +timers +times +timesaver +timesavers +timesaving +timescale +timescales +timeserver +timeservers +timeserving +timeservings +timetable +timetables +timework +timeworker +timeworkers +timeworks +timeworn +timid +timider +timidest +timidities +timidity +timidly +timidness +timidnesses +timing +timings +timocracies +timocracy +timocratic +timocratical +timolol +timolols +timorous +timorously +timorousness +timorousnesses +timothies +timothy +timpana +timpani +timpanist +timpanists +timpano +timpanum +timpanums +tin +tinamou +tinamous +tincal +tincals +tinct +tincted +tincting +tinctorial +tinctorially +tincts +tincture +tinctured +tinctures +tincturing +tinder +tinderbox +tinderboxes +tinders +tindery +tine +tinea +tineal +tineas +tined +tineid +tineids +tines +tinfoil +tinfoils +tinful +tinfuls +ting +tinge +tinged +tingeing +tinges +tinging +tingle +tingled +tingler +tinglers +tingles +tinglier +tingliest +tingling +tinglingly +tingly +tings +tinhorn +tinhorns +tinier +tiniest +tinily +tininess +tininesses +tining +tinker +tinkered +tinkerer +tinkerers +tinkering +tinkers +tinkle +tinkled +tinkler +tinklers +tinkles +tinklier +tinkliest +tinkling +tinklings +tinkly +tinlike +tinman +tinmen +tinned +tinner +tinners +tinnier +tinniest +tinnily +tinniness +tinninesses +tinning +tinnitus +tinnituses +tinny +tinplate +tinplates +tins +tinsel +tinseled +tinseling +tinselled +tinselling +tinselly +tinsels +tinsmith +tinsmithing +tinsmithings +tinsmiths +tinstone +tinstones +tint +tinted +tinter +tinters +tinting +tintings +tintinnabulary +tintinnabulation +tintinnabulations +tintless +tints +tintype +tintypes +tinware +tinwares +tinwork +tinworks +tiny +tip +tipcart +tipcarts +tipcat +tipcats +tipi +tipis +tipless +tipoff +tipoffs +tippable +tipped +tipper +tippers +tippet +tippets +tippier +tippiest +tipping +tipple +tippled +tippler +tipplers +tipples +tippling +tippy +tippytoe +tippytoed +tippytoeing +tippytoes +tips +tipsier +tipsiest +tipsily +tipsiness +tipsinesses +tipstaff +tipstaffs +tipstaves +tipster +tipsters +tipstock +tipstocks +tipsy +tiptoe +tiptoed +tiptoeing +tiptoes +tiptop +tiptops +tirade +tirades +tiramisu +tiramisus +tire +tired +tireder +tiredest +tiredly +tiredness +tirednesses +tireless +tirelessly +tirelessness +tirelessnesses +tires +tiresome +tiresomely +tiresomeness +tiresomenesses +tiring +tirl +tirled +tirling +tirls +tiro +tiros +tirrivee +tirrivees +tis +tisane +tisanes +tissual +tissue +tissued +tissues +tissuey +tissuing +tissular +tit +titan +titanate +titanates +titaness +titanesses +titania +titanias +titanic +titanically +titaniferous +titanism +titanisms +titanite +titanites +titanium +titaniums +titanous +titans +titbit +titbits +titer +titers +titfer +titfers +tithable +tithe +tithed +tither +tithers +tithes +tithing +tithings +tithonia +tithonias +titi +titian +titians +titillate +titillated +titillates +titillating +titillatingly +titillation +titillations +titillative +titis +titivate +titivated +titivates +titivating +titivation +titivations +titlark +titlarks +title +titled +titleholder +titleholders +titles +titling +titlist +titlists +titman +titmen +titmice +titmouse +titrable +titrant +titrants +titratable +titrate +titrated +titrates +titrating +titration +titrations +titrator +titrators +titre +titres +titrimetric +tits +titter +tittered +titterer +titterers +tittering +titters +tittie +titties +tittivate +tittivated +tittivates +tittivating +tittle +tittles +tittup +tittuped +tittuping +tittupped +tittupping +tittuppy +tittups +titty +titular +titularies +titularly +titulars +titulary +tivy +tizzies +tizzy +tmeses +tmesis +to +toad +toadeater +toadeaters +toadfish +toadfishes +toadflax +toadflaxes +toadied +toadies +toadish +toadless +toadlike +toads +toadstone +toadstones +toadstool +toadstools +toady +toadying +toadyish +toadyism +toadyisms +toast +toasted +toaster +toasters +toastier +toastiest +toasting +toastmaster +toastmasters +toastmistress +toastmistresses +toasts +toasty +tobacco +tobaccoes +tobacconist +tobacconists +tobaccos +tobies +toboggan +tobogganed +tobogganer +tobogganers +tobogganing +tobogganings +tobogganist +tobogganists +toboggans +toby +toccata +toccatas +toccate +tocher +tochered +tochering +tochers +tocologies +tocology +tocopherol +tocopherols +tocsin +tocsins +tod +today +todays +toddies +toddle +toddled +toddler +toddlerhood +toddlerhoods +toddlers +toddles +toddling +toddy +todies +tods +tody +toe +toea +toecap +toecaps +toed +toehold +toeholds +toeing +toeless +toelike +toenail +toenailed +toenailing +toenails +toepiece +toepieces +toeplate +toeplates +toes +toeshoe +toeshoes +toff +toffee +toffees +toffies +toffs +toffy +toft +tofts +tofu +tofus +tog +toga +togae +togaed +togas +togate +togated +together +togetherness +togethernesses +togged +toggeries +toggery +togging +toggle +toggled +toggler +togglers +toggles +toggling +togs +togue +togues +toil +toile +toiled +toiler +toilers +toiles +toilet +toileted +toileting +toiletries +toiletry +toilets +toilette +toilettes +toilful +toilfully +toiling +toils +toilsome +toilsomely +toilsomeness +toilsomenesses +toilworn +toit +toited +toiting +toits +tokamak +tokamaks +tokay +tokays +toke +toked +token +tokened +tokening +tokenism +tokenisms +tokens +toker +tokers +tokes +toking +tokologies +tokology +tokomak +tokomaks +tokonoma +tokonomas +tola +tolan +tolane +tolanes +tolans +tolas +tolbooth +tolbooths +tolbutamide +tolbutamides +told +tole +toled +toledo +toledos +tolerabilities +tolerability +tolerable +tolerably +tolerance +tolerances +tolerant +tolerantly +tolerate +tolerated +tolerates +tolerating +toleration +tolerations +tolerative +tolerator +tolerators +toles +tolidin +tolidine +tolidines +tolidins +toling +toll +tollage +tollages +tollbar +tollbars +tollbooth +tollbooths +tolled +toller +tollers +tollgate +tollgates +tollhouse +tollhouses +tolling +tollman +tollmen +tolls +tollway +tollways +tolu +toluate +toluates +toluene +toluenes +toluic +toluid +toluide +toluides +toluidin +toluidine +toluidines +toluidins +toluids +toluol +toluole +toluoles +toluols +tolus +toluyl +toluyls +tolyl +tolyls +tom +tomahawk +tomahawked +tomahawking +tomahawks +tomalley +tomalleys +toman +tomans +tomatillo +tomatillos +tomato +tomatoes +tomatoey +tomb +tombac +tomback +tombacks +tombacs +tombak +tombaks +tombal +tombed +tombing +tombless +tomblike +tombola +tombolas +tombolo +tombolos +tomboy +tomboyish +tomboyishness +tomboyishnesses +tomboys +tombs +tombstone +tombstones +tomcat +tomcats +tomcatted +tomcatting +tomcod +tomcods +tome +tomenta +tomentose +tomentum +tomes +tomfool +tomfooleries +tomfoolery +tomfools +tommed +tommies +tomming +tommy +tommyrot +tommyrots +tomogram +tomograms +tomographic +tomographies +tomography +tomorrow +tomorrows +tompion +tompions +toms +tomtit +tomtits +ton +tonal +tonalities +tonality +tonally +tondi +tondo +tondos +tone +tonearm +tonearms +toned +toneless +tonelessly +tonelessness +tonelessnesses +toneme +tonemes +tonemic +toner +toners +tones +tonetic +tonetically +tonetics +tonette +tonettes +toney +tong +tonga +tongas +tonged +tonger +tongers +tonging +tongman +tongmen +tongs +tongue +tongued +tongueless +tonguelike +tongues +tonguing +tonguings +tonic +tonically +tonicities +tonicity +tonics +tonier +toniest +tonight +tonights +toning +tonish +tonishly +tonlet +tonlets +tonnage +tonnages +tonne +tonneau +tonneaus +tonneaux +tonner +tonners +tonnes +tonnish +tonometer +tonometers +tonometries +tonometry +tonoplast +tonoplasts +tons +tonsil +tonsilar +tonsillar +tonsillectomies +tonsillectomy +tonsillites +tonsillitides +tonsillitis +tonsillitises +tonsils +tonsorial +tonsure +tonsured +tonsures +tonsuring +tontine +tontines +tonus +tonuses +tony +too +took +tool +toolbox +toolboxes +tooled +tooler +toolers +toolhead +toolheads +toolholder +toolholders +toolhouse +toolhouses +tooling +toolings +toolless +toolmaker +toolmakers +toolmaking +toolmakings +toolroom +toolrooms +tools +toolshed +toolsheds +toom +toon +toons +toot +tooted +tooter +tooters +tooth +toothache +toothaches +toothbrush +toothbrushes +toothbrushing +toothbrushings +toothed +toothier +toothiest +toothily +toothing +toothless +toothlike +toothpaste +toothpastes +toothpick +toothpicks +tooths +toothsome +toothsomely +toothsomeness +toothsomenesses +toothwort +toothworts +toothy +tooting +tootle +tootled +tootler +tootlers +tootles +tootling +toots +tootses +tootsie +tootsies +tootsy +top +topaz +topazes +topazine +topcoat +topcoats +topcross +topcrosses +topdressing +topdressings +tope +toped +topee +topees +toper +topers +topes +topflight +topful +topfull +topgallant +topgallants +toph +tophe +tophes +tophi +tophs +tophus +topi +topiaries +topiary +topic +topical +topicalities +topicality +topically +topics +toping +topis +topkick +topkicks +topknot +topknots +topless +toplessness +toplessnesses +topline +toplines +toploftical +toploftier +toploftiest +toploftily +toploftiness +toploftinesses +toplofty +topmast +topmasts +topminnow +topminnows +topmost +topnotch +topnotcher +topnotchers +topocentric +topographer +topographers +topographic +topographical +topographically +topographies +topography +topoi +topological +topologically +topologies +topologist +topologists +topology +toponym +toponymic +toponymical +toponymies +toponymist +toponymists +toponyms +toponymy +topos +topotype +topotypes +topped +topper +toppers +topping +toppings +topple +toppled +topples +toppling +tops +topsail +topsails +topside +topsider +topsiders +topsides +topsoil +topsoiled +topsoiling +topsoils +topspin +topspins +topstitch +topstitched +topstitches +topstitching +topstone +topstones +topwork +topworked +topworking +topworks +toque +toques +toquet +toquets +tor +tora +torah +torahs +toras +torc +torch +torchbearer +torchbearers +torched +torchere +torcheres +torches +torchier +torchiers +torchiest +torching +torchlight +torchlights +torchon +torchons +torchwood +torchwoods +torchy +torcs +tore +toreador +toreadors +torero +toreros +tores +toreutic +toreutics +tori +toric +tories +torii +torment +tormented +tormenter +tormenters +tormentil +tormentils +tormenting +tormentor +tormentors +torments +torn +tornadic +tornado +tornadoes +tornados +tornillo +tornillos +toro +toroid +toroidal +toroidally +toroids +toros +torose +torosities +torosity +torot +toroth +torous +torpedo +torpedoed +torpedoes +torpedoing +torpedos +torpid +torpidities +torpidity +torpidly +torpids +torpor +torpors +torquate +torque +torqued +torquer +torquers +torques +torqueses +torquing +torr +torrefied +torrefies +torrefy +torrefying +torrent +torrential +torrentially +torrents +torrid +torrider +torridest +torridities +torridity +torridly +torridness +torridnesses +torrified +torrifies +torrify +torrifying +tors +torsade +torsades +torse +torses +torsi +torsion +torsional +torsionally +torsions +torsk +torsks +torso +torsos +tort +torte +tortellini +tortellinis +torten +tortes +torticollis +torticollises +tortile +tortilla +tortillas +tortious +tortiously +tortoise +tortoises +tortoiseshell +tortoiseshells +tortoni +tortonis +tortricid +tortricids +tortrix +tortrixes +torts +tortuosities +tortuosity +tortuous +tortuously +tortuousness +tortuousnesses +torture +tortured +torturer +torturers +tortures +torturing +torturous +torturously +torula +torulae +torulas +torus +tory +tosh +toshes +toss +tossed +tosser +tossers +tosses +tossing +tosspot +tosspots +tossup +tossups +tost +tostada +tostadas +tostado +tostados +tot +totable +total +totaled +totaling +totalisator +totalisators +totalise +totalised +totalises +totalising +totalism +totalisms +totalist +totalistic +totalists +totalitarian +totalitarianism +totalitarianisms +totalitarianize +totalitarianized +totalitarianizes +totalitarianizing +totalitarians +totalities +totality +totalizator +totalizators +totalize +totalized +totalizer +totalizers +totalizes +totalizing +totalled +totalling +totally +totals +tote +toted +totem +totemic +totemism +totemisms +totemist +totemistic +totemists +totemite +totemites +totems +toter +toters +totes +tother +toting +totipotencies +totipotency +totipotent +tots +totted +totter +tottered +totterer +totterers +tottering +totteringly +totters +tottery +totting +toucan +toucans +touch +touchable +touchback +touchbacks +touchdown +touchdowns +touche +touched +toucher +touchers +touches +touchhole +touchholes +touchier +touchiest +touchily +touchiness +touchinesses +touching +touchingly +touchline +touchlines +touchmark +touchmarks +touchstone +touchstones +touchup +touchups +touchwood +touchwoods +touchy +tough +toughed +toughen +toughened +toughening +toughens +tougher +toughest +toughie +toughies +toughing +toughish +toughly +toughness +toughnesses +toughs +toughy +toupee +toupees +tour +touraco +touracos +tourbillion +tourbillions +tourbillon +tourbillons +toured +tourer +tourers +touring +tourings +tourism +tourisms +tourist +touristic +touristically +tourists +touristy +tourmaline +tourmalines +tournament +tournaments +tournedos +tourney +tourneyed +tourneying +tourneys +tourniquet +tourniquets +tours +touse +toused +touses +tousing +tousle +tousled +tousles +tousling +tout +touted +touter +touters +touting +touts +touzle +touzled +touzles +touzling +tovarich +tovariches +tovarish +tovarishes +tow +towage +towages +toward +towardliness +towardlinesses +towardly +towards +towaway +towaways +towboat +towboats +towed +towel +toweled +towelette +towelettes +toweling +towelings +towelled +towelling +towellings +towels +tower +towered +towerier +toweriest +towering +toweringly +towerlike +towers +towery +towhead +towheaded +towheads +towhee +towhees +towie +towies +towing +towline +towlines +towmond +towmonds +towmont +towmonts +town +townee +townees +townfolk +townhome +townhomes +townhouse +townhouses +townie +townies +townish +townless +townlet +townlets +towns +townscape +townscapes +townsfolk +township +townships +townsman +townsmen +townspeople +townswoman +townswomen +townwear +towny +towpath +towpaths +towrope +towropes +tows +towy +toxaemia +toxaemias +toxaemic +toxaphene +toxaphenes +toxemia +toxemias +toxemic +toxic +toxical +toxicant +toxicants +toxicities +toxicity +toxicologic +toxicological +toxicologically +toxicologies +toxicologist +toxicologists +toxicology +toxicoses +toxicosis +toxics +toxigenic +toxigenicities +toxigenicity +toxin +toxine +toxines +toxins +toxoid +toxoids +toxophilies +toxophilite +toxophilites +toxophily +toxoplasma +toxoplasmas +toxoplasmic +toxoplasmoses +toxoplasmosis +toy +toyed +toyer +toyers +toying +toyish +toyless +toylike +toyo +toyon +toyons +toyos +toys +toyshop +toyshops +trabeate +trabeated +trabeation +trabeations +trabecula +trabeculae +trabecular +trabeculas +trabeculate +trace +traceabilities +traceability +traceable +traced +traceless +tracer +traceried +traceries +tracers +tracery +traces +trachea +tracheae +tracheal +tracheary +tracheas +tracheate +tracheated +tracheid +tracheids +tracheites +tracheitides +tracheitis +tracheitises +tracheobronchial +tracheolar +tracheole +tracheoles +tracheophyte +tracheophytes +tracheostomies +tracheostomy +tracheotomies +tracheotomy +trachle +trachled +trachles +trachling +trachoma +trachomas +trachyte +trachytes +trachytic +tracing +tracings +track +trackage +trackages +trackball +trackballs +tracked +tracker +trackers +tracking +trackings +tracklayer +tracklayers +tracklaying +tracklayings +trackless +trackman +trackmen +tracks +trackside +tracksides +tracksuit +tracksuits +trackwalker +trackwalkers +trackway +trackways +tract +tractabilities +tractability +tractable +tractableness +tractablenesses +tractably +tractate +tractates +tractile +traction +tractional +tractions +tractive +tractor +tractors +tracts +trad +tradable +trade +tradeable +tradecraft +tradecrafts +traded +trademark +trademarked +trademarking +trademarks +tradeoff +tradeoffs +trader +traders +trades +tradescantia +tradescantias +tradesman +tradesmen +tradespeople +trading +tradition +traditional +traditionalism +traditionalisms +traditionalist +traditionalistic +traditionalists +traditionalize +traditionalized +traditionalizes +traditionalizing +traditionally +traditionary +traditionless +traditions +traditor +traditores +traduce +traduced +traducement +traducements +traducer +traducers +traduces +traducing +traffic +trafficabilities +trafficability +trafficable +trafficked +trafficker +traffickers +trafficking +traffics +tragacanth +tragacanths +tragedian +tragedians +tragedienne +tragediennes +tragedies +tragedy +tragi +tragic +tragical +tragically +tragicomedies +tragicomedy +tragicomic +tragicomical +tragics +tragopan +tragopans +tragus +traik +traiked +traiking +traiks +trail +trailblazer +trailblazers +trailblazing +trailbreaker +trailbreakers +trailed +trailer +trailerable +trailered +trailering +trailerings +trailerist +trailerists +trailerite +trailerites +trailers +trailhead +trailheads +trailing +trailless +trails +trailside +train +trainabilities +trainability +trainable +trainband +trainbands +trainbearer +trainbearers +trained +trainee +trainees +traineeship +traineeships +trainer +trainers +trainful +trainfuls +training +trainings +trainload +trainloads +trainman +trainmen +trains +trainway +trainways +traipse +traipsed +traipses +traipsing +trait +traitor +traitoress +traitoresses +traitorous +traitorously +traitors +traitress +traitresses +traits +traject +trajected +trajecting +trajection +trajections +trajectories +trajectory +trajects +tram +tramcar +tramcars +tramel +trameled +trameling +tramell +tramelled +tramelling +tramells +tramels +tramless +tramline +tramlines +trammed +trammel +trammeled +trammeling +trammelled +trammelling +trammels +tramming +tramontane +tramontanes +tramp +tramped +tramper +trampers +tramping +trampish +trample +trampled +trampler +tramplers +tramples +trampling +trampoline +trampoliner +trampoliners +trampolines +trampolining +trampolinings +trampolinist +trampolinists +tramps +tramroad +tramroads +trams +tramway +tramways +trance +tranced +trancelike +trances +tranche +tranches +trancing +trangam +trangams +trank +tranks +tranq +tranqs +tranquil +tranquiler +tranquilest +tranquilities +tranquility +tranquilize +tranquilized +tranquilizer +tranquilizers +tranquilizes +tranquilizing +tranquiller +tranquillest +tranquillities +tranquillity +tranquillize +tranquillized +tranquillizer +tranquillizers +tranquillizes +tranquillizing +tranquilly +tranquilness +tranquilnesses +trans +transact +transacted +transacting +transactinide +transaction +transactional +transactions +transactor +transactors +transacts +transalpine +transaminase +transaminases +transamination +transaminations +transatlantic +transaxle +transaxles +transceiver +transceivers +transcend +transcended +transcendence +transcendences +transcendencies +transcendency +transcendent +transcendental +transcendentalism +transcendentalisms +transcendentalist +transcendentalists +transcendentally +transcendently +transcending +transcends +transcontinental +transcribe +transcribed +transcriber +transcribers +transcribes +transcribing +transcript +transcriptase +transcriptases +transcription +transcriptional +transcriptionally +transcriptionist +transcriptionists +transcriptions +transcripts +transcultural +transcutaneous +transdermal +transdisciplinary +transduce +transduced +transducer +transducers +transduces +transducing +transductant +transductants +transduction +transductional +transductions +transect +transected +transecting +transection +transections +transects +transept +transeptal +transepts +transfect +transfected +transfecting +transfection +transfections +transfects +transfer +transferabilities +transferability +transferable +transferal +transferals +transferase +transferases +transferee +transferees +transference +transferences +transferential +transferor +transferors +transferrable +transferred +transferrer +transferrers +transferrin +transferring +transferrins +transfers +transfiguration +transfigurations +transfigure +transfigured +transfigures +transfiguring +transfinite +transfix +transfixed +transfixes +transfixing +transfixion +transfixions +transfixt +transform +transformable +transformation +transformational +transformationalist +transformationalists +transformationally +transformations +transformative +transformed +transformer +transformers +transforming +transforms +transfusable +transfuse +transfused +transfuses +transfusible +transfusing +transfusion +transfusional +transfusions +transgenerational +transgenic +transgress +transgressed +transgresses +transgressing +transgression +transgressions +transgressive +transgressor +transgressors +tranship +transhipped +transhipping +tranships +transhistorical +transhumance +transhumances +transhumant +transhumants +transience +transiences +transiencies +transiency +transient +transiently +transients +transilluminate +transilluminated +transilluminates +transilluminating +transillumination +transilluminations +transilluminator +transilluminators +transistor +transistorise +transistorised +transistorises +transistorising +transistorization +transistorizations +transistorize +transistorized +transistorizes +transistorizing +transistors +transit +transited +transiting +transition +transitional +transitionally +transitions +transitive +transitively +transitiveness +transitivenesses +transitivities +transitivity +transitorily +transitoriness +transitorinesses +transitory +transits +translatabilities +translatability +translatable +translate +translated +translates +translating +translation +translational +translations +translative +translator +translators +translatory +transliterate +transliterated +transliterates +transliterating +transliteration +transliterations +translocate +translocated +translocates +translocating +translocation +translocations +translucence +translucences +translucencies +translucency +translucent +translucently +transmarine +transmembrane +transmigrate +transmigrated +transmigrates +transmigrating +transmigration +transmigrations +transmigrator +transmigrators +transmigratory +transmissibilities +transmissibility +transmissible +transmission +transmissions +transmissive +transmissivities +transmissivity +transmissometer +transmissometers +transmit +transmits +transmittable +transmittal +transmittals +transmittance +transmittances +transmitted +transmitter +transmitters +transmitting +transmogrification +transmogrifications +transmogrified +transmogrifies +transmogrify +transmogrifying +transmontane +transmountain +transmutable +transmutation +transmutations +transmutative +transmute +transmuted +transmutes +transmuting +transnational +transnationalism +transnationalisms +transnatural +transoceanic +transom +transoms +transonic +transpacific +transparence +transparences +transparencies +transparency +transparent +transparentize +transparentized +transparentizes +transparentizing +transparently +transparentness +transparentnesses +transpersonal +transpicuous +transpierce +transpierced +transpierces +transpiercing +transpiration +transpirational +transpirations +transpire +transpired +transpires +transpiring +transplacental +transplacentally +transplant +transplantabilities +transplantability +transplantable +transplantation +transplantations +transplanted +transplanter +transplanters +transplanting +transplants +transpolar +transponder +transponders +transpontine +transport +transportabilities +transportability +transportable +transportation +transportational +transportations +transported +transportee +transportees +transporter +transporters +transporting +transports +transposable +transpose +transposed +transposes +transposing +transposition +transpositional +transpositions +transposon +transposons +transsexual +transsexualism +transsexualisms +transsexualities +transsexuality +transsexuals +transshape +transshaped +transshapes +transshaping +transship +transshipment +transshipments +transshipped +transshipping +transships +transsonic +transthoracic +transthoracically +transubstantial +transubstantiate +transubstantiated +transubstantiates +transubstantiating +transubstantiation +transubstantiations +transudate +transudates +transudation +transudations +transude +transuded +transudes +transuding +transuranic +transuranics +transuranium +transvaluate +transvaluated +transvaluates +transvaluating +transvaluation +transvaluations +transvalue +transvalued +transvalues +transvaluing +transversal +transversals +transverse +transversely +transverses +transvestism +transvestisms +transvestite +transvestites +trap +trapan +trapanned +trapanning +trapans +trapball +trapballs +trapdoor +trapdoors +trapes +trapesed +trapeses +trapesing +trapeze +trapezes +trapezia +trapezii +trapezist +trapezists +trapezium +trapezius +trapeziuses +trapezohedra +trapezohedron +trapezohedrons +trapezoid +trapezoidal +trapezoids +traplike +trapline +traplines +trapnest +trapnested +trapnesting +trapnests +trappean +trapped +trapper +trappers +trapping +trappings +trappose +trappous +traprock +traprocks +traps +trapshooter +trapshooters +trapshooting +trapshootings +trapt +trapunto +trapuntos +trash +trashed +trashes +trashier +trashiest +trashily +trashiness +trashinesses +trashing +trashman +trashmen +trashy +trass +trasses +trattoria +trattorias +trattorie +trauchle +trauchled +trauchles +trauchling +trauma +traumas +traumata +traumatic +traumatically +traumatise +traumatised +traumatises +traumatising +traumatism +traumatisms +traumatization +traumatizations +traumatize +traumatized +traumatizes +traumatizing +travail +travailed +travailing +travails +trave +travel +traveled +traveler +travelers +traveling +travelled +traveller +travellers +travelling +travelog +travelogs +travelogue +travelogues +travels +traversable +traversal +traversals +traverse +traversed +traverser +traversers +traverses +traversing +travertine +travertines +traves +travestied +travesties +travesty +travestying +travois +travoise +travoises +trawl +trawled +trawler +trawlerman +trawlermen +trawlers +trawley +trawleys +trawling +trawlnet +trawlnets +trawls +tray +trayful +trayfuls +trays +treacheries +treacherous +treacherously +treacherousness +treacherousnesses +treachery +treacle +treacles +treacly +tread +treaded +treader +treaders +treading +treadle +treadled +treadler +treadlers +treadles +treadless +treadling +treadmill +treadmills +treads +treason +treasonable +treasonably +treasonous +treasons +treasurable +treasure +treasured +treasurer +treasurers +treasurership +treasurerships +treasures +treasuries +treasuring +treasury +treat +treatabilities +treatability +treatable +treated +treater +treaters +treaties +treating +treatise +treatises +treatment +treatments +treats +treaty +treble +trebled +trebles +trebling +trebly +trebuchet +trebuchets +trebucket +trebuckets +trecento +trecentos +treddle +treddled +treddles +treddling +tredecillion +tredecillions +tree +treed +treehopper +treehoppers +treeing +treelawn +treelawns +treeless +treelike +treen +treenail +treenails +treens +treenware +treenwares +trees +treetop +treetops +tref +trefah +trefoil +trefoils +trehala +trehalas +trehalose +trehaloses +treillage +treillages +trek +trekked +trekker +trekkers +trekking +treks +trellis +trellised +trellises +trellising +trelliswork +trellisworks +trematode +trematodes +tremble +trembled +trembler +tremblers +trembles +tremblier +trembliest +trembling +trembly +tremendous +tremendously +tremendousness +tremendousnesses +tremolite +tremolites +tremolitic +tremolo +tremolos +tremor +tremors +tremulant +tremulous +tremulously +tremulousness +tremulousnesses +trenail +trenails +trench +trenchancies +trenchancy +trenchant +trenchantly +trenched +trencher +trencherman +trenchermen +trenchers +trenches +trenching +trend +trended +trendier +trendies +trendiest +trendily +trendiness +trendinesses +trending +trends +trendsetter +trendsetters +trendsetting +trendy +trepan +trepanation +trepanations +trepang +trepangs +trepanned +trepanning +trepans +trephination +trephinations +trephine +trephined +trephines +trephining +trepid +trepidant +trepidation +trepidations +treponema +treponemal +treponemas +treponemata +treponematoses +treponematosis +treponeme +treponemes +trespass +trespassed +trespasser +trespassers +trespasses +trespassing +tress +tressed +tressel +tressels +tresses +tressier +tressiest +tressour +tressours +tressure +tressures +tressy +trestle +trestles +trestlework +trestleworks +tret +tretinoin +tretinoins +trets +trevet +trevets +trews +trey +treys +triable +triac +triacetate +triacetates +triacid +triacids +triacs +triad +triadic +triadically +triadics +triadism +triadisms +triads +triage +triaged +triages +triaging +trial +trialogue +trialogues +trials +triamcinolone +triamcinolones +triangle +triangles +triangular +triangularities +triangularity +triangularly +triangulate +triangulated +triangulates +triangulating +triangulation +triangulations +triarchies +triarchy +triathlete +triathletes +triathlon +triathlons +triatomic +triaxial +triaxialities +triaxiality +triazin +triazine +triazines +triazins +triazole +triazoles +tribade +tribades +tribadic +tribal +tribalism +tribalisms +tribally +tribasic +tribe +tribes +tribesman +tribesmen +tribespeople +triboelectric +triboelectricities +triboelectricity +tribological +tribologies +tribologist +tribologists +tribology +triboluminescence +triboluminescences +triboluminescent +tribrach +tribrachic +tribrachs +tribulate +tribulated +tribulates +tribulating +tribulation +tribulations +tribunal +tribunals +tribunate +tribunates +tribune +tribunes +tribuneship +tribuneships +tributaries +tributary +tribute +tributes +tricarboxylic +trice +triced +triceps +tricepses +triceratops +triceratopses +trices +trichiases +trichiasis +trichina +trichinae +trichinal +trichinas +trichinize +trichinized +trichinizes +trichinizing +trichinoses +trichinosis +trichinosises +trichinous +trichite +trichites +trichlorfon +trichlorfons +trichloroethylene +trichloroethylenes +trichlorphon +trichlorphons +trichocyst +trichocysts +trichogyne +trichogynes +trichoid +trichologies +trichologist +trichologists +trichology +trichome +trichomes +trichomonacidal +trichomonacide +trichomonacides +trichomonad +trichomonads +trichomonal +trichomoniases +trichomoniasis +trichopteran +trichopterans +trichothecene +trichothecenes +trichotomies +trichotomous +trichotomously +trichotomy +trichromat +trichromatic +trichromatism +trichromatisms +trichromats +tricing +trick +tricked +tricker +trickeries +trickers +trickery +trickie +trickier +trickiest +trickily +trickiness +trickinesses +tricking +trickish +trickishly +trickishness +trickishnesses +trickle +trickled +trickles +tricklier +trickliest +trickling +trickly +tricks +tricksier +tricksiest +tricksiness +tricksinesses +trickster +tricksters +tricksy +tricky +triclad +triclads +triclinia +triclinic +triclinium +tricolette +tricolettes +tricolor +tricolored +tricolors +tricorn +tricorne +tricornered +tricornes +tricorns +tricot +tricotine +tricotines +tricots +trictrac +trictracs +tricuspid +tricuspids +tricycle +tricycles +tricyclic +tricyclics +trident +tridents +tridimensional +tridimensionalities +tridimensionality +triduum +triduums +tried +triene +trienes +triennia +triennial +triennially +triennials +triennium +trienniums +triens +trientes +trier +trierarch +trierarchies +trierarchs +trierarchy +triers +tries +triethyl +trifecta +trifectas +trifid +trifle +trifled +trifler +triflers +trifles +trifling +triflings +trifluoperazine +trifluoperazines +trifluralin +trifluralins +trifocal +trifocals +trifold +trifoliate +trifoliolate +trifolium +trifoliums +triforia +triforium +triform +trifurcate +trifurcated +trifurcates +trifurcating +trifurcation +trifurcations +trig +trigeminal +trigeminals +trigged +trigger +triggered +triggerfish +triggerfishes +triggering +triggerman +triggermen +triggers +triggest +trigging +trigly +triglyceride +triglycerides +triglyph +triglyphic +triglyphical +triglyphs +trigness +trignesses +trigo +trigon +trigonal +trigonally +trigonometric +trigonometrical +trigonometrically +trigonometries +trigonometry +trigons +trigos +trigram +trigrams +trigraph +trigraphic +trigraphs +trigs +trihalomethane +trihalomethanes +trihedra +trihedral +trihedrals +trihedron +trihedrons +trihybrid +trihybrids +trihydroxy +triiodothyronine +triiodothyronines +trijet +trijets +trike +trikes +trilateral +trilbies +trilby +trilinear +trilingual +trilingually +triliteral +triliteralism +triliteralisms +triliterals +trill +trilled +triller +trillers +trilling +trillion +trillions +trillionth +trillionths +trillium +trilliums +trills +trilobal +trilobate +trilobed +trilobite +trilobites +trilogies +trilogy +trim +trimaran +trimarans +trimer +trimeric +trimerous +trimers +trimester +trimesters +trimeter +trimeters +trimethoprim +trimethoprims +trimetrogon +trimetrogons +trimly +trimmed +trimmer +trimmers +trimmest +trimming +trimmings +trimness +trimnesses +trimonthly +trimorph +trimorphic +trimorphs +trimotor +trimotors +trims +trinal +trinary +trindle +trindled +trindles +trindling +trine +trined +trines +trining +trinitarian +trinities +trinitrotoluene +trinitrotoluenes +trinity +trinket +trinketed +trinketer +trinketers +trinketing +trinketries +trinketry +trinkets +trinkums +trinocular +trinodal +trinomial +trinomials +trinucleotide +trinucleotides +trio +triode +triodes +triol +triolet +triolets +triols +trios +triose +trioses +trioxid +trioxide +trioxides +trioxids +trip +tripack +tripacks +tripart +tripartite +tripe +tripedal +tripes +triphase +triphenylmethane +triphenylmethanes +triphosphate +triphosphates +triphthong +triphthongal +triphthongs +tripinnate +tripinnately +triplane +triplanes +triple +tripled +triples +triplet +tripletail +tripletails +triplets +triplex +triplexes +triplicate +triplicated +triplicates +triplicating +triplication +triplications +triplicities +triplicity +tripling +triplite +triplites +triploblastic +triploid +triploidies +triploids +triploidy +triply +tripod +tripodal +tripodic +tripodies +tripods +tripody +tripoli +tripolis +tripos +triposes +tripped +tripper +trippers +trippet +trippets +trippier +trippiest +tripping +trippingly +trippings +trippy +trips +triptane +triptanes +triptyca +triptycas +triptych +triptychs +tripwire +tripwires +triquetrous +triradiate +trireme +triremes +trisaccharide +trisaccharides +triscele +trisceles +trisect +trisected +trisecting +trisection +trisections +trisector +trisectors +trisects +triseme +trisemes +trisemic +trishaw +trishaws +triskaidekaphobia +triskaidekaphobias +triskele +triskeles +triskelion +triskelions +trismic +trismus +trismuses +trisoctahedra +trisoctahedron +trisoctahedrons +trisome +trisomes +trisomic +trisomics +trisomies +trisomy +tristate +triste +tristearin +tristearins +tristeza +tristezas +tristful +tristfully +tristfulness +tristfulnesses +tristich +tristichs +tristimulus +trisubstituted +trisulfide +trisulfides +trisyllabic +trisyllable +trisyllables +trite +tritely +triteness +tritenesses +triter +tritest +tritheism +tritheisms +tritheist +tritheistic +tritheistical +tritheists +trithing +trithings +tritiated +triticale +triticales +triticum +triticums +tritium +tritiums +tritoma +tritomas +triton +tritone +tritones +tritons +triturable +triturate +triturated +triturates +triturating +trituration +triturations +triturator +triturators +triumph +triumphal +triumphalism +triumphalisms +triumphalist +triumphalists +triumphant +triumphantly +triumphed +triumphing +triumphs +triumvir +triumvirate +triumvirates +triumviri +triumvirs +triune +triunes +triunities +triunity +trivalent +trivalve +trivalves +trivet +trivets +trivia +trivial +trivialise +trivialised +trivialises +trivialising +trivialist +trivialists +trivialities +triviality +trivialization +trivializations +trivialize +trivialized +trivializes +trivializing +trivially +trivium +triweeklies +triweekly +troak +troaked +troaking +troaks +trocar +trocars +trochaic +trochaics +trochal +trochanter +trochanteral +trochanteric +trochanters +trochar +trochars +troche +trochee +trochees +troches +trochil +trochili +trochils +trochilus +trochlea +trochleae +trochlear +trochlears +trochleas +trochoid +trochoidal +trochoids +trochophore +trochophores +trock +trocked +trocking +trocks +trod +trodden +trode +troffer +troffers +troglodyte +troglodytes +troglodytic +trogon +trogons +troika +troikas +troilism +troilisms +troilite +troilites +troilus +troiluses +trois +troke +troked +trokes +troking +troland +trolands +troll +trolled +troller +trollers +trolley +trolleybus +trolleybuses +trolleybusses +trolleyed +trolleying +trolleys +trollied +trollies +trolling +trollings +trollop +trollops +trollopy +trolls +trolly +trollying +trombone +trombones +trombonist +trombonists +trommel +trommels +tromp +trompe +tromped +trompes +tromping +tromps +trona +tronas +trone +trones +troop +trooped +trooper +troopers +troopial +troopials +trooping +troops +troopship +troopships +trooz +trop +trope +tropes +trophallaxes +trophallaxis +trophic +trophically +trophied +trophies +trophoblast +trophoblastic +trophoblasts +trophozoite +trophozoites +trophy +trophying +tropic +tropical +tropicalize +tropicalized +tropicalizes +tropicalizing +tropically +tropics +tropin +tropine +tropines +tropins +tropism +tropisms +tropistic +tropocollagen +tropocollagens +tropologic +tropological +tropologically +tropomyosin +tropomyosins +troponin +troponins +tropopause +tropopauses +troposphere +tropospheres +tropospheric +tropotaxes +tropotaxis +trot +troth +trothed +trothing +trothplight +trothplighted +trothplighting +trothplights +troths +trotline +trotlines +trots +trotted +trotter +trotters +trotting +trotyl +trotyls +troubadour +troubadours +trouble +troubled +troublemaker +troublemakers +troublemaking +troublemakings +troubler +troublers +troubles +troubleshoot +troubleshooter +troubleshooters +troubleshooting +troubleshoots +troubleshot +troublesome +troublesomely +troublesomeness +troublesomenesses +troubling +troublous +troublously +troublousness +troublousnesses +trough +troughs +trounce +trounced +trouncer +trouncers +trounces +trouncing +troupe +trouped +trouper +troupers +troupes +troupial +troupials +trouping +trouser +trousers +trousseau +trousseaus +trousseaux +trout +troutier +troutiest +trouts +trouty +trouvere +trouveres +trouveur +trouveurs +trove +trover +trovers +troves +trow +trowed +trowel +troweled +troweler +trowelers +troweling +trowelled +trowelling +trowels +trowing +trows +trowsers +trowth +trowths +troy +troys +truancies +truancy +truant +truanted +truanting +truantries +truantry +truants +truce +truced +truces +trucing +truck +truckage +truckages +trucked +trucker +truckers +truckful +truckfuls +trucking +truckings +truckle +truckled +truckler +trucklers +truckles +truckline +trucklines +truckling +truckload +truckloads +truckman +truckmaster +truckmasters +truckmen +trucks +truculence +truculences +truculencies +truculency +truculent +truculently +trudge +trudged +trudgen +trudgens +trudgeon +trudgeons +trudger +trudgers +trudges +trudging +true +trueblue +trueblues +trueborn +truebred +trued +truehearted +trueheartedness +trueheartednesses +trueing +truelove +trueloves +trueness +truenesses +truepennies +truepenny +truer +trues +truest +truffe +truffes +truffle +truffled +truffles +trug +trugs +truing +truism +truisms +truistic +trull +trulls +truly +trumeau +trumeaux +trump +trumped +trumperies +trumpery +trumpet +trumpeted +trumpeter +trumpeters +trumpeting +trumpetlike +trumpets +trumping +trumps +truncate +truncated +truncates +truncating +truncation +truncations +truncheon +truncheoned +truncheoning +truncheons +trundle +trundled +trundler +trundlers +trundles +trundling +trunk +trunked +trunkfish +trunkfishes +trunkful +trunkfuls +trunks +trunksful +trunnel +trunnels +trunnion +trunnions +truss +trussed +trusser +trussers +trusses +trussing +trussings +trust +trustabilities +trustability +trustable +trustbuster +trustbusters +trusted +trustee +trusteed +trusteeing +trustees +trusteeship +trusteeships +truster +trusters +trustful +trustfully +trustfulness +trustfulnesses +trustier +trusties +trustiest +trustily +trustiness +trustinesses +trusting +trustingly +trustingness +trustingnesses +trustless +trustor +trustors +trusts +trustworthily +trustworthiness +trustworthinesses +trustworthy +trusty +truth +truthful +truthfully +truthfulness +truthfulnesses +truths +try +trying +tryingly +tryma +trymata +tryout +tryouts +trypanosome +trypanosomes +trypanosomiases +trypanosomiasis +trypsin +trypsinogen +trypsinogens +trypsins +tryptamine +tryptamines +tryptic +tryptophan +tryptophane +tryptophanes +tryptophans +trysail +trysails +tryst +tryste +trysted +tryster +trysters +trystes +trysting +trysts +tryworks +tsade +tsades +tsadi +tsadis +tsar +tsardom +tsardoms +tsarevna +tsarevnas +tsarina +tsarinas +tsarism +tsarisms +tsarist +tsarists +tsaritza +tsaritzas +tsars +tsetse +tsetses +tsimmes +tsimmeses +tsk +tsked +tsking +tsks +tsktsk +tsktsked +tsktsking +tsktsks +tsooris +tsores +tsoris +tsorriss +tsuba +tsunami +tsunamic +tsunamis +tsuris +tsutsugamushi +tuatara +tuataras +tuatera +tuateras +tub +tuba +tubae +tubaist +tubaists +tubal +tubas +tubate +tubbable +tubbed +tubber +tubbers +tubbier +tubbiest +tubbing +tubby +tube +tubed +tubeless +tubelike +tubenose +tubenoses +tuber +tubercle +tubercles +tubercular +tuberculars +tuberculate +tuberculated +tuberculin +tuberculins +tuberculoid +tuberculoses +tuberculosis +tuberculous +tuberoid +tuberose +tuberoses +tuberosities +tuberosity +tuberous +tubers +tubes +tubework +tubeworks +tubful +tubfuls +tubifex +tubifexes +tubificid +tubificids +tubiform +tubing +tubings +tubist +tubists +tublike +tubocurarine +tubocurarines +tubs +tubular +tubulate +tubulated +tubulates +tubulating +tubule +tubules +tubulin +tubulins +tubulose +tubulous +tubulure +tubulures +tuchun +tuchuns +tuck +tuckahoe +tuckahoes +tucked +tucker +tuckered +tuckering +tuckers +tucket +tuckets +tucking +tucks +tuckshop +tuckshops +tufa +tufaceous +tufas +tuff +tuffaceous +tuffet +tuffets +tuffs +tufoli +tuft +tufted +tufter +tufters +tuftier +tuftiest +tuftily +tufting +tufts +tufty +tug +tugboat +tugboats +tugged +tugger +tuggers +tugging +tughrik +tughriks +tugless +tugrik +tugriks +tugs +tui +tuille +tuilles +tuis +tuition +tuitional +tuitions +tuladi +tuladis +tularemia +tularemias +tularemic +tule +tules +tulip +tulips +tulipwood +tulipwoods +tulle +tulles +tullibee +tullibees +tumble +tumblebug +tumblebugs +tumbled +tumbledown +tumbler +tumblerful +tumblerfuls +tumblers +tumbles +tumbleweed +tumbleweeds +tumbling +tumblings +tumbrel +tumbrels +tumbril +tumbrils +tumefaction +tumefactions +tumefied +tumefies +tumefy +tumefying +tumescence +tumescences +tumescent +tumid +tumidities +tumidity +tumidly +tummies +tummler +tummlers +tummy +tumor +tumoral +tumorigeneses +tumorigenesis +tumorigenic +tumorigenicities +tumorigenicity +tumorlike +tumorous +tumors +tumour +tumours +tump +tumped +tumping +tumpline +tumplines +tumps +tumular +tumuli +tumulose +tumulous +tumult +tumults +tumultuary +tumultuous +tumultuously +tumultuousness +tumultuousnesses +tumulus +tumuluses +tun +tuna +tunabilities +tunability +tunable +tunableness +tunablenesses +tunably +tunas +tundish +tundishes +tundra +tundras +tune +tuneable +tuneably +tuned +tuneful +tunefully +tunefulness +tunefulnesses +tuneless +tunelessly +tuner +tuners +tunes +tunesmith +tunesmiths +tuneup +tuneups +tung +tungs +tungstate +tungstates +tungsten +tungstens +tungstic +tunic +tunica +tunicae +tunicate +tunicated +tunicates +tunicle +tunicles +tunics +tuning +tunnage +tunnages +tunned +tunnel +tunneled +tunneler +tunnelers +tunneling +tunnelled +tunnellike +tunnelling +tunnels +tunnies +tunning +tunny +tuns +tup +tupelo +tupelos +tupik +tupiks +tupped +tuppence +tuppences +tuppenny +tupping +tups +tuque +tuques +turaco +turacos +turacou +turacous +turban +turbaned +turbanned +turbans +turbaries +turbary +turbellarian +turbellarians +turbeth +turbeths +turbid +turbidimeter +turbidimeters +turbidimetric +turbidimetrically +turbidimetries +turbidimetry +turbidite +turbidites +turbidities +turbidity +turbidly +turbidness +turbidnesses +turbinal +turbinals +turbinate +turbinated +turbinates +turbine +turbines +turbit +turbith +turbiths +turbits +turbo +turbocar +turbocars +turbocharged +turbocharger +turbochargers +turboelectric +turbofan +turbofans +turbogenerator +turbogenerators +turbojet +turbojets +turbomachineries +turbomachinery +turboprop +turboprops +turbos +turboshaft +turboshafts +turbot +turbots +turbulence +turbulences +turbulencies +turbulency +turbulent +turbulently +turd +turdine +turds +tureen +tureens +turf +turfed +turfier +turfiest +turfing +turfless +turflike +turfman +turfmen +turfs +turfski +turfskiing +turfskiings +turfskis +turfy +turgencies +turgency +turgent +turgescence +turgescences +turgescent +turgid +turgidities +turgidity +turgidly +turgidness +turgidnesses +turgite +turgites +turgor +turgors +turista +turistas +turk +turkey +turkeys +turkois +turkoises +turks +turmeric +turmerics +turmoil +turmoiled +turmoiling +turmoils +turn +turnable +turnabout +turnabouts +turnaround +turnarounds +turnbuckle +turnbuckles +turncoat +turncoats +turndown +turndowns +turned +turner +turneries +turners +turnery +turnhall +turnhalls +turning +turnings +turnip +turnips +turnkey +turnkeys +turnoff +turnoffs +turnout +turnouts +turnover +turnovers +turnpike +turnpikes +turns +turnsole +turnsoles +turnspit +turnspits +turnstile +turnstiles +turnstone +turnstones +turntable +turntables +turnup +turnups +turnverein +turnvereins +turophile +turophiles +turpentine +turpentined +turpentines +turpentining +turpeth +turpeths +turpitude +turpitudes +turps +turquois +turquoise +turquoises +turret +turreted +turrets +turrical +turtle +turtleback +turtlebacks +turtled +turtledove +turtledoves +turtlehead +turtleheads +turtleneck +turtlenecked +turtlenecks +turtler +turtlers +turtles +turtling +turtlings +turves +tusche +tusches +tush +tushed +tushes +tushie +tushies +tushing +tushy +tusk +tusked +tusker +tuskers +tusking +tuskless +tusklike +tusks +tussah +tussahs +tussal +tussar +tussars +tusseh +tussehs +tusser +tussers +tussis +tussises +tussive +tussle +tussled +tussles +tussling +tussock +tussocks +tussocky +tussor +tussore +tussores +tussors +tussuck +tussucks +tussur +tussurs +tut +tutee +tutees +tutelage +tutelages +tutelar +tutelaries +tutelars +tutelary +tutor +tutorage +tutorages +tutored +tutoress +tutoresses +tutorial +tutorials +tutoring +tutors +tutorship +tutorships +tutoyed +tutoyer +tutoyered +tutoyering +tutoyers +tuts +tutted +tutti +tutties +tutting +tuttis +tutty +tutu +tutus +tux +tuxedo +tuxedoed +tuxedoes +tuxedos +tuxes +tuyer +tuyere +tuyeres +tuyers +twa +twaddle +twaddled +twaddler +twaddlers +twaddles +twaddling +twae +twaes +twain +twains +twang +twanged +twanger +twangers +twangier +twangiest +twanging +twangle +twangled +twangler +twanglers +twangles +twangling +twangs +twangy +twankies +twanky +twas +twasome +twasomes +twat +twats +twattle +twattled +twattles +twattling +twayblade +twayblades +tweak +tweaked +tweakier +tweakiest +tweaking +tweaks +tweaky +twee +tweed +tweedier +tweediest +tweediness +tweedinesses +tweedle +tweedled +tweedles +tweedling +tweeds +tweedy +tween +tweenies +tweeny +tweet +tweeted +tweeter +tweeters +tweeting +tweets +tweeze +tweezed +tweezer +tweezers +tweezes +tweezing +twelfth +twelfths +twelve +twelvemo +twelvemonth +twelvemonths +twelvemos +twelves +twenties +twentieth +twentieths +twenty +twerp +twerps +twibil +twibill +twibills +twibils +twice +twiddle +twiddled +twiddler +twiddlers +twiddles +twiddlier +twiddliest +twiddling +twiddly +twier +twiers +twig +twigged +twiggen +twiggier +twiggiest +twigging +twiggy +twigless +twiglike +twigs +twilight +twilights +twilit +twill +twilled +twilling +twillings +twills +twin +twinberries +twinberry +twinborn +twine +twined +twiner +twiners +twines +twinflower +twinflowers +twinge +twinged +twingeing +twinges +twinging +twinier +twiniest +twinight +twining +twinjet +twinjets +twinkle +twinkled +twinkler +twinklers +twinkles +twinkling +twinklings +twinkly +twinned +twinning +twinnings +twins +twinset +twinsets +twinship +twinships +twiny +twirl +twirled +twirler +twirlers +twirlier +twirliest +twirling +twirls +twirly +twirp +twirps +twist +twisted +twister +twisters +twistier +twistiest +twisting +twistings +twists +twisty +twit +twitch +twitched +twitcher +twitchers +twitches +twitchier +twitchiest +twitchily +twitching +twitchy +twits +twitted +twitter +twittered +twittering +twitters +twittery +twitting +twixt +two +twofer +twofers +twofold +twofolds +twopence +twopences +twopenny +twos +twosome +twosomes +twyer +twyers +tycoon +tycoons +tye +tyee +tyees +tyer +tyers +tyes +tying +tyke +tykes +tylosin +tylosins +tymbal +tymbals +tympan +tympana +tympanal +tympani +tympanic +tympanies +tympanist +tympanists +tympanites +tympaniteses +tympanitic +tympano +tympans +tympanum +tympanums +tympany +tyne +tyned +tynes +tyning +typable +typal +type +typeable +typebar +typebars +typecase +typecases +typecast +typecasting +typecasts +typed +typeface +typefaces +typefounder +typefounders +typefounding +typefoundings +types +typescript +typescripts +typeset +typesets +typesetter +typesetters +typesetting +typesettings +typestyle +typestyles +typewrite +typewriter +typewriters +typewrites +typewriting +typewritings +typewritten +typewrote +typey +typhlosole +typhlosoles +typhoid +typhoids +typhon +typhonic +typhons +typhoon +typhoons +typhose +typhous +typhus +typhuses +typic +typical +typicalities +typicality +typically +typicalness +typicalnesses +typier +typiest +typification +typifications +typified +typifier +typifiers +typifies +typify +typifying +typing +typist +typists +typo +typograph +typographed +typographer +typographers +typographic +typographical +typographically +typographies +typographing +typographs +typography +typological +typologically +typologies +typologist +typologists +typology +typos +typp +typps +typy +tyramine +tyramines +tyrannic +tyrannical +tyrannically +tyrannicalness +tyrannicalnesses +tyrannicide +tyrannicides +tyrannies +tyrannise +tyrannised +tyrannises +tyrannising +tyrannize +tyrannized +tyrannizer +tyrannizers +tyrannizes +tyrannizing +tyrannosaur +tyrannosaurs +tyrannosaurus +tyrannosauruses +tyrannous +tyrannously +tyranny +tyrant +tyrants +tyre +tyred +tyres +tyring +tyro +tyrocidin +tyrocidine +tyrocidines +tyrocidins +tyronic +tyros +tyrosinase +tyrosinases +tyrosine +tyrosines +tyrothricin +tyrothricins +tythe +tythed +tythes +tything +tzaddik +tzaddikim +tzar +tzardom +tzardoms +tzarevna +tzarevnas +tzarina +tzarinas +tzarism +tzarisms +tzarist +tzarists +tzaritza +tzaritzas +tzars +tzetze +tzetzes +tzigane +tziganes +tzimmes +tzimmeses +tzitzis +tzitzit +tzitzith +tzuris +ubieties +ubiety +ubique +ubiquinone +ubiquinones +ubiquities +ubiquitous +ubiquitously +ubiquitousness +ubiquitousnesses +ubiquity +udder +udders +udo +udometer +udometers +udometries +udometry +udos +ufological +ufologies +ufologist +ufologists +ufology +ugh +ughs +uglier +uglies +ugliest +uglification +uglifications +uglified +uglifier +uglifiers +uglifies +uglify +uglifying +uglily +ugliness +uglinesses +ugly +ugsome +uh +uhlan +uhlans +uintahite +uintahites +uintaite +uintaites +ukase +ukases +uke +ukelele +ukeleles +ukes +ukulele +ukuleles +ulama +ulamas +ulan +ulans +ulcer +ulcerate +ulcerated +ulcerates +ulcerating +ulceration +ulcerations +ulcerative +ulcered +ulcering +ulcerogenic +ulcerous +ulcers +ulema +ulemas +ulexite +ulexites +ullage +ullaged +ullages +ulna +ulnad +ulnae +ulnar +ulnas +ulpan +ulpanim +ulster +ulsters +ulterior +ulteriorly +ultima +ultimacies +ultimacy +ultimas +ultimata +ultimate +ultimated +ultimately +ultimateness +ultimatenesses +ultimates +ultimating +ultimatum +ultimatums +ultimo +ultimogeniture +ultimogenitures +ultra +ultrabasic +ultrabasics +ultracareful +ultracasual +ultracautious +ultracentrifugal +ultracentrifugally +ultracentrifugation +ultracentrifugations +ultracentrifuge +ultracentrifuged +ultracentrifuges +ultracentrifuging +ultrachic +ultracivilized +ultraclean +ultracold +ultracommercial +ultracompact +ultracompetent +ultraconservatism +ultraconservatisms +ultraconservative +ultraconservatives +ultracontemporaries +ultracontemporary +ultraconvenient +ultracool +ultracritical +ultrademocratic +ultradense +ultradistance +ultradistances +ultradistant +ultradry +ultraefficient +ultraenergetic +ultraexclusive +ultrafamiliar +ultrafast +ultrafastidious +ultrafeminine +ultrafiche +ultrafiches +ultrafiltrate +ultrafiltrates +ultrafiltration +ultrafiltrations +ultrafine +ultraglamorous +ultrahazardous +ultraheat +ultraheated +ultraheating +ultraheats +ultraheavy +ultrahigh +ultrahip +ultrahot +ultrahuman +ultraism +ultraisms +ultraist +ultraistic +ultraists +ultraleft +ultraleftism +ultraleftisms +ultraleftist +ultraleftists +ultraliberal +ultraliberalism +ultraliberalisms +ultraliberals +ultralight +ultralights +ultralightweight +ultralow +ultramafic +ultramarathon +ultramarathoner +ultramarathoners +ultramarathons +ultramarine +ultramarines +ultramasculine +ultramicro +ultramicroscope +ultramicroscopes +ultramicroscopic +ultramicroscopical +ultramicroscopically +ultramicrotome +ultramicrotomes +ultramicrotomies +ultramicrotomy +ultramilitant +ultraminiature +ultraminiaturized +ultramodern +ultramodernist +ultramodernists +ultramontane +ultramontanes +ultramontanism +ultramontanisms +ultranationalism +ultranationalisms +ultranationalist +ultranationalistic +ultranationalists +ultraorthodox +ultraparadoxical +ultrapatriotic +ultraphysical +ultrapowerful +ultrapractical +ultraprecise +ultraprecision +ultraprecisions +ultraprofessional +ultraprogressive +ultraprogressives +ultrapure +ultraquiet +ultraradical +ultraradicals +ultrarapid +ultrarare +ultrararefied +ultrarational +ultrarealism +ultrarealisms +ultrarealist +ultrarealistic +ultrarealists +ultrared +ultrareds +ultrarefined +ultrareliable +ultrarespectable +ultrarevolutionaries +ultrarevolutionary +ultrarich +ultraright +ultrarightist +ultrarightists +ultraromantic +ultraroyalist +ultraroyalists +ultras +ultrasafe +ultrasecret +ultrasegregationist +ultrasegregationists +ultrasensitive +ultraserious +ultrasharp +ultrashort +ultrasimple +ultraslick +ultraslow +ultrasmall +ultrasmart +ultrasmooth +ultrasoft +ultrasonic +ultrasonically +ultrasonics +ultrasonographer +ultrasonographers +ultrasonographic +ultrasonographies +ultrasonography +ultrasophisticated +ultrasound +ultrasounds +ultrastructural +ultrastructurally +ultrastructure +ultrastructures +ultrathin +ultravacua +ultravacuum +ultravacuums +ultraviolence +ultraviolences +ultraviolent +ultraviolet +ultraviolets +ultravirile +ultravirilities +ultravirility +ultrawide +ulu +ululant +ululate +ululated +ululates +ululating +ululation +ululations +ulus +ulva +ulvas +um +umangite +umangites +umbel +umbeled +umbellar +umbellate +umbelled +umbellet +umbellets +umbellifer +umbelliferous +umbellifers +umbels +umber +umbered +umbering +umbers +umbilical +umbilicals +umbilicate +umbilicated +umbilication +umbilications +umbilici +umbilicus +umbilicuses +umbles +umbo +umbonal +umbonate +umbones +umbonic +umbos +umbra +umbrae +umbrage +umbrageous +umbrageously +umbrageousness +umbrageousnesses +umbrages +umbral +umbras +umbrella +umbrellaed +umbrellaing +umbrellas +umbrette +umbrettes +umiac +umiack +umiacks +umiacs +umiak +umiaks +umiaq +umiaqs +umlaut +umlauted +umlauting +umlauts +umm +ump +umped +umping +umpirage +umpirages +umpire +umpired +umpires +umpiring +umps +umpteen +umpteenth +umteenth +un +unabashed +unabashedly +unabated +unabatedly +unable +unabraded +unabridged +unabsorbed +unabsorbent +unabused +unacademic +unacademically +unaccented +unacceptabilities +unacceptability +unacceptable +unacceptably +unaccepted +unacclimated +unacclimatized +unaccommodated +unaccommodating +unaccompanied +unaccountabilities +unaccountability +unaccountable +unaccountably +unaccounted +unaccredited +unacculturated +unaccustomed +unaccustomedly +unachieved +unacknowledged +unacquainted +unactable +unacted +unactorish +unadaptable +unadapted +unaddressed +unadjudicated +unadjusted +unadmired +unadmitted +unadoptable +unadorned +unadult +unadulterated +unadulteratedly +unadventurous +unadvertised +unadvised +unadvisedly +unaesthetic +unaffected +unaffectedly +unaffectedness +unaffectednesses +unaffecting +unaffectionate +unaffectionately +unaffiliated +unaffluent +unaffordable +unafraid +unaged +unageing +unaggressive +unagile +unaging +unai +unaided +unaimed +unaired +unais +unakin +unakite +unakites +unalienable +unalienated +unaligned +unalike +unalleviated +unallied +unallocated +unalloyed +unalluring +unalterabilities +unalterability +unalterable +unalterableness +unalterablenesses +unalterably +unaltered +unambiguous +unambiguously +unambitious +unambivalent +unambivalently +unamenable +unamended +unamiable +unamortized +unamplified +unamused +unamusing +unanalyzable +unanalyzed +unanchor +unanchored +unanchoring +unanchors +unaneled +unanesthetized +unanimities +unanimity +unanimous +unanimously +unannotated +unannounced +unanswerabilities +unanswerability +unanswerable +unanswerably +unanswered +unanticipated +unanticipatedly +unapologetic +unapologetically +unapologizing +unapparent +unappealable +unappealing +unappealingly +unappeasable +unappeasably +unappeased +unappetizing +unappetizingly +unappreciated +unappreciation +unappreciations +unappreciative +unapproachabilities +unapproachability +unapproachable +unapproachably +unappropriated +unapproved +unapt +unaptly +unaptness +unaptnesses +unarguable +unarguably +unargued +unarm +unarmed +unarming +unarmored +unarms +unarrogant +unartful +unarticulated +unartistic +unary +unashamed +unashamedly +unasked +unaspirated +unassailabilities +unassailability +unassailable +unassailableness +unassailablenesses +unassailably +unassailed +unassembled +unassertive +unassertively +unassigned +unassimilable +unassimilated +unassisted +unassociated +unassuageable +unassuaged +unassuming +unassumingness +unassumingnesses +unathletic +unatoned +unattached +unattainable +unattended +unattenuated +unattested +unattractive +unattractively +unattractiveness +unattractivenesses +unattributable +unattributed +unattuned +unau +unaudited +unaus +unauthentic +unauthorized +unautomated +unavailabilities +unavailability +unavailable +unavailing +unavailingly +unavailingness +unavailingnesses +unaverage +unavoidable +unavoidably +unavowed +unawaked +unawakened +unawarded +unaware +unawarely +unawareness +unawarenesses +unawares +unawed +unawesome +unbacked +unbaked +unbalance +unbalanced +unbalances +unbalancing +unballasted +unban +unbandage +unbandaged +unbandages +unbandaging +unbanned +unbanning +unbans +unbaptized +unbar +unbarbed +unbarbered +unbarred +unbarricaded +unbarring +unbars +unbased +unbated +unbathed +unbe +unbear +unbearable +unbearably +unbeared +unbearing +unbears +unbeatable +unbeatably +unbeaten +unbeautiful +unbeautifully +unbecoming +unbecomingly +unbecomingness +unbecomingnesses +unbeholden +unbeknown +unbeknownst +unbelief +unbeliefs +unbelievable +unbelievably +unbeliever +unbelievers +unbelieving +unbelievingly +unbelligerent +unbeloved +unbelt +unbelted +unbelting +unbelts +unbemused +unbend +unbendable +unbended +unbending +unbends +unbenign +unbent +unbeseeming +unbiased +unbiasedness +unbiasednesses +unbiblical +unbid +unbidden +unbilled +unbind +unbinding +unbinds +unbitted +unbitten +unbitter +unblamed +unbleached +unblemished +unblenched +unblended +unblessed +unblest +unblinded +unblinking +unblinkingly +unblock +unblocked +unblocking +unblocks +unblooded +unbloodied +unbloody +unblushing +unblushingly +unbodied +unbolt +unbolted +unbolting +unbolts +unboned +unbonnet +unbonneted +unbonneting +unbonnets +unbookish +unborn +unbosom +unbosomed +unbosoming +unbosoms +unbought +unbouncy +unbound +unbounded +unboundedness +unboundednesses +unbowdlerized +unbowed +unbox +unboxed +unboxes +unboxing +unbrace +unbraced +unbraces +unbracing +unbracketed +unbraid +unbraided +unbraiding +unbraids +unbrake +unbraked +unbrakes +unbraking +unbranched +unbranded +unbreachable +unbreakable +unbreathable +unbred +unbreech +unbreeched +unbreeches +unbreeching +unbridgeable +unbridged +unbridle +unbridled +unbridles +unbridling +unbriefed +unbright +unbrilliant +unbroke +unbroken +unbruised +unbrushed +unbuckle +unbuckled +unbuckles +unbuckling +unbudgeable +unbudgeably +unbudgeted +unbudging +unbudgingly +unbuffered +unbuild +unbuildable +unbuilding +unbuilds +unbuilt +unbulky +unbundle +unbundled +unbundles +unbundling +unburden +unburdened +unburdening +unburdens +unbureaucratic +unburied +unburnable +unburned +unburnt +unbusinesslike +unbusted +unbusy +unbuttered +unbutton +unbuttoned +unbuttoning +unbuttons +uncage +uncaged +uncages +uncaging +uncake +uncaked +uncakes +uncaking +uncalcified +uncalcined +uncalculated +uncalculating +uncalibrated +uncalled +uncalloused +uncanceled +uncandid +uncandidly +uncannier +uncanniest +uncannily +uncanniness +uncanninesses +uncanny +uncanonical +uncap +uncapitalized +uncapped +uncapping +uncaps +uncaptioned +uncapturable +uncaring +uncarpeted +uncase +uncased +uncases +uncashed +uncasing +uncasked +uncastrated +uncataloged +uncatchable +uncatchy +uncategorizable +uncaught +uncaused +unceasing +unceasingly +uncelebrated +uncensored +uncensorious +uncensured +unceremonious +unceremoniously +unceremoniousness +unceremoniousnesses +uncertain +uncertainly +uncertainness +uncertainnesses +uncertainties +uncertainty +uncertified +unchain +unchained +unchaining +unchains +unchallengeable +unchallenged +unchallenging +unchancy +unchangeabilities +unchangeability +unchangeable +unchangeableness +unchangeablenesses +unchangeably +unchanged +unchanging +unchangingly +unchangingness +unchangingnesses +unchanneled +unchaperoned +uncharacteristic +uncharacteristically +uncharge +uncharged +uncharges +uncharging +uncharismatic +uncharitable +uncharitableness +uncharitablenesses +uncharitably +uncharming +uncharted +unchartered +unchary +unchaste +unchastely +unchasteness +unchastenesses +unchastities +unchastity +unchauvinistic +uncheckable +unchecked +unchewable +unchewed +unchic +unchicly +unchildlike +unchivalrous +unchivalrously +unchlorinated +unchoke +unchoked +unchokes +unchoking +unchoreographed +unchosen +unchristened +unchristian +unchronicled +unchronological +unchurch +unchurched +unchurches +unchurching +unchurchly +unci +uncia +unciae +uncial +uncially +uncials +unciform +unciforms +unciliated +uncinal +uncinariases +uncinariasis +uncinate +uncinematic +uncini +uncinus +uncirculated +uncircumcised +uncircumcision +uncircumcisions +uncivil +uncivilized +uncivilly +unclad +unclaimed +unclamp +unclamped +unclamping +unclamps +unclarified +unclarities +unclarity +unclasp +unclasped +unclasping +unclasps +unclassical +unclassifiable +unclassified +uncle +unclean +uncleaned +uncleaner +uncleanest +uncleanliness +uncleanlinesses +uncleanly +uncleanness +uncleannesses +unclear +unclearer +unclearest +unclench +unclenched +unclenches +unclenching +uncles +uncliched +unclimbable +unclimbableness +unclimbablenesses +unclinch +unclinched +unclinches +unclinching +unclip +unclipped +unclipping +unclips +uncloak +uncloaked +uncloaking +uncloaks +unclog +unclogged +unclogging +unclogs +unclose +unclosed +uncloses +unclosing +unclothe +unclothed +unclothes +unclothing +uncloud +unclouded +uncloudedly +unclouding +unclouds +uncloyed +uncloying +unclubbable +unclutter +uncluttered +uncluttering +unclutters +unco +uncoalesce +uncoalesced +uncoalesces +uncoalescing +uncoated +uncoating +uncock +uncocked +uncocking +uncocks +uncoded +uncodified +uncoerced +uncoercive +uncoercively +uncoffin +uncoffined +uncoffining +uncoffins +uncoil +uncoiled +uncoiling +uncoils +uncoined +uncollected +uncollectible +uncollectibles +uncolored +uncombative +uncombed +uncombined +uncomely +uncomfortable +uncomfortably +uncomic +uncommercial +uncommercialized +uncommitted +uncommon +uncommoner +uncommonest +uncommonly +uncommonness +uncommonnesses +uncommunicable +uncommunicative +uncompassionate +uncompelling +uncompensated +uncompetitive +uncompetitiveness +uncompetitivenesses +uncomplacent +uncomplaining +uncomplainingly +uncompleted +uncomplicated +uncomplimentary +uncompounded +uncomprehended +uncomprehending +uncomprehendingly +uncompromisable +uncompromising +uncompromisingly +uncompromisingness +uncompromisingnesses +uncomputerized +unconcealed +unconceivable +unconcern +unconcerned +unconcernedly +unconcernedness +unconcernednesses +unconcerns +unconditional +unconditionally +unconditioned +unconfessed +unconfined +unconfirmed +unconformable +unconformably +unconformities +unconformity +unconfounded +unconfuse +unconfused +unconfuses +unconfusing +uncongenial +uncongenialities +uncongeniality +unconjugated +unconnected +unconquerable +unconquerably +unconquered +unconscionabilities +unconscionability +unconscionable +unconscionableness +unconscionablenesses +unconscionably +unconscious +unconsciouses +unconsciously +unconsciousness +unconsciousnesses +unconsecrated +unconsidered +unconsolidated +unconstitutional +unconstitutionalities +unconstitutionality +unconstitutionally +unconstrained +unconstraint +unconstraints +unconstricted +unconstructed +unconstructive +unconsumed +unconsummated +uncontainable +uncontaminated +uncontemplated +uncontemporary +uncontentious +uncontested +uncontracted +uncontradicted +uncontrived +uncontrollabilities +uncontrollability +uncontrollable +uncontrollably +uncontrolled +uncontroversial +uncontroversially +unconventional +unconventionalities +unconventionality +unconventionally +unconverted +unconvinced +unconvincing +unconvincingly +unconvincingness +unconvincingnesses +unconvoyed +uncooked +uncool +uncooled +uncooperative +uncoordinated +uncopyrightable +uncork +uncorked +uncorking +uncorks +uncorrectable +uncorrected +uncorrelated +uncorroborated +uncorrupt +uncorseted +uncos +uncountable +uncounted +uncouple +uncoupled +uncoupler +uncouplers +uncouples +uncoupling +uncourageous +uncouth +uncouthly +uncouthness +uncouthnesses +uncovenanted +uncover +uncovered +uncovering +uncovers +uncoy +uncracked +uncrate +uncrated +uncrates +uncrating +uncrazy +uncreate +uncreated +uncreates +uncreating +uncreative +uncredentialed +uncredited +uncrippled +uncritical +uncritically +uncropped +uncross +uncrossable +uncrossed +uncrosses +uncrossing +uncrowded +uncrown +uncrowned +uncrowning +uncrowns +uncrumple +uncrumpled +uncrumples +uncrumpling +uncrushable +uncrystallized +unction +unctions +unctuous +unctuously +unctuousness +unctuousnesses +uncuff +uncuffed +uncuffing +uncuffs +uncultivable +uncultivated +uncultured +uncurb +uncurbed +uncurbing +uncurbs +uncured +uncurious +uncurl +uncurled +uncurling +uncurls +uncurrent +uncursed +uncurtained +uncus +uncustomarily +uncustomary +uncut +uncute +uncynical +uncynically +undamaged +undamped +undanceable +undaring +undated +undauntable +undaunted +undauntedly +unde +undead +undebatable +undebatably +undecadent +undeceive +undeceived +undeceives +undeceiving +undecidabilities +undecidability +undecidable +undecided +undecideds +undecillion +undecillions +undecipherable +undeciphered +undecked +undeclared +undecomposed +undecorated +undedicated +undee +undefeated +undefended +undefiled +undefinable +undefined +undefoliated +undeformed +undelegated +undeliverable +undelivered +undeluded +undemanding +undemocratic +undemocratically +undemonstrative +undemonstratively +undemonstrativeness +undemonstrativenesses +undeniable +undeniableness +undeniablenesses +undeniably +undenied +undenominational +undependable +under +underachieve +underachieved +underachievement +underachievements +underachiever +underachievers +underachieves +underachieving +underact +underacted +underacting +underactive +underactivities +underactivity +underacts +underage +underages +underappreciated +underarm +underarms +underate +underbellies +underbelly +underbid +underbidder +underbidders +underbidding +underbids +underbodies +underbody +underboss +underbosses +underbought +underbred +underbrim +underbrims +underbrush +underbrushes +underbud +underbudded +underbudding +underbudgeted +underbuds +underbuy +underbuying +underbuys +undercapitalized +undercard +undercards +undercarriage +undercarriages +undercharge +undercharged +undercharges +undercharging +underclass +underclasses +underclassman +underclassmen +underclothes +underclothing +underclothings +undercoat +undercoating +undercoatings +undercoats +undercool +undercooled +undercooling +undercools +undercount +undercounted +undercounting +undercounts +undercover +undercroft +undercrofts +undercurrent +undercurrents +undercut +undercuts +undercutting +underdeveloped +underdevelopment +underdevelopments +underdid +underdo +underdoes +underdog +underdogs +underdoing +underdone +underdrawers +undereat +undereaten +undereating +undereats +undereducated +underemphases +underemphasis +underemphasize +underemphasized +underemphasizes +underemphasizing +underemployed +underemployment +underemployments +underestimate +underestimated +underestimates +underestimating +underestimation +underestimations +underexpose +underexposed +underexposes +underexposing +underexposure +underexposures +underfed +underfeed +underfeeding +underfeeds +underfinanced +underfoot +underfund +underfunded +underfunding +underfunds +underfur +underfurs +undergarment +undergarments +undergird +undergirded +undergirding +undergirds +undergirt +underglaze +underglazes +undergo +undergod +undergods +undergoes +undergoing +undergone +undergrad +undergrads +undergraduate +undergraduates +underground +undergrounder +undergrounders +undergrounds +undergrowth +undergrowths +underhand +underhanded +underhandedly +underhandedness +underhandednesses +underinflated +underinflation +underinflations +underinsured +underinvestment +underinvestments +underjaw +underjaws +underlaid +underlain +underlap +underlapped +underlapping +underlaps +underlay +underlaying +underlayment +underlayments +underlays +underlet +underlets +underletting +underlie +underlies +underline +underlined +underlines +underling +underlings +underlining +underlip +underlips +underlit +underlying +underlyingly +undermanned +undermine +undermined +undermines +undermining +undermost +underneath +undernourished +undernourishment +undernourishments +undernutrition +undernutritions +underpaid +underpainting +underpaintings +underpants +underpart +underparts +underpass +underpasses +underpay +underpaying +underpayment +underpayments +underpays +underpin +underpinned +underpinning +underpinnings +underpins +underplay +underplayed +underplaying +underplays +underplot +underplots +underpopulated +underpowered +underprepared +underprice +underpriced +underprices +underpricing +underprivileged +underproduction +underproductions +underproof +underpublicized +underqualified +underran +underrate +underrated +underrates +underrating +underreact +underreacted +underreacting +underreacts +underreport +underreported +underreporting +underreports +underrepresentation +underrepresentations +underrepresented +underrun +underrunning +underruns +undersaturated +underscore +underscored +underscores +underscoring +undersea +underseas +undersecretaries +undersecretary +undersell +underselling +undersells +underserved +underset +undersets +undersexed +undersheriff +undersheriffs +undershirt +undershirted +undershirts +undershoot +undershooting +undershoots +undershorts +undershot +undershrub +undershrubs +underside +undersides +undersigned +undersize +undersized +underskirt +underskirts +underslung +undersold +underspin +underspins +understaffed +understaffing +understaffings +understand +understandabilities +understandability +understandable +understandably +understanding +understandingly +understandings +understands +understate +understated +understatedly +understatement +understatements +understates +understating +understeer +understeered +understeering +understeers +understood +understories +understory +understrapper +understrappers +understrength +understudied +understudies +understudy +understudying +undersupplies +undersupply +undersurface +undersurfaces +undertake +undertaken +undertaker +undertakers +undertakes +undertaking +undertakings +undertax +undertaxed +undertaxes +undertaxing +undertenant +undertenants +underthrust +underthrusting +underthrusts +undertone +undertones +undertook +undertow +undertows +undertrick +undertricks +underused +underutilization +underutilizations +underutilize +underutilized +underutilizes +underutilizing +undervaluation +undervaluations +undervalue +undervalued +undervalues +undervaluing +underwater +underway +underwear +underweight +underweights +underwent +underwhelm +underwhelmed +underwhelming +underwhelms +underwing +underwings +underwood +underwoods +underwool +underwools +underworld +underworlds +underwrite +underwriter +underwriters +underwrites +underwriting +underwritten +underwrote +undescended +undescribable +undeserved +undeserving +undesignated +undesigning +undesirabilities +undesirability +undesirable +undesirableness +undesirablenesses +undesirables +undesirably +undesired +undetectable +undetected +undeterminable +undetermined +undeterred +undeveloped +undeviating +undeviatingly +undevout +undiagnosable +undiagnosed +undialectical +undid +undidactic +undies +undifferentiated +undigested +undigestible +undignified +undiluted +undiminished +undimmed +undine +undines +undiplomatic +undiplomatically +undirected +undischarged +undisciplined +undisclosed +undiscouraged +undiscoverable +undiscovered +undiscriminating +undiscussed +undisguised +undisguisedly +undismayed +undisputable +undisputed +undissociated +undissolved +undistinguished +undistorted +undistracted +undistributed +undisturbed +undivided +undo +undoable +undocile +undock +undocked +undocking +undocks +undoctored +undoctrinaire +undocumented +undoer +undoers +undoes +undogmatic +undogmatically +undoing +undoings +undomestic +undomesticated +undone +undotted +undouble +undoubled +undoubles +undoubling +undoubtable +undoubted +undoubtedly +undoubting +undrained +undramatic +undramatically +undramatized +undrape +undraped +undrapes +undraping +undraw +undrawing +undrawn +undraws +undreamed +undreamt +undress +undressed +undresses +undressing +undrest +undrew +undried +undrilled +undrinkable +undrunk +undubbed +undue +undulant +undular +undulate +undulated +undulates +undulating +undulation +undulations +undulatory +undulled +unduly +unduplicated +undutiful +undutifully +undutifulness +undutifulnesses +undy +undyed +undying +undynamic +uneager +unearmarked +unearned +unearth +unearthed +unearthing +unearthliness +unearthlinesses +unearthly +unearths +unease +uneases +uneasier +uneasiest +uneasily +uneasiness +uneasinesses +uneasy +uneatable +uneaten +uneccentric +unecological +uneconomic +uneconomical +unedible +unedifying +unedited +uneducable +uneducated +unelaborate +unelectable +unelected +unelectrified +unembarrassed +unembellished +unembittered +unemotional +unemotionally +unemphatic +unemphatically +unempirical +unemployabilities +unemployability +unemployable +unemployables +unemployed +unemployeds +unemployment +unemployments +unenchanted +unenclosed +unencouraging +unencumbered +unendearing +unended +unending +unendingly +unendurable +unendurableness +unendurablenesses +unendurably +unenforceable +unenforced +unenlarged +unenlightened +unenlightening +unenriched +unenterprising +unenthusiastic +unenthusiastically +unenviable +unenvied +unenvious +unequal +unequaled +unequalled +unequally +unequals +unequipped +unequivocably +unequivocal +unequivocally +unerased +unerotic +unerring +unerringly +unescapable +unessential +unestablished +unethical +unevaded +unevaluated +uneven +unevener +unevenest +unevenly +unevenness +unevennesses +uneventful +uneventfully +uneventfulness +uneventfulnesses +unevolved +unexamined +unexampled +unexcelled +unexceptionable +unexceptionableness +unexceptionablenesses +unexceptionably +unexceptional +unexcitable +unexcited +unexciting +unexcused +unexercised +unexotic +unexpected +unexpectedly +unexpectedness +unexpectednesses +unexpended +unexpert +unexpired +unexplainable +unexplained +unexploded +unexploited +unexplored +unexposed +unexpressed +unexpressive +unexpurgated +unextraordinary +unfaded +unfading +unfadingly +unfailing +unfailingly +unfair +unfairer +unfairest +unfairly +unfairness +unfairnesses +unfaith +unfaithful +unfaithfully +unfaithfulness +unfaithfulnesses +unfaiths +unfaked +unfallen +unfalsifiable +unfaltering +unfalteringly +unfamiliar +unfamiliarities +unfamiliarity +unfamiliarly +unfamous +unfancy +unfashionable +unfashionableness +unfashionablenesses +unfashionably +unfasten +unfastened +unfastening +unfastens +unfastidious +unfathered +unfathomable +unfavorable +unfavorableness +unfavorablenesses +unfavorably +unfavorite +unfazed +unfeared +unfeasible +unfed +unfeeling +unfeelingly +unfeelingness +unfeelingnesses +unfeigned +unfeignedly +unfelt +unfeminine +unfence +unfenced +unfences +unfencing +unfermented +unfertile +unfertilized +unfetter +unfettered +unfettering +unfetters +unfilial +unfilially +unfilled +unfilmed +unfiltered +unfindable +unfinished +unfired +unfished +unfit +unfitly +unfitness +unfitnesses +unfits +unfitted +unfitting +unfix +unfixed +unfixes +unfixing +unfixt +unflagging +unflaggingly +unflamboyant +unflappabilities +unflappability +unflappable +unflappably +unflashy +unflattering +unflatteringly +unfledged +unflexed +unflinching +unflinchingly +unflyable +unfocused +unfocussed +unfoiled +unfold +unfolded +unfolder +unfolders +unfolding +unfoldment +unfoldments +unfolds +unfond +unforced +unforeseeable +unforeseen +unforested +unforged +unforgettable +unforgettably +unforgivable +unforgiving +unforgivingness +unforgivingnesses +unforgot +unforked +unformed +unformulated +unforthcoming +unfortified +unfortunate +unfortunately +unfortunates +unfossiliferous +unfought +unfound +unfounded +unframed +unfree +unfreed +unfreedom +unfreedoms +unfreeing +unfrees +unfreeze +unfreezes +unfreezing +unfrequented +unfriended +unfriendlier +unfriendliest +unfriendliness +unfriendlinesses +unfriendly +unfrivolous +unfrock +unfrocked +unfrocking +unfrocks +unfroze +unfrozen +unfruitful +unfruitfully +unfruitfulness +unfruitfulnesses +unfulfillable +unfulfilled +unfunded +unfunny +unfurl +unfurled +unfurling +unfurls +unfurnished +unfused +unfussily +unfussy +ungainlier +ungainliest +ungainliness +ungainlinesses +ungainly +ungallant +ungallantly +ungalled +ungarnished +ungenerosities +ungenerosity +ungenerous +ungenerously +ungenial +ungenteel +ungentle +ungentlemanly +ungently +ungentrified +ungerminated +ungifted +ungimmicky +ungird +ungirded +ungirding +ungirds +ungirt +unglamorized +unglamorous +unglazed +unglove +ungloved +ungloves +ungloving +unglue +unglued +unglues +ungluing +ungodlier +ungodliest +ungodliness +ungodlinesses +ungodly +ungot +ungotten +ungovernable +ungowned +ungraced +ungraceful +ungracefully +ungracious +ungraciously +ungraciousness +ungraciousnesses +ungraded +ungrammatical +ungrammaticalities +ungrammaticality +ungraspable +ungrateful +ungratefully +ungratefulness +ungratefulnesses +ungreedy +unground +ungrounded +ungrouped +ungrudging +ungual +unguard +unguarded +unguardedly +unguardedness +unguardednesses +unguarding +unguards +unguent +unguenta +unguents +unguentum +ungues +unguessable +unguided +unguis +ungula +ungulae +ungular +ungulate +ungulates +unhackneyed +unhailed +unhair +unhaired +unhairing +unhairs +unhallow +unhallowed +unhallowing +unhallows +unhalved +unhampered +unhand +unhanded +unhandicapped +unhandier +unhandiest +unhandily +unhandiness +unhandinesses +unhanding +unhands +unhandsome +unhandsomely +unhandy +unhang +unhanged +unhanging +unhangs +unhappier +unhappiest +unhappily +unhappiness +unhappinesses +unhappy +unharmed +unharness +unharnessed +unharnesses +unharnessing +unharvested +unhasty +unhat +unhatched +unhats +unhatted +unhatting +unhealed +unhealthful +unhealthier +unhealthiest +unhealthily +unhealthiness +unhealthinesses +unhealthy +unheard +unheated +unhedged +unheeded +unheeding +unhelm +unhelmed +unhelming +unhelms +unhelped +unhelpful +unhelpfully +unheralded +unheroic +unhesitating +unhesitatingly +unhewn +unhindered +unhinge +unhinged +unhinges +unhinging +unhip +unhired +unhistorical +unhitch +unhitched +unhitches +unhitching +unholier +unholiest +unholily +unholiness +unholinesses +unholy +unhomogenized +unhonored +unhood +unhooded +unhooding +unhoods +unhook +unhooked +unhooking +unhooks +unhoped +unhopeful +unhorse +unhorsed +unhorses +unhorsing +unhouse +unhoused +unhouseled +unhouses +unhousing +unhuman +unhumorous +unhung +unhurried +unhurriedly +unhurt +unhusk +unhusked +unhusking +unhusks +unhydrolyzed +unhygienic +unhyphenated +unhysterical +unhysterically +unialgal +uniaxial +unicameral +unicamerally +unicellular +unicolor +unicorn +unicorns +unicycle +unicycles +unicyclist +unicyclists +unideaed +unideal +unidentifiable +unidentified +unideological +unidimensional +unidimensionalities +unidimensionality +unidiomatic +unidirectional +unidirectionally +uniface +unifaces +unifiable +unific +unification +unifications +unified +unifier +unifiers +unifies +unifilar +unifoliate +unifoliolate +uniform +uniformed +uniformer +uniformest +uniforming +uniformitarian +uniformitarianism +uniformitarianisms +uniformitarians +uniformities +uniformity +uniformly +uniformness +uniformnesses +uniforms +unify +unifying +unignorable +unilateral +unilaterally +unilineal +unilinear +unilingual +unilluminating +unillusioned +unilobed +unilocular +unimaginable +unimaginably +unimaginative +unimaginatively +unimbued +unimmunized +unimpaired +unimpassioned +unimpeachable +unimpeachably +unimpeded +unimplemented +unimportance +unimportances +unimportant +unimposing +unimpressed +unimpressive +unimproved +unincorporated +unindexed +unindicted +unindustrialized +uninfected +uninflated +uninflected +uninfluenced +uninformative +uninformatively +uninformed +uningratiating +uninhabitable +uninhabited +uninhibited +uninhibitedly +uninhibitedness +uninhibitednesses +uninitiate +uninitiated +uninitiates +uninjured +uninoculated +uninspected +uninspired +uninspiring +uninstructed +uninstructive +uninsulated +uninsurable +uninsured +unintegrated +unintellectual +unintelligent +unintelligently +unintelligibilities +unintelligibility +unintelligible +unintelligibleness +unintelligiblenesses +unintelligibly +unintended +unintentional +unintentionally +uninterest +uninterested +uninteresting +uninterests +uninterrupted +uninterruptedly +unintimidated +uninucleate +uninventive +uninvited +uninviting +uninvolved +union +unionisation +unionisations +unionise +unionised +unionises +unionising +unionism +unionisms +unionist +unionists +unionization +unionizations +unionize +unionized +unionizes +unionizing +unions +uniparental +uniparentally +unipod +unipods +unipolar +unique +uniquely +uniqueness +uniquenesses +uniquer +uniques +uniquest +unironed +unironically +unirradiated +unirrigated +unisex +unisexes +unisexual +unisexualities +unisexuality +unison +unisonal +unisons +unissued +unit +unitage +unitages +unitard +unitards +unitarian +unitarianism +unitarianisms +unitarians +unitarily +unitary +unite +united +unitedly +uniter +uniters +unites +unities +uniting +unitive +unitization +unitizations +unitize +unitized +unitizer +unitizers +unitizes +unitizing +unitrust +unitrusts +units +unity +univalent +univalents +univalve +univalves +univariate +universal +universalism +universalisms +universalist +universalistic +universalists +universalities +universality +universalization +universalizations +universalize +universalized +universalizes +universalizing +universally +universalness +universalnesses +universals +universe +universes +universities +university +univocal +univocally +univocals +unjaded +unjoined +unjoint +unjointed +unjointing +unjoints +unjoyful +unjudged +unjust +unjustifiable +unjustifiably +unjustified +unjustly +unjustness +unjustnesses +unkempt +unkend +unkenned +unkennel +unkenneled +unkenneling +unkennelled +unkennelling +unkennels +unkent +unkept +unkind +unkinder +unkindest +unkindlier +unkindliest +unkindliness +unkindlinesses +unkindly +unkindness +unkindnesses +unkingly +unkink +unkinked +unkinking +unkinks +unkissed +unknit +unknits +unknitted +unknitting +unknot +unknots +unknotted +unknotting +unknowabilities +unknowability +unknowable +unknowing +unknowingly +unknowings +unknowledgeable +unknown +unknowns +unkosher +unlabeled +unlace +unlaced +unlaces +unlacing +unlade +unladed +unladen +unlades +unlading +unladylike +unlaid +unlamented +unlash +unlashed +unlashes +unlashing +unlatch +unlatched +unlatches +unlatching +unlaundered +unlawful +unlawfully +unlawfulness +unlawfulnesses +unlay +unlaying +unlays +unlead +unleaded +unleading +unleads +unlearn +unlearnable +unlearned +unlearning +unlearns +unlearnt +unleased +unleash +unleashed +unleashes +unleashing +unleavened +unled +unless +unlet +unlethal +unletted +unlettered +unlevel +unleveled +unleveling +unlevelled +unlevelling +unlevels +unlevied +unliberated +unlicensed +unlicked +unlikable +unlike +unlikelier +unlikeliest +unlikelihood +unlikelihoods +unlikeliness +unlikelinesses +unlikely +unlikeness +unlikenesses +unlimber +unlimbered +unlimbering +unlimbers +unlimited +unlimitedly +unlined +unlink +unlinked +unlinking +unlinks +unlisted +unlistenable +unlit +unliterary +unlivable +unlive +unlived +unlively +unlives +unliving +unload +unloaded +unloader +unloaders +unloading +unloads +unlobed +unlocalized +unlock +unlocked +unlocking +unlocks +unloose +unloosed +unloosen +unloosened +unloosening +unloosens +unlooses +unloosing +unlovable +unloved +unlovelier +unloveliest +unloveliness +unlovelinesses +unlovely +unloving +unluckier +unluckiest +unluckily +unluckiness +unluckinesses +unlucky +unlyrical +unmacho +unmade +unmagnified +unmake +unmaker +unmakers +unmakes +unmaking +unmalicious +unmaliciously +unman +unmanageable +unmanageably +unmanaged +unmanful +unmanipulated +unmanlier +unmanliest +unmanliness +unmanlinesses +unmanly +unmanned +unmannered +unmanneredly +unmannerliness +unmannerlinesses +unmannerly +unmanning +unmans +unmapped +unmarked +unmarketable +unmarred +unmarried +unmarrieds +unmasculine +unmask +unmasked +unmasker +unmaskers +unmasking +unmasks +unmatchable +unmatched +unmated +unmatted +unmeaning +unmeant +unmeasurable +unmeasured +unmechanized +unmediated +unmedicated +unmeet +unmeetly +unmellow +unmelodious +unmelodiousness +unmelodiousnesses +unmelted +unmemorable +unmemorably +unmended +unmentionable +unmentionables +unmentioned +unmerciful +unmercifully +unmerited +unmerry +unmesh +unmeshed +unmeshes +unmeshing +unmet +unmetabolized +unmew +unmewed +unmewing +unmews +unmilitary +unmilled +unmindful +unmined +unmingle +unmingled +unmingles +unmingling +unmistakable +unmistakably +unmiter +unmitered +unmitering +unmiters +unmitigated +unmitigatedly +unmitigatedness +unmitigatednesses +unmitre +unmitred +unmitres +unmitring +unmix +unmixable +unmixed +unmixes +unmixing +unmixt +unmodernized +unmodified +unmodish +unmold +unmolded +unmolding +unmolds +unmolested +unmolten +unmonitored +unmoor +unmoored +unmooring +unmoors +unmoral +unmoralities +unmorality +unmotivated +unmounted +unmovable +unmoved +unmoving +unmown +unmuffle +unmuffled +unmuffles +unmuffling +unmusical +unmuzzle +unmuzzled +unmuzzles +unmuzzling +unmyelinated +unnail +unnailed +unnailing +unnails +unnameable +unnamed +unnatural +unnaturally +unnaturalness +unnaturalnesses +unnecessarily +unnecessary +unneeded +unnegotiable +unnerve +unnerved +unnerves +unnerving +unnervingly +unneurotic +unnewsworthy +unnilhexium +unnilhexiums +unnilpentium +unnilpentiums +unnilquadium +unnilquadiums +unnoisy +unnoted +unnoticeable +unnoticed +unnourishing +unnumbered +unobjectionable +unobservable +unobservant +unobserved +unobstructed +unobtainable +unobtrusive +unobtrusively +unobtrusiveness +unobtrusivenesses +unoccupied +unofficial +unofficially +unoiled +unopen +unopenable +unopened +unopposed +unordered +unorganized +unoriginal +unornamented +unornate +unorthodox +unorthodoxies +unorthodoxly +unorthodoxy +unostentatious +unostentatiously +unowned +unoxygenated +unpack +unpacked +unpacker +unpackers +unpacking +unpacks +unpaged +unpaid +unpainted +unpaired +unpalatabilities +unpalatability +unpalatable +unparalleled +unparasitized +unpardonable +unparented +unparliamentary +unparted +unpassable +unpasteurized +unpastoral +unpatentable +unpatriotic +unpaved +unpaying +unpedantic +unpeeled +unpeg +unpegged +unpegging +unpegs +unpen +unpenned +unpenning +unpens +unpent +unpeople +unpeopled +unpeoples +unpeopling +unperceived +unperceptive +unperfect +unperformable +unperformed +unperson +unpersons +unpersuaded +unpersuasive +unperturbed +unpick +unpicked +unpicking +unpicks +unpicturesque +unpile +unpiled +unpiles +unpiling +unpin +unpinned +unpinning +unpins +unpitied +unplaced +unplait +unplaited +unplaiting +unplaits +unplanned +unplausible +unplayable +unplayed +unpleasant +unpleasantly +unpleasantness +unpleasantnesses +unpleased +unpleasing +unpliant +unplowed +unplug +unplugged +unplugging +unplugs +unplumbed +unpoetic +unpoised +unpolarized +unpoliced +unpolished +unpolite +unpolitical +unpolled +unpolluted +unpopular +unpopularities +unpopularity +unposed +unposted +unpotted +unpractical +unprecedented +unprecedentedly +unpredictabilities +unpredictability +unpredictable +unpredictables +unpredictably +unpregnant +unprejudiced +unpremeditated +unprepared +unpreparedness +unpreparednesses +unprepossessing +unpressed +unpressured +unpressurized +unpretending +unpretentious +unpretentiously +unpretentiousness +unpretentiousnesses +unpretty +unpriced +unprimed +unprincipled +unprincipledness +unprinciplednesses +unprintable +unprivileged +unprized +unprobed +unproblematic +unprocessed +unproduced +unproductive +unprofessed +unprofessional +unprofessionally +unprofessionals +unprofitable +unprofitableness +unprofitablenesses +unprofitably +unprogrammable +unprogrammed +unprogressive +unpromising +unpromisingly +unprompted +unpronounceable +unpronounced +unpropitious +unprosperous +unprotected +unprovable +unproved +unproven +unprovoked +unpruned +unpublicized +unpublishable +unpublished +unpucker +unpuckered +unpuckering +unpuckers +unpunctual +unpunctualities +unpunctuality +unpunctuated +unpunished +unpure +unpurged +unpuzzle +unpuzzled +unpuzzles +unpuzzling +unqualified +unqualifiedly +unquantifiable +unquenchable +unquestionable +unquestionably +unquestioned +unquestioning +unquestioningly +unquiet +unquieter +unquietest +unquietly +unquietness +unquietnesses +unquiets +unquote +unquoted +unquotes +unquoting +unraised +unraked +unranked +unrated +unravel +unraveled +unraveling +unravelled +unravelling +unravels +unravished +unrazed +unreachable +unreached +unread +unreadable +unreadier +unreadiest +unreadiness +unreadinesses +unready +unreal +unrealistic +unrealistically +unrealities +unreality +unrealizable +unrealized +unreally +unreason +unreasonable +unreasonableness +unreasonablenesses +unreasonably +unreasoned +unreasoning +unreasoningly +unreasons +unreceptive +unreclaimable +unreclaimed +unrecognizable +unrecognizably +unrecognized +unreconcilable +unreconciled +unreconstructed +unrecorded +unrecoverable +unrecovered +unrecyclable +unredeemable +unredeemed +unredressed +unreel +unreeled +unreeler +unreelers +unreeling +unreels +unreeve +unreeved +unreeves +unreeving +unrefined +unreflective +unreformed +unrefrigerated +unregenerate +unregenerately +unregistered +unregulated +unrehearsed +unreinforced +unrelated +unrelaxed +unrelenting +unrelentingly +unreliabilities +unreliability +unreliable +unrelieved +unrelievedly +unreligious +unreluctant +unremarkable +unremarkably +unremarked +unremembered +unreminiscent +unremitting +unremittingly +unremorseful +unremovable +unrent +unrented +unrepaid +unrepair +unrepairs +unrepeatable +unrepentant +unrepentantly +unreported +unrepresentative +unrepresentativeness +unrepresentativenesses +unrepresented +unrepressed +unrequited +unreserve +unreserved +unreservedly +unreservedness +unreservednesses +unreserves +unresistant +unresisting +unresolvable +unresolved +unrespectable +unresponsive +unresponsively +unresponsiveness +unresponsivenesses +unrest +unrested +unrestful +unrestored +unrestrained +unrestrainedly +unrestrainedness +unrestrainednesses +unrestraint +unrestraints +unrestricted +unrests +unretouched +unreturnable +unrevealed +unreviewable +unreviewed +unrevised +unrevolutionary +unrewarded +unrewarding +unrhetorical +unrhymed +unrhythmic +unridable +unriddle +unriddled +unriddles +unriddling +unrifled +unrig +unrigged +unrigging +unrighteous +unrighteously +unrighteousness +unrighteousnesses +unrigs +unrimed +unrinsed +unrip +unripe +unripely +unripened +unripeness +unripenesses +unriper +unripest +unripped +unripping +unrips +unrisen +unrivaled +unrivalled +unrobe +unrobed +unrobes +unrobing +unroll +unrolled +unrolling +unrolls +unromantic +unromantically +unromanticized +unroof +unroofed +unroofing +unroofs +unroot +unrooted +unrooting +unroots +unroped +unrough +unround +unrounded +unrounding +unrounds +unrove +unroven +unruffled +unruled +unrulier +unruliest +unruliness +unrulinesses +unruly +unrushed +unrusted +uns +unsaddle +unsaddled +unsaddles +unsaddling +unsafe +unsafely +unsafeties +unsafety +unsaid +unsalable +unsalaried +unsalted +unsalvageable +unsanctioned +unsanitary +unsated +unsatisfactorily +unsatisfactoriness +unsatisfactorinesses +unsatisfactory +unsatisfied +unsatisfying +unsaturate +unsaturated +unsaturates +unsaved +unsavory +unsawed +unsawn +unsay +unsayable +unsaying +unsays +unscalable +unscaled +unscarred +unscathed +unscented +unscheduled +unscholarly +unschooled +unscientific +unscientifically +unscramble +unscrambled +unscrambler +unscramblers +unscrambles +unscrambling +unscreened +unscrew +unscrewed +unscrewing +unscrews +unscripted +unscriptural +unscrupulous +unscrupulously +unscrupulousness +unscrupulousnesses +unseal +unsealed +unsealing +unseals +unseam +unseamed +unseaming +unseams +unsearchable +unsearchably +unseared +unseasonable +unseasonableness +unseasonablenesses +unseasonably +unseasoned +unseat +unseated +unseating +unseats +unseaworthy +unsecured +unseeded +unseeing +unseemlier +unseemliest +unseemliness +unseemlinesses +unseemly +unseen +unsegmented +unsegregated +unseized +unselected +unselective +unselectively +unselfish +unselfishly +unselfishness +unselfishnesses +unsell +unsellable +unselling +unsells +unsensational +unsensitized +unsent +unsentimental +unseparated +unserious +unseriousness +unseriousnesses +unserved +unserviceable +unset +unsets +unsetting +unsettle +unsettled +unsettledness +unsettlednesses +unsettlement +unsettlements +unsettles +unsettling +unsettlingly +unsew +unsewed +unsewing +unsewn +unsews +unsex +unsexed +unsexes +unsexing +unsexual +unsexy +unshackle +unshackled +unshackles +unshackling +unshaded +unshakable +unshakably +unshaken +unshamed +unshaped +unshapely +unshapen +unshared +unsharp +unshaved +unshaven +unsheathe +unsheathed +unsheathes +unsheathing +unshed +unshell +unshelled +unshelling +unshells +unshift +unshifted +unshifting +unshifts +unship +unshipped +unshipping +unships +unshockable +unshod +unshorn +unshowy +unshrunk +unshut +unsicker +unsifted +unsight +unsighted +unsighting +unsightlier +unsightliest +unsightliness +unsightlinesses +unsightly +unsights +unsigned +unsilent +unsinful +unsinkable +unsized +unskilled +unskillful +unskillfully +unskillfulness +unskillfulnesses +unslakable +unslaked +unsliced +unsling +unslinging +unslings +unslung +unsmart +unsmiling +unsmoked +unsmoothed +unsnap +unsnapped +unsnapping +unsnaps +unsnarl +unsnarled +unsnarling +unsnarls +unsoaked +unsober +unsociabilities +unsociability +unsociable +unsociableness +unsociablenesses +unsociably +unsocial +unsocialized +unsocially +unsoiled +unsold +unsolder +unsoldered +unsoldering +unsolders +unsoldierly +unsolicited +unsolid +unsolvable +unsolved +unsoncy +unsonsie +unsonsy +unsophisticated +unsophistication +unsophistications +unsorted +unsought +unsound +unsounded +unsounder +unsoundest +unsoundly +unsoundness +unsoundnesses +unsoured +unsowed +unsown +unsparing +unsparingly +unspeak +unspeakable +unspeakably +unspeaking +unspeaks +unspecialized +unspecifiable +unspecific +unspecified +unspectacular +unspent +unsphere +unsphered +unspheres +unsphering +unspilt +unspiritual +unsplit +unspoiled +unspoilt +unspoke +unspoken +unsportsmanlike +unspotted +unsprayed +unsprung +unspun +unstable +unstableness +unstablenesses +unstabler +unstablest +unstably +unstack +unstacked +unstacking +unstacks +unstained +unstandardized +unstartling +unstate +unstated +unstates +unstating +unstayed +unsteadied +unsteadier +unsteadies +unsteadiest +unsteadily +unsteadiness +unsteadinesses +unsteady +unsteadying +unsteel +unsteeled +unsteeling +unsteels +unstep +unstepped +unstepping +unsteps +unsterile +unsterilized +unstick +unsticking +unsticks +unstinted +unstinting +unstintingly +unstitch +unstitched +unstitches +unstitching +unstoned +unstop +unstoppable +unstoppably +unstopped +unstopper +unstoppered +unstoppering +unstoppers +unstopping +unstops +unstrained +unstrap +unstrapped +unstrapping +unstraps +unstratified +unstress +unstressed +unstresses +unstring +unstringing +unstrings +unstructured +unstrung +unstuck +unstudied +unstuffy +unstung +unstylish +unsubdued +unsubsidized +unsubstantial +unsubstantialities +unsubstantiality +unsubstantially +unsubstantiated +unsubtle +unsubtly +unsuccess +unsuccesses +unsuccessful +unsuccessfully +unsuitabilities +unsuitability +unsuitable +unsuitably +unsuited +unsullied +unsung +unsunk +unsupervised +unsupportable +unsupported +unsure +unsurely +unsurpassable +unsurpassed +unsurprised +unsurprising +unsurprisingly +unsusceptible +unsuspected +unsuspecting +unsuspectingly +unsuspicious +unsustainable +unswathe +unswathed +unswathes +unswathing +unswayed +unswear +unswearing +unswears +unsweetened +unswept +unswerving +unswore +unsworn +unsymmetrical +unsymmetrically +unsympathetic +unsympathetically +unsymptomatic +unsynchronized +unsystematic +unsystematically +unsystematized +untack +untacked +untacking +untacks +untactful +untagged +untainted +untaken +untalented +untamable +untame +untamed +untangle +untangled +untangles +untangling +untanned +untapped +untarnished +untasted +untaught +untaxed +unteach +unteachable +unteaches +unteaching +untechnical +untempered +untenabilities +untenability +untenable +untenanted +untended +untented +untenured +untestable +untested +untether +untethered +untethering +untethers +unthawed +untheoretical +unthink +unthinkabilities +unthinkability +unthinkable +unthinkably +unthinking +unthinkingly +unthinks +unthought +unthread +unthreaded +unthreading +unthreads +unthreatening +unthrifty +unthrone +unthroned +unthrones +unthroning +untidied +untidier +untidies +untidiest +untidily +untidiness +untidinesses +untidy +untidying +untie +untied +unties +until +untillable +untilled +untilted +untimelier +untimeliest +untimeliness +untimelinesses +untimely +untimeous +untinged +untipped +untired +untiring +untiringly +untitled +unto +untogether +untold +untorn +untouchabilities +untouchability +untouchable +untouchables +untouched +untoward +untowardly +untowardness +untowardnesses +untraceable +untraced +untraditional +untraditionally +untrained +untrammeled +untransformed +untranslatabilities +untranslatability +untranslatable +untranslated +untraveled +untraversed +untread +untreading +untreads +untreated +untrendy +untried +untrim +untrimmed +untrimming +untrims +untrod +untrodden +untroubled +untrue +untruer +untruest +untruly +untruss +untrussed +untrusses +untrussing +untrusting +untrustworthy +untrusty +untruth +untruthful +untruthfully +untruthfulness +untruthfulnesses +untruths +untuck +untucked +untucking +untucks +untufted +untune +untuned +untunes +untuning +unturned +untutored +untwine +untwined +untwines +untwining +untwist +untwisted +untwisting +untwists +untying +untypical +untypically +ununderstandable +ununited +unurged +unusable +unused +unusual +unusually +unusualness +unusualnesses +unutilized +unutterable +unutterably +unvaccinated +unvalued +unvanquished +unvaried +unvarnished +unvarying +unveil +unveiled +unveiling +unveils +unveined +unventilated +unverbalized +unverifiable +unverified +unversed +unvexed +unvext +unviable +unvisited +unvocal +unvoice +unvoiced +unvoices +unvoicing +unwalled +unwaning +unwanted +unwarier +unwariest +unwarily +unwariness +unwarinesses +unwarlike +unwarmed +unwarned +unwarped +unwarrantable +unwarrantably +unwarranted +unwary +unwashed +unwashedness +unwashednesses +unwasheds +unwasted +unwatchable +unwavering +unwaveringly +unwaxed +unweaned +unwearable +unwearied +unweariedly +unweary +unweathered +unweave +unweaves +unweaving +unwed +unwedded +unweeded +unweeting +unweetingly +unweight +unweighted +unweighting +unweights +unwelcome +unwelded +unwell +unwept +unwetted +unwhite +unwholesome +unwholesomely +unwieldier +unwieldiest +unwieldily +unwieldiness +unwieldinesses +unwieldy +unwifely +unwilled +unwilling +unwillingly +unwillingness +unwillingnesses +unwind +unwinder +unwinders +unwinding +unwinds +unwinnable +unwisdom +unwisdoms +unwise +unwisely +unwiser +unwisest +unwish +unwished +unwishes +unwishing +unwit +unwits +unwitted +unwitting +unwittingly +unwomanly +unwon +unwonted +unwontedly +unwontedness +unwontednesses +unwooded +unwooed +unworkabilities +unworkability +unworkable +unworkables +unworked +unworldliness +unworldlinesses +unworldly +unworn +unworried +unworthier +unworthies +unworthiest +unworthily +unworthiness +unworthinesses +unworthy +unwound +unwounded +unwove +unwoven +unwrap +unwrapped +unwrapping +unwraps +unwreathe +unwreathed +unwreathes +unwreathing +unwritten +unwrung +unyeaned +unyielding +unyieldingly +unyoke +unyoked +unyokes +unyoking +unyoung +unzip +unzipped +unzipping +unzips +unzoned +up +upas +upases +upbear +upbearer +upbearers +upbearing +upbears +upbeat +upbeats +upbind +upbinding +upbinds +upboil +upboiled +upboiling +upboils +upbore +upborne +upbound +upbow +upbows +upbraid +upbraided +upbraider +upbraiders +upbraiding +upbraids +upbringing +upbringings +upbuild +upbuilding +upbuilds +upbuilt +upby +upbye +upcast +upcasting +upcasts +upchuck +upchucked +upchucking +upchucks +upclimb +upclimbed +upclimbing +upclimbs +upcoast +upcoil +upcoiled +upcoiling +upcoils +upcoming +upcountry +upcurl +upcurled +upcurling +upcurls +upcurve +upcurved +upcurves +upcurving +updart +updarted +updarting +updarts +update +updated +updater +updaters +updates +updating +updive +updived +updives +updiving +updo +updos +updove +updraft +updrafts +updried +updries +updry +updrying +upend +upended +upending +upends +upfield +upfling +upflinging +upflings +upflow +upflowed +upflowing +upflows +upflung +upfold +upfolded +upfolding +upfolds +upfront +upgather +upgathered +upgathering +upgathers +upgaze +upgazed +upgazes +upgazing +upgird +upgirded +upgirding +upgirds +upgirt +upgoing +upgradabilities +upgradability +upgradable +upgrade +upgradeabilities +upgradeability +upgradeable +upgraded +upgrades +upgrading +upgrew +upgrow +upgrowing +upgrown +upgrows +upgrowth +upgrowths +upheap +upheaped +upheaping +upheaps +upheaval +upheavals +upheave +upheaved +upheaver +upheavers +upheaves +upheaving +upheld +uphill +uphills +uphoard +uphoarded +uphoarding +uphoards +uphold +upholder +upholders +upholding +upholds +upholster +upholstered +upholsterer +upholsterers +upholsteries +upholstering +upholsters +upholstery +uphove +uphroe +uphroes +upkeep +upkeeps +upland +uplander +uplanders +uplands +upleap +upleaped +upleaping +upleaps +upleapt +uplift +uplifted +uplifter +uplifters +uplifting +uplifts +uplight +uplighted +uplighting +uplights +uplink +uplinks +uplit +upload +uploaded +uploading +uploads +upmanship +upmanships +upmarket +upmost +upo +upon +upped +upper +uppercase +uppercased +uppercases +uppercasing +upperclassman +upperclassmen +uppercut +uppercuts +uppercutting +uppermost +upperpart +upperparts +uppers +uppile +uppiled +uppiles +uppiling +upping +uppings +uppish +uppishly +uppishness +uppishnesses +uppitiness +uppitinesses +uppity +uppityness +uppitynesses +upprop +uppropped +uppropping +upprops +upraise +upraised +upraiser +upraisers +upraises +upraising +uprate +uprated +uprates +uprating +upreach +upreached +upreaches +upreaching +uprear +upreared +uprearing +uprears +upright +uprighted +uprighting +uprightly +uprightness +uprightnesses +uprights +uprise +uprisen +upriser +uprisers +uprises +uprising +uprisings +upriver +uprivers +uproar +uproarious +uproariously +uproariousness +uproariousnesses +uproars +uproot +uprootal +uprootals +uprooted +uprootedness +uprootednesses +uprooter +uprooters +uprooting +uproots +uprose +uprouse +uproused +uprouses +uprousing +uprush +uprushed +uprushes +uprushing +ups +upscale +upscaled +upscales +upscaling +upsend +upsending +upsends +upsent +upset +upsets +upsetter +upsetters +upsetting +upshift +upshifted +upshifting +upshifts +upshoot +upshooting +upshoots +upshot +upshots +upside +upsides +upsilon +upsilons +upsoar +upsoared +upsoaring +upsoars +upsprang +upspring +upspringing +upsprings +upsprung +upstage +upstaged +upstages +upstaging +upstair +upstairs +upstand +upstanding +upstandingness +upstandingnesses +upstands +upstare +upstared +upstares +upstaring +upstart +upstarted +upstarting +upstarts +upstate +upstater +upstaters +upstates +upstep +upstepped +upstepping +upsteps +upstir +upstirred +upstirring +upstirs +upstood +upstream +upstroke +upstrokes +upsurge +upsurged +upsurges +upsurging +upsweep +upsweeping +upsweeps +upswell +upswelled +upswelling +upswells +upswept +upswing +upswinging +upswings +upswollen +upswung +uptake +uptakes +uptear +uptearing +uptears +upthrew +upthrow +upthrowing +upthrown +upthrows +upthrust +upthrusting +upthrusts +uptick +upticks +uptight +uptightness +uptightnesses +uptilt +uptilted +uptilting +uptilts +uptime +uptimes +uptore +uptorn +uptoss +uptossed +uptosses +uptossing +uptown +uptowner +uptowners +uptowns +uptrend +uptrends +upturn +upturned +upturning +upturns +upwaft +upwafted +upwafting +upwafts +upward +upwardly +upwardness +upwardnesses +upwards +upwell +upwelled +upwelling +upwellings +upwells +upwind +upwinds +uracil +uracils +uraei +uraemia +uraemias +uraemic +uraeus +uraeuses +uralite +uralites +uralitic +urania +uranias +uranic +uranide +uranides +uraninite +uraninites +uranism +uranisms +uranite +uranites +uranitic +uranium +uraniums +uranographies +uranography +uranous +uranyl +uranylic +uranyls +urare +urares +urari +uraris +urase +urases +urate +urates +uratic +urb +urban +urbane +urbanely +urbaner +urbanest +urbanisation +urbanisations +urbanise +urbanised +urbanises +urbanising +urbanism +urbanisms +urbanist +urbanistic +urbanistically +urbanists +urbanite +urbanites +urbanities +urbanity +urbanization +urbanizations +urbanize +urbanized +urbanizes +urbanizing +urbanologies +urbanologist +urbanologists +urbanology +urbia +urbias +urbs +urceolate +urchin +urchins +urd +urds +urea +ureal +ureas +urease +ureases +uredia +uredial +uredinia +uredinial +urediniospore +urediniospores +uredinium +urediospore +urediospores +uredium +uredo +uredos +uredospore +uredospores +ureic +ureide +ureides +uremia +uremias +uremic +ureotelic +ureotelism +ureotelisms +ureter +ureteral +ureteric +ureters +urethan +urethane +urethanes +urethans +urethra +urethrae +urethral +urethras +urethrites +urethritides +urethritis +urethritises +urethroscope +urethroscopes +uretic +urge +urged +urgencies +urgency +urgent +urgently +urger +urgers +urges +urging +urgingly +urial +urials +uric +uricosuric +uricotelic +uricotelism +uricotelisms +uridine +uridines +urinal +urinals +urinalyses +urinalysis +urinaries +urinary +urinate +urinated +urinates +urinating +urination +urinations +urine +urinemia +urinemias +urinemic +urines +urinogenital +urinometer +urinometers +urinose +urinous +urn +urnlike +urns +urochord +urochordate +urochordates +urochords +urochrome +urochromes +urodele +urodeles +urogenital +urokinase +urokinases +urolith +urolithiases +urolithiasis +uroliths +urologic +urological +urologies +urologist +urologists +urology +uropod +uropodal +uropods +uropygia +uropygium +uropygiums +uroscopies +uroscopy +urostyle +urostyles +ursa +ursae +ursiform +ursine +urtext +urtexts +urticant +urticants +urticaria +urticarial +urticarias +urticate +urticated +urticates +urticating +urtication +urtications +urus +uruses +urushiol +urushiols +us +usabilities +usability +usable +usableness +usablenesses +usably +usage +usages +usance +usances +usaunce +usaunces +use +useable +useably +used +useful +usefully +usefulness +usefulnesses +useless +uselessly +uselessness +uselessnesses +user +users +uses +usher +ushered +usherette +usherettes +ushering +ushers +using +usnea +usneas +usquabae +usquabaes +usque +usquebae +usquebaes +usquebaugh +usquebaughs +usques +ustulate +usual +usually +usualness +usualnesses +usuals +usufruct +usufructs +usufructuaries +usufructuary +usurer +usurers +usuries +usurious +usuriously +usuriousness +usuriousnesses +usurp +usurpation +usurpations +usurped +usurper +usurpers +usurping +usurps +usury +ut +uta +utas +utensil +utensils +uteri +uterine +uterus +uteruses +utile +utilidor +utilidors +utilise +utilised +utiliser +utilisers +utilises +utilising +utilitarian +utilitarianism +utilitarianisms +utilitarians +utilities +utility +utilizable +utilization +utilizations +utilize +utilized +utilizer +utilizers +utilizes +utilizing +utmost +utmosts +utopia +utopian +utopianism +utopianisms +utopians +utopias +utopism +utopisms +utopist +utopistic +utopists +utricle +utricles +utricular +utriculi +utriculus +uts +utter +utterable +utterance +utterances +uttered +utterer +utterers +uttering +utterly +uttermost +uttermosts +utters +uvarovite +uvarovites +uvea +uveal +uveas +uveitic +uveitis +uveitises +uveous +uvula +uvulae +uvular +uvularly +uvulars +uvulas +uvulitis +uvulitises +uxorial +uxoricide +uxoricides +uxorious +uxoriously +uxoriousness +uxoriousnesses +vac +vacancies +vacancy +vacant +vacantly +vacantness +vacantnesses +vacate +vacated +vacates +vacating +vacation +vacationed +vacationer +vacationers +vacationing +vacationist +vacationists +vacationland +vacationlands +vacations +vaccina +vaccinal +vaccinas +vaccinate +vaccinated +vaccinates +vaccinating +vaccination +vaccinations +vaccinator +vaccinators +vaccine +vaccinee +vaccinees +vaccines +vaccinia +vaccinial +vaccinias +vacillate +vacillated +vacillates +vacillating +vacillatingly +vacillation +vacillations +vacillator +vacillators +vacs +vacua +vacuities +vacuity +vacuolar +vacuolate +vacuolated +vacuolation +vacuolations +vacuole +vacuoles +vacuous +vacuously +vacuousness +vacuousnesses +vacuum +vacuumed +vacuuming +vacuums +vadose +vagabond +vagabondage +vagabondages +vagabonded +vagabonding +vagabondish +vagabondism +vagabondisms +vagabonds +vagal +vagally +vagaries +vagarious +vagariously +vagary +vagi +vagile +vagilities +vagility +vagina +vaginae +vaginal +vaginally +vaginas +vaginate +vaginismus +vaginismuses +vaginitis +vaginitises +vagotomies +vagotomy +vagotonia +vagotonias +vagotonic +vagrancies +vagrancy +vagrant +vagrantly +vagrants +vagrom +vague +vaguely +vagueness +vaguenesses +vaguer +vaguest +vagus +vahine +vahines +vail +vailed +vailing +vails +vain +vainer +vainest +vainglories +vainglorious +vaingloriously +vaingloriousness +vaingloriousnesses +vainglory +vainly +vainness +vainnesses +vair +vairs +vakeel +vakeels +vakil +vakils +valance +valanced +valances +valancing +vale +valediction +valedictions +valedictorian +valedictorians +valedictories +valedictory +valence +valences +valencia +valencias +valencies +valency +valentine +valentines +valerate +valerates +valerian +valerians +valeric +vales +valet +valeted +valeting +valets +valetudinarian +valetudinarianism +valetudinarianisms +valetudinarians +valetudinaries +valetudinary +valgoid +valgus +valguses +valiance +valiances +valiancies +valiancy +valiant +valiantly +valiantness +valiantnesses +valiants +valid +validate +validated +validates +validating +validation +validations +validities +validity +validly +valine +valines +valise +valises +valkyr +valkyrie +valkyries +valkyrs +vallate +vallecula +valleculae +vallecular +valley +valleys +valonia +valonias +valor +valorise +valorised +valorises +valorising +valorization +valorizations +valorize +valorized +valorizes +valorizing +valorous +valorously +valors +valour +valours +valpolicella +valpolicellas +valse +valses +valuable +valuableness +valuablenesses +valuables +valuably +valuate +valuated +valuates +valuating +valuation +valuational +valuationally +valuations +valuator +valuators +value +valued +valueless +valuelessness +valuelessnesses +valuer +valuers +values +valuing +valuta +valutas +valval +valvar +valvate +valve +valved +valveless +valvelet +valvelets +valves +valving +valvula +valvulae +valvular +valvule +valvules +valvulites +valvulitides +valvulitis +valvulitises +vambrace +vambraces +vamoose +vamoosed +vamooses +vamoosing +vamose +vamosed +vamoses +vamosing +vamp +vamped +vamper +vampers +vamping +vampire +vampires +vampiric +vampirish +vampirism +vampirisms +vampish +vamps +van +vanadate +vanadates +vanadic +vanadium +vanadiums +vanadous +vanaspati +vanaspatis +vanda +vandal +vandalic +vandalise +vandalised +vandalises +vandalising +vandalism +vandalisms +vandalistic +vandalization +vandalizations +vandalize +vandalized +vandalizes +vandalizing +vandals +vandas +vandyke +vandyked +vandykes +vane +vaned +vanes +vang +vangs +vanguard +vanguardism +vanguardisms +vanguardist +vanguardists +vanguards +vanilla +vanillas +vanillic +vanillin +vanillins +vanish +vanished +vanisher +vanishers +vanishes +vanishing +vanishingly +vanitied +vanities +vanitories +vanitory +vanity +vanman +vanmen +vanned +vanner +vanners +vanning +vanpool +vanpooling +vanpoolings +vanpools +vanquish +vanquishable +vanquished +vanquisher +vanquishers +vanquishes +vanquishing +vans +vantage +vantages +vanward +vapid +vapidities +vapidity +vapidly +vapidness +vapidnesses +vapor +vapored +vaporer +vaporers +vaporetti +vaporetto +vaporettos +vaporing +vaporings +vaporise +vaporised +vaporises +vaporish +vaporishness +vaporishnesses +vaporising +vaporizable +vaporization +vaporizations +vaporize +vaporized +vaporizer +vaporizers +vaporizes +vaporizing +vaporous +vaporously +vaporousness +vaporousnesses +vapors +vaporware +vaporwares +vapory +vapour +vapoured +vapourer +vapourers +vapouring +vapours +vapoury +vaquero +vaqueros +var +vara +varactor +varactors +varas +varia +variabilities +variability +variable +variableness +variablenesses +variables +variably +variance +variances +variant +variants +variate +variated +variates +variating +variation +variational +variationally +variations +varicella +varicellas +varices +varicocele +varicoceles +varicolored +varicose +varicosed +varicosities +varicosity +varied +variedly +variegate +variegated +variegates +variegating +variegation +variegations +variegator +variegators +varier +variers +varies +varietal +varietals +varieties +variety +variform +variola +variolar +variolas +variole +varioles +variometer +variometers +variorum +variorums +various +variously +variousness +variousnesses +varisized +varistor +varistors +varix +varlet +varletries +varletry +varlets +varment +varments +varmint +varmints +varna +varnas +varnish +varnished +varnisher +varnishers +varnishes +varnishing +varnishy +varoom +varoomed +varooming +varooms +vars +varsities +varsity +varus +varuses +varve +varved +varves +vary +varying +varyingly +vas +vasa +vasal +vascula +vascular +vascularities +vascularity +vascularization +vascularizations +vasculature +vasculatures +vasculitides +vasculitis +vasculum +vasculums +vase +vasectomies +vasectomize +vasectomized +vasectomizes +vasectomizing +vasectomy +vaselike +vases +vasiform +vasoactive +vasoactivities +vasoactivity +vasoconstriction +vasoconstrictions +vasoconstrictive +vasoconstrictor +vasoconstrictors +vasodilatation +vasodilatations +vasodilation +vasodilations +vasodilator +vasodilators +vasomotor +vasopressin +vasopressins +vasopressor +vasopressors +vasospasm +vasospasms +vasospastic +vasotocin +vasotocins +vasotomies +vasotomy +vasovagal +vassal +vassalage +vassalages +vassals +vast +vaster +vastest +vastier +vastiest +vastities +vastitude +vastitudes +vastity +vastly +vastness +vastnesses +vasts +vasty +vat +vatful +vatfuls +vatic +vatical +vaticide +vaticides +vaticinal +vaticinate +vaticinated +vaticinates +vaticinating +vaticination +vaticinations +vaticinator +vaticinators +vats +vatted +vatting +vatu +vatus +vau +vaudeville +vaudevilles +vaudevillian +vaudevillians +vault +vaulted +vaulter +vaulters +vaultier +vaultiest +vaulting +vaultingly +vaultings +vaults +vaulty +vaunt +vaunted +vaunter +vaunters +vauntful +vauntie +vaunting +vauntingly +vaunts +vaunty +vaus +vav +vavasor +vavasors +vavasour +vavasours +vavassor +vavassors +vavs +vaw +vaward +vawards +vawntie +vaws +veal +vealed +vealer +vealers +vealier +vealiest +vealing +veals +vealy +vector +vectored +vectorial +vectorially +vectoring +vectors +vedalia +vedalias +vedette +vedettes +vee +veejay +veejays +veena +veenas +veep +veepee +veepees +veeps +veer +veered +veeries +veering +veeringly +veers +veery +vees +veg +vegan +veganism +veganisms +vegans +vegetable +vegetables +vegetably +vegetal +vegetant +vegetarian +vegetarianism +vegetarianisms +vegetarians +vegetate +vegetated +vegetates +vegetating +vegetation +vegetational +vegetations +vegetative +vegetatively +vegetativeness +vegetativenesses +vegete +vegetist +vegetists +vegetive +veggie +veggies +vegie +vegies +vehemence +vehemences +vehement +vehemently +vehicle +vehicles +vehicular +veil +veiled +veiledly +veiler +veilers +veiling +veilings +veillike +veils +vein +veinal +veined +veiner +veiners +veinier +veiniest +veining +veinings +veinless +veinlet +veinlets +veinlike +veins +veinule +veinules +veinulet +veinulets +veiny +vela +velamen +velamina +velar +velaria +velarium +velarization +velarizations +velarize +velarized +velarizes +velarizing +velars +velate +veld +velds +veldt +veldts +veliger +veligers +velites +velleities +velleity +vellum +vellums +veloce +velocimeter +velocimeters +velocipede +velocipedes +velocities +velocity +velodrome +velodromes +velour +velours +veloute +veloutes +velum +velure +velured +velures +veluring +velveret +velverets +velvet +velveted +velveteen +velveteens +velvetlike +velvets +velvety +vena +venae +venal +venalities +venality +venally +venatic +venation +venations +vend +vendable +vendables +vendace +vendaces +vended +vendee +vendees +vender +venders +vendetta +vendettas +vendeuse +vendeuses +vendibilities +vendibility +vendible +vendibles +vendibly +vending +vendor +vendors +vends +vendue +vendues +veneer +veneered +veneerer +veneerers +veneering +veneerings +veneers +venenate +venenated +venenates +venenating +venenose +venerabilities +venerability +venerable +venerableness +venerablenesses +venerably +venerate +venerated +venerates +venerating +veneration +venerations +venerator +venerators +venereal +veneries +venery +venesection +venesections +venetian +venetians +venge +vengeance +vengeances +venged +vengeful +vengefully +vengefulness +vengefulnesses +venges +venging +venial +venially +venialness +venialnesses +venin +venine +venines +venins +venipuncture +venipunctures +venire +venireman +veniremen +venires +venison +venisons +venogram +venograms +venographies +venography +venom +venomed +venomer +venomers +venoming +venomous +venomously +venomousness +venomousnesses +venoms +venose +venosities +venosity +venous +venously +vent +ventage +ventages +ventail +ventails +vented +venter +venters +ventifact +ventifacts +ventilate +ventilated +ventilates +ventilating +ventilation +ventilations +ventilator +ventilators +ventilatory +venting +ventless +ventral +ventrally +ventrals +ventricle +ventricles +ventricose +ventricular +ventriculi +ventriculus +ventriloquial +ventriloquially +ventriloquies +ventriloquism +ventriloquisms +ventriloquist +ventriloquistic +ventriloquists +ventriloquize +ventriloquized +ventriloquizes +ventriloquizing +ventriloquy +ventrolateral +ventromedial +vents +venture +ventured +venturer +venturers +ventures +venturesome +venturesomely +venturesomeness +venturesomenesses +venturi +venturing +venturis +venturous +venturously +venturousness +venturousnesses +venue +venues +venular +venule +venules +venulose +venulous +vera +veracious +veraciously +veraciousness +veraciousnesses +veracities +veracity +veranda +verandaed +verandah +verandahed +verandahs +verandas +verapamil +verapamils +veratria +veratrias +veratridine +veratridines +veratrin +veratrine +veratrines +veratrins +veratrum +veratrums +verb +verbal +verbalism +verbalisms +verbalist +verbalistic +verbalists +verbalization +verbalizations +verbalize +verbalized +verbalizer +verbalizers +verbalizes +verbalizing +verbally +verbals +verbatim +verbena +verbenas +verbiage +verbiages +verbicide +verbicides +verbid +verbids +verbified +verbifies +verbify +verbifying +verbigeration +verbigerations +verbile +verbiles +verbless +verbose +verbosely +verboseness +verbosenesses +verbosities +verbosity +verboten +verbs +verdancies +verdancy +verdant +verdantly +verderer +verderers +verderor +verderors +verdict +verdicts +verdigris +verdigrises +verdin +verdins +verditer +verditers +verdure +verdured +verdures +verdurous +verecund +verge +verged +vergence +vergences +verger +vergers +verges +verging +verglas +verglases +veridic +veridical +veridicalities +veridicality +veridically +verier +veriest +verifiabilities +verifiability +verifiable +verifiableness +verifiablenesses +verification +verifications +verified +verifier +verifiers +verifies +verify +verifying +verily +verisimilar +verisimilarly +verisimilitude +verisimilitudes +verisimilitudinous +verism +verismo +verismos +verisms +verist +veristic +verists +veritable +veritableness +veritablenesses +veritably +veritas +veritates +verite +verites +verities +verity +verjuice +verjuices +vermeil +vermeils +vermes +vermian +vermicelli +vermicellis +vermicide +vermicides +vermicular +vermiculate +vermiculated +vermiculation +vermiculations +vermiculite +vermiculites +vermiform +vermifuge +vermifuges +vermilion +vermilions +vermillion +vermillions +vermin +verminous +vermis +vermoulu +vermouth +vermouths +vermuth +vermuths +vernacle +vernacles +vernacular +vernacularism +vernacularisms +vernacularly +vernaculars +vernal +vernalization +vernalizations +vernalize +vernalized +vernalizes +vernalizing +vernally +vernation +vernations +vernicle +vernicles +vernier +verniers +vernissage +vernissages +vernix +vernixes +veronica +veronicas +verruca +verrucae +verrucose +versal +versant +versants +versatile +versatilely +versatileness +versatilenesses +versatilities +versatility +verse +versed +verseman +versemen +verser +versers +verses +verset +versets +versicle +versicles +versicular +versification +versifications +versified +versifier +versifiers +versifies +versify +versifying +versine +versines +versing +version +versional +versions +verso +versos +verst +verste +verstes +versts +versus +vert +vertebra +vertebrae +vertebral +vertebras +vertebrate +vertebrates +vertex +vertexes +vertical +verticalities +verticality +vertically +verticalness +verticalnesses +verticals +vertices +verticil +verticillate +verticils +vertigines +vertiginous +vertiginously +vertigo +vertigoes +vertigos +verts +vertu +vertus +vervain +vervains +verve +verves +vervet +vervets +very +vesica +vesicae +vesical +vesicant +vesicants +vesicate +vesicated +vesicates +vesicating +vesicle +vesicles +vesicula +vesiculae +vesicular +vesicularities +vesicularity +vesiculate +vesiculated +vesiculates +vesiculating +vesiculation +vesiculations +vesper +vesperal +vesperals +vespers +vespertilian +vespertine +vespiaries +vespiary +vespid +vespids +vespine +vessel +vesseled +vessels +vest +vesta +vestal +vestally +vestals +vestas +vested +vestee +vestees +vestiaries +vestiary +vestibular +vestibule +vestibuled +vestibules +vestige +vestiges +vestigia +vestigial +vestigially +vestigium +vesting +vestings +vestless +vestlike +vestment +vestmental +vestments +vestral +vestries +vestry +vestryman +vestrymen +vests +vestural +vesture +vestured +vestures +vesturing +vesuvian +vesuvianite +vesuvianites +vesuvians +vet +vetch +vetches +vetchling +vetchlings +veteran +veterans +veterinarian +veterinarians +veterinaries +veterinary +vetiver +vetivers +vetivert +vetiverts +veto +vetoed +vetoer +vetoers +vetoes +vetoing +vets +vetted +vetting +vex +vexation +vexations +vexatious +vexatiously +vexatiousness +vexatiousnesses +vexed +vexedly +vexer +vexers +vexes +vexil +vexilla +vexillar +vexillologic +vexillological +vexillologies +vexillologist +vexillologists +vexillology +vexillum +vexils +vexing +vexingly +vext +via +viabilities +viability +viable +viably +viaduct +viaducts +vial +vialed +vialing +vialled +vialling +vials +viand +viands +viatic +viatica +viatical +viaticum +viaticums +viator +viatores +viators +vibe +vibes +vibist +vibists +vibraharp +vibraharpist +vibraharpists +vibraharps +vibrance +vibrances +vibrancies +vibrancy +vibrant +vibrantly +vibrants +vibraphone +vibraphones +vibraphonist +vibraphonists +vibrate +vibrated +vibrates +vibratile +vibrating +vibration +vibrational +vibrationless +vibrations +vibrato +vibratoless +vibrator +vibrators +vibratory +vibratos +vibrio +vibrioid +vibrion +vibrionic +vibrions +vibrios +vibrioses +vibriosis +vibrissa +vibrissae +vibronic +viburnum +viburnums +vicar +vicarage +vicarages +vicarate +vicarates +vicarial +vicariance +vicariances +vicariant +vicariants +vicariate +vicariates +vicarious +vicariously +vicariousness +vicariousnesses +vicarly +vicars +vicarship +vicarships +vice +viced +vicegerencies +vicegerency +vicegerent +vicegerents +viceless +vicenary +vicennial +viceregal +viceregally +vicereine +vicereines +viceroy +viceroyalties +viceroyalty +viceroys +viceroyship +viceroyships +vices +vichies +vichy +vichyssoise +vichyssoises +vicinage +vicinages +vicinal +vicing +vicinities +vicinity +vicious +viciously +viciousness +viciousnesses +vicissitude +vicissitudes +vicissitudinous +vicomte +vicomtes +victim +victimhood +victimhoods +victimise +victimised +victimises +victimising +victimization +victimizations +victimize +victimized +victimizer +victimizers +victimizes +victimizing +victimless +victimologies +victimologist +victimologists +victimology +victims +victor +victoria +victorias +victories +victorious +victoriously +victoriousness +victoriousnesses +victors +victory +victress +victresses +victual +victualed +victualer +victualers +victualing +victualled +victualler +victuallers +victualling +victuals +vicugna +vicugnas +vicuna +vicunas +vide +videlicet +video +videocassette +videocassettes +videoconference +videoconferences +videoconferencing +videoconferencings +videodisc +videodiscs +videodisk +videodisks +videographer +videographers +videographies +videography +videoland +videolands +videophile +videophiles +videophone +videophones +videos +videotape +videotaped +videotapes +videotaping +videotex +videotexes +videotext +videotexts +vidette +videttes +vidicon +vidicons +viduities +viduity +vie +vied +vier +viers +vies +view +viewable +viewdata +viewdatas +viewed +viewer +viewers +viewership +viewerships +viewfinder +viewfinders +viewier +viewiest +viewing +viewings +viewless +viewlessly +viewpoint +viewpoints +views +viewy +vig +viga +vigas +vigesimal +vigil +vigilance +vigilances +vigilant +vigilante +vigilantes +vigilantism +vigilantisms +vigilantly +vigils +vigintillion +vigintillions +vigneron +vignerons +vignette +vignetted +vignetter +vignetters +vignettes +vignetting +vignettist +vignettists +vigor +vigorish +vigorishes +vigoroso +vigorous +vigorously +vigorousness +vigorousnesses +vigors +vigour +vigours +vigs +viking +vikings +vilayet +vilayets +vile +vilely +vileness +vilenesses +viler +vilest +vilification +vilifications +vilified +vilifier +vilifiers +vilifies +vilify +vilifying +vilipend +vilipended +vilipending +vilipends +vill +villa +villadom +villadoms +villae +village +villager +villageries +villagers +villagery +villages +villain +villainess +villainesses +villainies +villainous +villainously +villainousness +villainousnesses +villains +villainy +villanella +villanelle +villanelles +villas +villatic +villein +villeins +villenage +villenages +villi +villiform +villose +villosities +villosity +villous +vills +villus +vim +vimen +vimina +viminal +vims +vina +vinaceous +vinaigrette +vinaigrettes +vinal +vinals +vinas +vinasse +vinasses +vinblastine +vinblastines +vinca +vincas +vincible +vincibly +vincristine +vincristines +vincula +vinculum +vinculums +vindaloo +vindaloos +vindicable +vindicate +vindicated +vindicates +vindicating +vindication +vindications +vindicative +vindicator +vindicators +vindicatory +vindictive +vindictively +vindictiveness +vindictivenesses +vine +vineal +vined +vinedresser +vinedressers +vinegar +vinegared +vinegarish +vinegars +vinegary +vineries +vinery +vines +vineyard +vineyardist +vineyardists +vineyards +vinic +viniculture +vinicultures +vinier +viniest +vinifera +viniferas +vinification +vinifications +vinified +vinifies +vinify +vinifying +vining +vino +vinos +vinosities +vinosity +vinous +vinously +vintage +vintager +vintagers +vintages +vintner +vintners +viny +vinyl +vinylic +vinylidene +vinylidenes +vinyls +viol +viola +violabilities +violability +violable +violableness +violablenesses +violably +violaceous +violas +violate +violated +violater +violaters +violates +violating +violation +violations +violative +violator +violators +violence +violences +violent +violently +violet +violets +violin +violinist +violinistic +violinists +violins +violist +violists +violoncelli +violoncellist +violoncellists +violoncello +violoncellos +violone +violones +viols +viomycin +viomycins +viper +viperine +viperish +viperous +viperously +vipers +viraginous +virago +viragoes +viragos +viral +virally +virelai +virelais +virelay +virelays +viremia +viremias +viremic +vireo +vireos +vires +virescence +virescences +virescent +virga +virgas +virgate +virgates +virgin +virginal +virginalist +virginalists +virginally +virginals +virginities +virginity +virgins +virgule +virgules +viricidal +viricide +viricides +virid +viridescent +viridian +viridians +viridities +viridity +virile +virilely +virilism +virilisms +virilities +virility +virion +virions +virl +virls +viroid +viroids +virologic +virological +virologically +virologies +virologist +virologists +virology +viroses +virosis +virtu +virtual +virtualities +virtuality +virtually +virtue +virtueless +virtues +virtuosa +virtuosas +virtuose +virtuosi +virtuosic +virtuosities +virtuosity +virtuoso +virtuosos +virtuous +virtuously +virtuousness +virtuousnesses +virtus +virucidal +virucide +virucides +virulence +virulences +virulencies +virulency +virulent +virulently +viruliferous +virus +viruses +vis +visa +visaed +visage +visaged +visages +visaing +visard +visards +visas +viscacha +viscachas +viscera +visceral +viscerally +viscid +viscidities +viscidity +viscidly +viscoelastic +viscoelasticities +viscoelasticity +viscoid +viscometer +viscometers +viscometric +viscometries +viscometry +viscose +viscoses +viscosimeter +viscosimeters +viscosimetric +viscosities +viscosity +viscount +viscountcies +viscountcy +viscountess +viscountesses +viscounties +viscounts +viscounty +viscous +viscously +viscousness +viscousnesses +viscus +vise +vised +viseed +viseing +viselike +vises +visibilities +visibility +visible +visibleness +visiblenesses +visibly +vising +vision +visional +visionally +visionaries +visionariness +visionarinesses +visionary +visioned +visioning +visionless +visions +visit +visitable +visitant +visitants +visitation +visitations +visitatorial +visited +visiter +visiters +visiting +visitor +visitors +visits +visive +visor +visored +visoring +visorless +visors +vista +vistaed +vistas +visual +visualise +visualised +visualises +visualising +visualization +visualizations +visualize +visualized +visualizer +visualizers +visualizes +visualizing +visually +visuals +vita +vitae +vital +vitalise +vitalised +vitalises +vitalising +vitalism +vitalisms +vitalist +vitalistic +vitalists +vitalities +vitality +vitalization +vitalizations +vitalize +vitalized +vitalizes +vitalizing +vitally +vitals +vitamer +vitamers +vitamin +vitamine +vitamines +vitamins +vitellin +vitelline +vitellins +vitellogeneses +vitellogenesis +vitellus +vitelluses +vitesse +vitesses +vitiable +vitiate +vitiated +vitiates +vitiating +vitiation +vitiations +vitiator +vitiators +viticultural +viticulturally +viticulture +viticultures +viticulturist +viticulturists +vitiligo +vitiligos +vitrain +vitrains +vitrectomies +vitrectomy +vitreous +vitreouses +vitric +vitrics +vitrifiable +vitrification +vitrifications +vitrified +vitrifies +vitrify +vitrifying +vitrine +vitrines +vitriol +vitrioled +vitriolic +vitrioling +vitriolled +vitriolling +vitriols +vitta +vittae +vittate +vittle +vittled +vittles +vittling +vituline +vituperate +vituperated +vituperates +vituperating +vituperation +vituperations +vituperative +vituperatively +vituperator +vituperators +vituperatory +viva +vivace +vivaces +vivacious +vivaciously +vivaciousness +vivaciousnesses +vivacities +vivacity +vivandiere +vivandieres +vivaria +vivaries +vivarium +vivariums +vivary +vivas +vive +viverrid +viverrids +vivers +vivid +vivider +vividest +vividly +vividness +vividnesses +vivific +vivification +vivifications +vivified +vivifier +vivifiers +vivifies +vivify +vivifying +vivipara +viviparities +viviparity +viviparous +viviparously +vivisect +vivisected +vivisecting +vivisection +vivisectional +vivisectionist +vivisectionists +vivisections +vivisector +vivisectors +vivisects +vixen +vixenish +vixenly +vixens +vizard +vizarded +vizards +vizcacha +vizcachas +vizier +vizierate +vizierates +vizierial +viziers +viziership +vizierships +vizir +vizirate +vizirates +vizirial +vizirs +vizor +vizored +vizoring +vizors +vizsla +vizslas +vocable +vocables +vocably +vocabular +vocabularies +vocabulary +vocal +vocalic +vocalically +vocalics +vocalise +vocalised +vocalises +vocalising +vocalism +vocalisms +vocalist +vocalists +vocalities +vocality +vocalization +vocalizations +vocalize +vocalized +vocalizer +vocalizers +vocalizes +vocalizing +vocally +vocals +vocation +vocational +vocationalism +vocationalisms +vocationalist +vocationalists +vocationally +vocations +vocative +vocatively +vocatives +voces +vociferant +vociferate +vociferated +vociferates +vociferating +vociferation +vociferations +vociferator +vociferators +vociferous +vociferously +vociferousness +vociferousnesses +vocoder +vocoders +vodka +vodkas +vodoun +vodouns +vodun +voduns +voe +voes +vogie +vogue +vogued +vogueing +voguer +voguers +vogues +voguing +voguish +voguishness +voguishnesses +voice +voiced +voiceful +voicefulness +voicefulnesses +voiceless +voicelessly +voicelessness +voicelessnesses +voiceprint +voiceprints +voicer +voicers +voices +voicing +void +voidable +voidableness +voidablenesses +voidance +voidances +voided +voider +voiders +voiding +voidness +voidnesses +voids +voila +voile +voiles +volant +volante +volar +volatile +volatileness +volatilenesses +volatiles +volatilise +volatilised +volatilises +volatilising +volatilities +volatility +volatilizable +volatilization +volatilizations +volatilize +volatilized +volatilizes +volatilizing +volcanic +volcanically +volcanicities +volcanicity +volcanics +volcanism +volcanisms +volcano +volcanoes +volcanologic +volcanological +volcanologies +volcanologist +volcanologists +volcanology +volcanos +vole +voled +voleries +volery +voles +voling +volitant +volition +volitional +volitions +volitive +volkslied +volkslieder +volley +volleyball +volleyballs +volleyed +volleyer +volleyers +volleying +volleys +volost +volosts +volplane +volplaned +volplanes +volplaning +volt +volta +voltage +voltages +voltaic +voltaism +voltaisms +volte +voltes +volti +voltmeter +voltmeters +volts +volubilities +volubility +voluble +volubleness +volublenesses +volubly +volume +volumed +volumes +volumeter +volumeters +volumetric +volumetrically +voluming +voluminosities +voluminosity +voluminous +voluminously +voluminousness +voluminousnesses +voluntaries +voluntarily +voluntariness +voluntarinesses +voluntarism +voluntarisms +voluntarist +voluntaristic +voluntarists +voluntary +voluntaryism +voluntaryisms +voluntaryist +voluntaryists +volunteer +volunteered +volunteering +volunteerism +volunteerisms +volunteers +voluptuaries +voluptuary +voluptuous +voluptuously +voluptuousness +voluptuousnesses +volute +voluted +volutes +volutin +volutins +volution +volutions +volva +volvas +volvate +volvox +volvoxes +volvuli +volvulus +volvuluses +vomer +vomerine +vomers +vomica +vomicae +vomit +vomited +vomiter +vomiters +vomiting +vomitive +vomitives +vomito +vomitories +vomitory +vomitos +vomitous +vomits +vomitus +vomituses +voodoo +voodooed +voodooing +voodooism +voodooisms +voodooist +voodooistic +voodooists +voodoos +voracious +voraciously +voraciousness +voraciousnesses +voracities +voracity +vorlage +vorlages +vortex +vortexes +vortical +vortically +vorticella +vorticellae +vorticellas +vortices +vorticism +vorticisms +vorticist +vorticists +vorticities +vorticity +vorticose +votable +votaress +votaresses +votaries +votarist +votarists +votary +vote +voteable +voted +voteless +voter +voters +votes +voting +votive +votively +votiveness +votivenesses +votress +votresses +vouch +vouched +vouchee +vouchees +voucher +vouchered +vouchering +vouchers +vouches +vouching +vouchsafe +vouchsafed +vouchsafement +vouchsafements +vouchsafes +vouchsafing +voussoir +voussoirs +vouvray +vouvrays +vow +vowed +vowel +vowelize +vowelized +vowelizes +vowelizing +vowels +vower +vowers +vowing +vowless +vows +vox +voyage +voyaged +voyager +voyagers +voyages +voyageur +voyageurs +voyaging +voyeur +voyeurism +voyeurisms +voyeuristic +voyeuristically +voyeurs +vroom +vroomed +vrooming +vrooms +vrouw +vrouws +vrow +vrows +vug +vugg +vuggier +vuggiest +vuggs +vuggy +vugh +vughs +vugs +vulcanian +vulcanic +vulcanicities +vulcanicity +vulcanisate +vulcanisates +vulcanisation +vulcanisations +vulcanise +vulcanised +vulcanises +vulcanising +vulcanism +vulcanisms +vulcanizate +vulcanizates +vulcanization +vulcanizations +vulcanize +vulcanized +vulcanizer +vulcanizers +vulcanizes +vulcanizing +vulcanologies +vulcanologist +vulcanologists +vulcanology +vulgar +vulgarer +vulgarest +vulgarian +vulgarians +vulgarise +vulgarised +vulgarises +vulgarising +vulgarism +vulgarisms +vulgarities +vulgarity +vulgarization +vulgarizations +vulgarize +vulgarized +vulgarizer +vulgarizers +vulgarizes +vulgarizing +vulgarly +vulgars +vulgate +vulgates +vulgo +vulgus +vulguses +vulnerabilities +vulnerability +vulnerable +vulnerableness +vulnerablenesses +vulnerably +vulneraries +vulnerary +vulpine +vulture +vultures +vulturine +vulturish +vulturous +vulva +vulvae +vulval +vulvar +vulvas +vulvate +vulvitis +vulvitises +vulvovaginitis +vulvovaginitises +vying +vyingly +wab +wabble +wabbled +wabbler +wabblers +wabbles +wabblier +wabbliest +wabbling +wabbly +wabs +wack +wacke +wackes +wackier +wackiest +wackily +wackiness +wackinesses +wacko +wackos +wacks +wacky +wad +wadable +wadded +wadder +wadders +waddie +waddied +waddies +wadding +waddings +waddle +waddled +waddler +waddlers +waddles +waddling +waddly +waddy +waddying +wade +wadeable +waded +wader +waders +wades +wadi +wadies +wading +wadis +wadmaal +wadmaals +wadmal +wadmals +wadmel +wadmels +wadmol +wadmoll +wadmolls +wadmols +wads +wadset +wadsets +wadsetted +wadsetting +wady +wae +waeful +waeness +waenesses +waes +waesuck +waesucks +wafer +wafered +wafering +wafers +wafery +waff +waffed +waffie +waffies +waffing +waffle +waffled +waffler +wafflers +waffles +wafflestomper +wafflestompers +waffling +wafflings +waffs +waft +waftage +waftages +wafted +wafter +wafters +wafting +wafts +wafture +waftures +wag +wage +waged +wageless +wager +wagered +wagerer +wagerers +wagering +wagers +wages +wageworker +wageworkers +wagged +wagger +waggeries +waggers +waggery +wagging +waggish +waggishly +waggishness +waggishnesses +waggle +waggled +waggles +waggling +waggly +waggon +waggoned +waggoner +waggoners +waggoning +waggons +waging +wagon +wagonage +wagonages +wagoned +wagoner +wagoners +wagonette +wagonettes +wagoning +wagons +wags +wagsome +wagtail +wagtails +wahconda +wahcondas +wahine +wahines +wahoo +wahoos +waif +waifed +waifing +waiflike +waifs +wail +wailed +wailer +wailers +wailful +wailfully +wailing +wails +wailsome +wain +wains +wainscot +wainscoted +wainscoting +wainscotings +wainscots +wainscotted +wainscotting +wainscottings +wainwright +wainwrights +wair +waired +wairing +wairs +waist +waistband +waistbands +waistcoat +waistcoated +waistcoats +waisted +waister +waisters +waisting +waistings +waistline +waistlines +waists +wait +waited +waiter +waiters +waiting +waitings +waitperson +waitpersons +waitress +waitressed +waitresses +waitressing +waits +waive +waived +waiver +waivers +waives +waiving +wakanda +wakandas +wake +waked +wakeful +wakefully +wakefulness +wakefulnesses +wakeless +waken +wakened +wakener +wakeners +wakening +wakenings +wakens +waker +wakerife +wakers +wakes +wakiki +wakikis +waking +wale +waled +waler +walers +wales +walies +waling +walk +walkable +walkabout +walkabouts +walkathon +walkathons +walkaway +walkaways +walked +walker +walkers +walking +walkings +walkingstick +walkingsticks +walkout +walkouts +walkover +walkovers +walks +walkup +walkups +walkway +walkways +walkyrie +walkyries +wall +walla +wallabies +wallaby +wallah +wallahs +wallaroo +wallaroos +wallas +wallboard +wallboards +walled +wallet +wallets +walleye +walleyed +walleyes +wallflower +wallflowers +wallie +wallies +walling +wallop +walloped +walloper +wallopers +walloping +wallops +wallow +wallowed +wallower +wallowers +wallowing +wallows +wallpaper +wallpapered +wallpapering +wallpapers +walls +wally +wallydraigle +wallydraigles +walnut +walnuts +walrus +walruses +waltz +waltzed +waltzer +waltzers +waltzes +waltzing +waly +wamble +wambled +wambles +wamblier +wambliest +wambling +wambly +wame +wamefou +wamefous +wameful +wamefuls +wames +wammus +wammuses +wampish +wampished +wampishes +wampishing +wampum +wampumpeag +wampumpeags +wampums +wampus +wampuses +wamus +wamuses +wan +wand +wander +wandered +wanderer +wanderers +wandering +wanderings +wanderlust +wanderlusts +wanderoo +wanderoos +wanders +wandle +wands +wane +waned +wanes +waney +wangan +wangans +wangle +wangled +wangler +wanglers +wangles +wangling +wangun +wanguns +wanier +waniest +wanigan +wanigans +waning +wanion +wanions +wanly +wanned +wanner +wanness +wannesses +wannest +wannigan +wannigans +wanning +wans +want +wantage +wantages +wanted +wanter +wanters +wanting +wanton +wantoned +wantoner +wantoners +wantoning +wantonly +wantonness +wantonnesses +wantons +wants +wany +wap +wapentake +wapentakes +wapiti +wapitis +wapped +wappenschawing +wappenschawings +wapping +waps +war +warble +warbled +warbler +warblers +warbles +warbling +warbonnet +warbonnets +warcraft +warcrafts +ward +warded +warden +wardenries +wardenry +wardens +wardenship +wardenships +warder +warders +warding +wardress +wardresses +wardrobe +wardrobes +wardroom +wardrooms +wards +wardship +wardships +ware +wared +warehouse +warehoused +warehouseman +warehousemen +warehouser +warehousers +warehouses +warehousing +wareroom +warerooms +wares +warfare +warfares +warfarin +warfarins +warhead +warheads +warhorse +warhorses +warier +wariest +warily +wariness +warinesses +waring +warison +warisons +wark +warked +warking +warks +warless +warlike +warlock +warlocks +warlord +warlordism +warlordisms +warlords +warm +warmaker +warmakers +warmblooded +warmed +warmer +warmers +warmest +warmhearted +warmheartedness +warmheartednesses +warming +warmish +warmly +warmness +warmnesses +warmonger +warmongering +warmongerings +warmongers +warmouth +warmouths +warms +warmth +warmths +warmup +warmups +warn +warned +warner +warners +warning +warningly +warnings +warns +warp +warpage +warpages +warpath +warpaths +warped +warper +warpers +warping +warplane +warplanes +warpower +warpowers +warps +warpwise +warragal +warragals +warrant +warrantable +warrantableness +warrantablenesses +warrantably +warranted +warrantee +warrantees +warranter +warranters +warranties +warranting +warrantless +warrantor +warrantors +warrants +warranty +warred +warren +warrener +warreners +warrens +warrigal +warrigals +warring +warrior +warriors +wars +warsaw +warsaws +warship +warships +warsle +warsled +warsler +warslers +warsles +warsling +warstle +warstled +warstler +warstlers +warstles +warstling +wart +warted +warthog +warthogs +wartier +wartiest +wartime +wartimes +wartless +wartlike +warts +warty +warwork +warworks +warworn +wary +was +wasabi +wasabis +wash +washabilities +washability +washable +washables +washateria +washaterias +washbasin +washbasins +washboard +washboards +washbowl +washbowls +washcloth +washcloths +washday +washdays +washed +washer +washerman +washermen +washers +washerwoman +washerwomen +washes +washeteria +washeterias +washhouse +washhouses +washier +washiest +washing +washings +washout +washouts +washrag +washrags +washroom +washrooms +washstand +washstands +washtub +washtubs +washup +washups +washwoman +washwomen +washy +wasp +waspier +waspiest +waspily +waspish +waspishly +waspishness +waspishnesses +wasplike +wasps +waspy +wassail +wassailed +wassailer +wassailers +wassailing +wassails +wast +wastable +wastage +wastages +waste +wastebasket +wastebaskets +wasted +wasteful +wastefully +wastefulness +wastefulnesses +wasteland +wastelands +wastelot +wastelots +wastepaper +wastepapers +waster +wasterie +wasteries +wasters +wastery +wastes +wastewater +wastewaters +wasteway +wasteways +wasting +wastrel +wastrels +wastrie +wastries +wastry +wasts +wat +watap +watape +watapes +wataps +watch +watchable +watchables +watchband +watchbands +watchcase +watchcases +watchcries +watchcry +watchdog +watchdogged +watchdogging +watchdogs +watched +watcher +watchers +watches +watcheye +watcheyes +watchful +watchfully +watchfulness +watchfulnesses +watching +watchmaker +watchmakers +watchmaking +watchmakings +watchman +watchmen +watchout +watchouts +watchtower +watchtowers +watchword +watchwords +water +waterage +waterages +waterbed +waterbeds +waterbird +waterbirds +waterborne +waterbuck +waterbucks +watercolor +watercolorist +watercolorists +watercolors +watercooler +watercoolers +watercourse +watercourses +watercraft +watercrafts +watercress +watercresses +waterdog +waterdogs +watered +waterer +waterers +waterfall +waterfalls +waterflood +waterflooded +waterflooding +waterfloods +waterfowl +waterfowler +waterfowlers +waterfowling +waterfowlings +waterfowls +waterfront +waterfronts +waterier +wateriest +waterily +wateriness +waterinesses +watering +waterings +waterish +waterishness +waterishnesses +waterleaf +waterleafs +waterless +waterlessness +waterlessnesses +waterline +waterlines +waterlog +waterlogged +waterlogging +waterlogs +waterloo +waterloos +waterman +watermanship +watermanships +watermark +watermarked +watermarking +watermarks +watermelon +watermelons +watermen +waterpower +waterpowers +waterproof +waterproofed +waterproofer +waterproofers +waterproofing +waterproofings +waterproofness +waterproofnesses +waterproofs +waters +waterscape +waterscapes +watershed +watersheds +waterside +watersides +waterskiing +waterskiings +waterspout +waterspouts +waterthrush +waterthrushes +watertight +watertightness +watertightnesses +waterway +waterways +waterweed +waterweeds +waterwheel +waterwheels +waterworks +waterworn +watery +waterzooi +waterzoois +wats +watt +wattage +wattages +wattape +wattapes +watter +wattest +watthour +watthours +wattle +wattlebird +wattlebirds +wattled +wattles +wattless +wattling +wattmeter +wattmeters +watts +waucht +wauchted +wauchting +wauchts +waugh +waught +waughted +waughting +waughts +wauk +wauked +wauking +wauks +waul +wauled +wauling +wauls +waur +wave +waveband +wavebands +waved +waveform +waveforms +waveguide +waveguides +wavelength +wavelengths +waveless +wavelessly +wavelet +wavelets +wavelike +waveoff +waveoffs +waver +wavered +waverer +waverers +wavering +waveringly +wavers +wavery +waves +waveshape +waveshapes +wavey +waveys +wavier +wavies +waviest +wavily +waviness +wavinesses +waving +wavy +waw +wawl +wawled +wawling +wawls +waws +wax +waxberries +waxberry +waxbill +waxbills +waxed +waxen +waxer +waxers +waxes +waxier +waxiest +waxily +waxiness +waxinesses +waxing +waxings +waxlike +waxplant +waxplants +waxweed +waxweeds +waxwing +waxwings +waxwork +waxworks +waxworm +waxworms +waxy +way +waybill +waybills +wayfarer +wayfarers +wayfaring +waygoing +waygoings +waylaid +waylay +waylayer +waylayers +waylaying +waylays +wayless +ways +wayside +waysides +wayward +waywardly +waywardness +waywardnesses +wayworn +we +weak +weaken +weakened +weakener +weakeners +weakening +weakens +weaker +weakest +weakfish +weakfishes +weakhearted +weakish +weaklier +weakliest +weakliness +weaklinesses +weakling +weaklings +weakly +weakness +weaknesses +weakside +weaksides +weal +weald +wealds +weals +wealth +wealthier +wealthiest +wealthily +wealthiness +wealthinesses +wealths +wealthy +wean +weaned +weaner +weaners +weaning +weanling +weanlings +weans +weapon +weaponed +weaponing +weaponless +weaponries +weaponry +weapons +wear +wearabilities +wearability +wearable +wearables +wearer +wearers +wearied +wearier +wearies +weariest +weariful +wearifully +wearifulness +wearifulnesses +weariless +wearilessly +wearily +weariness +wearinesses +wearing +wearingly +wearish +wearisome +wearisomely +wearisomeness +wearisomenesses +wears +weary +wearying +weasand +weasands +weasel +weaseled +weaseling +weaselled +weaselling +weaselly +weasels +weasely +weason +weasons +weather +weatherabilities +weatherability +weatherboard +weatherboarded +weatherboarding +weatherboardings +weatherboards +weathercast +weathercaster +weathercasters +weathercasts +weathercock +weathercocks +weathered +weatherglass +weatherglasses +weathering +weatherings +weatherization +weatherizations +weatherize +weatherized +weatherizes +weatherizing +weatherly +weatherman +weathermen +weatherperson +weatherpersons +weatherproof +weatherproofed +weatherproofing +weatherproofness +weatherproofnesses +weatherproofs +weathers +weatherworn +weave +weaved +weaver +weaverbird +weaverbirds +weavers +weaves +weaving +weazand +weazands +web +webbed +webbier +webbiest +webbing +webbings +webby +weber +webers +webfed +webfeet +webfoot +webless +weblike +webs +webster +websters +webwork +webworks +webworm +webworms +wecht +wechts +wed +wedded +wedder +wedders +wedding +weddings +wedel +wedeled +wedeling +wedeln +wedelns +wedels +wedge +wedged +wedges +wedgie +wedgier +wedgies +wedgiest +wedging +wedgy +wedlock +wedlocks +weds +wee +weed +weeded +weeder +weeders +weedier +weediest +weedily +weediness +weedinesses +weeding +weedless +weedlike +weeds +weedy +week +weekday +weekdays +weekend +weekended +weekender +weekenders +weekending +weekends +weeklies +weeklong +weekly +weeknight +weeknights +weeks +weel +ween +weened +weenie +weenier +weenies +weeniest +weening +weens +weensier +weensiest +weensy +weeny +weep +weeper +weepers +weepie +weepier +weepies +weepiest +weeping +weepings +weeps +weepy +weer +wees +weest +weet +weeted +weeting +weets +weever +weevers +weevil +weeviled +weevilly +weevils +weevily +weewee +weeweed +weeweeing +weewees +weft +wefts +weftwise +weigela +weigelas +weigelia +weigelias +weigh +weighable +weighed +weigher +weighers +weighing +weighman +weighmen +weighs +weight +weighted +weighter +weighters +weightier +weightiest +weightily +weightiness +weightinesses +weighting +weightless +weightlessly +weightlessness +weightlessnesses +weightlifter +weightlifters +weightlifting +weightliftings +weights +weighty +weimaraner +weimaraners +weiner +weiners +weir +weird +weirder +weirdest +weirdie +weirdies +weirdly +weirdness +weirdnesses +weirdo +weirdoes +weirdos +weirds +weirdy +weirs +weisenheimer +weisenheimers +weka +wekas +welch +welched +welcher +welchers +welches +welching +welcome +welcomed +welcomely +welcomeness +welcomenesses +welcomer +welcomers +welcomes +welcoming +weld +weldable +welded +welder +welders +welding +weldless +weldment +weldments +weldor +weldors +welds +welfare +welfares +welfarism +welfarisms +welfarist +welfarists +welkin +welkins +well +welladay +welladays +wellaway +wellaways +wellborn +wellcurb +wellcurbs +welldoer +welldoers +welled +wellhead +wellheads +wellhole +wellholes +wellie +wellies +welling +wellness +wellnesses +wells +wellsite +wellsites +wellspring +wellsprings +welly +welsh +welshed +welsher +welshers +welshes +welshing +welt +weltanschauung +weltanschauungen +weltanschauungs +welted +welter +weltered +weltering +welters +welterweight +welterweights +welting +weltings +welts +weltschmerz +weltschmerzes +wen +wench +wenched +wencher +wenchers +wenches +wenching +wend +wended +wendigo +wendigos +wending +wends +wennier +wenniest +wennish +wenny +wens +went +wentletrap +wentletraps +wept +were +weregild +weregilds +werewolf +werewolves +wergeld +wergelds +wergelt +wergelts +wergild +wergilds +wert +werwolf +werwolves +weskit +weskits +wessand +wessands +west +westbound +wester +westered +westering +westerlies +westerly +western +westerner +westerners +westernisation +westernisations +westernise +westernised +westernises +westernising +westernization +westernizations +westernize +westernized +westernizes +westernizing +westernmost +westerns +westers +westing +westings +westmost +wests +westward +westwards +wet +wetback +wetbacks +wether +wethers +wetland +wetlands +wetly +wetness +wetnesses +wetproof +wets +wettabilities +wettability +wettable +wetted +wetter +wetters +wettest +wetting +wettings +wettish +wha +whack +whacked +whacker +whackers +whackier +whackiest +whacking +whacko +whackos +whacks +whacky +whale +whaleback +whalebacks +whaleboat +whaleboats +whalebone +whalebones +whaled +whalelike +whaleman +whalemen +whaler +whalers +whales +whaling +whalings +wham +whammed +whammies +whamming +whammo +whammy +whamo +whams +whang +whanged +whangee +whangees +whanging +whangs +whap +whapped +whapper +whappers +whapping +whaps +wharf +wharfage +wharfages +wharfed +wharfing +wharfinger +wharfingers +wharfmaster +wharfmasters +wharfs +wharve +wharves +what +whatchamacallit +whatchamacallits +whatever +whatness +whatnesses +whatnot +whatnots +whats +whatsis +whatsises +whatsit +whatsits +whatsoever +whaup +whaups +wheal +wheals +wheat +wheatear +wheatears +wheaten +wheatens +wheats +whee +wheedle +wheedled +wheedler +wheedlers +wheedles +wheedling +wheel +wheelbarrow +wheelbarrowed +wheelbarrowing +wheelbarrows +wheelbase +wheelbases +wheelchair +wheelchairs +wheeled +wheeler +wheelers +wheelhorse +wheelhorses +wheelhouse +wheelhouses +wheelie +wheelies +wheeling +wheelings +wheelless +wheelman +wheelmen +wheels +wheelsman +wheelsmen +wheelwork +wheelworks +wheelwright +wheelwrights +wheen +wheens +wheep +wheeped +wheeping +wheeple +wheepled +wheeples +wheepling +wheeps +wheeze +wheezed +wheezer +wheezers +wheezes +wheezier +wheeziest +wheezily +wheeziness +wheezinesses +wheezing +wheezy +whelk +whelkier +whelkiest +whelks +whelky +whelm +whelmed +whelming +whelms +whelp +whelped +whelping +whelps +when +whenas +whence +whencesoever +whenever +whens +whensoever +where +whereabout +whereabouts +whereas +whereases +whereat +whereby +wherefore +wherefores +wherefrom +wherein +whereinto +whereof +whereon +wheres +wheresoever +wherethrough +whereto +whereunto +whereupon +wherever +wherewith +wherewithal +wherewithals +wherried +wherries +wherry +wherrying +wherve +wherves +whet +whether +whets +whetstone +whetstones +whetted +whetter +whetters +whetting +whew +whews +whey +wheyey +wheyface +wheyfaces +wheyish +wheylike +wheys +which +whichever +whichsoever +whicker +whickered +whickering +whickers +whid +whidah +whidahs +whidded +whidding +whids +whiff +whiffed +whiffer +whiffers +whiffet +whiffets +whiffing +whiffle +whiffled +whiffler +whifflers +whiffles +whiffletree +whiffletrees +whiffling +whiffs +whig +whigmaleerie +whigmaleeries +whigs +while +whiled +whiles +whiling +whilom +whilst +whim +whimbrel +whimbrels +whimper +whimpered +whimpering +whimpers +whims +whimsey +whimseys +whimsical +whimsicalities +whimsicality +whimsically +whimsicalness +whimsicalnesses +whimsied +whimsies +whimsy +whin +whinchat +whinchats +whine +whined +whiner +whiners +whines +whiney +whinge +whinged +whingeing +whinges +whinging +whinier +whiniest +whining +whiningly +whinnied +whinnier +whinnies +whinniest +whinny +whinnying +whins +whinstone +whinstones +whiny +whip +whipcord +whipcords +whiplash +whiplashes +whiplike +whipped +whipper +whippers +whippersnapper +whippersnappers +whippet +whippets +whippier +whippiest +whipping +whippings +whippletree +whippletrees +whippoorwill +whippoorwills +whippy +whipray +whiprays +whips +whipsaw +whipsawed +whipsawing +whipsawn +whipsaws +whipstitch +whipstitched +whipstitches +whipstitching +whipstock +whipstocks +whipt +whiptail +whiptails +whipworm +whipworms +whir +whirl +whirled +whirler +whirlers +whirlier +whirlies +whirliest +whirligig +whirligigs +whirling +whirlpool +whirlpools +whirls +whirlwind +whirlwinds +whirly +whirlybird +whirlybirds +whirr +whirred +whirried +whirries +whirring +whirrs +whirry +whirrying +whirs +whish +whished +whishes +whishing +whisht +whishted +whishting +whishts +whisk +whisked +whisker +whiskered +whiskers +whiskery +whiskey +whiskeys +whiskies +whisking +whisks +whisky +whisper +whispered +whisperer +whisperers +whispering +whisperingly +whisperings +whispers +whispery +whist +whisted +whisting +whistle +whistleable +whistleblower +whistleblowers +whistleblowing +whistleblowings +whistled +whistler +whistlers +whistles +whistling +whistlings +whists +whit +white +whitebait +whitebaits +whitebeard +whitebeards +whitecap +whitecaps +whited +whiteface +whitefaces +whitefish +whitefishes +whiteflies +whitefly +whitehead +whiteheads +whitely +whiten +whitened +whitener +whiteners +whiteness +whitenesses +whitening +whitenings +whitens +whiteout +whiteouts +whiter +whites +whitesmith +whitesmiths +whitest +whitetail +whitetails +whitethroat +whitethroats +whitewall +whitewalls +whitewash +whitewashed +whitewasher +whitewashers +whitewashes +whitewashing +whitewashings +whitewing +whitewings +whitewood +whitewoods +whitey +whiteys +whither +whithersoever +whitherward +whitier +whities +whitiest +whiting +whitings +whitish +whitlow +whitlows +whitrack +whitracks +whits +whitter +whitters +whittle +whittled +whittler +whittlers +whittles +whittling +whittlings +whittret +whittrets +whity +whiz +whizbang +whizbangs +whizz +whizzbang +whizzbangs +whizzed +whizzer +whizzers +whizzes +whizzing +who +whoa +whodunit +whodunits +whodunnit +whodunnits +whoever +whole +wholehearted +wholeheartedly +wholeness +wholenesses +wholes +wholesale +wholesaled +wholesaler +wholesalers +wholesales +wholesaling +wholesome +wholesomely +wholesomeness +wholesomenesses +wholism +wholisms +wholistic +wholly +whom +whomever +whomp +whomped +whomping +whomps +whomso +whomsoever +whoof +whoofed +whoofing +whoofs +whoop +whooped +whoopee +whoopees +whooper +whoopers +whooping +whoopla +whooplas +whoops +whoosh +whooshed +whooshes +whooshing +whoosis +whoosises +whop +whopped +whopper +whoppers +whopping +whops +whore +whored +whoredom +whoredoms +whorehouse +whorehouses +whoremaster +whoremasters +whoremonger +whoremongers +whores +whoreson +whoresons +whoring +whorish +whorl +whorled +whorls +whort +whortle +whortleberries +whortleberry +whortles +whorts +whose +whosesoever +whosever +whosis +whosises +whoso +whosoever +whump +whumped +whumping +whumps +why +whydah +whydahs +whys +wich +wiches +wick +wickape +wickapes +wicked +wickeder +wickedest +wickedly +wickedness +wickednesses +wicker +wickers +wickerwork +wickerworks +wicket +wickets +wicking +wickings +wickiup +wickiups +wicks +wickyup +wickyups +wicopies +wicopy +widder +widders +widdershins +widdie +widdies +widdle +widdled +widdles +widdling +widdy +wide +wideawake +wideawakes +wideband +widely +widemouthed +widen +widened +widener +wideners +wideness +widenesses +widening +widens +wideout +wideouts +wider +wides +widespread +widest +widgeon +widgeons +widget +widgets +widish +widow +widowed +widower +widowerhood +widowerhoods +widowers +widowhood +widowhoods +widowing +widows +width +widths +widthway +wield +wielded +wielder +wielders +wieldier +wieldiest +wielding +wields +wieldy +wiener +wieners +wienerwurst +wienerwursts +wienie +wienies +wife +wifed +wifedom +wifedoms +wifehood +wifehoods +wifeless +wifelier +wifeliest +wifelike +wifeliness +wifelinesses +wifely +wifes +wifing +wiftier +wiftiest +wifty +wig +wigan +wigans +wigeon +wigeons +wigged +wiggeries +wiggery +wiggier +wiggiest +wigging +wiggings +wiggle +wiggled +wiggler +wigglers +wiggles +wigglier +wiggliest +wiggling +wiggly +wiggy +wight +wights +wigless +wiglet +wiglets +wiglike +wigmaker +wigmakers +wigs +wigwag +wigwagged +wigwagging +wigwags +wigwam +wigwams +wikiup +wikiups +wilco +wild +wildcat +wildcats +wildcatted +wildcatter +wildcatters +wildcatting +wildebeest +wildebeests +wilder +wildered +wildering +wilderment +wilderments +wilderness +wildernesses +wilders +wildest +wildfire +wildfires +wildflower +wildflowers +wildfowl +wildfowler +wildfowlers +wildfowling +wildfowlings +wildfowls +wilding +wildings +wildish +wildland +wildlands +wildlife +wildling +wildlings +wildly +wildness +wildnesses +wilds +wildwood +wildwoods +wile +wiled +wiles +wilful +wilfully +wilier +wiliest +wilily +wiliness +wilinesses +wiling +will +willable +willed +willemite +willemites +willer +willers +willet +willets +willful +willfully +willfulness +willfulnesses +willied +willies +willing +willinger +willingest +willingly +willingness +willingnesses +williwau +williwaus +williwaw +williwaws +willow +willowed +willower +willowers +willowier +willowiest +willowing +willowlike +willows +willowware +willowwares +willowy +willpower +willpowers +wills +willy +willyard +willyart +willying +willywaw +willywaws +wilt +wilted +wilting +wilts +wily +wimble +wimbled +wimbles +wimbling +wimp +wimpier +wimpiest +wimpiness +wimpinesses +wimpish +wimpishness +wimpishnesses +wimple +wimpled +wimples +wimpling +wimps +wimpy +win +wince +winced +wincer +wincers +winces +wincey +winceys +winch +winched +wincher +winchers +winches +winching +wincing +wind +windable +windage +windages +windbag +windbags +windblast +windblasts +windblown +windbreak +windbreaker +windbreakers +windbreaks +windburn +windburned +windburning +windburns +windburnt +windchill +windchills +winded +winder +winders +windfall +windfalls +windflaw +windflaws +windflower +windflowers +windgall +windgalls +windhover +windhovers +windier +windiest +windigo +windigos +windily +windiness +windinesses +winding +windings +windjammer +windjammers +windjamming +windjammings +windlass +windlassed +windlasses +windlassing +windle +windled +windles +windless +windlessly +windlestraw +windlestraws +windling +windlings +windmill +windmilled +windmilling +windmills +window +windowed +windowing +windowless +windowpane +windowpanes +windows +windowsill +windowsills +windpipe +windpipes +windproof +windrow +windrowed +windrowing +windrows +winds +windscreen +windscreens +windshield +windshields +windsock +windsocks +windstorm +windstorms +windsurf +windsurfed +windsurfing +windsurfings +windsurfs +windswept +windthrow +windthrows +windup +windups +windward +windwards +windway +windways +windy +wine +wined +wineglass +wineglasses +winegrower +winegrowers +wineless +winemaker +winemakers +winemaking +winemakings +winepress +winepresses +wineries +winery +wines +wineshop +wineshops +wineskin +wineskins +winesop +winesops +winey +wing +wingback +wingbacks +wingbow +wingbows +wingding +wingdings +winged +wingedly +winger +wingers +wingier +wingiest +winging +wingless +winglessness +winglessnesses +winglet +winglets +winglike +wingman +wingmen +wingover +wingovers +wings +wingspan +wingspans +wingspread +wingspreads +wingtip +wingtips +wingy +winier +winiest +wining +winish +wink +winked +winker +winkers +winking +winkle +winkled +winkles +winkling +winks +winless +winnable +winned +winner +winners +winning +winningly +winnings +winnock +winnocks +winnow +winnowed +winnower +winnowers +winnowing +winnows +wino +winoes +winos +wins +winsome +winsomely +winsomeness +winsomenesses +winsomer +winsomest +winter +winterberries +winterberry +wintered +winterer +winterers +wintergreen +wintergreens +winterier +winteriest +wintering +winterization +winterizations +winterize +winterized +winterizes +winterizing +winterkill +winterkills +winterly +winters +wintertide +wintertides +wintertime +wintertimes +wintery +wintle +wintled +wintles +wintling +wintrier +wintriest +wintrily +wintriness +wintrinesses +wintry +winy +winze +winzes +wipe +wiped +wipeout +wipeouts +wiper +wipers +wipes +wiping +wirable +wire +wired +wiredraw +wiredrawer +wiredrawers +wiredrawing +wiredrawn +wiredraws +wiredrew +wirehair +wirehaired +wirehairs +wireless +wirelessed +wirelesses +wirelessing +wirelike +wireman +wiremen +wirephoto +wirephotos +wirer +wirers +wires +wiretap +wiretapped +wiretapper +wiretappers +wiretapping +wiretaps +wireway +wireways +wirework +wireworks +wireworm +wireworms +wirier +wiriest +wirily +wiriness +wirinesses +wiring +wirings +wirra +wiry +wis +wisdom +wisdoms +wise +wiseacre +wiseacres +wiseass +wiseasses +wisecrack +wisecracked +wisecracker +wisecrackers +wisecracking +wisecracks +wised +wiselier +wiseliest +wisely +wiseness +wisenesses +wisenheimer +wisenheimers +wisent +wisents +wiser +wises +wisest +wisewoman +wisewomen +wish +wisha +wishbone +wishbones +wished +wisher +wishers +wishes +wishful +wishfully +wishfulness +wishfulnesses +wishing +wishless +wising +wisp +wisped +wispier +wispiest +wispily +wispiness +wispinesses +wisping +wispish +wisplike +wisps +wispy +wiss +wissed +wisses +wissing +wist +wistaria +wistarias +wisted +wisteria +wisterias +wistful +wistfully +wistfulness +wistfulnesses +wisting +wists +wit +witan +witch +witchcraft +witchcrafts +witched +witcheries +witchery +witches +witchgrass +witchgrasses +witchier +witchiest +witching +witchings +witchlike +witchweed +witchweeds +witchy +wite +wited +witenagemot +witenagemote +witenagemotes +witenagemots +wites +with +withal +withdraw +withdrawable +withdrawal +withdrawals +withdrawing +withdrawn +withdrawnness +withdrawnnesses +withdraws +withdrew +withe +withed +wither +withered +witherer +witherers +withering +witheringly +witherite +witherites +withers +withershins +withes +withheld +withhold +withholder +withholders +withholding +withholds +withier +withies +withiest +within +withindoors +withing +withins +without +withoutdoors +withouts +withstand +withstanding +withstands +withstood +withy +witing +witless +witlessly +witlessness +witlessnesses +witling +witlings +witloof +witloofs +witness +witnessed +witnesses +witnessing +witney +witneys +wits +witted +witticism +witticisms +wittier +wittiest +wittily +wittiness +wittinesses +witting +wittingly +wittings +wittol +wittols +witty +wive +wived +wiver +wivern +wiverns +wivers +wives +wiving +wiz +wizard +wizardly +wizardries +wizardry +wizards +wizen +wizened +wizening +wizens +wizes +wizzen +wizzens +wo +woad +woaded +woads +woadwax +woadwaxes +woald +woalds +wobble +wobbled +wobbler +wobblers +wobbles +wobblier +wobblies +wobbliest +wobbliness +wobblinesses +wobbling +wobbly +wobegone +wodge +wodges +woe +woebegone +woebegoneness +woebegonenesses +woeful +woefuller +woefullest +woefully +woefulness +woefulnesses +woeness +woenesses +woes +woesome +woful +wofully +wog +wogs +wok +woke +woken +woks +wold +wolds +wolf +wolfberries +wolfberry +wolfed +wolfer +wolfers +wolffish +wolffishes +wolfhound +wolfhounds +wolfing +wolfish +wolfishly +wolfishness +wolfishnesses +wolflike +wolfram +wolframite +wolframites +wolframs +wolfs +wolfsbane +wolfsbanes +wollastonite +wollastonites +wolver +wolverine +wolverines +wolvers +wolves +woman +womaned +womanhood +womanhoods +womaning +womanise +womanised +womanises +womanish +womanishly +womanishness +womanishnesses +womanising +womanize +womanized +womanizer +womanizers +womanizes +womanizing +womankind +womanless +womanlier +womanliest +womanlike +womanliness +womanlinesses +womanly +womanpower +womanpowers +womans +womb +wombat +wombats +wombed +wombier +wombiest +wombs +womby +women +womenfolk +womenfolks +womenkind +womera +womeras +wommera +wommeras +won +wonder +wondered +wonderer +wonderers +wonderful +wonderfully +wonderfulness +wonderfulnesses +wondering +wonderland +wonderlands +wonderment +wonderments +wonders +wonderwork +wonderworks +wondrous +wondrously +wondrousness +wondrousnesses +wonk +wonkier +wonkiest +wonks +wonky +wonned +wonner +wonners +wonning +wons +wont +wonted +wontedly +wontedness +wontednesses +wonting +wonton +wontons +wonts +woo +wood +woodbin +woodbind +woodbinds +woodbine +woodbines +woodbins +woodblock +woodblocks +woodbox +woodboxes +woodcarver +woodcarvers +woodcarving +woodcarvings +woodchat +woodchats +woodchopper +woodchoppers +woodchuck +woodchucks +woodcock +woodcocks +woodcraft +woodcrafts +woodcut +woodcuts +woodcutter +woodcutters +woodcutting +woodcuttings +wooded +wooden +woodener +woodenest +woodenhead +woodenheaded +woodenheads +woodenly +woodenness +woodennesses +woodenware +woodenwares +woodhen +woodhens +woodie +woodier +woodies +woodiest +woodiness +woodinesses +wooding +woodland +woodlander +woodlanders +woodlands +woodlark +woodlarks +woodless +woodlore +woodlores +woodlot +woodlots +woodman +woodmen +woodnote +woodnotes +woodpecker +woodpeckers +woodpile +woodpiles +woodruff +woodruffs +woods +woodshed +woodshedded +woodshedding +woodsheds +woodsia +woodsias +woodsier +woodsiest +woodsman +woodsmen +woodstove +woodstoves +woodsy +woodwax +woodwaxes +woodwind +woodwinds +woodwork +woodworker +woodworkers +woodworking +woodworkings +woodworks +woodworm +woodworms +woody +wooed +wooer +wooers +woof +woofed +woofer +woofers +woofing +woofs +wooing +wooingly +wool +wooled +woolen +woolens +wooler +woolers +woolfell +woolfells +woolgatherer +woolgatherers +woolgathering +woolgatherings +woolhat +woolhats +woolie +woolier +woolies +wooliest +woolled +woollen +woollens +woollier +woollies +woolliest +woollike +woollily +woolliness +woollinesses +woolly +woolman +woolmen +woolpack +woolpacks +wools +woolsack +woolsacks +woolshed +woolsheds +woolskin +woolskins +woolwork +woolworks +wooly +woomera +woomeras +woops +woopsed +woopses +woopsing +woorali +wooralis +woorari +wooraris +woos +woosh +wooshed +wooshes +wooshing +woozier +wooziest +woozily +wooziness +woozinesses +woozy +wop +wops +word +wordage +wordages +wordbook +wordbooks +worded +wordier +wordiest +wordily +wordiness +wordinesses +wording +wordings +wordless +wordlessly +wordlessness +wordlessnesses +wordmonger +wordmongers +wordplay +wordplays +words +wordsmith +wordsmitheries +wordsmithery +wordsmiths +wordy +wore +work +workabilities +workability +workable +workableness +workablenesses +workaday +workaholic +workaholics +workaholism +workaholisms +workbag +workbags +workbasket +workbaskets +workbench +workbenches +workboat +workboats +workbook +workbooks +workbox +workboxes +workday +workdays +worked +worker +workers +workfare +workfares +workfolk +workfolks +workforce +workforces +workhorse +workhorses +workhouse +workhouses +working +workingman +workingmen +workings +workingwoman +workingwomen +workless +worklessness +worklessnesses +workload +workloads +workman +workmanlike +workmanly +workmanship +workmanships +workmate +workmates +workmen +workout +workouts +workpeople +workpiece +workpieces +workplace +workplaces +workroom +workrooms +works +worksheet +worksheets +workshop +workshops +workstation +workstations +worktable +worktables +workup +workups +workweek +workweeks +workwoman +workwomen +world +worldlier +worldliest +worldliness +worldlinesses +worldling +worldlings +worldly +worlds +worldview +worldviews +worldwide +worm +wormed +wormer +wormers +wormhole +wormholes +wormier +wormiest +wormil +wormils +worming +wormish +wormlike +wormroot +wormroots +worms +wormseed +wormseeds +wormwood +wormwoods +wormy +worn +wornness +wornnesses +worried +worriedly +worrier +worriers +worries +worriment +worriments +worrisome +worrisomely +worrisomeness +worrisomenesses +worrit +worrited +worriting +worrits +worry +worrying +worrywart +worrywarts +worse +worsen +worsened +worsening +worsens +worser +worses +worset +worsets +worship +worshiped +worshiper +worshipers +worshipful +worshipfully +worshipfulness +worshipfulnesses +worshiping +worshipless +worshipped +worshipper +worshippers +worshipping +worships +worst +worsted +worsteds +worsting +worsts +wort +worth +worthed +worthful +worthier +worthies +worthiest +worthily +worthiness +worthinesses +worthing +worthless +worthlessly +worthlessness +worthlessnesses +worths +worthwhile +worthwhileness +worthwhilenesses +worthy +worts +wos +wost +wot +wots +wotted +wotting +would +wouldest +wouldst +wound +wounded +wounding +woundless +wounds +wove +woven +wovens +wow +wowed +wowing +wows +wowser +wowsers +wrack +wracked +wrackful +wracking +wracks +wraith +wraithlike +wraiths +wrang +wrangle +wrangled +wrangler +wranglers +wrangles +wrangling +wrangs +wrap +wraparound +wraparounds +wrapped +wrapper +wrappers +wrapping +wrappings +wraps +wrapt +wrasse +wrasses +wrassle +wrassled +wrassles +wrassling +wrastle +wrastled +wrastles +wrastling +wrath +wrathed +wrathful +wrathfully +wrathfulness +wrathfulnesses +wrathier +wrathiest +wrathily +wrathing +wraths +wrathy +wreak +wreaked +wreaker +wreakers +wreaking +wreaks +wreath +wreathe +wreathed +wreathen +wreathes +wreathing +wreaths +wreathy +wreck +wreckage +wreckages +wrecked +wrecker +wreckers +wreckful +wrecking +wreckings +wrecks +wren +wrench +wrenched +wrenches +wrenching +wrenchingly +wrens +wrest +wrested +wrester +wresters +wresting +wrestle +wrestled +wrestler +wrestlers +wrestles +wrestling +wrestlings +wrests +wretch +wretched +wretcheder +wretchedest +wretchedly +wretchedness +wretchednesses +wretches +wrick +wricked +wricking +wricks +wried +wrier +wries +wriest +wriggle +wriggled +wriggler +wrigglers +wriggles +wrigglier +wriggliest +wriggling +wriggly +wright +wrights +wring +wringed +wringer +wringers +wringing +wrings +wrinkle +wrinkled +wrinkles +wrinklier +wrinkliest +wrinkling +wrinkly +wrist +wristband +wristbands +wristier +wristiest +wristlet +wristlets +wristlock +wristlocks +wrists +wristwatch +wristwatches +wristy +writ +writable +write +writer +writerly +writers +writes +writhe +writhed +writhen +writher +writhers +writhes +writhing +writing +writings +writs +written +wrong +wrongdoer +wrongdoers +wrongdoing +wrongdoings +wronged +wronger +wrongers +wrongest +wrongful +wrongfully +wrongfulness +wrongfulnesses +wrongheaded +wrongheadedly +wrongheadedness +wrongheadednesses +wronging +wrongly +wrongness +wrongnesses +wrongs +wrote +wroth +wrothful +wrought +wrung +wry +wryer +wryest +wrying +wryly +wryneck +wrynecks +wryness +wrynesses +wud +wulfenite +wulfenites +wunderkind +wunderkinder +wurst +wursts +wurzel +wurzels +wuss +wusses +wussier +wussies +wussiest +wussy +wuther +wuthered +wuthering +wuthers +wyandotte +wyandottes +wych +wyches +wye +wyes +wyle +wyled +wyles +wyliecoat +wyliecoats +wyling +wyn +wynd +wynds +wynn +wynns +wyns +wyte +wyted +wytes +wyting +wyvern +wyverns +xanthan +xanthans +xanthate +xanthates +xanthein +xantheins +xanthene +xanthenes +xanthic +xanthin +xanthine +xanthines +xanthins +xanthoma +xanthomas +xanthomata +xanthone +xanthones +xanthophyll +xanthophylls +xanthous +xebec +xebecs +xenia +xenial +xenias +xenic +xenobiotic +xenobiotics +xenodiagnoses +xenodiagnosis +xenodiagnostic +xenogamies +xenogamy +xenogeneic +xenogenies +xenogeny +xenograft +xenografts +xenolith +xenolithic +xenoliths +xenon +xenons +xenophile +xenophiles +xenophobe +xenophobes +xenophobia +xenophobias +xenophobic +xenophobically +xenotropic +xerarch +xeric +xerographic +xerographically +xerographies +xerography +xerophile +xerophilies +xerophilous +xerophily +xerophthalmia +xerophthalmias +xerophthalmic +xerophyte +xerophytes +xerophytic +xerophytism +xerophytisms +xeroradiographies +xeroradiography +xerosere +xeroseres +xeroses +xerosis +xerothermic +xerotic +xerox +xeroxed +xeroxes +xeroxing +xerus +xeruses +xi +xiphisterna +xiphisternum +xiphoid +xiphoids +xis +xu +xylan +xylans +xylem +xylems +xylene +xylenes +xylidin +xylidine +xylidines +xylidins +xylitol +xylitols +xylocarp +xylocarps +xylograph +xylographer +xylographers +xylographic +xylographical +xylographies +xylographs +xylography +xyloid +xylol +xylols +xylophagous +xylophone +xylophones +xylophonist +xylophonists +xylose +xyloses +xylotomies +xylotomy +xylyl +xylyls +xyst +xyster +xysters +xysti +xystoi +xystos +xysts +xystus +ya +yabber +yabbered +yabbering +yabbers +yacht +yachted +yachter +yachters +yachting +yachtings +yachtman +yachtmen +yachts +yachtsman +yachtsmen +yack +yacked +yacking +yacks +yaff +yaffed +yaffing +yaffs +yager +yagers +yagi +yagis +yah +yahoo +yahooism +yahooisms +yahoos +yahrzeit +yahrzeits +yaird +yairds +yak +yakitori +yakitoris +yakked +yakker +yakkers +yakking +yaks +yald +yam +yamalka +yamalkas +yamen +yamens +yammer +yammered +yammerer +yammerers +yammering +yammers +yams +yamulka +yamulkas +yamun +yamuns +yang +yangs +yank +yanked +yanking +yanks +yanqui +yanquis +yantra +yantras +yap +yapock +yapocks +yapok +yapoks +yapon +yapons +yapped +yapper +yappers +yapping +yaps +yar +yard +yardage +yardages +yardarm +yardarms +yardbird +yardbirds +yarded +yarding +yardland +yardlands +yardman +yardmaster +yardmasters +yardmen +yards +yardstick +yardsticks +yardwand +yardwands +yardwork +yardworks +yare +yarely +yarer +yarest +yarmelke +yarmelkes +yarmulke +yarmulkes +yarn +yarned +yarner +yarners +yarning +yarns +yarrow +yarrows +yashmac +yashmacs +yashmak +yashmaks +yasmak +yasmaks +yatagan +yatagans +yataghan +yataghans +yatter +yattered +yattering +yatters +yaud +yauds +yauld +yaup +yauped +yauper +yaupers +yauping +yaupon +yaupons +yaups +yautia +yautias +yaw +yawed +yawing +yawl +yawled +yawling +yawls +yawmeter +yawmeters +yawn +yawned +yawner +yawners +yawning +yawningly +yawns +yawp +yawped +yawper +yawpers +yawping +yawpings +yawps +yaws +yay +yays +ycleped +yclept +ye +yea +yeah +yealing +yealings +yean +yeaned +yeaning +yeanling +yeanlings +yeans +year +yearbook +yearbooks +yearend +yearends +yearlies +yearling +yearlings +yearlong +yearly +yearn +yearned +yearner +yearners +yearning +yearningly +yearnings +yearns +years +yeas +yeasayer +yeasayers +yeast +yeasted +yeastier +yeastiest +yeastily +yeastiness +yeastinesses +yeasting +yeasts +yeasty +yecch +yecchs +yech +yechs +yechy +yeelin +yeelins +yegg +yeggman +yeggmen +yeggs +yeh +yeld +yelk +yelks +yell +yelled +yeller +yellers +yelling +yellow +yellowed +yellower +yellowest +yellowfin +yellowfins +yellowhammer +yellowhammers +yellowing +yellowish +yellowlegs +yellowly +yellows +yellowtail +yellowtails +yellowthroat +yellowthroats +yellowware +yellowwares +yellowwood +yellowwoods +yellowy +yells +yelp +yelped +yelper +yelpers +yelping +yelps +yen +yenned +yenning +yens +yenta +yentas +yente +yentes +yeoman +yeomanly +yeomanries +yeomanry +yeomen +yep +yerba +yerbas +yerk +yerked +yerking +yerks +yes +yeses +yeshiva +yeshivah +yeshivahs +yeshivas +yeshivot +yeshivoth +yessed +yesses +yessing +yester +yesterday +yesterdays +yestern +yesternight +yesternights +yesteryear +yesteryears +yestreen +yestreens +yet +yeti +yetis +yett +yetts +yeuk +yeuked +yeuking +yeuks +yeuky +yew +yews +yid +yids +yield +yielded +yielder +yielders +yielding +yields +yikes +yill +yills +yin +yince +yins +yip +yipe +yipes +yipped +yippee +yippie +yippies +yipping +yips +yird +yirds +yirr +yirred +yirring +yirrs +yirth +yirths +ylem +ylems +yo +yob +yobbo +yobboes +yobbos +yobs +yock +yocked +yocking +yocks +yod +yodel +yodeled +yodeler +yodelers +yodeling +yodelled +yodeller +yodellers +yodelling +yodels +yodh +yodhs +yodle +yodled +yodler +yodlers +yodles +yodling +yods +yoga +yogas +yogee +yogees +yogh +yoghourt +yoghourts +yoghs +yoghurt +yoghurts +yogi +yogic +yogin +yogini +yoginis +yogins +yogis +yogurt +yogurts +yohimbine +yohimbines +yoicks +yok +yoke +yoked +yokefellow +yokefellows +yokel +yokeless +yokelish +yokels +yokemate +yokemates +yokes +yoking +yokozuna +yokozunas +yoks +yolk +yolked +yolkier +yolkiest +yolks +yolky +yom +yomim +yon +yond +yonder +yoni +yonic +yonis +yonker +yonkers +yore +yores +you +young +youngberries +youngberry +younger +youngers +youngest +youngish +youngling +younglings +youngness +youngnesses +youngs +youngster +youngsters +younker +younkers +youpon +youpons +your +yourn +yours +yourself +yourselves +youse +youth +youthen +youthened +youthening +youthens +youthful +youthfully +youthfulness +youthfulnesses +youthquake +youthquakes +youths +yow +yowe +yowed +yowes +yowie +yowies +yowing +yowl +yowled +yowler +yowlers +yowling +yowls +yows +yperite +yperites +ytterbia +ytterbias +ytterbic +ytterbium +ytterbiums +yttria +yttrias +yttric +yttrium +yttriums +yuan +yuans +yuca +yucas +yucca +yuccas +yucch +yuch +yuck +yucked +yuckier +yuckiest +yucking +yucks +yucky +yuga +yugas +yuk +yukked +yukking +yuks +yulan +yulans +yule +yules +yuletide +yuletides +yum +yummier +yummies +yummiest +yummy +yup +yupon +yupons +yuppie +yuppies +yups +yurt +yurta +yurts +ywis +zabaglione +zabagliones +zabaione +zabaiones +zabajone +zabajones +zacaton +zacatons +zaddick +zaddik +zaddikim +zaffar +zaffars +zaffer +zaffers +zaffir +zaffirs +zaffre +zaffres +zaftig +zag +zagged +zagging +zags +zaibatsu +zaikai +zaikais +zaire +zaires +zamarra +zamarras +zamarro +zamarros +zamia +zamias +zamindar +zamindari +zamindaris +zamindars +zanana +zananas +zander +zanders +zanier +zanies +zaniest +zanily +zaniness +zaninesses +zany +zanyish +zanza +zanzas +zap +zapateado +zapateados +zapateo +zapateos +zapped +zapper +zappers +zappier +zappiest +zapping +zappy +zaps +zaptiah +zaptiahs +zaptieh +zaptiehs +zaratite +zaratites +zareba +zarebas +zareeba +zareebas +zarf +zarfs +zariba +zaribas +zarzuela +zarzuelas +zastruga +zastrugi +zax +zaxes +zayin +zayins +zazen +zazens +zeal +zealot +zealotries +zealotry +zealots +zealous +zealously +zealousness +zealousnesses +zeals +zeatin +zeatins +zebec +zebeck +zebecks +zebecs +zebra +zebraic +zebras +zebrass +zebrasses +zebrawood +zebrawoods +zebrine +zebroid +zebu +zebus +zecchin +zecchini +zecchino +zecchinos +zecchins +zechin +zechins +zed +zedoaries +zedoary +zeds +zee +zees +zein +zeins +zeitgeber +zeitgebers +zeitgeist +zeitgeists +zek +zeks +zelkova +zelkovas +zemindar +zemindaries +zemindars +zemindary +zemstva +zemstvo +zemstvos +zenaida +zenaidas +zenana +zenanas +zenith +zenithal +zeniths +zeolite +zeolites +zeolitic +zephyr +zephyrs +zeppelin +zeppelins +zerk +zerks +zero +zeroed +zeroes +zeroing +zeros +zeroth +zest +zested +zester +zesters +zestful +zestfully +zestfulness +zestfulnesses +zestier +zestiest +zesting +zestless +zests +zesty +zeta +zetas +zeugma +zeugmas +zibeline +zibelines +zibelline +zibellines +zibet +zibeth +zibeths +zibets +zidovudine +zidovudines +zig +zigged +zigging +ziggurat +ziggurats +zigs +zigzag +zigzagged +zigzagging +zigzags +zikkurat +zikkurats +zikurat +zikurats +zilch +zilches +zill +zillah +zillahs +zillion +zillionaire +zillionaires +zillions +zillionth +zills +zin +zinc +zincate +zincates +zinced +zincic +zincified +zincifies +zincify +zincifying +zincing +zincite +zincites +zincked +zincking +zincky +zincoid +zincous +zincs +zincy +zineb +zinebs +zinfandel +zinfandels +zing +zingani +zingano +zingara +zingare +zingari +zingaro +zinged +zinger +zingers +zingier +zingiest +zinging +zings +zingy +zinkified +zinkifies +zinkify +zinkifying +zinky +zinnia +zinnias +zins +zip +zipless +zipped +zipper +zippered +zippering +zippers +zippier +zippiest +zipping +zippy +zips +ziram +zirams +zircon +zirconia +zirconias +zirconic +zirconium +zirconiums +zircons +zit +zither +zitherist +zitherists +zithern +zitherns +zithers +ziti +zitis +zits +zizit +zizith +zizzle +zizzled +zizzles +zizzling +zlote +zloties +zloty +zlotych +zlotys +zoa +zoantharian +zoantharians +zoaria +zoarial +zoarium +zodiac +zodiacal +zodiacs +zoea +zoeae +zoeal +zoeas +zoecia +zoecium +zoftig +zoic +zoisite +zoisites +zombi +zombie +zombielike +zombies +zombification +zombifications +zombified +zombifies +zombify +zombifying +zombiism +zombiisms +zombis +zonal +zonally +zonary +zonate +zonated +zonation +zonations +zone +zoned +zoneless +zoner +zoners +zones +zonetime +zonetimes +zoning +zonk +zonked +zonking +zonks +zonula +zonulae +zonular +zonulas +zonule +zonules +zoo +zoochore +zoochores +zooecia +zooecium +zoogenic +zoogeographer +zoogeographers +zoogeographic +zoogeographical +zoogeographically +zoogeographies +zoogeography +zooglea +zoogleae +zoogleal +zoogleas +zoogloea +zoogloeae +zoogloeas +zooid +zooidal +zooids +zookeeper +zookeepers +zooks +zoolater +zoolaters +zoolatries +zoolatry +zoologic +zoological +zoologically +zoologies +zoologist +zoologists +zoology +zoom +zoomania +zoomanias +zoomed +zoometries +zoometry +zooming +zoomorph +zoomorphic +zoomorphs +zooms +zoon +zoonal +zoonoses +zoonosis +zoonotic +zoons +zoophile +zoophiles +zoophilic +zoophilies +zoophilous +zoophily +zoophobe +zoophobes +zoophyte +zoophytes +zooplankter +zooplankters +zooplankton +zooplanktonic +zooplanktons +zoos +zoosperm +zoosperms +zoosporangia +zoosporangium +zoospore +zoospores +zoosporic +zoosterol +zoosterols +zootechnical +zootechnics +zootier +zootiest +zootomic +zootomies +zootomy +zooty +zooxanthella +zooxanthellae +zori +zoril +zorilla +zorillas +zorille +zorilles +zorillo +zorillos +zorils +zoris +zoster +zosters +zouave +zouaves +zounds +zowie +zoysia +zoysias +zucchetto +zucchettos +zucchini +zucchinis +zwieback +zwiebacks +zwitterion +zwitterionic +zwitterions +zydeco +zydecos +zygapophyses +zygapophysis +zygodactyl +zygodactylous +zygoid +zygoma +zygomas +zygomata +zygomatic +zygomorphic +zygomorphies +zygomorphy +zygose +zygoses +zygosis +zygosities +zygosity +zygospore +zygospores +zygote +zygotene +zygotenes +zygotes +zygotic +zymase +zymases +zyme +zymes +zymogen +zymogene +zymogenes +zymogens +zymogram +zymograms +zymologies +zymology +zymosan +zymosans +zymoses +zymosis +zymotic +zymurgies +zymurgy +zyzzyva +zyzzyvas \ No newline at end of file diff --git a/pytudes/ipynb/money.png b/pytudes/ipynb/money.png new file mode 100644 index 0000000000000000000000000000000000000000..f8a9b02075bc4680867ecb0ccb74caf6bb754d24 GIT binary patch literal 17886 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 vSOdPG=Ouk9;>Uvj^E)M9znZC;^!xt len(self.best):\n", + " self.best = self.left + list(self.right)\n", + " if N - self.Nshown > 1000 or N > 16000:\n", + " self.Nshown = N\n", + " print(self.report())\n", + " \n", + " def report(self):\n", + " N = len(self.best)\n", + " nwords = N + sum(self.dict[p].count(' ') for p in self.best)\n", + " nletters = sum(len(p) for p in self.best)\n", + " return ('Pal: {:6,d} phrases, {:6,d} words, {:6,d} letters ({:,d} steps, {} seconds)'\n", + " .format(N, nwords, nletters, self.i+1, round(time.time() - self.t0)))\n", + " \n", + " def applicable_actions(self):\n", + " L, R, D = self.L, self.R, self.dict\n", + " actions = []\n", + " def score(A): return D.prefixes[L+A] * D.suffixes[A+R]\n", + " if self.is_allowed(L):\n", + " actions.append(',')\n", + " if self.is_allowed(R):\n", + " actions.append(';')\n", + " for A in sorted(alphabet, key=score):\n", + " if score(A) > 0:\n", + " actions.append(A) \n", + " return actions\n", + " \n", + " def is_allowed(self, phrase): return phrase in self.dict and phrase not in self.set\n", + " \n", + " def is_palindrome(self): \n", + " \"Is this a palindrome? (Does any extra .L or .R match the other side?)\"\n", + " return ((self.L == '' and self.left[-1].endswith(self.R)) or \n", + " (self.R == '' and self.right[0].startswith(self.L)))\n", + "\n", + "alphabet = 'abcdefghijklmnopqrstuvwxyz'\n", + "cat = ''.join\n", + "UndoCommand = str\n", + "DoCommand = list\n", + " \n", + "def test2():\n", + " p1 = Panama()\n", + " assert p1.is_palindrome()\n", + " assert str(p1) == 'a man, a plan, a canal, Panama'\n", + " p2 = Panama(['aman','aplan'], 'acadd','dd', ['acanal', 'panama'])\n", + " assert not p2.is_palindrome()\n", + " p3 = Panama(['maya'], '', '', ['ayam'])\n", + " assert p3.is_palindrome()\n", + " assert str(p3) == 'Maya, a yam'\n", + " return 'ok'\n", + "\n", + "test2()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The main point of the `Panama` class is to allow the `.search()` method to search for a long palindrome. The [overall strategy](http://norvig.com/pal-alg.html#v3) is explained elsewhere. The search\n", + "adds a lett1er at a time to both left and right side, backtracking when necessary. The state of the search is represented by the four fields `.left, .L, .R, .right`, for example:\n", + " \n", + " A man, a plan, a cam, a yak, a yam, a canal, Panama\n", + " \n", + "gets encoded into the four fields like this:\n", + " \n", + " .left: ['aman', 'aplan', 'acam', 'ayak']\n", + " .L: ''\n", + " .R: 'k'\n", + " .right: ['ayam', 'acanal', 'panama']\n", + " \n", + "We always maintain the invariant:\n", + "\n", + " cat(left + [L]) == cat([R] + right)[::-1]\n", + " \n", + "The `search` method would be more straightforward if we could write it is a recursive function. But Python does not perform well when recursing to 100 thousand levels deep. So instead I manually manage a *stack* of *commands* that tell the search what to do and to undo. A command can be a `DoCommand`, which consists of a list of letters describing all the possible actions we could take at this point. Actions include letters that could be added (only the letters that make a legitimate prefix of a known phrase in `.L` and a legitimate suffix of a known phrase in `.R`). Actions can also include the character `','`, which is used to dignal that `.L` is a complete word and should be moved ontot he `.left` list, or `';'` to signal the same for `.R/.right`. A command can also be a `UndoCommand`, which consists of a single character; one that was previously chosen to be done. So the list of characters in a `DoCommand` constitutes a choice point; we first choose one, and continue deeper from there, but we put on the command stack an `UndoCommand` to reverse the effects of the action, and put back the remaining characters to try instead, if the first character doesn't work out. Note that we pop characters off the end of a `DoCommand`, so the last character is the first one tried.\n", + "\n", + "Let's see how it works:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pal: 1,001 phrases, 1,395 words, 6,246 letters (30,023 steps, 1 seconds)\n", + "Pal: 2,003 phrases, 2,802 words, 12,375 letters (112,614 steps, 3 seconds)\n", + "CPU times: user 5.61 s, sys: 17.4 ms, total: 5.63 s\n", + "Wall time: 5.65 s\n" + ] + } + ], + "source": [ + "p = Panama()\n", + "%time p.search(200000)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Pal: 2,791 phrases, 3,876 words, 17,101 letters (200,000 steps, 4 seconds)'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p.report()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That seemed to go ok; let's try a longer search (100 million steps):" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pal: 1,001 phrases, 1,395 words, 6,246 letters (30,023 steps, 1 seconds)\n", + "Pal: 2,003 phrases, 2,802 words, 12,375 letters (112,614 steps, 2 seconds)\n", + "Pal: 3,004 phrases, 4,162 words, 18,341 letters (227,472 steps, 5 seconds)\n", + "Pal: 4,005 phrases, 5,507 words, 24,199 letters (386,226 steps, 8 seconds)\n", + "Pal: 5,019 phrases, 6,890 words, 30,137 letters (619,790 steps, 12 seconds)\n", + "Pal: 6,021 phrases, 8,235 words, 35,931 letters (877,024 steps, 17 seconds)\n", + "Pal: 7,023 phrases, 9,568 words, 41,593 letters (1,183,926 steps, 23 seconds)\n", + "Pal: 8,024 phrases, 10,878 words, 47,259 letters (1,561,761 steps, 30 seconds)\n", + "Pal: 9,026 phrases, 12,183 words, 52,965 letters (1,947,540 steps, 38 seconds)\n", + "Pal: 10,028 phrases, 13,467 words, 58,583 letters (2,480,848 steps, 48 seconds)\n", + "Pal: 11,029 phrases, 14,730 words, 64,117 letters (3,206,870 steps, 61 seconds)\n", + "Pal: 12,030 phrases, 16,018 words, 69,588 letters (4,044,269 steps, 77 seconds)\n", + "Pal: 13,031 phrases, 17,293 words, 74,967 letters (5,272,674 steps, 99 seconds)\n", + "Pal: 14,033 phrases, 18,519 words, 80,203 letters (7,091,166 steps, 133 seconds)\n", + "Pal: 15,034 phrases, 19,753 words, 85,307 letters (10,753,057 steps, 201 seconds)\n", + "Pal: 16,003 phrases, 20,886 words, 90,015 letters (27,084,693 steps, 506 seconds)\n", + "Pal: 16,004 phrases, 20,886 words, 90,015 letters (27,149,605 steps, 508 seconds)\n", + "Pal: 16,005 phrases, 20,890 words, 90,017 letters (27,316,698 steps, 511 seconds)\n", + "Pal: 16,009 phrases, 20,896 words, 90,039 letters (27,350,925 steps, 511 seconds)\n", + "Pal: 16,010 phrases, 20,896 words, 90,039 letters (27,412,633 steps, 513 seconds)\n", + "Pal: 16,011 phrases, 20,897 words, 90,045 letters (27,427,058 steps, 513 seconds)\n", + "Pal: 16,013 phrases, 20,898 words, 90,049 letters (27,567,249 steps, 516 seconds)\n", + "Pal: 16,014 phrases, 20,898 words, 90,046 letters (27,592,882 steps, 516 seconds)\n", + "Pal: 16,016 phrases, 20,900 words, 90,055 letters (27,595,464 steps, 516 seconds)\n", + "Pal: 16,019 phrases, 20,903 words, 90,070 letters (27,616,478 steps, 517 seconds)\n", + "Pal: 16,020 phrases, 20,904 words, 90,073 letters (27,670,352 steps, 518 seconds)\n", + "Pal: 16,022 phrases, 20,908 words, 90,081 letters (27,690,556 steps, 518 seconds)\n", + "Pal: 16,024 phrases, 20,908 words, 90,096 letters (27,750,047 steps, 519 seconds)\n", + "Pal: 16,025 phrases, 20,911 words, 90,097 letters (27,902,094 steps, 522 seconds)\n", + "Pal: 16,028 phrases, 20,916 words, 90,113 letters (27,913,484 steps, 523 seconds)\n", + "Pal: 16,029 phrases, 20,916 words, 90,119 letters (28,000,410 steps, 524 seconds)\n", + "Pal: 16,030 phrases, 20,916 words, 90,115 letters (28,199,063 steps, 528 seconds)\n", + "Pal: 16,033 phrases, 20,920 words, 90,131 letters (28,207,363 steps, 528 seconds)\n", + "Pal: 16,035 phrases, 20,924 words, 90,143 letters (28,222,377 steps, 529 seconds)\n", + "Pal: 16,036 phrases, 20,924 words, 90,145 letters (28,245,911 steps, 529 seconds)\n", + "Pal: 16,038 phrases, 20,928 words, 90,155 letters (28,319,574 steps, 530 seconds)\n", + "Pal: 16,039 phrases, 20,927 words, 90,165 letters (28,357,649 steps, 531 seconds)\n", + "Pal: 16,044 phrases, 20,933 words, 90,179 letters (28,398,480 steps, 532 seconds)\n", + "Pal: 16,045 phrases, 20,936 words, 90,187 letters (28,669,877 steps, 537 seconds)\n", + "Pal: 16,046 phrases, 20,936 words, 90,193 letters (28,756,803 steps, 538 seconds)\n", + "Pal: 16,047 phrases, 20,937 words, 90,195 letters (28,951,247 steps, 542 seconds)\n", + "Pal: 16,048 phrases, 20,937 words, 90,195 letters (29,168,799 steps, 546 seconds)\n", + "Pal: 16,049 phrases, 20,939 words, 90,197 letters (29,304,707 steps, 548 seconds)\n", + "Pal: 16,050 phrases, 20,940 words, 90,200 letters (29,402,659 steps, 550 seconds)\n", + "Pal: 16,055 phrases, 20,946 words, 90,223 letters (29,483,409 steps, 552 seconds)\n", + "Pal: 16,060 phrases, 20,951 words, 90,241 letters (29,703,353 steps, 556 seconds)\n", + "Pal: 16,062 phrases, 20,951 words, 90,257 letters (29,935,767 steps, 560 seconds)\n", + "Pal: 16,065 phrases, 20,957 words, 90,261 letters (30,401,372 steps, 568 seconds)\n", + "Pal: 16,066 phrases, 20,957 words, 90,267 letters (30,488,256 steps, 570 seconds)\n", + "Pal: 16,067 phrases, 20,961 words, 90,271 letters (30,742,860 steps, 575 seconds)\n", + "Pal: 16,068 phrases, 20,961 words, 90,277 letters (30,829,744 steps, 576 seconds)\n", + "Pal: 16,069 phrases, 20,965 words, 90,279 letters (31,091,412 steps, 581 seconds)\n", + "Pal: 16,070 phrases, 20,965 words, 90,285 letters (31,178,296 steps, 583 seconds)\n", + "Pal: 16,071 phrases, 20,969 words, 90,287 letters (31,452,702 steps, 588 seconds)\n", + "Pal: 16,072 phrases, 20,969 words, 90,293 letters (31,539,586 steps, 589 seconds)\n", + "Pal: 16,075 phrases, 20,973 words, 90,299 letters (31,899,517 steps, 597 seconds)\n", + "Pal: 16,077 phrases, 20,975 words, 90,305 letters (32,079,651 steps, 600 seconds)\n", + "Pal: 16,079 phrases, 20,978 words, 90,317 letters (32,418,194 steps, 606 seconds)\n", + "Pal: 16,080 phrases, 20,977 words, 90,327 letters (32,456,269 steps, 607 seconds)\n", + "Pal: 16,085 phrases, 20,983 words, 90,341 letters (32,497,076 steps, 608 seconds)\n", + "Pal: 16,087 phrases, 20,985 words, 90,351 letters (32,651,838 steps, 611 seconds)\n", + "Pal: 16,090 phrases, 20,986 words, 90,365 letters (32,782,954 steps, 613 seconds)\n", + "Pal: 16,091 phrases, 20,988 words, 90,363 letters (33,528,985 steps, 627 seconds)\n", + "Pal: 16,093 phrases, 20,992 words, 90,375 letters (33,696,891 steps, 630 seconds)\n", + "Pal: 16,094 phrases, 20,992 words, 90,381 letters (33,783,775 steps, 631 seconds)\n", + "Pal: 16,095 phrases, 20,992 words, 90,379 letters (34,151,848 steps, 638 seconds)\n", + "Pal: 16,096 phrases, 20,995 words, 90,389 letters (34,283,539 steps, 640 seconds)\n", + "Pal: 16,098 phrases, 20,996 words, 90,397 letters (34,342,030 steps, 642 seconds)\n", + "Pal: 16,099 phrases, 20,998 words, 90,397 letters (34,699,703 steps, 648 seconds)\n", + "Pal: 16,100 phrases, 21,001 words, 90,405 letters (36,050,560 steps, 673 seconds)\n", + "Pal: 16,102 phrases, 21,002 words, 90,413 letters (36,109,051 steps, 674 seconds)\n", + "Pal: 16,103 phrases, 21,004 words, 90,413 letters (36,466,496 steps, 680 seconds)\n", + "Pal: 16,105 phrases, 21,005 words, 90,411 letters (37,036,344 steps, 691 seconds)\n", + "Pal: 16,106 phrases, 21,004 words, 90,423 letters (76,003,720 steps, 1522 seconds)\n", + "Pal: 16,107 phrases, 21,006 words, 90,423 letters (76,361,384 steps, 1530 seconds)\n", + "Pal: 16,108 phrases, 21,009 words, 90,431 letters (77,712,187 steps, 1559 seconds)\n", + "Pal: 16,110 phrases, 21,010 words, 90,439 letters (77,770,678 steps, 1560 seconds)\n", + "Pal: 16,111 phrases, 21,012 words, 90,439 letters (78,128,114 steps, 1568 seconds)\n", + "CPU times: user 33min 11s, sys: 13 s, total: 33min 24s\n", + "Wall time: 33min 38s\n" + ] + } + ], + "source": [ + "p = Panama()\n", + "%time p.search(10**8)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"a man, a plan, a caretaker, a moksha, Lufkin, a jacinth, Gile, Daniell, Ivanov, an odor, a negativeness, a tsarevna, melanomas, an ire, Gib, Olga, Lata Narayanan, a meld, an elecampane, an evonymus, an anatase, Rachael, an anabasis, an anaesthetics, an anamniote, an ani, DRE, Fredra, Cal, Parette, Serang, Isaacs, a ramark, IHD, a nonacademic, an obstet, Sellers, Sanalda, Erbe, Eba, an ane, Zaneski, Red, Erfurt, Sinai, Sale, Gene Roddenberry, a nonactive, Cenaean, Namangan, a mell, Everes, a nonanimal, a sanitarian, a non-American, Gat, Noman, an arista, Lattimer, a nonemendation, Eberta, Poe, LCT, an anaerobe, Ranita, Marella, an antired, ipsissima verba, a nan, a manille, Tiv, a nonet, an one, Kenney, a caret, Alon, Omar Epps, an analemma, an enami, Barents, Regen, A. H. Taub, a self, Farant, Caresse, RdAc, a nil, a nonrevocation, a melanite, Ranite, Canarese, NEbE, an allanite, Caressa, an all, IJssel, DNA, Carolee Carmello, Sara, Pareto, Oran, a mel, Dissenter, Cesare, Tema, an alt, Evslin, an alienist, anabases, a torpedoman, a meta, Garett, a csk, Cabaeus, an aloneness, Emelita, an alerion, Eleni, a cong, Ilan Adler, a keratoderma, an alg, Roe, generalities, a nonrateability, a hellebore, an anatta, Ranitta, petits, a baresark, unities, an iman, a non-Indian, a non-Israelite, Delano, Ita, Ranit, Ame, a hanaper, Tanah, an alarum, an alpha, Lacedaemonian, a tab, Cenac, an alette, Levona, an airbrasive, Lody, Nnadia Chan, a naira, an airstream, Macedon, an anatexis, an aileron, a nail, arts, UART, San, a nong, a morceau, dice, Delavan, a mete, Parent, Artemas, Esau, an ora, Hsingan, Amero, FAD, Naman, Amery, Bareilly, Hwang, Inanna, an aider, Acre, Vona, an ait, an aisle, a decare, billies, Banares, ARE, Nanakuli, codette, Lemon, a nonmember, a jaconet, an aigrette, Sang, Tanagra, Genet, a portal, an ore, Pip, a non-Uralian, Bohaty, a parent, Sikang, Amorette, Locrian, Cameron, Anna, Carole, Delaware, Temenus, an iterativeness, Enos, an aim, a danaite, Ahrens, Enarete, Mona, Marelda, an ataractic, a noise, lanais, anatexes, a noisette, Long, APS, Enalus, Omari, a natl, Usanis, an attestator, Gean, an oiliness, an oilskin, Numanus, Ari, Hellene, RCAF, a caresser, Pare, Tem, a torsel, a nat, a kokanee, LaSorella, Gipsies, Irby, an aperient, Mareld, an enallage, a decalcomania, an argali, an arbalester, an imagnableness, an arith, a nonsensitiveness, Anam, Kramer, a caress, a parens, Asel, Ujiji, Emelina, PMA, Carena, ELAS, an it's, Estella, Marela, Edana, Melba, Tsana, Mel, Bonar, a nidana, Meri, Fareham, an arum, a receivable, Gene Geter, a grammarian, Alanah, Ana, Hsian, a lenity, an aug, an oil, a decane, an arrest, Ibanez, an acosmist, an absorptance, a noisemaker, a metall, a gasser, an acuteness, Ender, an ossa, Maria, Teria, an acetal, a manilla, Marie, Benilda, Erb, a no-side, an amah, Drava, Lat, Ragan, Amer, O'Fallon, an amasser, Tai, Tini, Nanak, a nine, Leninabad, an enargite, Gilles, a benignancy, Lanam, an ami, Vanessa, LCI, Kikelia, Delamare, Terr, Efahan, a visitor, a nies, a nit, OFris, an amenorrhea, Laramie, Lipsey, an augend, Averell, a carelessness, oogoninia, Lad, a nose, Majel Barrett, an amen, AHSA, Lari, Oka, Hsi, Namara, an enate, Caren, a career, Gena, Jenna von Oy, a material, Lebanon, an abaca, an abalone, an abaser, a nebris, a benison, Aug, an osnaburg, a nosh, Tim, Selle, Baram, an aba, Hellen, a decal, a paretta, Marelya, Teri Polo, a predicate, leva, Warenne, R. Bayer, Fred Astaire, an abr, Unit, a legatee, RFA, Nananne, Kenner, Rawley, a greensand, Ronald, Barea, Benildas, an abb, inamoratas, an abuser, an illegalisation, a mess, a heller, a decapitation, a hello, Helles, Ignatia, Hsia-men, a hcl, a north, Gilda, Edan, a mesa, Barotse, Hts, an ill, a green, OPA, Ewan, a menu, Bret, epithalami, an adder, a nos, an ordainer, an adagio, Marion, a menses, a tsi, Perelman, a taker-in, Ume, Arp, an ord, a ceder, ACS, an oracy, Aneto, O'Kelley, Na-Dene, Lassell, a caramel, a derisiveness, a cudgel, an orang, Farewell, a beek, Sella, Geneva, Dela, Derian, a men, Arcadian, a meg, Rabassa, an adenoma, Gareth, Gilbart, Sandy, a hell, a mix, Elam, a danewort, an emanation, Matsys, a gala, Mario, Marilyn, a tob, an origan, a media, Sello, Cinerama, an asonia, Rania, Redeemer, an oddness, endia, Tsan, a medullation, a colin, a mee, RFD, a raft, a tsarina, Venita, an aulos, a ferret, Edna, Rgen, Alena, Idelle, Baras, an isotach, an oceanography, an orinasal, a bander, a jar, Tepic, a carabin, ANG, a mannan, A Mei, paralipses, ATC, Enola, a goner, a caracal, a spur-rowel, an agron, an oribi, an adenine, Lger, a wet, Agana, an agromania, Lehet, an oca, EdB, USAR, an ell, a veritas, an orca, Marena, Elgan, a morale, a m/s, inamoratos, a rasse, Irene, Csel, a dep, Ohara, a ballade, Paramatman, an agr, Efren, a ramie, Wenona, tubas, an ipm, a caravaner, a decanter, a nitrogen, a morn, Onalaska, a sinapine, LAC, Sellma, Lamas, an agar, Ihab, a rani, Artamas, an aga, Nana Visitor, an agnate, Lev, Lavater, Alli, paramos, a namaste, Lanae, a paretic, an orc, an anagrammatist, Ostap, an acariasis, an enemy, Carey, a let, Al Pacino, Tananarive, Lanark, an amateur, Carew, Arde, Ranie, Torp, Ate, Maren, archenia, Lai, H.P. Korver, an apse, an apery, an anarch, an octameter, Axa, Nanook, Coralie, nonolfactories, Sinatra, parastades, Behan, a mower, Italian, Sans, an orbitale, an evener, a seller, a manatee, Lana Turner, a kerogen, a leat, a monal, Emeline, an eta, Carolle, a nap, POB, Ivar, an aesc, a nip, Opalina, Braca, an aedes, a nim, a sedateness, a metal, a paregoric, a tsardom, a reserve, Freda, Elsi, Maretta, MSAE, an eremite, CAP, Sanfo, Lenin, an enema, a nae, linemen, Arch, an omnivore, Moran, a mowrah, Carola, Janetta, barotraumata, a navelwort, a nave, Tseng, a pareira, Vane, Marat Safin, a nene, Laveran, an orb, a ferule, Carol, an enol, a mane, Jenna, Iranian, an orfe, an aviator, a navarin, a raught, ansae, a negater, a nav, a heliotaxis, a nork, an ortolan, a mow, Seko, PSAT, Angara, a sell, a carapace, Sarette, Ste, Janette, LSS, an amora, laminae, an edema, Rakel, a deg, a predepletion, Rekha, Lala, Heller, Radnor, Ace, Ilse, Lenore, cicale, a metamale, a grisette, Sumerologist, a hgt, a nyala, Arcadia, Mae, Saretta, Harelda, Syr, rabatos, a vanadinite, Cam, Rep, Sarena, Eden, alae, Saree, Tenn, Osanna, Melete, an immune, Dou, Daniel Chan, a kleagle, an afar, an ugsomeness, a cud, Rego, Renita, Lapeer, an azan, a motto, an ayah, a metamer, paras, a carapa, Lamarre, Tanaka, Anaheim, an akala, Arg, Nasser, an ennobler, a notelet, a corban, a mot, a note, Lek, Sarah, Adna, Kenna, IRO, Lenora, Anaxo, Renie, Saragat, a carer, Ansar, Anu, Calan, a mol, Kenny, Lam, Meredi, a ranee, Lavery, Trammel, Asur, E.J. McShane, entea, Hare, Tell, Ibadan, an axe, Renata, Maril, a notable, a gab, a notary, an ektene, Sra, Sara Gilbert, Saipan, a mog, Ardath, Gilli, a tanager, an aortoclasia, an ajiva, an interfacing, an anapaest, Airel, an imagist, a consecrater, Alcaeus, Sinan, a monosyllabism, a rem, Meredith, Savannah, an immortal, a kerosene, MEA, Lattie, Cedarhurst, a hwan, a mara, Tak, Nev, mks units, Uru, Alan-a-dale, a gib, an ottar, an otto, Caro, Tara, Pesaro, Taro, Ball, O'Casey, a helio, Terena, Ebert, Sada, carabaos, a motor, a craniol, an anabasine, a carangid, a no-trumper, a novelese, an ironside, Elata, a metamere, Hsia, Lananna, hsien, Nor, epitra, Maris, Omarr, an ennead, an irenics, a predestitution, a cayman, tupelos, an iris-in, an irregular, an acetate, CAB, USA, an illamon, a cir, Emarie, Harod, an illative, lenos, an ovarium, Anil Kamath, an odium, an anabas, an engager, a weka, Baron, a maniac, an ileus, Sita, a nitramine, Cinelli, Kenn, a susso, an anadem, a nitrate, Let, ALP, an ova, Delisle, a greeter, a wae, Sarad, a nitre, Blane, Marra, Yetac, an italic, Artema, RFC, a net, Norford, a gov, an ovisac, an ital, Paraebius, Anita Mui, Lisa, Venite, Menard, a bene, Lanett, a pareu, a b/l, Freddi, Bred, Nun, a nov, Elena, Anita, Carolynne, Paharis, an octan, Rebeca, Rohn, a marseille, Brogle, a sanies, a car, aparejos, Aires, a ranula, Baroda, a niton, a mar, Ray Allen, a nitromannitol, an isotac, Edette, Lossa, Caravette, Lorene, Tihwa, anis, a moton, Asia, Paran, IHS, an ideal, a spp, Univ, Alfadir, a canaster, Eben, Alano, Italy, Niv, an oleate, an ide, Maregos, a noli-me-tangere, an iter, an idealiser, a bra, Benil, a sanidine, Benita, Lagasse, Nela, Maressa, Leno, T-stop, an olla, Freddy, Renate, an ips, an ignoramus, a tahsil, an acaridan, an omission, Illinoisan, an omicron, a legend, Air, an omen, Marina, Ieda, Lassa, Kenison, Eda, Nanete, a b/s, Ojai, Sarah Smith, Sarazen, a maid, Ninos, a mali, Mariken, Aloysia, Lacedaemon, a nome, a danio, Laney, an ivy, an user, a wassail, Lagash, Tol, CerE, Carolina, Nanna, Merta, Labannah, an omni, Art, Serpasil, a sri, Sell, a helipad, Arafat, a cuda, an ibex, a selectness, a nanako, Lomasi, a nib, a selamlik, a nomad, Ania, Lenox, a selah, an ihp, an ionomer, a wren, Nidaros, a vavasory, AKC, Uball, a caracara, a gems, an adermin, Amal, Caralie, Lanier, an ipr, a helix, Enone, Ugarit, Sarawak, an okay, an engr, Evert, Sass, Enid, a rage, maremme, an izard, a metacarpus, a noma, Leta, an ikan, Amata, Nanni, a trammie, Hort, Selimah, an oyelet, an odd, a barege, a nix, Elatia, Barocius, a yellow, Zenia, Colo, Helle, baronies, a carabid, Asante, Petite, Mimas, a nomarch, Nunes, a helotage, Lorena, Ewart, Serapis, an ode, Motu, an odyl, a carat, AFL, osar, Annamarie, Repeal, Lemal, an iff, Ursula, Selima, Caras, Aimee, Laroy, a dill, a helotry, Maridel, Ade, Vullo, Roca, Aniweta, robalos, a niyama, a mania, Rolanda, wares, a rfb, a rod, a noddle, Ifni, a ninetieth, Gilba, an elemi, an akela, Labors, Selig, Rani, Argo, Likasi, an adsorbate, Lamar, a nametape, an adsorbent, ACP, Italia, Terah, an imager, an anoia, Portage, Baroja, Mareah, Selia, Helli, an acarine, Ohare, an elem, a nod, a lava-lava, Zenobia, Loki, Nellie, SRO, Nanny, Leo, Jenni, Rocker, a greet, Elum, an oos, Sabaean, a helping, Ankara, a manifesto, Mari, a decan, a carafe, a lunacy, a dil, Lohse, Irena, Edessa, CSA, Ranee, Labanna, Meir, an elastin, a decade, Kip, Saros, AEF, Simah, an ideate, Selie, Nellir, Gareri, a peracid, a cranesbill, Abe, Sabatini, Nanji, Rena Komine, Maro, Faro, Tarra, Barak, a decating, a groma, labra, Kenaz, an eliminator, a secretin, an elegit, Serpens, Ian Robison, Amadas, a numen, a nemo, Lifar, an akene, Lesser, a stob, an emirate, Petit, Arany, a greed, a nematocyst, a paramo, Lapsey, a metage, Ledah, an ibid, a senility, BSE, RPO, a carucate, a gree, Tsai, Anna Bruss, Endo, Ogata, Ai Kato, Pedasus, a carder, Angarsk, Ase, Kimmie, Hellas, Salesian, Rabat, a morel, CSE, a lune, a predrawer, AWL, Ema, Nena, an eme, Jenner, Utahan, an emerald, a noon, Udelle, Barimah, an amatol, a basanite, Lemass, Ens, Selda, Oralla, Brett, Ubangi, Sedan, a madrepore, a luce, Fredie, Natalie Maines, Ajaccio, an orphan, Nahshon, a neral, an era, a nitrometer, a noodlehead, Agra, Sapporo, a camellia, Calen, Alo, BSA, Natalee, a lute, Seleucid, Emalee, Harald, an oogamy, an oomiak, an erector, a sea, Cartesian, Alroy, a dir, Fredi, Stu, Ona, an eristic, Ife, Daniele, begats, a nereis, a benne, Ill, AgE, Laver, a secret, a loo, Zaneta, an extent, Ramanujan, a tiptop, a caravan, an o-o, Ramadan, a card, Nassir, a pail, a tannage, an ess, a metabolism, a day, Elna, Tsushima, an estrade, a luge, Teri, an obsidian, Atsuko Okamoto, a cacanapa, Janeta, parodoi, Lehar, a sap, Nedrah, a laniard, an epit, a noddy, OLLA, Laband, YPSCE, Selah, Cimarosa, an earflap, an evader, a wardenry, Tsuda, Renault, a carte, Medell, Ave, RCS, an ugali, Arbela, Daniel, a jaw, Kenedy, Adi, Lohner, Aaron, Aella, Ark, an obs, Ilsedore, Morra, SECAM, a roe, Garey, Aleda, an evasion, Udella, Bac, Tarr, EST, nomas, a mob, a noble, Hell, a volatileness, Eiger, a hanap, a tamarao, Sim, Italianist, Uwton, a jaculator, an obb, Irakis, an eve, Tsuga, Biro, talli, Cavanagh, a yell, Averill, an octal, an oba, Geneina, Mede, Barram, an even, a lunate, Biton, Isaiah, Selry, Martin Amis, an obelus, PAC, a nob, a jailer, a kero, Macy, saris, Sac, Etam, Aranha, BGE, Isai, Sandra Reemer, Ahwaz, Angie, a lugsail, an edacity, Lom, salpas, Anderegg, an anorak, an editor, an opa, Carian, CMTC, a res, Seta, an ethanol, Iwo, a cipolin, a decile, Danie, tsuba, Tania, R. Carnap, an anomia, Selma, delis, a benny, Lenna, Irbil, a magnetron, a masseter, Ucalegon, an opp, interacra, a negatron, Sarid, a gassit, Rucker, a jailbird, an oxidant, a predonor, a belle, a baronetage, Rosene, Mixteco, VanAtta, RPQ, Arissa, Lanie, Tulare, Tepper, Tsui, Lenno, BAS, a cart, Apo, Elche, Paros, Serge, Raney, an oxen, an ogam, Argall, a bacteriolytic, an eelworm, a rgen, Alyda, Lab, a carotid, Artair, a neb, Ito, Martin', Kenya Moore, Delia, Genia, Codi, Lanital, an eel, a kerbaya, Latakia, Paris, Benito, Resa, a needle, a ben, an inalienableness, Egeria, Lihue, Alberti, Maria Laria, LCM, a rollaway, an ivory, Tanis, a sanbenito, Lenny, Rockel, a manit, a loe, Nelli, an etaerio, Mariah Carey, Alanna, Mahan, a tiger, a lac, Sarilda, Erastes, Sari, Apers, Idalia, Ted, an ogre, Rapallo, Ranna, MAA, Nella, Kenya, Merth, an ike, H-steel, Farah, Cananea, Carte, Peti, a warden, Nessie, Wenn, ASU, a lenis, a motet, an estragon, a siper, a llano, Issi, Meraree, Nonna, Caria, LBP, ANTA, Carin, Riksm', a roselle, Parik, a bray, Idell, Enya, Renaud, a neisseria, FFA, an ebonite, Rann, a mem, Ilsa, a help, a tsade, ABM, a sena, Bacau, a nodus, Areta, Mariam, Aney, Harappa, Natal, Liberal, Cartist, a recast, Alfreda, Elatus, Peh, Stahl, a nodule, Rosena, Morell, enigmas, Saharan, YCL, an aced, Odalys Garcia, Letsou, Kenmore, Monotremata, a nef, Ursuline, a lug, Nunu, Arber, Albania, Truc, an ogee, a lur, O'Malley, Ivette, Lahey, an anomite, a lube, Nelly, bissellia, Terrel, Peter Gacs, a robalo, Sapir, an eng, a salary, Terai, Cedar, Asare, Teide, a lub, IFS, a nylghai, a depressor, Parrott, a remainder, a jail, a reb, ILS, anmia, Rattigan, a nogg, a wase, Iraki, a pred, an enroller, Rabah, a nizamate, Lasala, a belly, Peter Clote, Mariolater, Ced, an ogle, an ejido, Lanita, Mehala, a majolica, Lauder, algae, a lulab, Arcady, Olfe, Allix, Amb, Ussuri, an ovalness, Enrika, an oregano, Martine, Gare, Tex, Enyo, Skaw, a seraph, Sarum, an enrollee, a lyre, TPN, a maharani, Ramah, anni, Jenne, Ide, moca, an orfray, a bell, Edam, an ornis, a baronet, Nata, Emalia, Trev, Lisan, a mako, Oza, barracks, a senega, an omer, Cart, a musette, Lian, an off, Ubald, Enugu, an aholt, a manic, Sercq, a rubella, Ebner, radarmen, a tuba, an omasum, a lah, Taney, Odawa, Len, a decimator, a tannate, a ripsaw, a say', Imelda, Ebn, a maestro, Peraea, Lucic, an ohm, a ria, Beniamino, a nomism, ARU, Palla, Mameluke, Ergener, a zany, a deer, Gedaliah, an oast, a rehearser, a leno, TSgt, Canaan, a losel, a dunite, lines, an oak, an o-wave, HCM, Artacia, an olio, a cirri, Barra, Mal, Kra, Marte, Tanner, Benia, Cub, Idalla, Bria, Harar, Egede, an oleaster, a batata, Ems, Redd, an anole, Marino, episedia, Ria, Teheran, Saruk, an obeah, CNO, Carie, Damali, a recitativo, Jenny, wellies, Ramses, a bat, a carol, Averi, Alla, GeV, Rehm, arcae, a rise, Delle, Basilio, Fri, an anoa, Cyler, Alf, an owner, Rad, Sem, a jai, sacra, a ha-Nasi, Trapani, Argades, Benis, a mater, a mutase, Ardys, Pel, Carib, Otaru, a sol, a gem, a now, Reddin, Assassin, a ratter, Aba, Cariocan, a milksop, an otalgia, Rct, a ramekin, an oik, an oiler, Rab, Fla, Hara, an oka, a hetaira, Vano, Isacco, NATSOPA, a nooser, a decibar, Asa, Kamerun, a manipulator, an ameer, Farand, Oberon, Aesir, a barony, a gregale, Arsippe, an ozonide, an oyer, Ambert, Sula, an okapi, HSM, a min, a named, Lahaina, Morelos, a name, Locris, Napaeae, an amowt, a barong, Isaac, an omelet, Sarre, a heth, CIF, an uta, an ultra, Had, Nilsson, a milo, Sera, Cid, Emelia, Ken, a baron, Elenore, an aniline, Dell, Edora, Madaras, Savanna, Hagen, a beretta, Marin, Nebr, Asti, RMA, an upas, a motel, Adm, ijmaa, a nude, Ardy, Helice, Cari, Ali, Heli, HCF, a radar, a spall, Ocala, a tsunami, a sedan, a cranage, Marty, Lenaea, Luci, PSS, a moil, Genie, Serov, Eddy, Ollen, a por, Parry, Tera, MDO, Orban, a mild, Ogallala, Lau, Odell, Edy, Seroka, a numskull, an aketon, Card, Nahshu, LBJ, a nudnik, a nubecula, Lapp, Estelle, Parr, an anise, ranli, Karena, Kibei, Latta, a nub, a tinea, Jenn, a sore, Arbe, Nette, L'Avare, Tali, Danilova, lapins, an amok, Ruthann, a heron, Aileen, a parade, Carrel, Tucson, a nunatak, an upset, an episode, Arbil, Annabelle, Bassein, Annamaria, Harrod, annals, a mock-up, a lovelock, a rayah, Andaman, Natie, Mart, Saba, Lanikai, a samara, an amp, Macedonia, Tanny, Lymann, a manikin, a carotin, a jarrah, Caruso, a recitative, Lahore, Mir, parts, Endres, a bed, an amylose, Arges, a crew, Olatha, Barret, an amyloid, a trend, a rad, Ligetti, Faletti, Welles, Orelee, Tsonga, Helban, an amyl, Lod, an amba, cartes, a mop, Ilene, Leiser, a vaticide, Maraj, anni mirabiles, Ufa, Laverne, Garofalo, Anniken, Arcata, Elbart, Sida, Annice, a sup, Merete, Morea, Natiha, Annorah, a rps, Amoy, MOI, Elene, Lehman, Emelun, Nip, an ambo, RDTE, Lords, a matador, annulli, atria, Harunobu, a belah, Cmdr, an octavo, Lani, Arda, Anny, Lenni, Maroney, a synod, Alec, an amir, remedies, a matelot, an animal, Orpah, Angadreme, RCMP, carli, Maros, a metic, Lacagnia, Latton, Eva, Harim, a dal, veniremen, Tupelo, Hero, Barre, HSH, Anya, Renan, Nereid, a senna, Ileane, Galena, Bab, Maroc, antennae, a recall, a ward, Nazar, a hassock, a raylet, a rank, Emelda, Lanni, Lanny, LFO, a tie, Lenee, Pete, a kerb, a saran, Nessim, a tatter, a grammar, a hanuman, a milliard, an amie, lustra, Harts, Banaras, Suharto, Ipsus, a tepal, Angi, Sarge, Raseta, Rape, Sallie, Nod, Erelia, Maritsa, Noma, Lal, a preta, E.H. Moore, Mohamed Mosbah, Antabuse, Jenilee, Barron, Karelian, an amino, Inuit, a namma, Andee, Madelon, a nymph, Barr, a barolo, Carl, Danila, Anyah, Serra, Bart, Nina Amenta, Ertha, Laina, Delos, Revere, Taran, a mire, Caryl, lenes, Lenard, Isabel, Garamas, a nye, Renado, a tress, Alcatraz, Omaha, Dannie, Lorca, Natika, Anh, a decremeter, Gelasias, ANC, a dirtfarmer, a tamara, Matteo, Parl, Gbari, Augeas, Sofer, a psalm, a senor, Tangier, an amtrac, Avo, Donall, a danny, LGk, a ratepayer, a tarata, Ergane, Mannos, a manioc, an amt, an anaemia, a tart, Salli, BEP, INS, an amuck, a repeller, Oleta, Roi, Lemar, ASM, Isadore, Asben, Arctic, Ernesto, Carrew, a taro, Serg, Ian, a carom, alcaides, Amado, a letter, a gramme, Lassie, a tar, Carrie Dobro, Tang, ERP, Minamoto, a samaj, a kerf, a kermes, a carob, a target, an ego, Mohamed, Aidan, a mir, Rebecca, Nath, Gilberte, Milli, Marabel, a tale, Matta, Geno, Tarah, Cassino, Illimani, a tpm, ARCS, a madame, lanugos, a madre, Tarcy So, a tal, a barat, an anima, Jenica, a tail, Icel, a decree, Petal, Parke, Bubalo, Soren, a coly, Marola, Vania, Massine, Delp, a manage, a meteor, Genna, Idel, an acetyl, carri, MeV, a decl, Udell, Eidson, a colitis, Opa-Locka, a pseud, Aletta, LPS, a macaroni, Artesia, Micaela, colascioni, a tremor, Carbo, Cary, Sally, Sall, a barabara, Teruel, Ossetia, Lepsius, Timi, Ruysdael, a sopor, Parhe, Lansberg, Italic, a taille, Wester, Ava, Laresa, Elaine, Jenifer, a fracas, a macro, Tait, Neto, Pan-African, Gigi Fu, Sert, Neckar, a naker, Afra, Wareing, a baraza, a tabla, nates, an airbill, a hero, Mac, Yser, a flew, an airt, Seal, a paravane, MATS, an aide, Marozas, a manner, Kellie, Broca, a taka, Renelle, a taker, a fanon, amlacra, Marou, qasidas, a pretrace, a tempo, Harte, Peta, Rip, an aide-mmoire, Bassett, Elli, a pretorian, Odab, a r-color, a tat, a yard, nattoria, Homans, Marozik, a saw, Aker, a tanna, Murtha, Laks, a heres, Semela, Carya, Tarazi, Saladin, Argyres, a malaria, Peralta, Zama, Lakeview, an anime, a harem, an animator, Ibada, Erdah, a repp, O'Callaghan, non-Muslims, a mitra, a tag, an anim, a gaseity, Ad Rock, a rissole, a tilery, a sense, Medawar, an aiglet, Silas, a miracidium, Rai, Deluc, a manness, a mib, a carrom, a carrus, a naive, USSCt, a tass, a cariama, a tassel, an acetone, carpalia, TBO, Barbe, Helbona, MMetE, Locrus, Salas, Ananias, Uhde, a belay, a tapa, Zeno, Tyra, Barb, Ansonia, Marga, a naif, Fasano, Ilan, Amida, Fred, Arapahos, an anna, Helbonnah, a rah-rah, Caz, a taw, a yelp, Pan-Arab, a belt, Sacrobosco, Damalus, Nina Brosh, a regale, a tannin, an ann, a kiva, Renell, an arteriole, Attu, Genni, Vedette, Luo, genua, Ebsen, a site, a craps, a mudslinger, autota, Serb, a ferula, a tad, a tay, a kola, Lait, a pretor, a gastronome, a herem, an art, a muser, a daren't, Rap, an arena, Mee, Zenas, Orel, an anion, a gasogene, Mayas, a muesli, a two, Carmena, Mehalek, a tav, a feria, LCL, a sop, Sid, an arcanum, a telesis, Ada, Veda, a tela, a tell, Emera, Dli, Kellia, Coralye, Welty, Lenca, Natta, Margit, a telfer, a dec, an aneroid, a lutanist, a kellet, a cor, Bard, Mocha, Laennec, a raster, Ajani, Alta, Carpaccio, a silesia, Mycah, a rath, Pahari, Massinissa, a metropolis, an arcs, an arroyo, Bel, Bat, Salahi, a saker, a gasp, a lealty, Oberg, Elara, Mada, Lvos, Salangi, Sneed, an alp, Senatobia, Rihana, Tezel, a serai, a snob, a narrater, Emmi, Wsan, Amiens, Amy, Auge, Acis, Even, a caribe, Delcina, Salazar, a loma, a tergum, Manno, ILP, a tercet, a red, Omagh, Carhart, Arakawa, Ley, Barye, TSF, Argyrol, a temper, Panini, lames, ACW, Olli, Pani, ATP, a carrot, an arak, Nassi, a negator, taros, Selassie, Genl, Imamite, a cur, Revell, ECU, Lette, Silesia, Marylyn, a tetanic, Irazu, RCP, a camelopard, Carpo, Cassel, Tamarah, a zero, Matt, a manus, a jane, a cardamom, an arbor, a maturer, Apsaras, Suhail, a rodeo, Hattie, Woking, Estell, a sarape, Hart, Cassatt, a rall, a belga, a teel, Fresnel, Faraday, Adara, Faria, Passover, a vil, Genk, Cornelle, a tee, Mlar, a lokacara, Margi, Menado, Owades, Ulla, Carpet, a recap, a carp, an annal, freemen, an arm, Isac, a carn, Emad, a rajas, a manual, a sis, an argal, a sruti, Artaud, Nihi, Ario, Marykay, a papain, Alansen, a metro, Farika, Fari, Alb, Cirenaica, Petty, Farra, Pass, Engel, Garifalia, Salema, Cassilda, Erse, Maje, a dirt, a pueblo, Carn, Omak, Arkie, Sinaloa, Petras, Lederer, Freehold, Orella, Bary, Danaus, a kat, Settera, a teff, a tanh, a carfax, a nuclein, a tef, an aryballus, a tedium, Major, a map, Utah, a darer, a fanegada, Ernest, Ramsey, a carse, a trap, settos, a metre, Benin, a carhop, Seto, Cassil, BAgSc, a kulak, an akee, Lalu, Erek, a trample, Kareem, Reval, Abakan, Amiel, Kelli, arbota, Marys, Saleme, Mary, markkaa, Lagos, Sabatier, Kellen, a gro, NATO, Pasia, Lavena, BSF, Low, a narwhal, a dBa, Heloise, Irvin, a leone, a dipole, Petra Yared, an arvo, Salita, a trawler, RADA, Lao, Karee, Nevada, Ehud, Nuba, a transudate, a din, Carma, Terti, Marko, Nassau, Qatar, a rate, Logi, Raseda, Terpstra, LCD, a remaker, a ked, an allegro, bagnios, Saber, Airy, Marc, Salim, a tremolo, Sylas, Ahlgren, an allopath, Gilford, Naseby, Gari, Algar, Alamanni, Leverett, a paraffin, Ogaden, Ralli, a spot, an al-Lat, a raj, Ugo, a bel, a saros, Secor, Pasiphae, lazarettos, a recon, Ida Lupino, Romanist, Eraste, Nodab, annates, sabalos, a rigatoni, Marks, Iberia, Mark, a carzey, Adall, OHMS, APSA, a treble, a trehalose, a diol, an alidade, a betatron, eila, Nason, a clover, Azalea, Lunn, a cark, a barred, a trope, Adai, Lehrer, Aorangi, Sven, a mesh, Tegea, Lune, Bahai, Satan, a suslik, Serena, Olaf, a nek, an alameda, Cassie, Renee, Keller, Odelet, Serene, PST, a rattener, Emil, a cargo, Gen, a sorb, Mars, FSR, a tryma, LaF, a meller, impis, SOGAT, a rustle, Marv, crania, Mert, a tinning, Ilario, Manolo, Cassirer, EHFA, Argyra, a tiller, Alameda, Clava, Cassi, a beta, Rima, Nast, a garage, Pasay, a sibyl, a denim, a till, a roc, an alarm, Benet, Erasure, Mihe, a mallee, a mall, Ezekiel, a gash, Tomsk, a senhor, Freeport, sacela, Matadi, a myriad, an ala, Daniala, Atila, a tilth, Gila, a tirade, a mela, Massimo, Olen, a sitar, a laser, Aosta, Cuyab, a sacaton, Eug, UHF, a lipase, Irl, a virelay, Ruelle, Wes, Sufu, Rennold, Arno, Cannae, Sorel, a grey, Alps, Idas, a rec, Onida, Lajoie, camerae, Bene, Legree, Salida, Freer, Gera, EKG, a bema, Garrek, a tire, Geri Halliwell, ECA, Nasho, Benni, Welcy, Cage, Manoah, Camellia, Farro, Cassy, Basseterre, IPA, Laredo, Cass, Eng, Nilla, Garrik, Salomo, Smoke, Amaral, Cann, a sushi, a damsel, a tarok, an alpaca, Leakey, a heriot, Civia, Hopeh, Catalan, Reviel, LaMee, Lareine, Dania, Morel, a tanner, Rawdin, a massivity, Oveta, Ragen, a varec, a ratio, Cadal, a sari, atlases, a barit, Sill, an alcayde, Merari, a fanega, Hynes, a canna, Hojo, Alabama, a label, a rabal, OAPC, a sard, Freeborn, Egadi, a mrem, an alkalimeter, Ossa, Marci, Mano, Iraqi, LaRue, a tiro, Manama, an enc, Orpha, Leela, Leaf, a recce, Lett, Ellerey, Alpert, Nec, an algarroba, a tirl, Atrahasis, a tor, Pasto, O'Reilly, a gremial, Casey, a kelleg, Nashe, Dray, a dotage, Petula, Salop, a time-lag, Nitro, Petua, Pelagias, an alga, Rasure, Mohammedan, EAM, an alba, Free, Shama, a titi, Veneti, LeMay, a pele, a mock, a selenide, a mucro, Tamer, Casie, Rask, a liter, Evette, Lucas, a relater, Eve, Lars, Geri, Albert, Neveda, Cranaus, a yelk, Carcas, Arella, a titter, EbS, a remark, Cuban, a myall, a tip, a canoe, an anniv, a tit, Ramsay, Alper, Evemerus, tamaraos, an alfalfa, Nelides, an alfa, Lea, Kimmi, an etalon, a tub, an acceder, Egide, Casi, Ansermet, Salot, an annotator, Telloh, Cindie, Reno, Harp, Endora, Dot, Nee, Leonardi, Setbal, Abba, Casatus, Aretta, Helot, Saida, a tiderip, a tariff, a kelebe, Dnieper, Ops, Aida, a tidemark, a sister, Rabaul, a bani, Kelis, Sima, a tid, an acc, a lamed, an ergate, Soma, Seidule, a mycetoma, a ticker, Edea, Lug, Illene, a kelep, a sales, self-ironies, a darg, a denial, a tic, a tremie, Helga, Ebro, Past, a fane, meinies, Orelia, Marge, llanos, a melodrama, Gniezno, bassi, Manassas, a tiki, Nels, a better, Alcaids, a reset, a reticule, a glade, Reina, Lema, Leucas, Rabin, a lie, Leto, Canicula, Leibniz, a bettor, a gas, Aramaic, Cotterell, Osage, Karoly, a time, Gerome, Kalbli, Asp, Otero, Farr, a tsk, a sinew, a grebe, Wales, a raker, Opal, a timer, an acarus, Nama, Lemnos, APA, Idaea, Llud, Emery, a fere, Moham, a retake, Helgeson, Kwa, Harv, Seiden, Amye, Gobat, a rumen, Akane Kanazawa, Lassus, Ratha, Lela, Lee, Neri, Alg, an attach, a ransom, a serif, a sera, Ohm, Arman, Amy Smart, Rebel, a ratal, Paske, Erbes, a lord, YHA, a tizzy, Bennu, Den, Erinna, Millar, EMU, Nash, Tamaru, a son, a titania, Modoc, an attar, a tonette, Soraya, Wat, a kelek, a tolan, Amur, Teno, BEd, Albanese, Elea, Reo, Marutani, a retaker, Omsk, a rataplan, Erda, NASD, a nanny, Lessing, Absa, Garm, Octave, a glebe, a gal, Petulah, Tarim, Azeria, Seibold, Orem, Adamsun, Amri, an angiocarp, Udela, G. de Leve, Lash, Taber, Olimbos, an att, Argyll, an anuran, a msl, Edrei, Lebanese, Nidia, Hbert, Itasca, a sin, OSA, Jenei, Danita, Salto, Rasht, a malkin, a luffa, Aharon, impalas, a ravel, Arblay, a ferv, a herd, a parol, Lepp, an anus, a native, Leslee, a girth, a razer, Olav, a last-minute, SDA, Warram, Dacey, Alkmaar, Pas, a ratoon, salts, a top, a salep, a melos, Eiffel, a canary, Patras, Names, Alberoni, Sleep, a canella, a tomato, Aoki, Ronnie, Suh, a tog, Ober, Old, Rowan, Amp, MUP, an ataraxia, Pudsey, an agal, an agamete, Magas, a rice, glassmen, Akela, Atoka, Del, a hwyl, a gaffer, an agama, Alas, an agility, Ohio, an ipecac, a token, a kop, Seiber, Odo, Efrem, a rcd, Arlen, OCTU, an ans, Oban, a mtier, a toe, LCF, Atlas, a rut, Lasko, BSME, Gerti, Lilli, Manala, Gert, Rashi, Held, Dara, a tut, Amelita, Lovash, Taos, Ardis, a tun, a denom, a lassie, Reine, Helsie, a giber, Odele, Cordy, Hanan, Nakada, Mayhew, Orcadian, a tumor, allodia, Suk, Ohl, a tot, an age, noddi, a salade, Manawyddan, Amtorg, a betel, Caniff, a waste, PPI, Tenney, a canner, Benn, a pariah, ESRO, Hanafee, Lila, Gassendi, Canada, Eliga, Levania, Marven, Egin, a lunes, Sejm, Arvada, Elayne, Goss, Idaho, Tetu, Arras, Atul, Avaria, Freida, Lady, a dye, Hanni, Lesya, Helse, Weld, Dawn, AMT, an assentor, rags, arrobas, a herb, Massie, LPG, a rasure, Dubrovnik, an acad, Arvy, Gannon, Aramean, Neper, OCD, Rahab, Arnelle, Bal, Lima, Canova, Seif, FET, Sean, Lunetta, Pet, a renege, Danika, Laski, Lefton, Karol, Yates, a herp, Map, a nagor, CST, a rue, Seabee, Lil, a grex, a wash, turtles, Sevan, Ambur, Gerda, Casavant, Sikata, Molli, Papen, a wasp, a canula, Freia, Marve, Nigel, a parrakeet, a kelt, Sarah Polley, Lesh, Warga, SbE, a gotra, Mah, Tedi, SALT, Bass, Ennis, Arm, Oct, a bai, Danava, Lula, a tug, Ras, Arva, Zena, Maida, Imalda, Elery, Tarsus, Aryn, Ice T, a riv, Elah, a ross, a melee, Perimele, a gunsel, a csc, a manuf, an aeronaut, Namtar, Com, Edrea, Gill, EGO, Adams, a treponema, Rema, Canea, Fano, ironies, OHG, a rpt, Abbasid, Alver, Oceanic, Siple, a letup, Erasme, Edroi, Reisman, a sorrel, a harim, Ida, Lvov, an assai, Marva, a tuy, Savaii, Russel, Ruhl, a colat, a maker, Ong, Isador, Maranh, a henna, elevenses, a rasp, an aedeagus, Tamarra, masses, a rcpt, KKt, a manuka, Leveroni, Lenape, Rif, an aet, Nadeen, Irisa, mukade, Mord, Nasya, Dyal, a turaco, Rea, Narew, a ngaio, an elative, a plaster, Ragg, a tabi, Daniyal, a pie, Lrida, a serum, Attenweiler, otters, Beno, braceros, Debarath, Sissel, Yablon, Gapin, Alma, Herod, a gomerel, Canter, Gerdie, denims, a jass, Erde, Raynor, castelli, Welsh, Warfore, Tarkany, Leonard, Nadabas, Alabamian, Natalie, Baranov, Eddie, Neale, a faradiser, Cant, East, Aesop, a canework, a soken, a wartime, a plucker, EGmc, Castra, Dani, Allayne, Elamite, LCVP, Minako Masumizu, a gager, Obe, Koh, Casta, Evey, a canso, Seaford, Nuri, Adim, an ass, a henry, Beng, a terbia, Bruno, Irbid, Algeria, ZANU, a fanion, OLG, an abohm, a haem, adenoids, a labarum, Ikeda, cans, a ye'se, a bet, Ariz, Ivanna, Mli, USSB, an assam, Attila, Attah, a thematic, ulta, Rus, an abo, Rosanna, MHE, Leilah, a tlo, Valaree, Hanno, Hiss, a lama, Denie, Heron, Salba, Nadab, a hallan, Ambie, Leila, Rolan, a hav, an abele, a pupa, Leda, a tchr, Heros, YMHA, Lienhard, Estel, a par, a liker, Obadias, a rim, a serving, a last, Rapp, a beret, Salbu, Patsis, Sabah, a ros, a menial, an ablator, Episc, Keli, Bomarc, sorgos, Satsuma, a tpd, an emagram, an abba, Rayna, tilak, a hen, a jam, a doit, a mgr, Alia, Benue, Jelena, Meyer, Obel, a barih, a navel, a resister, Rajab, a pret, Alsatia, Wallache, POA, Iliad, a menopause, Nada, Emden, AMLS, a lilac, a passe, Nevil, an assagai, Sab, an assorter, Rik, Salk, Dan Aykroyd, a bonehead, aerobia, Buddie, Bonilla, Denney, a merit, Tanaron, Iago, a dene, Lectra, Caetano, Iden, Airliah, Cimah, a hallah, a remake, Bernarr, A. Blass, Erdda, Nadia, Caspar, Tedra, gobos, Sura, Lebna, MEPA, Tamah, a revamp, CanF, a den, Aili, Leid, a retro, Tamaulipas, a loci, Neron, Leslie, Nero, Mag, a salad, narrows, a rev, Lasley, Addi, Manaus, Samalla, Manila, Takeo Kanade, Hazel, a bedel, Gasser, Tia, Wallas, Rett, a tasse, Neu, Gavan, Amhara, Lech, a rotary, Croce, a butter, Balarama, Rimola, Bme, Cash, Tiff, Irgun, a deli, Boma, Lezlie, Callida, Bobseine, Ewen, Ailene, Libau, an ikebana, taws, a locater, Alcaic, a repeal, LeCroy, a many, Lever, Alemanni, Ramsden, an average, Samal, a manway, an aviary, Calliope, Elsass, Erie, Hanny, Seda, Rina Tajima, Rakia, Biddie, DOP, Macareus, an avatar, Patsy, Cod, Incan, a mho, Benu, an assoc, an avenue, Frei, Lebrun, an akebi, gases, Aoede, Mic, Latif, an ahu, Wels, ilia, BBA, a reamer, Ogawa, leis, a delay, Oralia, Rayne, Ewall, a boko, a grade, Kelci, TUC, Anakim, Arela, Vener, Evania, Borel, a verb, Monagan, Samau, Gerd, Nally, tube-eyes, a baryta, Sama, a tret, Alsace, Sawyere, Ben, Aiden, Axe, Hannus, an ake, Patti, a rein, Nobell, Echemus, a lobe, Avonne, MEP, a trellis, an azote, Nome, Aia, Bertila, a renegade, Anax, a fell, Evalyn, a tahr, an emery, Beria, Zelle, Bamako, Oralie, Kelcy, Canossa, Wesermde, a refit, Orabel, Udele, Baraca, a wart, Samul, an assuror, Alcazar, Marja, Vanier, Evanne, Hegel, a kaross, Essa, Nadine, a proc, Sams, Ines, bistros, Llano, Icaria, Danella, Mitran, karos, Sucre, Patt, Argyle, a refer, Oken, a yds, Allenby, Ortegal, a code, Pater, Bataan, a dero, Leiria, Berio, Callie, Neille, a reebok, a head, Ehrsam, a handler, a reheat, a rip, Samia, Hebrew, a salal, a hallower, Oebalus, a lemma, Rozi, Marji, Herisau, an unassuredness, a luff, a warb, a sallow, Ester, grampuses, a bear, a pit, Lumen, aedegi, a pressie, Herra, Vanna, Mab, Alaska, Ewell, Eulalia, Kela, Esten, a merc, an assured, a sepal, a citadel, Sami, a lca, a rebirth, Gilletta, Basilian, a mGal, Fania, Canotas, Alber, Oyama, Riha, Loralee, Ray Romano, Iva, Nadiya, a reward, Nola, Calli, Codel, Akel, Aepyornis, a heat, a lea, CEA, NMU, Locke, Erasmo, Teddi, Vaden, Aornis, Sade, a zebrass, a cameo, Haney, Ogren, Argonne, Tamiko, a felon, IPY, Addams, a race, Nerine, Mode, Prot, a rap, Ivor, a misaim, an azine, Moe, Yetah, an embacle, a kimmer, Paten, a jalopy, advenae, Berar, Cannock, a labroid, a raga, intros, an embusqu, SAmer, Peri, a terce, Samp, Patnode, Erato, PHS, Adama, rhinaria, Jeno, Basilan, a mgt, a prodder, a zeta, Lipson, a ledger, Danete, Dustin, Samy, Gaspinsula, Kamet, Alpena, Rob, an empennage, Eddina, Economy, Tedd, Ube, a jalap, Makell, Emory, Admete, MSME, Aarau, Ganiats, an emulator, Ganny, Wallensis, Adelle, Bambie, BLA, Herr, Ottillia, Macario, Marfa, I-beam, Mame, Carboni, Roma, Nador, Minnie, Bello, Ivett, Ella, patia, Weser, an akhara, an eloper, Utu, Sassari, Ucayali, a rum, a sally, Dinan, a mwalimu, Saseno, Jal, a mateyness, Argos, Segal, a cassaba, a raki, a rakee, Lianna, MHA, Reiche, Jen, Ilesha, Lillie, Daneen, a jadedness, Naji, a roke, Cartan, Ammann, a meson, IFF, a rason, a psec, angia, Lorollas, Savage, Kelt, Subak, a leben, Illyria, Danene, EMet, a mil, canli, Kemi, Latia, Galligan, an octad, an assuager, Uno, Cath, Gil, Sasebo, a katydid, an emu, loli, Karoo, Mania, Wagner, Rabiah, Gnossus, Ainus, Massey, Eleen, Daven, a noontide, Marwin, a maya, Lorolla, Heti, Hwu, a serf, fisheyes, a passage, Mani, Albany, Lehi, Aldas, a dimer, UCCA, Miru, Patin, Losse, Iris, a ladanum, Dorena, Rist, Nady, Orth, Giraldo, Jere, Miss, a caser, Eimmart, Rabia, Kassel, a dell', Ewe, Jerome, Kaleva, Rayle, a mesolite, Irita, Rodez, an eld, Dirac, a muse, Carthal, a garote, Lacee, Limenia, Waller, Rafe, Kimmel, Sumer, Upali, a stirps, an emmenia, Wedgie, Wesa, a heme, Argovie, cargos, Okayama, a razee, Calama, Latoye, Nadda, Leif, Ferro, Callery, a dele, Difflugia, Kas, an emf, Lowery, Ted Baker, Tami, a romaji, a we'd, Lake, Calpe, mohalim, a hemmer, a mid, Alveta, Noe, NADH, Hanus, Mahalie, Neill, a tree, Basil, a del, Livenza, patios, Assamese, Napa, Jno, NADP, Panagia, Herb, Mohawk, Cataebates, Sabec, a pass, Erkan, a rupee, Loja, Loren, Ilke, catalos, Oeflein, a tantara, H-beam, Megan, a rozener, Rettig, an elbow, an elm, a hem, a lash, Cassite, Manya, Denna, Erbil, a mossie, Herc, an ilex, a kCi, Paton, Sayres, oraria, Vani, Alben, Ilmen, Ironside, Evang, a messan, Ivah, a ronde, Ercilla, Coe, Tamma, Haimes, a vario, Nereen, Daveta, Ngo, cates, summae, basisidia, Rayburn, an oocyte, FAS, an esse, nomina, a jakes, a jade, Mlaga, Amedeo, Reiko, a razor, a fanny, Wesla, Vanni, Wrekin, a brush, Cattell, a bass-bar, a hoy, Ikey, a felt, Tara Reid, Rockie, Reimer, Palau, Tiran, an eyesore, Negros, Netaji, Gery, Erevan, AWB, an enfeebler, Rafaelof, a karoo, Manresa, a baseliner, Uella, Hanratty, Peru, Tabu, Catto, Clawson, a jadder, Amie, Weinek, Camelot, Sayer, Alcina, fatsos, Nolan, an eikon, a remex, Offen, a garg, a beata, Eboh, a parasite, Nevsa, Avery, Gallico, Pales, See, Sedlik, Soracco, Romanizer, Eblis, a basis, AOU, a lip, an erron, an upside, Venola, Mallen, AMEDS, Eddi, a gude, Camarata, Tessie, Neiva, Tessi, Lemmy, Callahan, a yam, a retem, a gage, Manus, Tob, Basutos, a dammar, a mod, Nogales, Nabal, a cen, Estes, Sugar, a mogote, Nevai, Saidel, Livesay, a pun, Anetta, Latt, Albee, Luella, Dunne, PNA, Estevan, an uhlan, NAB, Russom, a romaine, a taste, Donata, Noyes, SEbS, a dart, Nessi, Rock, a loper, Uke, Cadena, Ipoh, a pastel, Laban, Aydin, IRS, a rode, Maller, a ticket, Rufe, Cad, an edifier, UAW, a see, Sayed, a robe, Denn, a grommet, Eridu, Massa, Romanov, Ebba, Aretus, an asemia, Resee, Resor, a rober, Cusanus, Llanelli, Mallet, a rogue, Masera, Emmit, Ignacia, Majlis, Nepalese, Idabel, a canzo, Pero, Mammon, Eva Larue, Caernarfon, Amoreta, Gelasius, a dahlia, Maseru, Lisa Loeb, Urania, Wollis, an eddo, Hassi, Rafat, a moss, a dragsaw, Oceania, Freyah, Tessa, Gabaon, a limes, Sejanus, Obara, Mukden, Rahel, Livy, a beer-up, an edh, Saktas, an egg, a lariat, Salado, Owena, WDC, a mCi, Mallis, Urdar, a massicot, an errata, Kelsi, Lamaist, a pasta, eyes, Silber, dreidels, Narbada, Emmott, Oballa, Dnitz, a potassa, Macapagal, a renegado, Oradea, Sivas, a casual, CVO, Ailey, a grad, a bus, an evocator, Ocnus, Yerga, Longan, Anyang, a det, a gramarye, NAACP, a rover, a cort, an evil, a megapode, Rollin, USTC, apasttra, Myca, a rove, Deny, a press, Eisen, Idona, Molossus, Sissi, Karim, Imp, a cwo, NSA, a rort, a pussy, Adda, lassos, Arie, Cretan, a zest, Napoleon, a psi, Henig, Erne, MSM, Lamus, an epagoge, Soo, Gallia, masais, Amarette, Gallas, Lawson, Imroz, a legato, Leix, a beet, Surt, an epic, Carbrey, a saliva, Cattima, a rimer, Dreeda, Loni, Weinreb, a rig, EHF, a jad, an aparejo, Bell, Iver, Billie, Talladega, Toor, a need, Rabi, a dawn, a cep, an e'en, Rahm, Ahl, Epis, a wkly, rebatos, a neep, a neuk, CMG, a lepton, races, Siusan, Ireton, a diagram, Lakin, Isidore, Tula, locos, Emmy, Sayles, Isaacson, Idalina, FFI, Tecu, a saloop, a rumour, a miter, Dr. Drew, a past, Nahama, a resurgam, a catalpa, Lotti, Osman, Iredell, Ives, Orton, Riplex, Anasazi, Reggi, Frey, a paseo, Dade, cacei, Latrell, Acta, Catt, Alpha, Lim, a ketubah, Sama-Veda, Aruba, NAAFI, a heinie, Henri, Basuto, Lamb, Cini, Alcman, Imray, a waragi, a dakoit, a pash, Conon, Airlia, MSEE, Lnos, a jaga, Lamson, Ivey, a desire, Cati, Batia, Walley, Roche, NYA, Leboff, a resumer, Duax, a ratafia, Tegan, a panatella, Caton, IPBM, a catena, Wein, a ledge, Issiah, tega, Topaze, a beef, a rub, Michael, Ramsdell, Abo, NAA, lobos, a caracole, putamina, Hocker, Reddy, Obeded, a ruse, a casino, Lamond, Orgell, Ivy, Ramey, a blab, mottos, Sitnik, an amanita, Pallas, Dahle, a jager, Gelya, Belg, a noggin, Nehru, a presa, Masan, Rapidan, a hamal, a deadener, Occam, Roch, a robot, a rpm, a slabber, gazelles, Omri, Myron, Ohaus, tubmen, a ruga, Namibia, Kato, Hamadan, Argia, Kahler, Ratib, a rasa, AAF, a rug, Este, nibs, a sable, Ikkela, a ruler, a civ, a newsreel, an eye, Nagasaki, a hallo, CATV, Bastia, WMO, Tees, Sela Ward, an effecter, Geraud, Russi, Keri, a dap, Malanie, HRIP, a he's, Sorce, Ciro, Mallon, Egham, Danni, Weir, Alcis, Ainu, a felucca, Saylor, a don, Sarkis, sargos, Caelum, Hsiang, Gader, Rumania, Weisler, a dom, a desirer, Bilac, a nebula, Lobo, Lamp, Galla, Callan, Rocray, Gamal, Adaminah, Teresina, CLU, Vasileior, Elsey, Esta, Calla, Callao, Danna, Mzi, Ewald, Omora, Karie, Kariba, Sedgemoor, Bely, a graver, Teillo, a rule, Cirri, Baker, Billi, a redan, a cultivar, Perret, Nannie, Henn, Austral, Liam Neeson, a ganger, Gel, Liva, Seely, a keno, BPI, Hasek, Oys, a snake, Cindi, a qasida, Artus, a make-work, Apl, a karakul, a yeti, a megabit, Argive, Lecia, Say, a waka, Osaka, a zila, a treillage, Eros, Nessa, Mast, tempi, Hasidim, Ardussi, Ald, Ronni, a pas, a pataca, Ido, Zasuwa, Arv, a megawatt, Alkoran, Negro, Tagalog, Nomi, Amii, Reneta, Bette, sordini, Mohave, Rika, LaBaw, Assam, a lab, Masury, Cally, a lad, Gama, Loise, Itnez, a poker, pudda, Arne, Okemah, Argus, Tubb, a cast, Tevis, Apoc, Seel, a rake-off, a qat, a hallucinosis, Sakta, Obelia, Neo, Tallulah, a rope, Calif, Luwana, Lydell, Irv, an inner, an illogic, Cassini, a meal, Lubet, a guff, Fowler, Hebron, Duster, Oba, Tallula, Loella, a panel, AFT, Sewel, Liv, a nudie, Mall, a psyllid, a leu, Massna, Morena, Odel, Liberec, an ilk, Colene, coenla, a grav, a yett, Eliot, an imagery, Pallua, Penn, Aulea, Rog, an imaret, a ganoid, Rocca, Naga, a heder, an ironer, Rodmur, a latino, Yeta, Gierek, a cash, Cufic, Circe, SBA, Loeffler, a doe, Dannel, Getter, Buatti, Minoru, Hengist, a dassie, Gesner, Orelie, Weisbart, Slyke, Cima, Nagel, Derayne, Mekka, Ethan, Iaria, Kile, Pellet, Seed, a lear, Freud, a loca, a long, Ivory, Teilo, Jeromy, Laden, Idun, a cuddle, Ifill, Abby, Ray J, Ramon, a brunet, Sirkin, Imogen, Deb, an irreg, an amalaka, a logogram, a log, Nogas, Adila, Kery, Bastrop, Saidee, Bast, Tavish, Paresh, a rozzer, Omor, eucti, Bahamas, Sereth, Cirilla, Keita, Caliban, a lob, Anissa, Heidi, a memorial, Noelle, a year, Basov, an idolater, gemses, a baby, a water, Issy, a romyko, Pall, an octet, Saito, Bett, Enalda, a vast, Tiffa, a wattage, Ray, a wee, Layard, an idlesse, Nitti, Wallie, Nono, Ibson, IWW, Ask, caballos, a lovely, a desert, Madag, a lugger, Keily, Kari, Bajan, Igerne, MSG, Igenia, Cali, Ladew, Oler, Yim, a slab, a nipa, Alodie, Cida, Ibycus, a loden, Iarbas, Sakti, Basra, Epsilon, a lollapalooza, Aloke, Cioban, Ibo, Cajun, a kennel, Osset, a boiler, Redmer, Teresita, Metsys, an iph, Reahard, Niela, KCMG, Adamina, Hokkaido, Keiko, Ocker, Demetre, Dec, a fino, Beta, Gwennie, Malayalam, Aloha, a litotes, Sibelle, Bea, Malines, Sorocaba, a lit, Seeto, Obau, a lues, a basic, a beep, an unavidness, Nelsen, Aerol, Yann, ACLU, Veno, Richara, Ozen, Iapyx, a lagena, Olsen, Ivie, Tab, a tuft, Adamik, a halavah, Sakais, Susannah, Keir, Ellata, obli, a saloon, Saied, a limacon, a keel, Artha, Lodie, CIO, Vasari, Dasya, Wanamaker, vila, Alic, Odette, Socred, a lati, Bedad, a dilemma, Heidy, Leese, Negress, OGO, Aidos, Calore, Malik Yoba, a lib, Yssel, Amadeo, Hekker, Obed, a life, Dann, a susu, Albamycin, Ibiza, necia, Malik, Iblis, Napoli, Maced, albarelli, Masry, a nurl, Limassol, a nullo, Callum, a lila, Pelles, NOP, a lily, Kei, Lacey, a memo, Sorcim, an ulu, Bezwada, a liza, Tumaco, Callas, Rusell, a desk, a pres, Algonac, Sotho, Danyluk, a beeves, Sokotra, Seem, Missi, Kevan, Kath, Gino, Tallu, Hasid, a revelry, Beall, Obaza, Pell, Imajin, IFC, a lilt, Adv, Ediva, Lomax, a minima, Alix, a trefah, Callot, Allah, Laven, Icarus, Palici, Trevah, Arri, Saiva, RRC, a placage, Tallbott, an anaspid, Nemea, Tivoli, Malena, Jerol, a gnamma, Erdei, Lennon, Nahum, Obadiah, Ally, CSC, a bandit, Oonagh, Nedi, SpEd, an ulema, Loyde, Ernie, vasa, AAAL, a macram, Ledeen, diseurs, a brute, Nissa, BASc, INH, Ceto, Ozalid, Offa, Danl, Omoo, Ramos, Narayan, a jag, a lepidolite, Olpe, crepes, SBLI, a grass, a kame, crabs, Abie, Calva, Pelagi, battels, a he'd, a lst, a ganof, Lahoma, Layamon, IMCO, Dasht-i-Lut, a tilt, a fan, a retally, Rebekah, a lupoma, Heida, a lud, a rash, Jerubbaal, Geof, a nut, a grab, a lactam, Aitken, a diam, a lye, Albi, Heigl, an udal, a redefeat, Settle, MSAM, Alfredo, Hesiod, Laveen, Katinka, Alboin, Nafis, Sulawesi, a legit, Sev, an udder, Domenic, Safar, a dak, Alsip, a task, a waratah, Calakmul, Lock, a meet, Semaleus, a gravel, Lillis, Umeko, Calia, Gab, an uhuru, an elf, Fayanne, Frear, tegmina, Zahavi, Lorens, Segner, Dugan, Elroy, a wrong, a demon, Gallup, Annora, Loy, a panier, Kev, an ogham, Otti, Brut, a seiren, Nuncia, Somalia, Leesburg, Urga, Alva, Keelin, Nejd, a doodah, Alikee, Ltd, Alhambra, battute, Cecilia, M'sieur, a rascal, Lida, Cattegat, Saiff, a demotic, Sadira, bokos, Rocco, Darees, Rafaelle, Byram, a sullen, a jasy, Layne, Knapp, an ascot, Senegal, a seignior, Gallus, Niebuhr, a dah, a surbase, retia, Kiah, a sudd, Adamok, Lewellen, a jabber, a sugar, a silicide, Nebo, Aello, remedied, Olympe, Edva, Seve, a meed, a seif, Fabri, busses, Saloma, a silex, a maremma, Hasan, Rosen, Emili, HBM, a damask, a yad, a silage, Vastah, Talia, Bates, Roddy, Catima, Dett, Erulus, Uruk, a siren, Izy, Teut, Rivalee, Regt, Sadler, Egk, a defeat, Socha, LOOM, a sennet, a sine, Curt, a sennit, seppa, Nagy, Matti, MSEM, Albay, a wye, Kati, bottegas, Bobette, Sumner, Demos, Naraka, Sokoto, Katti, lees, Sennett, a vas, a gapes, Romany, Lesli, a trey, a meekness, Ortiz, a prelim, a serpigo, Layla, Dmitri, Depew, obis, sugis, Sileas, Ruben, Ixelles, Sikes, Romaine, Guesde, Elsan, EDC, a situs, USNA, Mia, Camel, Somni, a psalmist, a watt, a wag, Igal, a rocker, Uzia, Kolomna, MSD, Nalda, Maloy, a fetter, Olson, Exod, an ameba, camisados, a sem, a jabiru, Adamo, Denise, lassoed, Ortles, Eogene, Coeus, Nakuru, a bee-eater, a grama, Lozano, Medeah, Cami, an elk, catalufa, Lugar, a daze, Curcio, Hesione, MSA, Geo, Hesse, TVA, Lugones, IMF, Fogel, Lido, a siege, Cuda, a sienna, MSL, IOF, a secular, a mama, Keelia, Bathulda, Hejaz, a halo, Rita Wilson, Idette, Susan, Nairobi, Rajiv, a necro, Fasto, Obote, Pali, a bee, Romalda, Hijaz, a gallet, Tilla, a venin, a jab, a basti, Remsen, Eth, a lust, Tips, a guddle, Iyar, a dived, a poll, a galleon, a sippet, SAA, Lukas, a guy, a catty, Ladino, Cardea, Troas, a gnu, Demo, Sonoma, a sorner, Glass, Eirene, Coimbra, Galati, Picco, Naomi, Aigneis, Alba, Tanya, Redon, Catania, Pedi, Manasseh, a soma, Ladoga, a solemnizer, Beal, Unni, Pedro, Cerell, DMSO, a cachou, Hett, Evyn, a rubasse, Nizam, a sett, Eliott, Augusta, Bia, Zadoc, a seta, Geanine, Seys, a kart, a sleet, a glia, Talien, Cmon, IUD, Laddy, Orsino, Daron, Yahata, Medea, Tadashi, Eward, Nut, a seton, a slut, a syntax, a set-off, a radiov, a sexiness, opai, a pagan, a rime, Cudlip, Ensoll, Echo, Camoens, a kalema, Hudnut, Saki, Leclair, a sego, Millais, a seeress, Ogg, a halibut, CWA, Tay, Nusku, an asb, a besom, a smokeho, Cammi, Reede, Eddas, Sabadell, Utta, OBulg, Naoma, Stephan, Munafo, Oisin, a jato, Janek, a watap, Sabin, Sabbath, a dilly, Redroe, Leeth, Saval, a cicada, Lopes, Ronny Cox, ennia, Brunelle, Sorci, Amorete, MSBA, Till, Emile, Malo, Cindee, Sabba, Bede, Pirri, cameos, a komatik, a supp, a panic, Ramiah, Tevet, Seow, a subsmile, Dillie, Vasta, Olive, Demy, a fete, MBA, Tiler, a dks, Uniat, Sochor, Geerts, a kudos, Morten, Elly, Camm, Amari, NSC, ramta, Ogpu, a jasey, Esd, Ribal, a hamaul, a prelabel, Bassano, Jeri, Fasta, Orgel, Baco, Vasti, Babel, Bactra, Cogan, ariki, a fetor, a suborner, Hamal, a far, a dkm, a damp, Fats Domino, reges, remains, a rape, Cupavo, Kval, Sango, Lobel, bags, a kraft, Silone, Alecto, Pto, Haslam, Asgard, Eddra, Haller, Rafa, Tilford, Isidor, Mensa, Mady, Ruella, Fatah, Cibis, Sorkin, Zinn, Ayo, Jerad, Rebah, a dekagram, a sub, Allys, a sfm, a demo, Toy, Mattah, Beeson, a haggard, a sully, HETP, a heeltap, a half-note, Vasos, a revel, Bambi, Raamses, Sabra, Devol, a direx, a mewl, a dirigo, Seoul, Eureka, Lalage, Raddatz, a kVA, Kid, Alves, RuPaul, Ultun, Cairo, a diva, Deva, Erny, rammi, a heed, Nary, a wailer, a sura, Gemara, Madel, BAM, a taler, Remy, a radio, Reeve, Lali, Avalon, Oval, Falla, Frau, Oboe, Macegan, Nidorf, a surplice, Caird, a hegari, Matejka, Berna, Mya, Lalo, a galliwasp, Atalee, Keele, Kalb, a divot, Siegel, Baul, a vagus, a dive, Colp, a surge, Cydippe, Pega, Tracay, a romp, a patella, Bath, Guanabara, Zomba, Hallagan, a hack, a deme, Caravaggio, Dever, Batruk, a div, Udaipur, Camus, Raddi, Keen, Nobel, Bax, Atalayah, Katt, a wail, a tango, Dari, Kuban, a hocket, Orissa, Melessa, Toru, Essy, Mewar, a moke, CBEL, Bap, a pate, Krips, a surg, Aeolia, Venu, Talos, Tejo, Tarawa, Key, UNIDO, Roberts, Aledo, Tav, Olin, New, Geer, a zap, a surd, a dibbuk, Susah, Cilix, a mew, Opelt, Tapaj, a resp, a lath, Ceb, a demy, Nagari, Hallam, Saul, USES, Runkel, a manroot, a baragnosis, Somme, Logan, a trapes, Ilione, Romains, Oby, a rock-eel, a sucrose, Illawarra, Madero, Mill, Ocko, OCDM, Salomi, Palm, Camp, Walli, Broz, a radial, Pals, Beeb, Ash, Tebet, a damfool, a fol, a groom, a kcal, Batum, a lampoon, Sausa, Yeisk, Cocke, Elgar, a bec, a fast, Topeka, RAdm, Devy, Galen, Ratisbon, Exc, a fatso, Pegu, a gallop, a demob, a lampad, Malca, Venn, AeE, Lello, yaws, a vidette, Ningal, Saud, Balla, Gaddi, a zed, a half, Eradis, padrones, Ilya, Laurel, a hewer, Caines, Semele, Signac, an omega, Laure, Messiah, Glynnis, Seth, a dagga, a delft, Sampo, Talya, Lenapes, Bee Gees, Sikh, a duo, Hallie, Matty, Darra, Edd, a path, Cilla, a waiter, Cullie, Froma, Maidy, Lely, a keen, Olia, Gahl, a roller, Evans, Susa, Tirolese, Nava, Jesse James, Ozmo, Darrell, an acacia, Lauri, Bahr, a biz, Nazler, Ocilla, Verona, Eleanor, Tammi, a massasauga, Katz, siloing, a bast, Olnee, Lauro, Bever, Overton, Eos, Avron, a titanate, Bittner, an areca, Matlock, a begar, Umea, bemata, POW, Mott, Sawyer, Roth, a mime, Jessi, Tammy, Malaya, Galway, a summa, Wall, Aggi, Reeva, a derby, Artima, Ratlam, a sumo, Cainite, Tanga, Mallory, a palais, UMT, Sakmar, Gorga, a dentil, psis, IADB, a dayan, Romeu, Gordan, a tittle, Cayla, Engud, a suite, Maisel, a gemmule, HJS, Aidin, Nepali, a demur, Bali, a fath, Sayette, Nippur, Ysabel, a keepsake, Bevash, a marbles, Sokil, a riprap, Sage, Tada, Navarro, Damal, a kalifate, Rolf, a suitor, Geez, a suit, Angil, a make, Tabor, Padriac, a sugi, Bores, Ialysus, a def, Luba, a dey, a manrope, Padegs, Aiken, Elrod, Apgar, Abruzzi, Lesly, Bissell, Artie, Weill, a venery, Padua, Balbo, Dallan, Raddy, Samoa, Halima, Jeane, Macey, a keep, Paramus, Kania, Bev, an etna, Naor, Eudora, Vlada, Ocie, Gresham, Uda, Tiu, Quar, PaD, a hom, Laue, Fayth, Gilbye, Ladin, Nedrud, a davit, a sordino, Elspet, Sami Zaiddan, a townee, Leven, Atli, Hedin, Sauk, a trad, Nipha, Luebke, Emily, Hedie, Weil, Ataliah, Pegg, Elsy, a salol, Liam, a daddy, Hali, a kali, Rycca, Rwy, Alcor, Ravenna, Edmee, Lashar, Rafi, a wake, Tayib, a satsuma, a dog-ear, BMus, AISI, a culture, Emie, fomites, Orono, Izard, Dennis, Inez, a halma, Cayuga, Trabue, Siva, Tresa, Cailean, Nairn, a supremo, Cadiz, a relic, Rambow, Safier, a sugh, a murk, Neva, Emlen, Orsini, Leal, Espy, Caia, Maisie, Tonye, Kassa, Keegan, a sillabub, a dot, a mense, I-spy, Gebler, a hdkf, Jelle, Byam, a dos-, a suet, Noella, a jay, a lect, serais, Ozkum, Raynell, Acmon, Rude, Tori, Perugino, Ripon, Obbard, a suede, Maiga, Hedi, Malin, a flu, Safi, a wanigan, Raji, AUA, Kesia, Raetic, Sibel, Pam, a cask, Comines, Olcott, Alfred, Albinoni, Ladonna, Mren, a sing, a hardy, a fen, Elreath, Cush, a tph, a pizaine, Dragon, Okla, Roma Maffia, Kasey, Bega, lepta, Kazan, a sika, a duro, kokos, Eisele, Kediri, Maiah, Kask, Costello, Capon, Kalila, Kemme, Fay, Aldan, a snow, Adur, Tekla, Weixel, a dub, rabbis, a sudor, a psocid, a mart, tumli, Elka, Orff, USRC, Cadel, a velum, a sukkah, Clo, Keyek, Cuba, a dual, a dragonet, Saxony, a caramba, Bekah, Acima, Trubow, Capp, an arc, Geb, an import, Sax, Alagez, a latah, Gal, a pipa, Adlee, Torbart, Natalya, Gardy, Hamamatsu, a copy, Hama, STOL, Faires, Yakima, Kali, Miami, Rudd, Islam, an arg, Madid, a lamina, yadim, a lebes, Urd, a dBm, alamos, Perr, udos, Lacy, Capua, a sinecure, WMC, a vapor, Dallon, Kallikak, a well, API, Verada, Epirus, a flake, Tobe, Raeburn, a gaddi, Rajkot, Rabbi, Raffin, Savadove, Jarash, a clamp, a pine, Gayleen, a maypop, a sinnet, a sinh, padres, Saw, Deniker, Gard, Doi, Riley, a jak, a sulk, a vols, a mag, a siree, Tove, Raff, a harikari, Rye, Naval, Sonora, Yesima, a maksoorah, Saturday, a basalt, an alec, Naxos, a sixain, Novara, Babette, Nibbs, Satie, Hrolf, a mort, Sava, LST, Seton, Gio, Madlen, amoles, UDC, a jawp, a modiste, Elfreda, famuli, Hamid, a veld, Diredawa, a miso, Zel, Bissau, lappilli, Faur, Biddle, Frog, Naboth, Supen, Eysk, a jowl, a pennon, Nadabb, Ullund, a category, a catnip, a sig, Ellett, Igorot, a satai, Lopez, albinos, SACEUR, Pepin, Keyte, Tova, a mimic, Slovenia, Ledda, Inigo, RDX, a satrap, a sailer, a psf, Foy, a paleontol, Paule, Idonna, Kohima, Trst, Septuagesima, Cape, Evatt, a bania, Gayelord, Algona, Clovah, Aviva, a miff, Farl, Laws, a jornada, Bayamo, Otto, Capt, Madden, a muddle, Vte, Irma, gayals, INRI, a call-up, Reeba, a mud, a sav, Ilokano, Morette, Nimrud, Nabis, USHA, Tizes, nidudi, Kneller, Rajput, Sudan, a gaffe, Ilyssa, Jed, a toll, a batter, Rabkin, Ulita, Maleki, Maddi, Legra, Malory, Teodora, Zales, a jazz, a taluk, Melany, cava, LACW, Behar, BEM, a halm, Dev, a haslock, Ajo, Rafer, Paul, Uziel, Dalenna, Jemy, a jaap, a keef, a sage, Dobro, Tavi, Titania, Gerard, disli, Greville, Rotorua, Macapa, a sago, Tarrah, Saktism, a palea, Nahtanha, Hebel, BiblHeb, a muon, a coma, Cap'n, Gary, KKK, a yak, a soliped, a trav, Nissy, Laos, Deery, Tally, Bish, Avrom, a fate, Backs, a mast, Siloa, Ostraw, Sappho, Jem, a gallon, Kegan, Maluku, Maddy, Legnica, DNB, a boa, Bayly, Leff, Ajax, a mary, Socorro, Mayence, Bezaleel, a hake, Turkey, bedemen, Mayan, Lovel, BOSS, Aymara, BTh, a vlei, Lombok, a jetted, a calabazilla, Rolfe, Lorry, Pau, a drone, Lou, Cavan, a gorget, a batta, Garber, Eckel, Sisile, Drago, Hamel, CAVU, Caves, Pocatello, Madge, Loz, an alamo, Caaba, a keek, Rudy, a battik, Rubel, Bodrogi, a coca, Idolla, Veta, Yasmine, Lowes, a circ, Augie, Lolly, Remde, Idden, a goby, a broth, a fool, a solo, Bolen, Okun, Robenia, Rollet, Timor, Ruth, a jib, a solv, a citral, Lipski, Leesa, Eph, Carissa, Tojo, titis, UNESCO, DMS, Aenea, a civet, a bile, Cabal, FAA, Toni, Laird, Naldo, Papua, Yami, Losey, Botti, Beyo, Reef, Foch, Calisa, Vidal, a dept, FOS, a sorites, Lupe, Ravel, Sikko, Okazaki, Lilla, Roer, Pape, Papp, Ansel, Bram, a crone, Macc, a lamppost, Simois, Orsola, Heda, Ern, a gob, a sori, Garbe, DEd, ADC, Magnien, oodles, Rugen, Neibart, Redleg, a maize, Nevin, Nolly, Retha, Kalahari, Jehol, a gramps, a wallet, Safavid, Volpe, LOA, Hamrah, a sorgo, Tibold, Alvarado, Daveda, Birt, a song, an alias, nuts, a sodomy, a hailer, Eck, a zakah, Sadirah, Cav, a billet, tipis, Rusel, a kibe, Limnaea, Portageville, Riff, Ezek, Ardelle, Nova, Reba, Bayer, Radha, Vonnie, Katayev, a crape, Luigino, Subway, a soot, a pawnage, Vasya, Wanonah, Stelu, Pacien, Urbanna, Islaen, a crepe, Lyris, Kall, a wallah, Sansen, Novello, Mayag, a crum, an aloe, Gaya, Rules, Lud, a sook, Nathan, Billen, Hedy, a bevel, Cacia, Majka, Oneida, Esth, Gilly, Radke, libretti, Steel, Gath, Sergo, Cabot, Moyna, Mrike, Suomi, LSM, a frock, a zimarra, Home, Siward, Raviv, a cup, a soom, a jet, Toledo, PSC, Iny, Cave, Ruyle, Seidel, Braga, Accad, a cnida, Gati, Ravi, Varese, Orsay, Garbo, Dayan, Lozar, a reverend, a key, Baalim, a kevel, Kehr, Alcott, a lpW, a hask, Cotswold, Ulm, a yeo, Reames, Word, a soil, Osmo, Hege, Iloilo, Faggi, BAA, TTY, Hrvatska, Odey, Block, a zebra, Baganda, pagnes, Bebel, PaG, a faller, Robena, Ossy, a hamlet, Seward, Riedel, Bur, a soiree, Brey, Emyle, Cicero, MTI, Debor, Pacifica, POD, Nisen, Epner, Bebe, Heep, Ulda, Garv, a grocery, a hasp, Pack, Calapan, Kalevala, Indio, Bol, Gaelic, Ody, a habu, Royette, Nansen, Nerin, Nobe, Sobel, Bekki, Luk, Ailin, a gin, Alfy, a fairy, Galer, Pepi, Paco, Ruddy, Keb, a behavior, Labe, Hebbe, Ravo, Rikki, Lupita, Mokha, Onega, SBIC, rectos, BEF, Asami Kanno, BEW, Eolic, Ludd, a fame, Lyall, a pallet, Nampa, Bagger, Gaige, a sou, Debi, Gaia, Raul, UNEF, Felic, Nancee, a cps, a cfs, senti, Wade, Mahadeva, Talyah, Star, Badoglio, Fabi, Battat, Sammy, pepla, Debs, Itys, sensa, Itagaki, Reniti, Neel, a mascot, Noby, a fuddle, Gabor, Badb, an alb, BAcc, Cauca, Valenta, Cuyp, a walla, MSSc, Idea, POGO, Laval, Cavit, a biri, Katlaps, Seigel, CIC, Safavi, Zeiler, Olnek, Cassell, OFlem, a jen, Novia, Inoue, Janeva, hamli, Fabe, Dayak, a cgs, Sorcha, Ofori, Hey, Dasht-i-Kavir, Paki, Regazzi, Pavo, Sark, Endor, Barbi, Lazar, Barbur, Bul, Edme, SbW, a papacy, Neo-Ju, a hammal, Falkner, bans, Banff, a jeer, game laws, Asoka, a hod, a hirer, Akh, Salaidh, Amalea, Jeff, Uranie, Paza, Iddo, Gibbon, Kaylil, a bun, IDP, a vodka, Oslo, Hardy, Harz, Escudero, Tatius, Gates, Erinn, auloi, Cullen, Urban, North, Camey, Cathar, Romo, Gamma, Gabo, a rarebit, a buhr, a jake, Soho, Troth, Cabral, Demakis, a jollity, a kotwal, Fawn, Nadya, Magner, a soke, Swat, a soja, Ind, Norrie, Waals, Etti, Riki, livres, Signy, Reseda, Hallel, Evy, a pallor, Reeda, Jehu, Latini, Vetter, Odom, Iams, Dan Mason, Yerkes, Epps, Esc, Stagg, Elliot, a soy, Alloa, Isus, Sofko, Baily, Xenia, Ralf, Fargo, Togo, Tupi, Luns, Sodom, OPEC, a facet, Lothar, Rumsey, Ortrud, Labuan, Hukill, Empson, Kaya, Jeuz, a keV, a calix, a natter, Rudin, Niven, Robi, Alcuin, a bod, cauli, a keblah, a bog, a dato, Crabbe, Waikiki, Luz, a lamb, CTC, Irene Wan, a gid, a maco, dues, Sokul, opuses, Surrey, a staw, Staw, Tatum, a galet, IGY, Ticino, Tadeo, a bozo, T-men, Robson, a limen, Rob Nash, Colombi, Babi, BDSA, Iain, Lyssa, Baraboo, Babur, a stool, Cressi, Vikki, Nadja, Wed, a fact, Gabbi, Gabe, Ezzo, rms, Supt, Surtsey, Weelkes, Yvor, Berosus, Seneca, Gabel, Babson, a like, SWA, Hammel, Karb, Mike Garey, a ladder, a stum, Strabo, Hals, Urfa, Illampu, Paxon, Kaine, Draco, Valry, Baird, a stg, a bezel, Tri, Kamin, Yap, a scf, a snivel, a bish, Pahlavi, Veradi, magi, a talc, Ceres, Sumo, TQ, a snap, Stoll, a batik, a billy, Daisy, a lamp, a yatter, Evered, a wadi, Laforge, Nika, a bidet, Tobago, Gambi, Baiel, Esk, Codd, a magnum, a snell, AMSW, a palpi, Dagny, Badajoz, a grig, a jole, USMC, Baber, Azariah, Tolima, Estren, Ierna, MTh, Gilder, dogs, S.S. Ravi, lobi, Romeo, Fedin, Urba, Izawa, Kuyp, a jot, a bur, a snug, a spore, Maya, Haiti, Telegu, a habbub, a blague, Jez, a masc, MFS, Eliphaz, Riti, Rollo, Cinda, wakas, siloed, Datnow, Kain, a mono, Mayor, lignes, Levey, Taegu, Urey, Datuk, a yawp, Urial, Favrot, Surinam, Harberd, Niall, Edsel, LIFO, Colan, a lobolo, BAU, a haver, Bazar, Gabi, a rapport, Tobey, Pax, a taig, a nazir, a yob, a spoor, Tarapoto, ICSH, Colby, Trask, Casady, Laith, Savill, Eudo, Cock, Campy, Taima, Jebb, a spool, Makkah, creda, Zuleika, Jeb, a gummy, Kado, Port, Sagitta, Hagi, Rosy, a sapor, Pablo, Kayla, Taimi, Ardeth, Colpoda, Rodd, Rayner, weeds, Ednie, Froh, a speer, Creel, Faxon, Nelan, Nolte, Bazil, Esdud, Abbi, Jania, Janina, Iggy, Taka, Pogany, Weed, Nudd, Rawden, Alodee, AAAA, a spy, Hayne, Edny, Borneo, Cleo, Janna, Igbo, Baxy, rectums, a sloop, Abdel, Trutko, Wake, madres, Iey, Tromp, Marc Alaimo, Ciri, Rodin, UMW, a came, Domagk, Paff, a datum, a sld, Abnaki, Pytho, Jann, Asosan, Olvan, a darby, Trocki, Reedy, Hakim, a padauk, Rutledge, Nork, a syllabub, ASW, a jog, a ragi, Waki, Ruy, a pct, Sudanic, Neses, Simms, Stover, Pepe, Takeo, Davey, Erund, Robet, Toyama, Mayo, Koy, a graze, Neruda, MIP, a guyot, a pawner, Peel, a sorbol, Gaw, a galoot, a regina, Mylo, Kahn, a glove, Nupe, NYP, a goi, Kagi, MSGM, Palos, Rusk, cubti, Roselani, Frum, Gaea, Isth, Gittle, Creek, a facsim, a reglet, Sully, Bisk, Columba, Wace, Fax, a flock, Cold, a palp, Mays, Ecua, Enlil, Hakan, Odilo, an atm, Gaekwar, Cree, FRGS, Maffa, Jany, Madras, Selena, Xerxes, Seaver, Tailor, paise, Negev, a saga, a rent, Rugg, a galop, a rennet, a goy, a gps, Elko, Ovid, a capo, OPCW, Nagoya, a kino, Mellie, Rimini, Luigi, Roraima, DOA, Laszlo, Hobey, Wear, Dex, Ellerd, a revert, a kip, a revolt, Spa, Pacific, Mellen, odds, Stow, Izmir, Gaul, UTWA, GCM, Akaba, Kapoor, Tak-Wah Lam, a job, Budd, Rogerio, Gerge, Romy, Web, a joy, a kaka, Vonny, Daddah, Croom, Xeres, Palaeozoic, Sabino, Bahia, Daub, a ballad, Narva, Jan, Relly, Kreiner, Gazzo, Crifasi, Rubio, Zebe, Dax, AFS, a knell, a dragnet, Kremer, Bajaj, Drew, a tact, Felty, Grey, Drer, Helm, Otha, Yila, a removal, a bajada, valses, Eyck, Cordell, Aeniah, Krems, Emp, Macau, a taxi, Deneb, a viremia, Jari, Waler, Taine, Tabbi, lawmen, Rubi, Niki, Brentt, Usk, Cordi, Krell, a zebu, a datto, Cidney, Takara, Gemini, Mods, Enyedy, Ettore, Dido, CNS, Edman, Raven, Rider, Ellon, Kabul, Fafnir, Eldo, Yacov, a haiku, Stijl, a bro, Havel, Charo, Beds, Euh, Puett, Emmet, SScD, FBA, Rodi, Sidur, Drugi, USPO, Happ, a kaki, Cukor, ODT, Navaho, Lillo, Temp, Mig, a reflet, a volva, Pavlodar, AFB, an adobe, digs, CBE, Diu, Greff, a zamarra, Hums, Cdiz, Zullo, Merc, a lop, a reffo, Hax, a temp, Medill, UPI, Kivu, Hao Wang, a rex, Errecart, a rhomb, a kapok, Iambe, Olnay, a lamboy, mesela, Geneseo, Janie, ZAPU, Yedo, Donn, a koko, Yeo, Vedi, Meilen, a dwarf, Furr, Elson, a pig, EAA, Robb, Edik, a saggar, Brent, Lawlor, Reece, etyma, GOP, an ado, Elazig, a waw, a rho, Bres, WOW!, a troch, coneys, Silva, Vaasa, Ynez, a magot, a trommel, Felt, Tillio, Brag, a troke, Diwali, Fars, Isbel, Krebs, OSD, NALGO, Grew, Olds, Breger, a fut, a trepanner, Taite, a hrs, Reviere, CBD, Rooke, Darby, Tacy, Todd, Nagle, Beograd, Ravid, a kago, Waupun, a vedette, Ruel, Fed, Newsom, a trike, Dud, a trf, a toom, a tort, Simpson, a villus, a fife, Dew, STD, Newel, trymata, a taj, a carabao, Meissen, a vireo, Dercy, Remmer, Elke, Gagnon, Nikki, Dahl, a gird, a mattock, Corbet, Sergu, Brew, ostrca, a caboclo, Doisy, Emily Bronte, MSBC, Irme, Femi, Holli, Rumi, Krutz, Tirrell, Etom, Leeke, Zeb, Minni, Jared Leto, Orsa, gedd, Nevski, Vespucci, Haggi, Brom, Ursel, Ludlew, ovoli, Hollah, Tacitus, Rew, Ardel, Doy, a tom-tom, a toy, Leanna, EDT, Nomura, ECG, a jinn, Enki, Brunk, a tungo, Haze, USP, Mulki, Dodona, ICJ, SMM, Ronny, Gish, Coop, a tunka, a bact, Vassily, Rorke, Zorn, a wop, a turps, Robigo, Yazd, an adnominal, Ruffi, Zed, Nilote, Mbm, Lotis, Littrow, a tuck, Corson, a welt, Nkomo, Chany, Dolli, Pepys, Sisto, Brahmsite, Codee, Braden, Urgel, dibs, RMC, SMB, Medii, a wahoo, Haynes, Lippi, Yafo, Lowl, Lark, AFM, AEng, Naples, Orsk, limli, Wafd, a yogh, Coo, Honor, Goldi, Puck, Cork, Axel, a tutee, Diahann, Alfi, Dobb, MFT, Todt, Taiwanese, Chal, Liza, Newlon, Aeria, Z-bar, a nonacid, Evoy, Minn, Osiris, EDP, Pilsner, Willi, Jadd, Ajit, Tenniel, Kroo, Bruhn, a madafu, Krupp, Pike, Popele, Gove, Pardo, Miksen, Azusa, Nollie, Paganini, Doll, a gnash, Coke, pix, Seiter, Usbeg, a detinue, Idou, Hilel, Lawes, Orlov, Ronen, Woden, WAFS, Nevile, Biegel, Kru, BSES, onaggri, Vinna, Timms, BSc, Javler, Emogene, Guest, IOU, Quill, Chad, Divali, culttelli, Wilno, Chap, Pammi, Harbin, Osyth, Crabb, Bock, Cohen, Metz, Tiny, Ruffo, Dash, Ciel, Grail, a devoir, Epiph, cippi, Vic, Grover, Trevorr, Eppie, silos, Sibiu, a maw, an ikon, Otranto, Gobi, Dotti, Wawro, Noyon, Edley, Cadmar, Gawra, Efram, Yapur, Previdi, dregs, Newell, Ewold, Lewanna, Elijah, a dew, STM, BSP, Pigs, Neff, Rech, Cu-bop, Pommard, a drawee, Oryol, ETD, NUWW, SNOBOL, Adrial, a drub, Sung, a minim, a dry, BSLM, suci, Pregl, a doom, a dorp, a doily, Culm, LLD, Lonier, SLBM, Hulbig, Posen, Ronsard, a malady, Roze, Yezd, an acid, Feb, Bobbi, Dodd, a jim, Mitzi, Fahr, Efik, Midi, Dirk, an oke, Borg, Swtz, trews, NbE, Boz, SJD, Elohim, Moth, Clim, a daud, a duel, Adnopoz, Nolitta, Rhamnes, Kreda, Duhl, Libna, a jut, Boll, Etowah, Shiah, Preble, a mural, Goren, a bahut, FGSA, Grube, Blok, Noemi, Scevo, Mohsen, Navada, ETV, Prov, a fado, Trelu, a magic, a murky, Eisk, Cop, a mug, a model, Restivo, Royo, Yassy, Letti, Polik, a morph, Clabo, Mohn, Waldo, OWI, Mims, Tuck, Roby, LSD, LRBM, a gaze, FLB, Leoni, Dorobo, Suckow, Kirkuk, Aleppo, KNP, Dibb, Arallu, Hoo, Winni, Bob, duomi, mobs, MHD, Tildi, Booz, a bawl, Monro, Chao, Korc, Levitt, Eyde, QMC, DSW, Etz, Tokyo, Bop, Gogol, a liang, a nabob, a cav, a paua, Golgi, cuffs, Moro, Coy, Hopi, Wyo, Howe, a motive, bds, MVD, NbW, Munro, a loop, a lhb, Lugo, Maxy, Rex, a pawn, WPB, an abt, Molopo, Hoye, Vig, apili, Finn, USV, FFC, CFI, Bibl, Luby, Haftarah, Vivi, Lyngi, Vivl, UFO, Pfaff, a caff, a wax, Mdm, DVS, DDT, Tiga, DFC, MGk, Stuka, Yoo, Jonah, KWOC, a prawn, Hoku, OSF, Noah Wyle, Govt, FBI, Garth, Sink, a peso, Jodi, FPC, Cluj, Lulea, Bui, Gyor, TLC, BMV, BCP, a plug, a pcf, a guv, a cpd, LHD, Guzel, Hakluyt, Diehl, Rigby, Dodds, JHVH, Yuu, ScB, BFS, NWbW, Sfc, GCB, a yew, Wolf, a knife, FIFO, Kori, Him, Rondi, Kapor, Cayey, a crop, a kid, Normi, Hiroko, Fife, Fink, a flow, Wey, ABC, GCF, SWbW, NSF, BBC, Suu, YHVH, JSD, Dody, B-girl, Heidt, Yul, Kahle, Zug, DHL, DPC, a vug, a fcp, a gulp, APC, BVM, BCL, Troy, Giuba, Elul, Jul, CCP, Fido, Josep, a knish, tragi, BFT, Vogel, YWHA, ONF, Sou, Kohn, Warp, a cow, Khano, Joo, Yakutsk, Gmc, FDA, Gitt, DDS, VDM, DMX, a waff, a caffa, FPO, Fulvi, Vigny, Livi, Vharat, Fahy, Bull, Bibi, FCC, FFV, Sunni, Filip, a give, Yoho, Polo, MTB, an abp, WNW, a pax, Eryx, a mogul, BHL, a pool, Aornum, Wbn, DVMS, DBE, Vito, Maewo, Hoy, WIPO, Hyo, Coro, MSF, fuci, Glogau, a pav, a cabob, an agnail, a logo, GPO, Boy, Kotz, Tews, DCM, QED, Yetti, Velcro, Koah, Corno, MLW, a bazoo, BID, LitD, HMS, bomi, Mou, DBO, Binni, Woo, Hull, a rabbi, DPN, Koppel, a kukri, Kwok, CUSO, Borodino, Elbl, Fez, a gamb, RLD, Sly, Bork, CUTS, Mimi, Woodlawn, Homo, Balch, PROM, a kilo, Pitt, Elyssa, Yo-Yo, Rovit, Serle, Dom, a gum, a pock, Siey, Krum, a cig, a mauler, Tod, a favor, Pvt, Eada, Vannes, Homovec, Simeon, Kolbe, Burgas, GFTU, Habanero, Glarum, Aelber, Phaih, Shaw, Otello, BTU, Jaan, Bill, Huda, Derksen, Mahratti, Lonzo, Pond, a leud, a duad, a milch, Tommi, Hole, DJS, Zobe, BNS, Wertz, TWS, Grobe, Konakri, Didi, M. Kifer, Hafiz, Timmi, Jaddo, Dib, Bobbe, FDIC, an adze, Yezo, Rydal, a madras, Norn, esopgi, Bluhm, BLS, Reinold, LLM, Lucy, Liod, a prod, a mood, Alger, Picus, MLS, Byrd, a mini, Magnus, Burd, a laird, a lobo, NSW, Wundt, Eloy, Roee, Ward, a dram, Moppo, Buch, Cerf, Fens, Gipps, BMT, Swed, a haji, Leann, a weld, Lowell, Ewens, Gerdi, Diver, Pru, Paymar, Fear, Wagram, Dacy, Elden, Oyo, Norw, a wit, to-di, Bogot, Narton, Okinawa, Maui, BIS, Solis, Eipper, Rover, Trevor, GCI, VIP, Pich, Piper, Ioved, a liar, Gleich, Sadoff, Ury, Nitz, Temne, Hock, Cobb, BArch, Tyson, Ibrahim, Mappah, conli, Willett, Lucila, Viddah, C.L. Liu, quoits, Eugene, Gomer, Elva, JCS, BSM, Mitanni, Virg, ganoses, Burkle, Geibel, Ivens, Fawne, Downe, Norvol, Rosewall, Elihu, Odie, United, a geb, sureties, Xipe, Koch, Sangallo, Dinin, a gape, Illona, Suzan, Eskimo, Drape, Vogele, Pope, Kipp, Pur, Kufa, Damanhur, Boor, Klein, Netti, Jadda, Jilli, Wrens, Lipp, Desiri, Sonni, Myo, Vedic, a non-Arab, Zairean, Olwena, Zillah, Cesena, Wiatt, Dott, FMB, Bodi, Flanna, Haidee, Tut, Alexa, Krock, Cupid, Logrono, Hooch, Goya, DFA, Wil, Milks, Rosel, Pang, Nea, MFA, Krall, Wolof, a yip, Pilsen, Yahoo, Hawaii, Demb, MSc, Mrs, Bidle, Grune, Darbee, Docetism, Harbot, Sissy, Pepillo, Dynah, Como, Knt, Lewan, Osrock, Cut, a wort, Tilsit, Olm, BMet, Olinde, Zif, Furlani, Mond, an adz, a yogi, Bors, Prut, a powan, Rozek, Rory, Lissa, VTC, a baa, Knut, a pooch, Sigyn, Norm, MSJ, Ciano, Dodi, Klump, Suez, a hognut, a knur, Bik, Nenni, JAG, Cear, Umont, Deanna, Elyot, a motmot, a yodle, drawers, Utica, Thallo, Hilo, Vowel, Dulles, Rumor, Bigg, a hiccup, Sevik, Svend, Degas, Root, Elder, a jinni, MBE, Zeke, Elmo, Teller, Ritz, Turki, Murillo, Hime, Fem, Ric, BSMet, Norby, limeys, Iodol, Cob, ACAA, CRT, Sower, Bug, Reste, Brock, Cott, a madrigal, Hadik, Kinnon, Gage, Kler, Emmery, Credo, Erivan, Essie, Moab, Aracaj, a taata, Myrtle, Wendt, Swede, FIFA, Sullivan, OSP, Mistrot, a moot, a frt, a dude, Kirt, Amos, Wende, Fleurette, Devan, UPU, a wog, a kadi, Vardar, Goebel, Gand, Doty, Caty, Brade, Koord, BCerE, Ivers, Rhaetia, Trenna, PERT, a tufa, Reger, BSD, Lower, Gog, lands, Osber, Klebs, Israfil, a wide, Kort, a garboil, Little, Flem, Mort, a toga, Maze, Nyasa, a vav, Lissy, Enoch, Cort, a wowser, Bohr, a wawa, Giza, Leod, an apogamy, Teece, Errol, Waltner, Bragg, a saki, Debbora, Aegipan, Osler, Ruff, Rawdan, Elie, Mide, Voe, Yoko Kanno, Dode, Yup, a zein, a joe, Senegalese, MYOB, Malayan, Loeb, Maikop, a kab, Mohr, a tracer, Rexer, a gnaw, Oahu, Viki, pulli, Demp, Metaxa, Hoffer, a polacre, Moll, Uzzi, DCS, Muharram, a zaffer, Guide, BCS, Gide, BOD, an abfarad, Olva, Pavlova, Telfer, a gimp, Metol, Lilo, Havant, Doro, Kucik, a kappa, hops, Uigur, Drud, Isidora, BFDC, SST, Emmett, Euphues, Deborah, Cleva, Horbal, Jit, Suki, a havoc, a yodler, Inf, a flub, a knoller, Edirne, Varna, MDES, NCO, Diderot, Teyde, Ynes, Domini, Megara, Katy, Endicott, a daube, Zaller, Kid Rock, Suttner, Bikini, Burne, MWA, Libb, a tenia, Trela, Wira, Jaime, Riva, Benedix, a tau, a camp, Mesmer, Khai, Neall, Edrock, cyeses, Lavada, Jabal, a vomer, Aaliyah, Tom Lehrer, Dyer, Gytle, FTC, a tawer, Djaja, Bremer, Kten, Gardal, Lenka, Sfax, a debe, Zoi, Buri, Safir, Cozza, Grenier, Kyl, Lerna, Jav, Randall, a babu, Adaiha, Boni, Bascio, Zoe, a lapser, Exmoor, Chadd, a dyn, Novak, a kayo, Jabe, Wymore, Gregoire, Gord, Dubbo, Jamal, Hawk, a troop, a kabaka, McGaw, Tulua, Grim, Ziwot, SSD, Donelle, MCi, FICA, Papst, Lover, a pika, Trever, Adrell, exedrae, Wye, Bohol, Zsa, Laodamia, Rori, Giulini, Mireille, Monika, a yoga, NWC, Poop, a cadi, Vookles, PGA, Yoga, Tenner, a pol, a gag, Gurtner, AAG, a save, Genesia, prolia, Treva, Essex, Rexane, Lessard, a myna, Jaffa, Msgr, Feer, Craw, Kea, GMT, an aoli, Dona, Kahlil, Neau, Cesya, MPL, a padlock, Colfax, a fec, a wab, Mulock, Sibyl, Lust, Elger, a misc, a fakeer, Celt, tights, IAEA, Gmur, finales, Orit, Bucks, Ursola, PMG, Smiga, Kioga, Pyne, Pune, Volga, NHA, Kolyma, Niger, a tool, a gaw, a glob, Rosalee, Pren, Wapato, Yuga, Pima, Durene, Zarga, Yokoyama, Mayotte, Bord, Nureyev, a doek, a tepe, Prevot, SSM, misses, Encina, Dust, CPA, Yurik, a wig, Arago, jaws, a bubal, Lys, a krone, Gdel, Turku, Adapa, Mika, Hyde, Erik, Corty, Bradan, Avlona, Sosanna, Joh, typika, NBA, DLS, a mut, a daff, a pkg, a modem, a caw, Muni, Dori, Rico, Mial, a cramp, Morty, Eiser, Damek, a wok, Turtle, DBA, pools, a smut, Ceryx, a bob, Gianna, Joel Coen, Robyn, Deenya, Hyps, AAA, AAeE, Dolan, Edward, Dundee, Wyn, a gopak, a tyg, Gianina, Jain, a jibba, duds, Elizabet, Lonna, Lennox, a fleer, creeps, a hor, Fein, Desdee, Wren, Yard, Dorado, Ploch, Ted Raimi, Atalya, Kolb, a prop, a say-so, Riga, Hatti, Gastropoda, Kym, Mugabe, Jakie, Luzader, Chak, Kamloops, Abbe, Jami, a typ, Mack, Coco, duelli, Vashtia, Lyda, Sacks, Arty, Bloch, Scioto, paratroops, a boyar, Izanagi, a tax, a pye, Bottrop, Paraiba, Graz, a breva, Hau, a bolo, Bolan, a loco, filles, Della, Indre, Brahmani, Rust, Orv, a flair, UPWA, Yakut, a dyer, Uuge, a tye, Velsen, Gilroy, a monomania, Kwon, Taddeo, Lissak, a wad, Nicol, Lori, Tirzah, piles, FMCS, a maze, Jeu, Galba, Bubba, Hauge, Letitia, Haya, Merops, a guns, a rubato, Jap, Yukawa, Zia, Bruni, Defoe, Mori, Bolivar, SSS, Godred, Lightman, Reinert, Seami, Lothair, a zareba, BCM, Suelo, Jagir, Gazo, Jada, Byng, a dipl, a paw, Smallens, a munga, Maddocks, Eleia, Bib, Magog, a botte, Diba, a kine, Grof, a lid, a wader, Everett, a yap, Malaysia, Dyl, Liba, Kit, a ballot, spans, a qto, Musser, Eccl, a taiga, Mid, a revival, Haphsiba, Levins, a fcs, a paynim, a kirtle, Zeba, GTS, Adria, Byrl, a voc, Ardenia, Knox, a pup, Mallia, frusla, Hobart, Smuts, a redd, a layerage, Kimbra, Klemm, a hawse, Kilan, OSB, a bleb, Agace, Nessus, Orebro, Vyse, Klee, wyes, Trust, Puss, Mroz, Zeeba, Gibb, a gtc, a fade, Wajda, Nikki Visser, Cloots, a rubaboo, Barabas, Sylni, Aias, DBib, a bib, Moloch, Sanborne, Milan, Osborne, MTO, Zoba, OED, a tonicity, Gitel, a gamut, a twat, swats, Ayer, Russes, Upolu, Koss, Eudoca, Madigan, a wen, Eric, TCBM, a lazuli, Kiki, a web, Barcot, a dagoba, Halbe, Kailua, Cdoba, Niu, Claiborne, Vinni, Durrett, an axil, a cave, Kazue, Jay, a knosp, Melli, Kuhnau, Baldur, Troyes, Murrah, Toltec, a face, Pomo, Doss, Nuli, Puto, Goto, Graff, Laraine, Xylia, Bok, Foss, USIA, Ollayos, a toil, Leggat, SCS, ESP, Pesek, Reynosa, MNA, DSM, Aimo, Dorette, Vinita, Luhe, Jade, Erroll, a pay, Velella, Hades, Eryn, Gisser, Vili, Kirit, Tesla, a weir, Rondnia, Jos, a tawse, Kos, a renga, Mayda, NNW, a flaw, Tokay, Tillo, Jasik, a medlar, Bach, Torto, Hose, Kajar, Huba, Tiber, a raob, a gamma, Gomorrah, Tacye, Mach, Tronna, Brunel, Lucio, Luanni, Reseta, G-suit, a tore, ducs, Ezra, Hydra, hols, Oak, DOVAP, Dinuba, Lily, a knob, Bigod, Diaz, a pein, a ruffe, Jaela, Mahdi, a lashkar, Eriha, Doha, a kos, a swale, Magree, Jaffna, BSNA, Brenk, Laflam, Mahau, Joe, NYC, a papaw, BSEM, delubrubra, Braz, a libra, Brod, Nekrasov, a pizza, Gerik, a priv, a kith, Sadye, Hiro, Foah, Cross, GCA, Kay, a deb, a film, a haven, a jeu, Onia, Ivonne, Jamel, folles, Sacken, Lorelie, Ziv, a fascicle, Giess, palta, Kiribati, Vaclav, a logopaedics, Small, a wap, Yucatnel, a vacua, CCC, a bbl, an abd, a brob, a geld, Dufay, Bontocs, a malee, Nitin, Erika, Gatias, Nessy, Tisbe, Dalpe, Pym, Mastat, Tabib, a foil, God, a brat, Shayla, Taveda, Hamed, a witness, FCA, SPCA, EEC, Nanci, Leffen, Ulu, a raia, Gibe, duos, Aegia, Gregg, a bap, Mantell, a pall, a ylem, a fad, Dulci, Loewe, Bonn, Akim, a safe, BSOT, cerci, BSAgE, Noah, Komati, pulik, Kirov, a rebbe, Heb, Alroi, Vahe, Babe, Kyd, Duroc, a pipe, prela, gyri, a fay, Flanigan, Ilia Kulik, Keble, Bose, Bonni, Rennes, Nanette, Yoruba, Hay, Docile, a globoid, Nial, a vel, a knap, a lack, Capps, a hay, Recor, Gavra, Gad, Lupee, Hebe, Bren, penes, Indo-Pacific, a probe, Ditmore, Cicely, Meyerbeer, Ios, a ruble, Deirdra, West, Elma, Hays, Soane, Borrell, a fag, a plebe, BSEng, a padnag, a barbe, Zak, Colbye, Doak, Stav, rhytta, a bigg, a folio, Liege, Homs, olios, a drowse, MAeroE, Yam, Ludlow, stocks, a haw, Platto, Clarhe, Kleve, Kamila, a bye, Kadner, Everara, Zolnay, a dobra, Gyas, Roeser, Aviv, a rit, a gad, Inca, Dacca, a garble, Diesel, Yurev, a cynic, Spode, Lotte, Jam, o-os, a puca, Viv, Ardra, Wise, Moharram, Izak, Corfam, Slim, Ouse, Kirman, yom tob, a cog, Resht, a gleet, Sitter, Bilek, Daryl, lights, Eadie, Noak, Jamaica, Cleve, Bay, Dehnel, Libnah, Tankoos, a dulse, Luray, a geol, an amurca, Gay, a moll, Evonne, Snashall, a wall, a ksi, Ryle, perca, Neal, Sianna, Brunei, Capulet, Shanon, a ways, a vegan, wapatoos, a yaw, Busoni, Giule, Parca, Vey, a take-in, Novah, Darrey, a babe, Ravonelle, Drake, Zeffirelli, Vega, Tropaean, Mile, Bikales, Ursi, Pittel, Libava, Chari, Dasha, Kazak, Cerelia, Haymo, dos, a stunsail, Anagnos, a tribade, Vadodara, Vlad, Lobito, Gros, a harm, a haole, Plovdiv, AFA, Stella, Wasp, Margalo, Hejira, Halakah, Teryl, Lonni, Venezia, Magel, dertra, Bienne, Gursel, Doone, Inga, McDade, Debra, giros, a bogan, Reade, halos, Rosio, Mists, Opp, Malacca, Menorca, Marble, Snapp, a pep, a preoral, Lili, Kaz, a kook, Kislev, a repulse, Tiros, a soft-pedal, Adivasi, Lach, Coffee, Roye, BIT, Tobye, Solim, a yaup, a pod, Landri, alinota, a flab, a celibate, vica, Aeneas, Mdoc, Senusi, Tito, jotas, Sirach, Pease, Elik, Spillar, Tica, Vlos, Abijah, Turro, Mittel, Loraine, Bornu, Kone, lobolos, a loofah, Torbay, Bogan, eddied, Meryl, Lole, Iguac, Rica, Sewole, Nims, a yate, Vallo, diacoca, Igor, Doble, Burkitt, a bay, Durkee, Kaaba, a comal, an azole, Gda, Mollet, a copse, Vacuva, Clem, a hog, Ardelis, Islek, cerebra, GATT, a bate, Grogan, a vacuole, Nordau, a pyrrole, Floral, Liz, a bal, a cadette, Jakob, Moli, Elvah, T-bar, Amyas, Soble, Volnay, a mneme, Debye, Krute, Kahaleel, a zebec, Ney, a morro, Cosyra, Maxa, Jaffe, Lyly, a baobab, NDAC, Inge, Lydda, Mukul, a mnage, Knoll, a game, Johppa, Swarts, OAO, lists, a mask, Cabet, a fam, Orvah, Sibylla, Tyree, DSO, Alyss, Invar, Tade, Pilos, a kayak, Kkyra, GNP, a camoca, Nouma, Behl, Bible, Behah, Nathanael, a pam, Sitka, Sharra, togas, AAP, a camauro, Torelli, Vergil, Siddra, Regain, a titivator, bodegas, a fee, Kapaa, Jayme, Jannel, Adlei, Zulu, a pref, a rojak, cols, a have, DML, a hame, Brahe, BWC, a lava, Cyna, Lemkul, a tazza, Jas, Elazaro, Doe, Tyrol, a marge, Lidda, Mikel, Amati, Lunik, Barrett, a ballotade, Jassy, Lief, Fagan, a dustup, Jarrell, Enkidu, Dinse, Zitah, Susi, Bandur, Minette, Romona, Kolivas, a duma, a beerpull, a cairn, Islay, a gam, Rietveld, Duma, Nedda, MTP, a cot, Toomay, Abadan, Rojas, Wallraff, Fima, Avivah, a volcano, Glad, Roley, a gain, a batt, a veep, a camise, Gaut, Pest, Srta, Miho Kanno, Dielu, a plot, Noel, a payoff, Spar, Elias, a part, a sax, Drogin, IAD, Delaine, Volsci, Mima, a vote, Tye, Knipe, Prue, cassoni, Blaze, Poliatas, a toro, Gittel, Legis, a pint, a cay, Roget, a cad, NUL, Lubba, Dannon, Nepal, Wojak, Syene, Pushto, Bangor, Feld, Dibru, a fillip, Paluas, Sible, Zosima, a wade, Riddle, Vadim, a hilum, a fader, Fleet, Sidoma, PWA, Jac, Duse, Loma, Nelda, Moigno, Test, Slav, a stroma, Flo, Rheita, SSB, Binette, Babara, Vonni, a xis, a sox, Ancel, an atlas, a baya, Dru, Tasha, Roos, Kama, a mise, Yaron, OSlav, an eyrir, Akira, Haff, a revote, Eris, Agama, Slovak, Lusaka, Jaye, lirioddra, Grekin, Ed Wasser, Daphnis, a tennis, a pop, Yama, Neely, a genipap, Malcah, Sarajevo, Dav, a sniff, a rib, Bartok, Jarid, Dagan, Rube, a rebote, Kalfas, Uri, Peadar, Evipal, Lewak, a kill, a knoll, a drop, a vac, Mweru, Cenis, AAUP, a cyc, Also, Durr, Epsom, a lambda, Druse, Bel-ami, dayanim, a la-di-da, MGr, an amal, siddurim, Aimil, a kami, Kayseri, a flotsam, a hypocaust, a mam, a hydra, Gayla, Tantra, Brote, Elda, a pipal, a ghat, a laze, Galax, a strop, Minabe, GCR, a nappa, CWO, Burta, Micah, a kebab, Maracay, Nox, a steno, Garda, Lauda, a buckeye, Kolchak, Kus, a mule, Valeda, CCR, Suffr, Oakleil, Muttra, Madi, COSPAR, Odus, a sib, Barbuda, Lexie, Walke, Truda, Wonsan, Adlay, a femme, Kalil, a knop, a collet, socks, Akhaia, miri, Dekeles, Ieso, Kokoruda, a kisan, a zakat, Pelage, byes, a kaif, FAM, a moral, Kono, Gardenia, Zipah, Ptah, Suchta, Erlene, Faydra, Hag, Nisan, Ermanno, Dali, Noni, Blader, Flatto, Close, Nimocks, a cam, a plebiscite, a raise, Kauai, Jarnagin, a waif, a sulfanilamide, hagia, Medeus, a drab, Bono, Pironi, Gur, Epirote, Durno, McAllen, Yarmuk, Zosi, a rest, Celaya, Jaal, Leonteus, a soda, Maybelle, JFK, Dhar, Elbe, Gypsies, Nematoda, Bub, Allisan, a gee, Kass, a keynote, Isia, Maia, cypselae, Linis, Ronel, Meave, Nkrumah, Gus, a reif, a swob, Marcile, Razid, a comer, Pusan, Rianna, Elia, Caserta, Viseu, Barta, Guy, a camla, Hazen, Isin, Neddra, Zion, Orose, Timofei, Meerut, Lucais, IAS, umbrae, Goda, a must, Asabi, Yate, Kawai, Farrah, Saleem, Deanne, Varro, Clay, WRAC, Cyril, a kail, a hyd, Dada, Maillol, a says, Legge, Phail, Atalie, Weide, hyli, Meek, Beulah, Pindar, Taku, a snide, Hiltan, Eveleen, Wotan, Addia, Zima, Steps, Leonid, Rosati, Vada, Dur, Denni, Daley, Blighty, a feu, Almohad, a prau, Quita, Dumah, Sergei, Coad, Alvaro, Duero, an antenave, Bain, Aksum, a rappee, Kaye, Camenae, Jamil, a haoma, Syd, Darnall, a dobl, a baud, a pyrene, Vallie, Wei, Tralles, Sibyls, Eliz, Zurbar, a gpad, Orlene, KIAS, ged, a pepo, RNA, Mayeda, Abulfeda, Susy, Laise, Robigus, a caird, a probate, Kamal, Ignatius, a zee, Grotius, a floret, a fil, a kalam, a dorr, a vanadate, Gaspar, Pirali, Kossel, Bramah, Save, Beka, Spee, Kaleb, a syrup, Pinette, Yasht, a fail, a brume, Dail, a penni, Dias, Jhelum, Megalesia, Metius, a dug, Nealy, a celt, Titan, a drogue, Mornay, a dab, Daisi, Split, Neda, a grogram, Kast, Musial, a payroll, a magnate, Tinia, Comus, a malt, a rami, Tray, Breda, a vee, Riggall, a wammus, a yawl, a gayal, a mym, Matisse, Jemimah, Torrey, Wast, Tom Wopat, amebae, Murage, Bak, Colt, a macer, an aren't, Tibetan, a titan, Orvas, Oeno, Trevor Eve, Boru, Aleen, lots, a bagnio, Liszt, a kagu, a sass, a maim, Matrona, Eleanore, Valli, Corel, Zanzibar, Habiru, a laic, a canaller, Radom, Zosema, Jesse, Javanese, Lorita, Sussna, Verel, Loral, Hagai, Lonee, Kayle, Lydia, Mamor, Feil, Lucretia, Waal, Licht, a pad, Dearr, adytta, Meill, a houdah, Kissee, Gee, BSEP, an elayl, a topmast, Fleda, Aggadah, Tessin, nylghais, Semeru, Alage, Monacan, Gisele, Messenia, Crewe, haleru, a lay, Lise, Nord, a psid, a refl, a hade, Zaid, Dagall, Abdu, a slag, Ninette, divas, Wayolle, Leeanne, Vacla, MDAP, Malabo, Meda, Poll, a gauge, Post, a fac, Xeno, BSIT, Arnel, a gyve, DMD, a rake, Potts, a facebar, a gleek, Cocks, Ieyasu, a snoop, Malamut, a blackamoor, Galofalo, OFM, a date, Bethsabee, BSL, a plaid, a razorbill, a wpm, a cml, a pimola, SMD, Cook, Collimore, Damarra, wallies, Orcus, a leek, Coray, Bosnia, Moreno, Ilise, Partan, a golem, Mossi, Song, a rabato, Orna, Malek, Nurse, Sulu, a small, Ahira, Ganymeda, Becht, a lapse, Raj, a pattle, Powe, Maxi, Lichas, Uskub, Bida, Drus, a pazaree, Gwenni, Lovato, Delastre, Borodin, Uyekawa, RATO, Jet Sol, a tune, Vail, Oeagrus, a spirket, a papable, BCE, Komara, Wemyss, Eurotas, Selemas, Sirotek, Cohan, Abukir, a dog, Natalia, Watt, a khayal, a taxable, Bonnee, Kidd, a rsum, a cru, Pia, Duvida, Kurt, a breve, Doig, Gav, a raceme, Dak, Cahan, a gall, Ahab, Mozarab, an aught, a ballet, a pap, Moray, a cartage, Peppi, Dyce, Grus, a ploce, Vida, Sug, a valuable, Geist, Ovida, Blakelee, Keel, a taps, a will, a gaol, a layman, Rebak, JET, a mirage, Hadria, Cecil, Prus, Afro, Dinnage, Cameo, Bouar, Fall, a flavonol, a vail, a levee, Roid, a ray, Merrel, a tamable, Damara, Megarus, Arelia, Way, Randee, Haim, Maryn, Reave, Davida, Oria, Cnut, Lulu, a purse, Vladikavkaz, Tadd, a regal, a lake, Ruelu, oesogi, Rida, Lwe, Max, Erida, Love, Darb, asses, Maarib, Mable, Vera Sos, a veto, NFL, a hap, Atlee, Hapte, Hyllus, a drag, Gahan, Osee, Bhatt, a myotome, Dam, FSA, Syllabus, a marga, Kedah, Aberdare, Joyann, Iznik, Rossi, Bichat, a fall, Eurydamas, Nemrod, Isidro, Flita, Farrell, a hard, Dedra, GSA, MALS, a hotpot, Celaeno, List, Farkas, Gable, Bologna, Slavkov, a puce, parasnia, Merse, Geronimo, DST, a fpm, a dam, Kdar, a fa-la, Mahren, Robus, a rote, Fai, Kiran, a go-cart, Cable, Babits, a vocable, groats, a fire, Jonas, Sable, Baler, Palua, Mahala, bird's-eyes, a jaup, Goat, Marc Snir, a mamma, Cyllene, Tromso, Dukas, Tree, Groh, Costain, Uskdar, Elita, BMetE, Fayme, Devi, Loats, a veil, Lide Li, MSBus, a woe, Steve, Thai, Marcin, a pappus, Akita, Mokas, OEM, a cirripede, Babb, a seed, Nicola, Meli, mellita, BSMetE, Romaic, Rosellen, Urbain, Nexo, Cyn, Norse, Polad, a cicala, Vashtee, Leor, Deryl, Lidah, Tabb, a snib, a spat, a waken, a jota, Janis, IOOF, a numnah, Petsamo, Angl, U-boat, Tulle, DAB, Assad, Deedee, Rimma, Cohe, Komsa, Mose, Babs, an auk, Sunyata, WCTU, Bil, a hag, Gosse, Rees, a sial, Limoges, a rial, Celik, a stun, Duhamel, a kas, Neoma, Coh, cellos, Nepil, Duce, Miran, agapai, a posse, nixes, a void, a raff, Otes, a xat, Nysa, Tulsa, notes, a tundra, Weihs, a data, edemata, Haynor, Adonis, Roydd, Alduino, McNeil, a tailgate, Elsa, Trakas, Yesenin, Aegates, a cod, a zaibatsu, Guat, toilettes, a maziness, a buran, Yvette, Huoh, cacaos, Mdlle, Recorde, pinnulae, Brezin, Melosa, a god, Alamosa, Hess, an amide, Pain, a tacnode, Raynata, Blasien, Giaimo, an occipital, a garb, Miocene, Riess, Algren, Rosa, a monosome, dungas, aortae, Draconid, a lytta, Cayugas, a kula, a step, Pisa, Noell, a gallopade, Vidar, a yield, Dugas, Pitts, Ulah, Tenes, merits, a baba, Janine, Vaal, Littell, a gaz, a jihad, Lamoree, Bail, a peto, Boots, a force, navi, Jarib, Orianna, Susette, Dino, Sliwa, Tirol, Ahaz, a jehad, Luht, a bailee, Kama-Mara, luces, a foilsman, Neisa, a duce, geisa, Odille, Goff, Miseno, Gula, Vtesse, Hoe, gasmen, Oise, Hoi, Cruce, Zadar, a gula, Ful, a tackle, Naima, Chae, Demona, Zola, Margareta, EEE, Bauru, Kansu, Eocene, Goeselt, rodeos, Salesin, Edom, a dau, Riba, James, a sod, a sima, Cabe, Manado, Xenos, Lorette, Fayola, Mad, Landsman, Molokai, Zurek, Coral, a gigawatt, a wat, Simla, Spain, Moslem, a caiman, Susu, Tisa, Cdenas, Leeds, Eugenia, Morse, Kissel, Lexine, bursae, Lissi, Gussi, Bowe, PEDir, Tim Daly, Alogi, Pres, a miler, Pazit, Rossen, Kee, Mayer, tails, Elyn, a morse, Pagas, a vat, Tennessee, Litt, a koto, Kosaka, Ransome, Dren, Musette, Bob Saget, Tobit, a keyway, a blame, Smitt, a myg, a nappe, Stinnes, a truce, Nisa, Tennes, a moolah, costae, Fedak, Gereld, a stge, Reel, a virtue, Tyzine, Risa, Kurusu, Lurette, Damita, Cyd, Dorset, a bail, a that's, a veg, Alisa, Dayaks, a madam, Bhili, Menes, Ornas, a hammer, a max, Elisa, a molasses, Subir, baffies, a dee, Maeve, Savdeep, mylodei, Demerol, Leao, Benedic, Ilisa, Ragusa, Rebba, Janelle, Welkom, a dad, Dusa, haikai, Teresa, Brusa, Hadar, Hube, Insull, a groin, Gies, a lagen, estocs, an app, Ankeny, Alysa, Janel, Lusa, Marybelle, a farseer, a doc, Corso, Kobarid, a sci, Tome, Daffi, a stag, Etta, Cadillac, Sara Rue, Ismaili, Cece, Tutt, a barb, Mahla, D.T. Lee, Kilah, a doodad, Jennilee, Kavla, a grugru, BSEE, Lail, a mosaic, nunneries, a turbit, Tomah, Gonave, Krein, a payola, Ronn, a pull, a gnome, Dag, Norway, Orlena, Gudren, Gessner, Oliva, hazanim, Getraer, Fenn, a yaffle, Nauru, Hun, Abagail, a coke, Musil, Lille, Vargas, Uel, a mestee, Mak, Collum, Kal, a chat, Arawaks, a tap, Isla, Kadar, a fascine, Modred, Dun, a vestige, Lais, Ewa, Lussi, Fanni, Obla, a knit, a knee, Val-d'Oise, Hoder, Flam, a smelt, testae, Federal, a dun, Algie, hibla, Eyla, Maidanek, Tiamat, Calabar, Gatun, a foe, Glaab, Bure, JHS, a radula, a die, Hamo, Pula, Hake, Beryl, Lateran, a fat, litatu, Lith, Sadoc, Mino, May, Alamo, Halfon, a gat, Slade, Haslett, Abigale, Pavla, ceibas, Barce, Makassar, Gail, BSSE, Perce, Ploeti, Lodi, Pelaga, Janaya, Ransom, a roo, Moln, a daffodil, a zootechnics, a bassinet, Urbas, Rue, Sidnee, Delmar, Camala, AAAS, a vein, Reed, Yola, Melun, a depside, NHG, an ootid, NABAC, Scylla, Haida, Bomu, Hannon, Nelie, Dream, Mangalore, Janela, Milo, vitae, Mendips, an anatto, BLL, a teg, a calpac, R. Ravi, a sirrah, a verticil, Apsu, Racine, Valhalla, Toll, a chafer, Taxila, a minimax, a mola, Videvdat, Lilac, Fini, Jamille, Paz, abollae, Byrle, Veradis, a hull, a tonight, a knave, Kissimmee, Sarto, Kosse, Vee, Baku, Lyn, a doh, Toscano, Glaser, Pakse, dalles, Ursal, lacoca, Mutazila, a daw, Zebulun, a microsome, Maye, Calie, Kylila, Ponselle, Palila, Mull, a collun, a loss, a millrun, a yrs, a miller, a blade, Camilo, Pansil, Bikila, Maice, Nazi, Bini, Cyma, Blau, Susann, a defilade, Borek, Kehoe, Damales, Sybila, a boy, Kila, Merola, CSO, Diao, Gosser, Genesee, Lydie, Hamm, Elidad, a debit, a lader, Cosette, Docila, a livre, Kam, an away, Sadiras, a voice, Idolah, Tralee, Kano, Camila, DEI, a snool, a sailboat, Allerie, Khanna, Sussi, a kasha, Val, a hakim, a dat, Futabatei, Vine, Sloane, Galaxy, Paine, Zoarah, Cirone, Vulcan, Naylor, Eanes, Lenssen, Div, a nun, a pee, Bacis, Abas, Eulau, a bootee, Stila, Abaco, Rosse, Nila, Maebelle, Bisset, Otila, Ahola, Malay, Alamein, Newgate, Boniface, Derte, Medrek, Cookie, Kodiak, Kohanim, a dag, McKale, Indra, Ha-erh-pin, a systematiser, Etrem, Derrel, Iobates, Solenne, KANU, Jacobina, Boice, Kola, a zool, a pal, Lola, Noli, Spears, a bit, Kassab, Raine, Dola, Sucy, Biadice, Idola, a pin, a balsam, Iyre, Lowe, Dalila, Caine, gigsmen, Regina, Jabir, a kylie, Kreg, Gulag, Adam Trese, Dayle, Vola, Soll, a backsaw, winos, Bion, Oneill, a wittiness, Eldin, a dray, a leeway, a regatta, Waaf, Fitts, a vaad, Lanette, boti, a stet, Conall, a poky, morays, Siret, a way, babas, Esme, Gretal, Odin, avos, a brae, Yael, Leon Lai, Rome, Maidie, Hassin, a bola, Nabila, Catie, Kalli, Richter, Essam, a habit, Cuero, Morez, Zorah, seraphs, Ivatts, a beedi, a sports, a byre, Kalidasa, Gongola, Margo, Gola, a kal, a manager, rin, Abednego, Mini, Kristen, Urbano, Marjy, arybballi, Field, Ducan, Udine, Dalymore, Jolie, Tyro, Vignola, a cola, Duer, fraela, Dee, Stelle, pelikai, Rainah, Teak, Kemeny, a redleg, an amice, Kylstra, BSIE, Weiler, Orense, Geis, Sadat, Signe, Huron, Imitt, Aubrette, Glenn, a deodar, Elf, Feola, BSEc, Ricci, Fuchs, a cake, Reigate, Yonit, a larum, Dorren, Orin, a rede, Haag, an accordion, a gate, Ramin, agorae, Luanne, Paull, a pyre, Gamin, a toilette, Yavar, Gaal, Neocene, Locklin, a cere, Bille, Doane, romans, Samuela, Dilly, Spalla, Mei, Dunaville, Westfalen, a paal, Leola, Lull, a taboret, Sudnor, Behre, Lwoff, Fugate, bullae, Mainis, Sacci, Gollin, a rennin, a vrille, Dylana, Wulfila, Ceporah, a lull, a toenail, E-boat, Kassi, Soni, Cull, a hat, a qaf, FOE, Karalee, Scopas, Ivetts, a cab, Butsu, Grahame, Koenraad, Dupre, Kopaz, enties, Iola, Magdala, Ylla, Cyrus, Ambala, Massawa, Balakirev, a hominid, Rosette, Baten, Eri Imai, Mongol, a gator, Gennaro, Klatt, a wage, Mavra, a wus, a zodiac, a tapas, a pain, Nord-lais, Sudra, Midis, a hip, Metts, a mass, Ensor, EEG, Allier, Taal, Izaak, a soakaway, a saice, Levi, Grati, BAgE, Maite, Yalu, Kara-Kalpak, Rowe, Kamasutra, a dis, a qaid, Nice, Kansas, yokes, a hipbone, Kaylee, Saville, Greg, Nagano, Seen, Maillart, Suanne, Hein, Nanterre, Pravit, Lucan, a derail, Libre, Kabir, Rice, Lura, Ollie, Trevar, Gayle, Broome, Gde, Sabir, a keir, a karo, Modla, Weizmann, a do-all, a calla, cat's-eyes, Leroi, Elis, a vulcaniser, Ethanim, Adala, Magyar, Cornall, a call, a gpm, a lobola, Luben, a calibre, Rise, Damodar, Elsie, Wain, a murre, Daggna, Ishmul, EACSO, Grassi, Krasnodar, Oly, a saccule, Faun, Iasi, Clarie, Winn, Admah, Genolla, Morice, Crosse, Hapi, Rhein, a lampadaire, Kiss, Urdu, a regret, CEF, Fen, a draw, a lessee, Tom Waits, a bvt, a coll, a haik, a sag, an eyen, a leer, Swen, a vicar, Elura, a lek, kielbasas, Binet, Segura, FAAAS, a rabi, Tarrel, Hakai, Granada, Maho Takai, Bim, an agura, Nembutsu, a honor, Ymir, Moselle, Zagreb, Balsam, Prato, Borah, Cormac, Corene, Daedala, Mahanadi, Parnas, a maser, Paur, Hennig, Gonagle, Bayle, Grega, Jael, Hadsall, a patin, a manakin, Tissot, Tombalbaye, Maryville, Grodno, Malonis, a caesura, Dede, Boyd, Derrek, Cohanim, a tupelo, Caracas, Obola, a no-ball, EdS, Marleah, Cimbura, Fee, Baez, a potage, Thais, Sieg, Delanie, Waneta, Camb, Pinot, a callet, an apanage, Taif, Atarax, Audre, Muse, Raffo, Belayneh, Coryell, a wait-a-bit, a cerise, Daye, vinos, Malaga, Jason Lee, Smail, Rianon, Ochs, a patio, Kadai, Garaway, Armina, McLain, ICBM, a lotus, a birne, Heinie, Haifa, an abura, a deva, Masha, Bute, Kamilah, Platt, a catcaller, Talie, cace, dadoes, a payer, Figge, Rizas, an axel, Pirnot, Roseville, Derina, M. Soittola, Plata, Camag, Ruse, Raama, Hants, a pawer, Dr. Dre, Timaru, Omura, Pool, a sauce, Tiffani, Ladinos, CAA, Sisely, a sym, mesocola, Lutero, Disini, Kalmar, Gaidano, Terina, Suisse, Carnot, Pelag, McKuen, a peen, a sot, a beryl, Kwasi, Pelham, Harneen, a pecan, Wadai, Bardeen, a rootage, Dall, a teil, Libreville, Bojer, a panada, Jaf, Hegira, Bernie, Winola, Deerdre, Mira, a mitt, a cavil, a sayer, Bracci, Pen, a trustee, Baxie, L'Otage, Lazor, Minos, Walsall, a getter, Amasias, a maill, a goosegog, a pen, a sum, almsmen, Regine, Hispano, Elo, pants, Ezana, Terceira, SOS, salad days, Supat, Rora, a snowcap, Mimir, a kiss, Issus, Soloman, Odine, Siesser, Payne, Devora, a cymar, TTS, a pact, Sunil, Loredo, Page, Mali, Ven, a trocar, Evora, PCA, an eyra, Margate, Dagna, Ynan, Agnola, Greysun, Corot, a coven, a subadar, Gaye, Liao, V. Claus, a casa, visaed, a rood, a general, a gap, a camass, a topaz, Tindall, a bottom, Mead, a bransle, Dierdre, Blisse, Yeats, a pat, Siam, a lisle, Katar, Renato, Cis, Samara, Drusilla, Micmac, Dwane, Wood, Alastair, a laggen, Asat, Kashden, a puree, Bayville, Harned, Kumar, a bosun, a jesse, Milano, a bagasse, Thayer, Faina, ECOWAS, Gardas, somata, Fariss, a hodden, a sill, Owain, a rubeola, Silures, a mail, Hadas, Uis, a legate, Romano, Fran, Reace, Ural, a venom, Mamore, Pozna, Caleb, a diesel, a pensil, Jamaican, gitim, Meares, a meu, Gora, Tella, Millen, Allsun, a sucre, Bora, Rose, Reese, Raimes, a nasute, Raab, Bevon, a morass, a mudir, Etem, Morganne, Debora, Dey, a seesaw, aurei, Fiden, a dace, Furtek, Citarella, Medora, Srini, Dyana, ballets, a paho, Piane, Dace, Kure, Polak, Coriss, entradas, Besse, Yonatan, Odets, a taenia, Mora, Moss, Urbannal, Hunan, a vet, Sean Penn, Udall, Eulee, Blatt, a latten, an upaya, Seville, Diasia, Veneto, Gomar, a gusset, Senecal, a bansela, Gondomar, Ammadas, Otus, Abbotsun, a megagamete, Ramayana, Halla, Cym, Melisse, Tavie, Neisse, Tatar, a mace, Dugaid, Desde, Manella, Malone, Vedis, Punan, Orren, a pilau, Oasis, a basil, Berezina, Mo Rocca, Roskilde, Seessel, a pocill, a gyre, Vaas, Venetis, Arapaho, beatae, BAgr, a ganef, Foxe, Merano, Kienan, Alonso, Stafani, Clarey, a stole, Mackenie, Weimar, Edda, Janos, Walcott, a cubature, PYT, Tarn, a hall, Eure, Niles, a baas, Erna, Moor, a kaf, Olea, Farrel, Bee, Fnen, a bwana, Ver, Eyre, Gij, a tensor, Gene Rose, Yenan, a ritual, a premie, Reik, Cordier, a rattle, Faye, Kiyohara, BSS, a ballett, a chs, Urbani, Kerwinn, a valse, Wynn, a faro, Zara, Okie, Roede, Maag, Almeda, Jase, Kajaani, Monessen, a safety, Coonan, Ruby, a raid, Isis, a beam, Musset, a cognate, Vadnee, Renoir, a vase, Mia Hamm, a teocalli, Creed, Norah, a vinasse, Magna, Veedis, Norine, M-line, Blain, a vair, a rosery, a snot, a pickaxe, Linacre, Heis, Somali, Breanne, Dayna, Metis, Sachs, a lame, Hamlen, a w/o, Blen, a git, Terrene, Zorana, gemmae, Bharat, Nataniel, Feosol, a tace, Kline, Rola, Jolee, Purana, Kress, a pace, Basset, a beat, a ckw, a hombre, Haig, an appd, a non-Japanese, Massasoit, A. Paz, Neville, Dalis, a beer, Tallie, Neila, Hamsun, a hhd, a neonate, Vladimar, Emme, Hamil, a homeplace, Kaldewaij, amoraim, a trek, a bde, Tyre, wolfmen, a sakai, Gulf, Fidele, Day, Rella, Corr, Effie, Ladd, an eyot, a lam, a lace, Ezara, a may, a koso, Grace, Ivo, Graeme, Haase, Weig, Dewain, Emmen, a spritsail, Apure, Muslem, Mike Farrell, a wain, Emilee, Caletor, a galah, Trace, Sumac, a riddle, Naze, Dorati, Rieti, Lose, Maely, a rave, Lakemore, Jewelle, Dales, Sakai, Bartram, Mieres, a cassimere, Jodl, a right, Royd, Antsirane, Rodmun, a dalasi, ries, Solnit, Apurimac, Cure, Midas, Adlai, Helyn, a blain, a megass, a pase, Yeh, Siffre, Sau, Whitehall, Orola, Yamani, WRA, Medit, Noonan, Evadnee, Leyes, Samsun, Iasus, Songhai, Barren, Gawain, a moor, a kilolumen, a didy, Takao, Bes, a slight, a conure, Gauss, an adat, Conan, a gill, a gait, a limekiln, a climate, Meenen, a dairy, L-line, Belak, a bustle, Keg, a vassal, Lorola, Ignace, Spanos, a raffinose, Mann, Amman, a trace, korai, Janssen, deda, Janeen, a deil, Lilah, Seline, Jeh, Cie, Rahmann, Ailee, Kara, Ikara, a bass, a cal, a gesso, Grasse, Nye, Tamala Jones, a sumi, Lawman, an idyll, a samurai, Lay, a cuirass, a suture, Pole, Naarah, Kanarese, Wait, a pallette, Violle, Bein, Nimrod, an amorino, Brace, mammae, Biafra, Moir, a camail, Lit, Torre, Halbeib, Mabelle, Dasi, Snell, a wynn, a grot, a lumen, a stain, a guar, AAE, MSMetE, M-day, Romelle, Kampala, Jae, Budde, Tymon, Oceanid, Deegan, nepmen, a borane, Plate, Makalu, snips, a gym, a snit, Sudeten, a dreg, Delanos, Pilate, Zared, Dorpat, G-man, Alis, a bone, Jair, an ihram, a dashpot, a reed, Ont, a ppm, a secretaire, Prem, a suq, submen, a sort, Niagara, Dior, Balak, Conn, a crare, Beane, V-Day, Pola, Janet, a prem, Mikael, cabmen, a hate, yeomen, Izanami, a simar, ovipara, torpedomen, Irene Cara, SMA, D-day, Pinole, FAO, Kim, a tenno, Graner, Goyen, a hoe, Macassar, Bezae, Dassin, Roane, Davidde, Toms, a reek, columnae caelatae, Hasin, Roy, Peale, Kale, Docilla, Calondra, Wera, a yid, an avion, Amory, a reel, Arola, Hiram, a yore, Blas, a ton, a cain, a flagman, Ailis, a battel, Light, Ribera, a claim, a sled, a tical, a pesade, Russ, an acre, Manet, Seale, Kaila, Luelle, Weaks, Alabaman, Navarre, Heisser, Paige, Deane, multiparae, Base, Sup, Margret, Sewoll, a sabra, Waf, Fulas, Sender, USS, an unau, a sire, Hijra, Mizoram, Melas, Ula, Beore, Woll, a halal, a sawer, Behaim, aspiratae, Hera, Reld, Nahamas, rhedae, Hako, Beera, Ellie, Neilla, Coire, Bai;, Rie, Loredana, a tabret, a pedocal, a get, Roybn, Ellas, Dyane, Kore, FERA, Ely, Gratt, a percussor, a knar, Tim Allen, Adair, a cion, all-sorts, Ibsenism, a scorpaenid, an assessor, a kale, Gehenna, Verein, a vajra, Mraz, a clar, ORuss, an alum, Astra, WAAC, Arabele, Duleba, Rotifera, EdM, Rese, Wasson, a cycle, Keil, a rook, Amabelle, Zaire, byre-men, a rhatany, Lavelle, Faxan, AEd, a genera, a litre, Baiae, Monet, Ozan, a siller, tapemen, novae, bolas, Umeh, Celle, Bonnie Raitt, a pekan, a sunn, a hexane, Diane, Berey, Waseca, Slater, Taam, a satyr, a base, Yee, Butyl, Landre, Guam, a snag, an ombre, Vale, Robaina, Verene, Valera, Mikan, a cuticle, Kedar, Gao, Koball, a weeny, a rail, a royale, Dasie, Law, a gore, Maera, Abbai, Lisle, Wuhan, a fit, Alcimede, oases, a gibe, Kananur, Belier, Feune, Van, a coss, an aune, Bohman, a cnidocyst, a prat, a van, a suer, a campodeid, Dibai, Karami, Jat, an irade, Synn, a heiress, a sleep, Oilla, Cyra, Ivan, a yawn, a malam, a segar, Evan, an eds, Marinna, Melar, Evelyn, a mayor, cellae, Pera, Cia, Clareta, Colas, Watanabe, Kinau, Abilene, Liane, weenies, Bobadilla, Ceil, Zela, Mobile, Danu, Griffiths, a cembalo, Miramar, a labret, tubae, Corcyra, Torah, Cela, Rahman, a vagueness, a tattersall, a waitress, a glede, Bale, Zahedan, a kOe, Katalin, a mallam, Assuan, a midday, Els, Alvera, Swor, Randal, a sagamore, Neils, Elnore, Nicolas, a pil, UAM, a torte, Radie, Liliane, Dafna, CPM, Avera, Ham, a tapeman, Bela, Russo, Bogarde, traps, a caid, an address, Albarran, Rebeka, Mera, Hall, a ha-ha, Michail, Riane, Dion, a teacart, Celene, Dao, Gainor, an attire, Mayenne, Dallin, Obeid, Dubai, Boreadae, Hen, Obad, York, Yan, a dkl, a skirret, Ross, an abasia, Gass, an aliveness, a paca, Lilas, Lman, Edmead, an esu, a pone, Madai, Liaopeh, Call, a wait, a slater, PABA, Jarret, Sisera, Levan, Ahir, a bale, Bore, Yemane, Lejeune, Bailar, Gmat, Iodama, Jane, Hak, a litany, a rabban, a marg, a menad, Pta, a mus, Tasso, Groscr, a mobile, KCSI, Perot, Alban, Alaine, Masorah, a bassist, a publ, a stere, BAppArts, a lag, Nivre, Samira Said, a bore, Kilar, a palet, Sedrah, Neilah, Mysore, HRH, CTA, Adela, pupae, Leban, a vahana, Loralie, Leibman, Allahabad, an abl, a snore, Heine, Damalas, Sihonn, a heer, a lavolta, Halie, Lehmann, a soroban, a surat, Lucita, Mehta, Hatta, Alitta, Mass, an abs, Suilmann, a vizirate, Baese, Yasna, Cade, Kimura, Balas, Dione, Dame, a ham, Hoban, a glonoin, a faun, a zaire, Gladi, Brion, Urbai, Bretagne, Byrne, Hassan, a midair, UNDRO, Fae, Sosna, Caye, Veats, a chokebore, Gagauzi, Musa, Mok, an impv, Cleti, Maleeny, Allain, a darts, a ccm, Gerek, culpae, Mitra, Wane, Kosak, Rowena, capos, eats, Aetna, Cresida, Rafael, Aeneid, Devon, Arabeila, tannaim, a balas, a bad, Andra, Noelyn, a krater, OFr, a whsle, willets, a crony, a redress, a jasmine, Deidre, Gretna, Clere, Mogadore, Hamlani, Pagnol, Bayless, Ishtar, a bedsore, Carbone, BSRet, Tore, Liew, Netta, Mure, Saadi, R. Leipala, Yin, a dibatag, Garret, salpae, Vitale, naoi, a gnawer, an aerocar, Uta, lay days, Andromeda, Kumasi, Rinee, Dantean, a firepan, Elinore, Vela, Kun, a mat, KKtP, crases, Samarra, Matsu, Gae, Dean, Apsarases, Neve, Leanne, Hahn, a ramrod, a signore, Kamat, a local, Hurless, Uriia, Vasyuta, Avra, Miass, an avo, Vladimir, a haler, Rosana, MSIE, Rior, Deems, a repute, Lael, piscinae, Core, Vladi, Sabbat, Prag, Hosein, Orion, a faena, cameramen, OPer, Tasm, Adao, Gelligaer, Democrat, Mantua, Norean, a fun, a mac, Scales, nugae, Lemire, Peele, Massorah, a levirate, Cinyras, USR, a tyre, Lead, Lamia Diamane, Zavras, arguta, a lulav, an adiabat, Comras, Inness, a btl, a side, Thamar, togae, BSAgr, a whse, Lyell, Oph, a rastle, Katee, Karr, a pale, Ginevra, Maier, Falun, a caps, a wane, papillomata, Kistna, Vas, a cadre, Grubman, a vessel, truths, a waxer, Galilee, BAE, Seurat, Scrogan, a pampre, Hase, Taylor, a knot, Feliks, a lakin, a degenerate, Patten, ulnae, Steffie, Savona, Camilla Belle, NRAB, a hardcore, pennae, Maranon, Nagyvrad, a canakin, VOR, Buderus, a rag, pleis, Sambre, Hasa, Borras, Garrot, Ness, an atman, Waddle, Wesle, Hayse, Linn, a heyday, Daladier, Fair, a valuta, Sarraute, Toh, a dissogeny, a lead, Avram, Jessen, Ulani, Genevra, Main, a vela, Gilead, an acidness, a galilee, Fan, a horsehair, a panne, Brenna, Cayenne, Tippets, a waf, Fina, Clete, BAg, Rotman, Addy, Wan, a medal, a said, Donegan, a total, Hokusai, Dollar, Omuta, Naida, Crowe, H. Yamada, Kannan, a hydrocele, Dore, bigae, Isle, Henie, Reis, Salamone, Danuta, Sidras, oaths, a volatile, Matuta, a raddle, HIH, Sartre, Galan, a millilitre, gemsboks, Alturas, Altaf, Cleota, Reitman, a bo's'n, a naut, Conelrad, Cramer, Feodore, BIE, Spokane, Kota, CAC, epinaoi, Hoyt, Iligan, a salaam, Agan, a ref, Fagaly, Whale, Dakota, a lekane, Mss, Algeciras, a gamete, Magan, a lagan, a yes, Dupaix, a ratan, a pumpman, a word-lore, Bogota, Husein, Noriko Aota, mota, Allen, a cape, Elsinore, Blase, Mansart, a pyran, a calef, Fiesole, Mapel, a sapota, STL, a snoot, Aras, a praam, Klaye, Cadmarr, a wadset, Uni, Mts, a lav, a lore, Zarah, trigae, Else, Levitan, a sun, an appellor, a padre, Havre, Fayal, Brale, varas, a lap, Minor, a haaf, Fulani, Klamaths, a rotl, a satin, a diene, Jason Isaacs, a titre, Bhai, Dinesen, a belier, Delsman, Arun, an ally, Grattan, a sob, Milore, baths, a level, Ed Gale, Dupr, a coign, an airman, USM, a dame, Rodl, Obie, Saire, Zamir, Athal, Ute, plagae, Belgae, Vat, Comr, a gasbag, Nisse, Lynn, an ads, an adrenal, Pat, Araks, More, Kate, Raina, Tura, Moerae, Leesen, a bladebone, Truman, a lota, Kele, Kataway, a rosette, nota, Rattan, a codomain, a titanosaur, a maths, a numeral, Limann, Irene Dunne, Byz, Zita, a hydrolase, breeks, a plat, a rale, Bertram, Syman, Amram, Hoare, Safire, Samos, Narah, Cattan, a glaire, neela, Lelah, Tarsuss, a law, Azan, a ken, a kane, Murat, a bogeyman, Edie, SVR, a hawknose, Gle, Hekate, Rama, Homere, Fayre, medullae, a diapason, Mela, Mansur, a can, a remital, a pore, Karas, Ela Weber, Gawen, Isak, Starr, a fore-topsail, Blakemore, Gemi Taylor, a keg, a solleret, Tocci, Amaras, a garotte, Bazin, Biela, Lucina, Cote, Leilani, Barsac, Uela, Melanie, red algae, Lucite, rates, Eras, Dia, Clarette, Basle, Nikita, Sassan, a miss, a bonze, Ingamar, Dole, Mason, Allegra, Mailer, Osei, Niemen, a fats, a porbeagle, Heimer, Tacita, Laine, DAgr, a dasein, Ori, Flessel, a sapele, Kaenel, ligulae, Derek, Cita, a mote, cymae, Ludie, Samoset, a grenade, Malaccan, a dita, a missile, Kinabalu, a barret, Sisak, Rame, Dita, a diaspore, PEI, Ndebele, Kaffir, a tapir, Edita, a diastole, Hatteras, Utas, a cabbala, BTE, Sidra, Noeleen Todaro, Dnepr, a hone, Reid, Nicholle, Trot, a tonn, Anatol, a stem, Resnais, a cedi, Gere, Deccan, a butanol, a tenaim, Mikaela, Flan, a sedile, Nafl, a flan, a soar, a matsu, REME, Vere, playas, Martita, Vinn, an aeon, a capital, Layman, a buckra, Meras, Beret, Tita, Alleras, a crackle, Yasu, an arcade, Ventre, Blaire, GSR, a leveret, Aleras, a culet, Tevere, tilaks, a reis, a cremator, Cumae, Dine, Lesak, comae, Lepaya, Melitene, vitita, a mahseer, Fablan, a maenad, Emma, Homerus, a raglan, a saiga, Lepaute, Portingale, Mita, Pol, a salute, Peg, a today, Ardehs, Angelle, Kayes, a claimer, Gayl, Lie, Roots, a protasis, a hartal, Rita, a bor, Raglan, a centre, Player, Ellette, Lecce, Rafaela, Leelah, Procne, Naaman, Amorita, Eur, a liq, Arion, a micra, Massorete, Mila, Klan, a mermaid, a genro, Beer, FDR, a sac, Paola Barale, Balaam, a balao, Johanna, Case, Nyhagen, a fair, a remedy, a clan, Allistir, a bases, Altair, a sal, a dacoit, a racer, a vane, Garate, Voyt, Ivis, Samanid, Warren, Natale, Romain, a denier, a lee, mallei, Vernal, a tache, Pohai, Victoire, Haye, Kaela, Caplan, a kor, a tales, Madaih, Susanna, Claramae, Komsomol, a skirr, a gallingness, a coder, Ala, Pierre, Tess, Abyss, a corr, a faille, Machaon, a megacycle, Winne, Bohs, a nacelle, Will, a hire, Gerita, Kerr, a gamebag, Keare, Greer, Fadil, a seer, Gelene, Beare, Maceio, Jala, Dinoceras, a displayer, Gale, Roseanna, Conrad, Lonne, Rufus Sewell, Euryale, rivalries, a pilaf, Huguenot, a casaba, Yucat, Soares, a lar, a tisane, Loomis, Samale, MAEd, a rita, a light, Lita, Alita, Alain, a dalan, a dairymaid, a tamale, Castro, Peer, Frohne, Saks, moths, a gale, Ike, Zellamae, Ellamae, Himerus, a retene, BMR, Alan, a corallita, MiNE, Daly, Bisayas, a peg, Aragats, an amirate, Baiss, a cavalcade, Malar, Ellita, Ary, Graaf, Here, Riss, a colon, a moir, a lignin, Nita, Tremain, a rcvr, a melt, Surat, a gossip, Mirelle, Mafala, Myrta, RSFSR, Ambrosane, Gogra, Calimere, Nett, a rat, Spener, Estele, Dorelle, Keene, Reiss, a cade, Malan, a kenaf, a loaner, Eskil, Susana, Tasia, habenulae, Gethsemane, V-sign, a roarer, Heliadae, Porta, Derr, a bakra, cannulae, Lazare, volcanos, an alienor, Tate, Baeda, Dilan, Aloidae, Sola, Herta, Elberta, a spasm, Holladay, Ezr, a cakra, Maire, Biskra, Minot, a girasol, a basset, Annaba, Donets, a retsina, Moroni, Pul, a dinoceras, Otter, Azaleah, pis, a processor, a sale, BAO, Gujarat, Allan, a topsail, Larned, a gonif, Far, a patter, Evelinn, a malar, a glair, a gybe, Sandro, Flight, a pollan, an erg, Lhasa, Lysol, Omer, Tamil, a scr, a myriare, Basso, Ingaborg, Ellan, a dekare, Kamerad, clarts, PRE, Tades, a rigolet, Ararat, a quass, an okra, Mitre, Tamra, cnidae, Tad, USN, Arta, a bundu, Head, a veneer, a koala, Darrel, Warta, a til, a sovran, a deray, Arte, Pelopidae, Noelani, Vries, Iole, Habdalah, Wran, a wolfsbane, Valais, a pot, an organelle, Kreit, a basso, Gala, Akkra, Myra, Memel, Assyr, Amato, Braille, Kleiman, a kabala, Vermeer, a kelp, Marta, Ker, Eulalee, Kanaka, Lukacs, G.A. Bliss, a cote, Spohr, a canine, Berte, Mas, Otte, Sparta, Esra, Cayes, Martsen, Read, a gen, a farer, Adaha, Tupamaro, Jammu, ideta, Sulla, Byran, a feta, Niel, Cunaxa, Fra, Cahn, a taffeta, Arette, S. Takasu, Anadyr, a baller, Odlo, Heer, Frere, Delsarte, Paola, Nisei, Krak, Amon-Ra, Colb, eupatridae, James Read, Liss, a camel, a sail, a fir, a glegness, a parr, a fytte, Pacian, Eric Blair, a fakir, a forte, manes, Nalani, a papaya, Kyra, Moirai, Hindu, a trait, Ursala, Gran, a sisal, Aun, Amasa, Jarad, Amen-Ra, caca, Simran, an emeer, Flann, an apr, a cap, a cerate, PRA, callused, a wood, an emigr, a maraca, Kolar, Almeeta, Ellen, Rockne, Glivare, Voss, a pair, a faraday, Adar, a flenser, Fleeta, Agle, Ballarat, Tass, a ctr, a hepar, a sallet, segni, Koweit, Tahoe, Doralia, Hussar, a sparer, Utamaro, Bran, a mom, a dracaena, Jasun, a mattamore, Zahara, Matless, a copra, Cdr, a pole, Macap, Cruz, a ricin, a tetany, Lyra, Maise, Lisette, Lucelle, verrucae, Tima, Milne, Geiss, a lessor, a trot, Agenais, Sankaran, a torr, a captain, a pillowcase, Malinin, a prep, Meta, Lory, Graf, Steyr, a byelaw, a karat, Rahr, a chg, a moderate, Creta, Plion, Nammu, Greta, a molar, Azal, a sanicle, Debir, a cane, vesicae, Guaymas, Neiman, a swimmeret, Arran, a bonsai, a resale, Zetana, Hirai, BOT, an esplanade, Ensign, a lasso, Vladamar, Alegre, Boyt, Laelaps, a gare, Kasai, Hal, a stableboy, Orran, a scran, a silo, Porte, Maas, Sinis, Samira, Haphtarah, a cymaise, Li-sao, ICC, APRA, Catlaina, Jaret, Saracen, Nealah, Comdr, a brocatelle, Katsina, tuladi, Oren, an ace, Dare, Fleta, Tigr, a matt, an acne, Lytle, Weyl, a rocaille, Kildare, Melleta, Aleta, a devadasi, Seleta, Mun, a cran, a disposal, Claire, Favata, Kel, a he-man, EMR, a cowtail, Seumas, a yamen, egos, a ganoin, an ale, Rosane, Zeeman, Eran, a partner, a dare, Sumatran, a mere, Haemon, orts, a garoter, Patiala, Lokayata, DATA, a lure, Fabre, Sato, Tuareg, Nils, Dumas, Parcae, tisanes, Beaune, Goulette, Devinne, guttae, Loire, Tran, Allene, Ravi Kannan, an inn, a tael, a gerah, Sorb, an insula, Madoc, Sobor, Castle, Babar, an apple, Yawata, Zachar, Harahan, Noble, Hannan, a soh, a parader, Fadiman, a lion, a saffian, AAgr, a main, Osnabr, a barytone, Zapata, Yale, BAEd, Husain, a nasal, Assur, Colet, Emma Noble, Hebr, a bobtail, Apr, a cenote, canales, sata, a mair, a cassata, TCS, Suevian, a surra, Camorra, Cabimas, Senn, a macule, Diarmuid, ICA, Rimas, a listel, Gian, a raw, a demesne, Sayre, Litae, Loss, Irak, Corday, ties, a gamin, an agata, Artimas, Mil, Sum, Nonnah, Gall, a copperah, a dread, a birota, Min, a namer, a haemin, an awe, Ive, Kala, Mazatl, a repair, a lamasery, Grani, Dal, a sizar, a tayra, Cale, Messere, Haskalah, Trumann, a tare, Kawasaki, Zora, MSN, a mohair, Ott, Andr, a ya-ta-ta, Rolo, Crab, Adonai, Roter, paillettes, Saberio, Mme, Dian, a pirate, Petr, a hop, metae, Carter, Pasadis, a quor, a marc, Almanon, a fare, Kata, Ellene, Rakata, a corbeille, Krenn, a mas, Azor, a median, a stamen, a var, a palaestrian, a welfare, Sycamore, Halli, Brian, a set, an albata, Azar, a bag, Nier, a warfare, Kanarak, Centre, Sufi, Gignac, Irfan, a potentiator, Camas, a carfare, Fine, Jeni, a leaser, a lavaret, Sewell, IATA, Cila, Tigre, BSN, a lehr, a proposal, Eads, Yuri Mitsui, Spelaites, Soleure, Tarabar, a ball, a syll, a syr, a cobra, Cromer, Taino, ICs, a locale, a cimaise, Trainor, Acamas, Platte, Ladue, Spaak, Col, a posit, Ilocanos, Dielle, Dulce, Dave Mirra, Clyte, Canale, Dianne, Groete, Maegan, a maple, Denis, Samain, a valor, Amy Locane, Rosol, Abu-Bekr, a plate, Peerce, Dale, Ciliata, a cine, Jamin, an atar, a balata, Osy, Crater, Damas, Ogun, Alem, Adamas, Cram, Ptain, a million, Issachar, a tone, Gattamelata, Lebar, a millimetre, Blight, an acce, Berriman, a diadem, a homogenate, Grata, Bor', a case, MRE, Kafre, Kaja, Masao, Tom, an impregnator, Bode, Irra, Crataeis, Salem, Margarette, Laodamas, Edi, a clamor, a canaigre, Sorata, Werra, Cotsen, Recit, Crane, BSAE, Roda, Simsar, a meliorate, Lorelle, Perak, Cuman, a snipe-bill, a strata, AIME, an anatman, a coin, a mason, Namen, a great, a rata, Rey, a pet, Arak, Glynn, a dallan, Odovacar, T-man, a reign, a trone, Saml, a spare, fossae, Guaira, Bglr, a poet, Tamara, Mata, Rem, RAF, Tridacna, Sais, Alegrete, Merce, Dahna, a kit, an acrolein, Nadaha, Mozart, a classer, Tao, Dane, Reyna, Samar, a gleba, Sidran, Elsene, Llyr, a ceriman, a rater, Eversole, Danialah, Treat, Nema, an intr, a barre, Shayna, a lin, a dlr, a color, a barr, a bhp, Myna, Nole, Dame Edna, Ammanati, Union, Iman, a nailer, a knorr, a beeline, Jesu, Batna, Hab, Som, Dem, a homeroom, Heater, palala, Monastir, a mailer, Ed O'Neill, a separates, a regr, a signal, a petasus, Piotr, a hussar, an abstr, a hart, Suleiman, a drail, Liman, a mun, a haram, Margaret, tatamis, Sennar, a sabre, Kaete, Peene, Leitao, Flynn, a linn, a ladle, Mekn, a ratel, Yarak, Cos, Sahara, Zandra, Wallace, Raeann, Etna, Cora, Mbabane, lagenae, Lianne, Sadie, Rennane, Raynah, Sherr, a borehole, Putnem, Erine, Vladamir, a have-not, Talaing, a calcite, Masora, MILR, a cpm, Cremer, Dagnah, a prolamin, Anatole, Tamas, eide, Merriman, a celadon, Ysaye, Nora, Minne, Lynna, a drain, a lovat, Conard, McHale, Baubo, Nur, a hairtail, Lunna, Rod, a tamas, Drolet, Drobman, a pinnule, Menam, Helene, leiomyomas, Praha, Ronna, a hit, an aerometer, Empusae, Cinna, a distr, a bleat, a crane, Kinna, Ola, For, a genre, Vala, Fuseli, Bari, Minna, Jara, Medici, Tavares, Ielene, lipomas, Etr, a cabman, a dollyman, an able, Hagno, Steele, Roselle, Witte, Lafitte, Gilda Radner, Tadio, Lyman, a terr, a baht, a lower-case, Grae, Solyman, a debaser, Dnestr, a primero, Halevi, Tat, Ice, Rao, Sur, a charr, a janitor, a canikin, Amann, Amy Lynn, a tain, Ode, Campman, Aara, Masai, a kin, alabastra, Meit, Annam, Adnah, a yarak, Cole, Volapuk, comas, Lanna, Dorr, a hair, a manna, Nies, Sabelle, Banna, librae, Dosi, penates, Punak, a tan, Una, Nos, Cutlerr, a cedar, a pane, Elianore, Hannah, Turkoman, Asni, pala, Volin, a dilater, a valet, Tenebrae, Rosanne, Jaen, Itabuna, Attalie, Bikaner, a kiln, a resin, an arr, a pellet, Seppala, Luce, Buna, Kin, Dunaj, Bluh, Shandra, CNote, Kanal, Luks, Muna, a kore, Sydelle, Douala, Lalla, Godliman, a broodmare, Tyrr, a propane, Lloyd Devore, Seine, gliomas, spiculae, an elytra, Meg, an arcana, Desai, Manu, Staal, a collapsar, a daraf, Chile, Hilaira, Cecile, hydrae, Duna, AAM, Jim Dale, Tomas, a puna, Amritsar, Bennir, a matte, Rebane, Gahanna, Vassar, a damar, Odelle, Deni, Lin, an aeron, Elenor, a bane, Kaile, Medicare, Soliman, OSS, Linda Hart, Luna, a tuna, Fichte, Haerr, a stele, Monaca, a signor, a batwoman, Aeaea, Pansir, Coleman, a sole, Romania, Haldeman, an imamship, a kona, a lustre, BMarE, Yona, Edin, Ozona, Epp, Israel, a ger, Gaynor, Abaris, Eanore, Bodnar, a freeman, a rot, a lupin, a manure, Makasar, a bice, Dares, Oona, a post, an occasion, a variate, Haakon, Aar, a half-barrel, Iona, Kiona, Nike, Marat, Craig, Latona, Pos, Kliman, a coir, a cabaret, Taranis, Sassanid, Derwon, a megalosaur, a tobira, clepsydrae, Satu-Mare, Tamasine, BSEd, a grain, a partisan, a haar, Casia, James Darren, Won, a flare, Lycaon, an airfoil, Isabelle, Desirae, a cram, Herve Gallaire, Valora, catabases, Marseille, Wynne, Jovita, Tice, Raila, Madeira, conchae, Bona, Kur, a snare, hetairai, Desi, Peonir, a melon, an adder's-meat, a tabaret, SAE, Lona, Ede, Gerar, a hairball, a dibucaine, Brenn, a tetra, Mark Lamarr, a birr, ICAO, Ilona, AIC, a tram, Chev, a won, a kaon, a sen, Iletin, Udale, Solana, an actg, Stone, lares, Rae, Herat, Saon, a hail, a degree-day, Nazarene, Greek, Ule, Mamallapuram, Simona, Oni, Maine, Bairam, Hon, aciculae, a report, Seaman, Beadle, Miyasawa, spirae, Tann, a tarot, a mice, Danelaw, a doyen, a thalamus, a mona, a butane, MRA, Darren, Bealle, Buraq, Crescin, a matlo, Hanau, Gun, Edla, Buffon, an ailette, Sumatra, Cremona, a gene, Sask, Carr, a bazookaman, a silvertail, a meat, Antenor, a basin, Rona, Madelle, Bayar, Frona, a comedienne, Jinnah, a marinara, Haman, pterylae, Ell, Orne, Namur, a shp, a resaw, Aksoyn, Exeter, a genit, Ramona, Gerona, a kirn, Essen, Lavona, Irus, submaxillae, Floyd, a crab, alulae, a glare, Duala, Cilo, Jamaal, a hematin, Alodi, Jena, Elgon, a decretal, OIr, a metol, Crete, Pylle, Baal, a salet, Ama, Zinah, a barrel, Lorne, Nader, Paik, Aries, a waggon, an agit, Tarai, MNAS, Liberalia, Jared, NIA, Merat, Torr, a prosser, Pedaiah, Glynas, fibulae, Dieter, Asar, a deciare, Tyr, a lasagne, Nari, Pasol, a borasca, Grete, Plerre, tailles, Sibylle, nebulae, Timon, an aye, Halette, Viyella, morulae, Egon, a curtain, a blare, Braun, ungulae, Nilus, Rufena, ATA, Merton, Omero, MNE, Kuo, stelai, Crag, Syl, a dodecanal, Cynara, Hassam, Ginelle, Romanes, Orelu, Donal, Hatshepsut, a leader, flats, a cerat, Sitra, Clare, Billat, an appar, a hyena, Mair, Amaterasu, Donau, a cabane, sambaed, a staple, Haas, Limemann, Aretino, Bena, affaires, Siena, Duane, Raynelle, Diyarbakir, Apelles, Oram, Skirnir, a catnap, Blair, a cannoneer, a remission, Allare, Pisano, Gart, Senate, Tomasine, Lausanne, Weiss, ennedra, Waite, Petra, Caen, an achar, a fleet, Shekinah, Tremayne, Kalle, Naamann, a roll, a parergon, a detail, a disrepair, assets, a read, Lir, a scalare, Gitana, Hamann, a layer, a chair, a moire, a tenaille, Neo-Latin, Amalek, Corynne, Loti, NEbn, a sasin, a tyro, Vinaya, Wal, Loram, Clair, a lair, a mitre, Blaeu, Hilaire, Gessen, Elba, Neil, an inane, Bael, Deena, a serotine, BSIR, a paik, Atalaya, Bre, Kaleena, Latin, a lidocaine, Gaile, Deroo, Mayne, Knitra, Moti Ben-Ari, a traditor, a cabala, Dylane, Gram, Row, Leena, City, Loiret, Caball, a gram, Agon, an exon, a yen, a regressor, a peh, Cleopatra, Casabonne, Liu, Strep, Peter, a lutein, a lass, Iraq, Pratt, an avocet, Ximenes, Oreg, a tenor, a bael, Lebaron, Oder, Patna, Dixon, a drib, Lia, Jarek, Curtiss, Agadir, a snort, a gena, ARC, Aret, Nippon, a nog, Ela, Curetes, Saman, Orten, Gamali, Brianne, Lynne, Basile, Damle, Saimon, an apa, NRA, Crain, a tabu, Stein, Adelice, Danilo, PICAO, Wilonah, Tena, a tesseract, McNair, a capon, a roti, Dena, Karon, an agger, Ednas, a plasmolytic, Adena, Lias, gulae, Ignaz, a whare, Meer, Ard, Nasia, Siegbahn, a ram, a tecassir, a sycamore, Karelia, Jabon, a capsule, Bon, a sim, Anitra, Myrle, Shaia, Sino-Tibetan, Ulane, Vena, Marr, a bedeman, Iene, Gabon, a lat, Conal, lire, Valle, Yahgan, a vacillator, Ibagu, Stevena, Sik, a ribbon, a rota, Luca, Janot, Wutsin, Aila, Timisoara, Matapan, a hare, Giessen, Eli, Tal, Ovalle, Helbon, abomasa, Montserrat Caballe, Dunois, a vena, a delayer, a georama, Cesar Romero, Des, Lisbon, a kraal, Leanor, Aaren, Holiday, Dene, Kwajalein, a dale, Braila, Gunas, crevalle, Demetra, CAT, Luane, Radu, Styr, Nedra, Ware, Davena, Pal, fraena, a sora, Michale, Secs, Pydna, Bala, Lloyd, Donati, Pena, Drain, a lahar, Denpasar, a heliodor, a paten, a japan, a cacao, Toma, Koo, Kustanai, Dis, Bonaire, tegulae, Dart, Sena, Ami, Hsu, Stanley Adams, ILO, Bate, Massena, Egan, Natalia Paris, Sandra, Canad, a maroon, a navar, a capot, Pitana, Jun, a martnet, Xena, a ten, a zoolater, Cesar, Eva Le Gallienne, Basie, Rena, Sta, Gebelein, a deficit, Sirena, an outsider, Friday, Orlanais, Etra, Caesar, OTC, Erena, Kai, Moon, Aym, a goon, Adlar, a heel, a medic, Uele, setulae, Elat, an asbolane, Lacaille, Macao, ROP, Pasargadae, Hel, Doon, a rete, Mor, Tina Arena, Larena, Noh, Shannah, pronaoi, CCA, Jasen, IAM, Eilat, an eider, feculae, Roper, Daman, a design, a butterball, a roadlessness, a meletin, a sabalo, Tamanaha, Mirabelle, Dunoon, Adlare, Mena, Naha, Turenne, Jemena, an enamelware, Warder, paenulae, scleromata, Barnaise, Lassalle, Heim, Mike Saks, Ragnar, Edra, casus, a depot, a kiaat, a goodness, Urbannai, a steer, Gaeta, Curacao, Presbyt, Iline, Sadi, Binah, a delegate, Mayes, Palomar, a patsy, Cot, Amena, Deer, Gayn, a ratite, Petar, Imena, Botsares, Selene, Kanara, Filomena, Nemunas, a daman, Osi, Born, Aisne, Prestige, Lena, Niter, Cesaro, Tani, Milena, Zane, Karbala, Morgagni, Tace, Dakar, a barrator, a foramen, Imo, Kane, Rijn, an init, a baseball, Ibsen, Arcadic, a repairer, a grille, Neile, setae, Dinah, a misfeasor, a spikedace, Danit, Salena, Riemann, a baleen, a rascasse, deaneries, Holliday, canulae, Fara, Canace, Daira, Mo-tse, Fin, a maar, a knag, Niple, Hanae, a bassoon, a muleteer, Garek, Corinne, Joelynn, an orseille, Nikolai, Bone, Zavala, Valadon, a melena, ERA, Hoenir, a canaille, Haile, Shaer, a major, a beg, a tropaion, an areg, a minah, a retail, a tipcat, Neb, Ros, Danae, Pate, Manara, Malet, a bros, Danais, a kilograin, Argile, SSR, Obala, lekanai, Melena, a blight, Eiten, Ina, Infield, Don, a dorab, Fraser, a wadna, Lorain, a ma'am, Ayina, Sol, a borate, Wina, a coroll, Uvedale, Dira, Myrt, Ole, Halliday, Oralee, Mia Sara, Camile, Salus, Ruffina, lamellae, Pereira, Mannar, a solfatara, Calydon, Automedon, a sip, a restr, a weaner, Oleg, a tole, Hasen, UNHCR, a monas, a mimetite, PETN, a sadi, Bar, a casein, Orabelle, Holocaine, Zwolle, Yasui, Cor, a bait, Alexina, Eger, Abaddon, a tele, Yonah, a mile, Stroheim, Martainn, an ataman, a kina, a telamon, a supr, a cate, Madra, Zina, Emmer, a megarad, Ines Sastre, Vergne, Nay, a konak, a war, a stir, a guenon, Exile, Harpina, Rein, a lei, Lara, Claman, Imre, Danas, megaara, Caracalla, buckayros, a vavasor, a dinnerware, Mon, Oina, Phina, Hale, Saxon, Elaina, Damon, a kil, Male, Sabina, Isa, Molokan, an assent, Cele, Saxe, Bina, a ducat, a farad, a pile, Halle, Sirsalis, a prestrain, Monahan, Nabala, Tremann, an anil, Ora, cerecloths, a galliass, a ware, Sunay, Vina, Yen, a loin, a daemon, a nom, Eade, Calais, Yolane, Kira, Mila Mason, Indiaman, Ezar, Ashti, MSHA, Rasia, Jos Baeten, an adenosine, Kassala, Deianira, Mnemon, Ariadne, Gelanor, Cimon, a nasion, Illinois, Simon, a nadir, a canalis, Hatasu, Maron, Gina, spinae, Tane, Rydder, Fallon, a potstone, Lasser, a maleness, a galatine, Beni, Din, a saline, Barbaresi, Lae, Dina, retinae, Reg, Nate, Milon, Aso, Ger, a medina, Eta, Elon, a vinylation, a lane, berets, an acarid, a flavin, Uppsala, Edina, Shinar, a paisano, Tomasina, a whitener, Olette, Var, a cassolette, Decato, Sina, Lot, Inn, a mor, Tina, Nell, a yarraman, Otina, a dor, a balun, a raser, Iaso, Jer, a paracasein, Asael, gorbellies, Raman, Horace, Bernat, Con, a sir, a ha'penny, Lora, Catina, an elevon, an underbidder, F.L. Bauer, a patten, Alene, Badr, an emetine, Vasiliu, Matina, Sui, Bear, a platina, Cas, Ivon, Avogadro, Frontenac, Frame, Traci, Latina, Cate, yarramen, Albertina, Dar, a seaware, Teer, Gael, Sile, Davon, a platelet, Artina, Medan, a naos, Susanne, Killen, Iceni, Martina, a tissue, Lina, Cain, a manor, a bakeware, Gagne, NASA, Ban, an amu, Idonah, Tama, Klina, Muir, Avon, a sone, Levit, Allina, Dor, a heir, Americano, Mallina, a subacetate, Canara, Luger, Rina, Nis, Irina, Sole, Putnam, Yacano, ITU, Tit, Seder, Pascin, Erina, DAE, NNE, Narra, Mosira, Marti, peronnei, Shannan, a lai, Shere, MatE, Maat, Aleedis, Norina, ESE, Levon, a rep, Murton, a dig, Nara, Caenis, a ban, an aloin, Arcaro, Tomaso, a bar, a cadastre, Beaner, Etoile, Hayes, a collaborator, a separator, a cotton, a ratton, Abigael, a dan, a laurustinus, K.M. Venkataraman, a what's, Ruhr, a deceit, Talaemenes, Ore, Kalat, Rom, Mina, Hanna, Vashti, Der, Emmeram, Sib, Allyson, Oman, an issue, a claret, Arce, Sno-Cat, Sig, a mina, Ler, IATSE, a pan, a nag, Nic, a fret, Nina, Avi, Jana, ais, Alcot, Roana, Regan, a taillight, a dragoman, a piastre, BLI, Gar, a sarsenet, Kenay, Raton, Abagael, Baton, a lira, Matane, Rexana, NAD, a billeter, a haet, Neenah, ScM, Jerusalem, Martyr, Evaleen, a raider, Emmalynne, Kloman, a lacunar, a snarer, a cat, a gar, a seine, Roxana, a rone, Lorianne, Kandahar, a skeleton, a toman, a brocatel, Eton, a rel, Bonne, nares, Sangraal, a kana, MIE, Hana, Akan, a terra, Mala, Para, Casar, a premate, Mahayana, Ottoman, Azana, Ree, Palatine, Roger-Ducasse, nemos, Gunar, a fana, Elga, Elkanah, Clein, a duodenum, minae, Telemann, a sonneteer, a sea-lane, Deaner, a spermaceti, Nida, Navasota, Barry Sadler, a hatter, a sea-maid, a craal, Aynat, Ghats, I-go, Lore, musettes, IrGael, a mate, Mael, a cicerone, Leslie Caron, Darrelle, halalah, kernoi, TEL, Peder, Pagedale, Karame, Denae, animala, Romanas, Sletten, a jet-setter, a sec, a para, Calle, Saar, a gnat, a spokeswoman, a lot, Ron, Akron, a six, a toile, Havana, Reta, genae, a snath, Guarani, Ravana, Rota, Ivana, Efron, an ain, Arianne, Jena Malone, Nalor, a celure, Fabron, an are, Valene, Nani, Fast, Aramen, a varier, a pagne, Stevana, Trow, Levana, a tam, UAR, Tor, a batten, a jalor, a charwoman, a romero, Vin, Monah, cranemen, Ileana, a mene, Nanine, Lofn, a space-time, Renae, a smatter, a misleader, Fevre, Seram, Odra, Staci, Roger, a palate, Massenet, a desaminase, Deana, a carbanil, a popinac, Seana, Ravi Boppana, Ellora, catenae, Nile, melanomata, Elane, Gore, Karen, Rutan, a leet, an amarelle, Sarene, venae, Lati, Bron, ASN, a snail, a tirewoman, a heb-sed, a tsar, a partan, Issei, ROT, CAF, Lon, Oneil, a rockoon, Anaxarete, Mat, Conah, Cran, an ayre, Pana, Espana, Rev, Rok, phialai, Neh, Craner, a metaprotein, a redrawer, a cruet, a manak, Ran, a lev, Iran, an atonic, a platelayer, a cymene, Nasi, Sair, a canap, a tsotsi, Tam, Mar, Gan, an acron, a citer, a paean, a let's, a manas, Omar, a pillaret, a valvelet, a n'gana, Roti, Sivan, a nagana, Sam, a train, a rab, a hiragana, Samala, Mlle, scaleni, Pan, Isaak, Sal, a non-Roman, Egor, Tinaret, Nace, Daren, a vara, Campinas, a butanone, Weimaraner, Fergana, Nam, Tamar, a pedal, labaara, Hopedale, sceneries, Sarasota, Roman, Ismael, a roman, a gleaner, a macron, a satire, Vallenar, a subdeaconate, Helaina, Morgana, an agateware, Glenine, Danai, Biron, an organa, Lew, Orr, Upsala, Cara, Care, Noga Alon, ectases, Pilar, a pieman, Anna Magnani, Bara, caci, Petra Jared, Nabalas, an iron, AYH, Par, Gona, Econah, Cato, Sinas, Arabelle, Diane Lane, Grande-Terre, Faso, Luana, a tine, Vanir, a statfarad, Freeman, Ilocano, Ital, Ludeman, a staidness, End, Donar, Emee, Derain, a rain, Osana, a mare, Nicolle, Saideman, a giron, a botany, Lira, Moira, Malagasy, stamnoi, Tan, a menat, Rowen, Adam Alexi-Malle, Haydn, a str, a blighter, a gamone, Dana, ASS, a bargeman, AID, a craneman, Airedale, Davene, Galle, Skee-Ball, Ewer, a fgn, Aron, a leg, Ducasse, Nevis, Iredale, Mara, Calles, Salene, Danyelle, Kootenay, Caron, a scare, Decadron, a praemunire, katana, Mler, epistases, Neman, Oira, MOIG, Adana, Reni, Adron, a sonar, Eddana, Ima, Lahti, Peter Buneman, a weaponeer, Gallinas, Thestor, a baseman, a deadlight, Ronal, Chane, Mai, Shaitan, Giselle, Holle, Hanoi, Tati, Pace, Darelle, Hasseman, Oita, Sil, a gel, Linares, Ubana, Sat, a rom, a nibbana, Sad, Line, Baer, a bdl, an ordn, a sneer, Gayel, Warrenne, Kennan, an afreet, a gelatin, Urbana, Eri, ATS, a der, Freya, Brenner, a wavelet, a cider, Paolo, Pire, Tayler, a matter, a palace, Danelle, Habana, Marabelle, Smithson, a grub, Anson, a guanosine, Basir, Benares, Abana, Eno, Labana, a cabana, Nona, Bellaire, Tamayo, Nov, Anne, Jane Greer, a caner, a cetane, Naara, Manisha Koirala, Shane, Manat, Terra, BLE, Jameson, Adalai, Nino, Goossens, Seler, a caller, Evadne, guanayes, pilei, Marala, Ehr, Rone, Mana, Sir, Fotinas, Einar, Otis, Ivanah, a ferreter, a male, Daile, Kiki Classen, a vimana, Man, a lyc, Nan, Gine, Basel, Ligeti, Grane, Nadaba, Nine, Leninakan, an initiatress, a mana, Noll, a foreman, Agartala, Vardhamana, Edison, a breadline, Beira, Mallin, a malate, Cana, Aire, Taira, Masson, a redness, ENE, Tucana, Ress, a gallate, Marek, Ames, Ion, AEC, Nat, Pros, Banat, Sims, Ocana, Zen, a bitser, Rana, Ena, Cedalion, a guanay, Tine, Lanai, Shanahan, a lanai, Ram, Margarete, Gene, Gelb, a vie, Ceram, Urana, Maher, a fireman, a dinar, a nobleman, a stableman, a dealer, a mallet, sestinas, a leaner, a campanile, Meiji, Jules Asner, a passer, a care, Mark Manasse, nevi, tis, Nes, Nonah, Tirana, SSE, Nel, Bang, a minaret, Sela, Brana, Ila, grana, Ain, a moc, Lace, Daegal, Lane, Nadler, a mtn, Eire, Panay, Briseis, Pigalle, Rosaleen, a ko-katana, Les, Rotameter, a presser, a caf, a crenelle, Hirasuna, Munniks, Lion, Assen, Ilion, an aegrotat, Set, Tana, Sin, a sultana, Ira, Mosul, an espagnolette, Sion, a sex, Etana, Sian, a lesion, a cit, Car, a tana, Adler, a manometer, an esne, Rhaetian, a damiana, Son, Essene, Vita, retinas, Une, Meter, a wale, Delora, Cannanore, Macnair, Colette, Romagna, Kistner, a payt, a hobnail, a run-on, a piperonal, Atropatene, Gargan, a tgn, a setter, Giana, Ten, Oca, Jareb, Memnon, an omelette, Docilu, Kan, an eraser, an abseil, Liberace, Dael, Siana, Tiana, an overcare, Diana, Ann, an ign, a why'll, Ier, a byre-man, Amanda Foreman, Agni, Sharon Au, a sesame, Tratner, a peteman, a vale, deciduae, Cro-Magnon, an astr, Australiana, Nore, Liana, Six, Etan, an anode, Cammaerts, Riana, Ariana, Nah, Cai, Danny Dolev, Isar, Briana, a novelette, Lana, Can, Ecbatana, Ino, Meade, Calah, Plana, Mur, Alana, Han, a trepan, a haematin, a rationale, deti, Lear, Sinon, an aid, Ninon, an aminase, Itin, Ukr, a ser, a bastite, Pattin, a rattan, an aero, Belle, Hayti, Lib, AET, Arnon, a sei, Tila, Rene, Georglana, Amr, Edo, Tare, Karel, Dan, a lignocaine, Lenoir, Elana, a tile, Messene, Nolana, Sue, a backscatter, a gateman, a mode, protases, a banat, Sine, Ilana, Nil, Svetlana, a meter, a secretness, Idleman, a rooter, a parasol, Lem, Race, Elora, Candless, Jillana, Asser, a cetin, Allana, Ebeneser, an acetin, a retina, Leman, OIt, a c/o, Vernon, a linac, a dresser, a ctn, a raffle, Sabu, a thane, Gerstner, a bimane, Naam, Melan, an asp, Per, a monolater, a cayenne, Kenon, a tenon, a vitellin, a manana, a brev, a missis, Piderit, Nana, a ller, a matin, a rebore, an anat, Cleopatre, Benoit, Adne, Menon, a remit, Tala, Tsiranana, Montagnac, Ire, Manon, an air, a tin, a salami, Nanon, a sere, Velleman, Agna, Mannaean, Ecevit, Canon, Ayr, Reb, Ned, Dorene, Gelasia, Nistru, Frederiksen, a zenana, a beebread, Lan, ASSR, Elle, Stets, bonaci, Med, a canon, a dhikr, a marasca, a sign, a resetter, a placarder, Ferdinana, ETO, Inman, an asci, Teh, Tse, an ana, Sis, a banana, Leah, Caresa, Tanana, Sumy, novenae, Nap, Mace, Len Adleman, a nay, Ara, Natala, globigerinas, a mon, a leman, Vera, Stassen, Evita, Genaro, Donavon, a villein, a delight, Nica, Janik, Fulahs, Komarek, a ter, a canal, Panama\"" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Success! We found a palindrome that is longer than any found before. We can do about 50,000 steps per second. I'll stop here, but there are many things to try; feel free to explore on your own:\n", + "\n", + "- I order the actions by the product of the number of prefixes and number of suffixes formed. In other words, choose first the character that forms the most possible completions. But maybe, at least in the early goings, I should choose more difficult combinations of letters, to use up the \"hard\" phrases and save the \"easy\" phrases for later.\n", + "- I'm not sure when to end a word and when to try to continue to a longer word; experimentation here would be useful.\n", + "- The program is deterministic, and thus always finds the same plaindrome. that's boring; can some randomness be introduced?\n", + "- Can we make more interesting phrases? Include determiners other than \"a\" and \"an\"; include adjectives, etc.\n", + "- The counts of prefixes and suffixes include all the phrases in the dictionary. But we are not allowed to repeat a phrase, so can we modify the code to subtract one from the counts every time a phrase is used (and add onr back in when we backtrack over the phrase)?\n", + "\n", + "Perhaps you can find other areas to explore.\n", + "\n", + "# Indefinite Articles\n", + "\n", + "What if every noun phrase (except \"Panama\") has to start with an indefinite article, as in \"an X\" or \"a Y\"? Let's see:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "! [ -e anpdict-short.txt ] || curl -O http://norvig.com/anpdict-short.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "DICT2 = PhraseDict(open('anpdict-short.txt'))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pal: 1,001 phrases, 2,001 words, 5,649 letters (473,669 steps, 13 seconds)\n", + "CPU times: user 44min 43s, sys: 25.2 s, total: 45min 8s\n", + "Wall time: 46min 55s\n" + ] + }, + { + "data": { + "text/plain": [ + "'Pal: 1,237 phrases, 2,473 words, 6,787 letters (100,000,000 steps, 2816 seconds)'" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p = Panama(dict=DICT2)\n", + "%time p.search(10**8)\n", + "p.report()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\"a man, a plan, a caret, a rec, a manana, an anabasis, a tsar, a tanager, an araban, a mat, an aromatic, an amadan, a melanoma, an anatman, an amowt, a barege, a jar, a tav, an arr, a parataxis, an amora, an agron, an ami, a caress, a paracasein, a salad, an allopath, a baronet, an all, a darer, a caravan, an alg, a ratal, an alfa, an agnate, an arg, an arcs, an arcanum, an air, an alp, a nail, a run-on, an aid, a ratan, an anabas, a pat, an ain, a baron, a manakin, a natator, a tarok, an attar, an apa, a nag, an animator, an apr, a tannin, a nap, a janitor, a carapa, an abaca, an atabal, an agal, an abb, a ratel, a salal, a harem, an anime, a hareem, an anim, a gala, a para, a maniac, an ann, a manit, a salep, a laniard, an acaridan, an aced, an adat, an abater, a lca, an amalaka, an aim, a daraf, an anion, a galliwasp, a caraway, a redan, a mow, a nae, a paretic, an avail, a guna, an iter, a nay, a daric, an aug, an origan, a mot, an orinasal, a barret, an ordn, an anil, a torc, an ord, a haram, a darts, an ani, a rater, an imaret, a rut, a sale, a taler, an orc, a nanowatt, an annot, an ore, an angina, a nit, a nos, a nonet, a nogg, a warb, an anus, a nog, a rap, a nome, a dater, a bat, a nom, a let, an ottar, an oil, a tale, a balata, an imam, a rate, a harim, an alapa, a nim, a lar, a cort, an oca, a nil, a saliva, an ips, an oxen, a nod, a rat, an alarum, an oak, an ital, a caracara, a hallah, a nipa, an elem, a nip, a latah, an isallobar, a core, an alias, an inner, a nib, a saloop, a nies, a carol, a varec, a radiov, an emagram, an etalon, a tuba, an evader, a nett, a parol, a jam, a lama, a net, a carob, a tamis, an egg, a lati, an alif, a neep, an eel, a ballot, an alley, an eyalet, a corban, a minah, a regal, a cariama, a nork, a nek, a wallaba, a nomad, an omasum, a lac, an ecad, an ogam, a lame, a haloid, a neb, an esu, a halo, a gallop, a nef, an uta, an okay, a radar, a fanegada, a var, a civ, a nunatak, a zap, an acarid, an upas, a pariah, an udal, a colat, a rabal, a cedar, a gallet, a nub, a retail, a kalam, an alegar, a geb, a retem, a gem, a redd, an alt, an alb, an attabal, a tepal, a timer, a redleg, a repp, an atlas, a ballup, a rep, a carioca, a nut, a resaw, a sal, a tip, a carrot, a resp, a lambda, a tat, a bal, a tot, a resin, a tob, a res, a radula, a tam, a tamas, an amatol, a removal, a sis, a rem, a gall, a carpus, a revel, a rev, a rad, a canalis, a bani, a rps, a recap, a rennet, a reed, a reel, a reek, a fanon, a canikin, a manioc, a reflet, a refl, a dep, a ref, a wall, a cerat, a tub, a reward, a reb, a saros, a vav, a rein, a pannus, a rex, a wanigan, a myriad, a rag, an amah, a rail, a rank, a raob, a rota, a tag, an amurca, a tass, a canoe, an assam, a catalpa, a tad, a room, a rood, a roll, a palais, a rod, a rim, a roc, a rial, a rip, a tapa, a jad, a catnap, a rub-a-dub, a tarp, a tanga, a tenaim, a rani, a tapis, a taps, a taka, a teff, a tap, a lanai, a snob, a tax, a taw, a tennis, a tew, a teg, a teel, a trapan, a mrem, a tram, a trad, a trot, a troop, a trid, a trf, a topaz, a galiot, a topsail, a manuf, a top, a catnip, a tool, a galop, a toom, a tonk, a tom-tom, a tog, a manway, a today, a rom, a titan, a trap, a tid, an assent, a pall, a mar, a bec, a fan, a lad, a til, a tum, a gal, a noma, a tef, a tug, a tufa, a tolan, a rasa, a margay, a datum, a tsi, a waterfall, a far, a mac, a jass, a lag, a batik, a tpd, a sard, a matins, a sav, a samaj, a tabard, a saga, a mallam, a dam, a sakai, a rum, a sari, a palikar, a misaim, a kalema, a mam, a sima, a mag, an assoc, a sumac, a lila, a molar, a peh, a sum, a ramrod, a supp, a pataca, a moc, a matt, a wadi, a matsu, a haeres, a sup, a subah, a lap, a calix, an ass, a pastel, a sepal, a mahaleb, a tabu, a dat, a cuda, a mob, a sex, an ashcan, a rub, a jasey, a strops, a stob, a sora, a minimax, a satsuma, a mix, a mass, a sadi, a ragi, a tab, a lulav, a lay, a wad, a cyc, a sorb, a soda, a mud, a sop, a snug, a slag, a scf, a lack, a laic, a fats, a cassaba, a recast, a hwan, a cep, a laud, a lev, a rayah, a leek, a vat, a gam, a slab, a leg, a baas, a camaca, a ruse, a camoca, a rug, an asb, an aery, an agnail, a lex, an abac, a leud, a liard, a lip, a lied, a lid, a loofah, a loom, a loca, a ripsaw, a swob, a lob, a lub, a bayard, a lyc, a nabob, a cadi, a sag, a dagoba, a lek, an app, a yapok, a dargah, a mib, a daud, a dap, a dab, a dig, a draw, an actg, a drib, a drub, a def, a deb, a dewan, a diam, a dopa, a lune, a papaya, a lug, a doom, a dorp, a dom, a doh, a dog, a doc, a duc, a marga, a liza, a capa, a cup, a marc, a madrigal, a pipa, a babassu, a gad, a dak, an oka, a belga, a grub, a maya, a gib, a map, a mesa, a goy, a mug, a misc, a fat, a qadi, a cay, a sap, a papaw, a myg, a mpg, a pagan, a gob, a powan, a wog, a pika, a pup, a pig, a proc, a peek, a plug, a pcf, a cav, a caf, a cig, a may, a tagrag, a garb, a gaw, a guv, a bob, a kabaka, a dis, a qaid, a kaki, a pay, a bai, a law, a rab, a ways, a jag, a gab, a jak, a yak, a boyar, a halavah, a boob, a haik, a raff, a caw, a pav, an away, a breva, a waw, a bubal, a brev, a flow, a wey, a kCi, a hag, a fay, a jaw, a hap, a baff, a wax, a maw, a dah, a doodad, a duo, a named, an anadem, an aoudad, a doodah, a daw, a max, a waff, a bap, a haw, a jay, a fag, a haick, a yew, a wolf, a verbal, a bub, a wawa, a verb, a yaw, a nav, a paw, a caff, a raki, a haboob, a hav, a lahar, a yob, a kayak, a jab, a gag, a jasy, a wab, a raw, a lai, a bay, a paik, a kadi, a qasida, a kab, a kabob, a vug, a wag, a brag, a garg, a tay, a magic, a fac, a vac, a fcp, a gulp, a keep, a corp, a gip, a pupa, a kip, a gowan, a wop, a bogan, a gap, a gpm, a gym, a wap, a pap, a say', a caid, a qat, a facsim, a gum, a yoga, a sem, a pam, a biga, a yam, a burga, a gleba, a konak, a dad, a gauss, a baba, a pipal, a gird, a macram, a puca, a paca, a zila, a gram, a cud, a cod, a god, a hod, a mod, a prod, a mood, a gula, a yap, a paenula, a pod, a maidan, a we'd, a bed, a fed, a burd, a bird, a gtc, an award, a gid, a bad, a pad, a duad, a bimah, a grad, a kop, a yapp, an akela, a bog, a dag, a said, a cabob, an acyl, a dray, a babul, a bol, a bowsaw, a spira, a col, a moolah, a fool, a dil, a deil, a pil, a drail, a duel, a cab, an axel, a liang, an ayre, an abs, an agura, a com, a caesura, a cam, a casa, a bagel, a balsam, a gat, a vakeel, a hay, a ravel, a dual, a pecan, a what's, a cera, a bass, a cast, a facial, a kcal, a fcs, a gals, a guns, a pos, a duma, a dos-, a bros, a cycad, a way, a lav, a lulab, a taig, a raid, a sass, a maxima, a must, a sax, a minima, a ros, a bots, a sports, a yes, a jaburan, a chs, an axes, a boma, a ducat, a daub, a tabel, a hamal, a pes, a let's, a pass, an axil, a cap, a lah, a bus, a pus, a sere, a haust, a maid, a watt, a macoma, a cat, a pappus, a dorm, a ramus, a hepar, a loma, a lilac, a mus, a coss, an agama, a mis, a mama, a mel, a kami, a simar, a kil, a pair, a samurai, a kas, a madam, a llama, a gas, a drab, a taj, a mas, a vas, a snit, a madras, a dpt, a kit, a bag, a lass, a jacamar, a fall, a fret, a waist, a mut, a day, a grama, a saran, a lota, a fut, a gut, a feta, a monal, a gamut, a lit, a dalan, a facebar, a mall, a patness, an adit, a partan, a tit, a moray, a dot, a yawn, a magot, a motmot, a knot, a moot, a pol, a galoot, a pint, a capot, a fun, a mali, a spot, a toil, a gaz, a pot, a frt, a dirt, a poort, a tort, a dart, a mart, a merman, a part, a leet, a get, a wet, a sinnet, a wat, a xat, a bonsai, an alap, a taffeta, a kat, a spat, a sip, a tain, a rami, an eta, a gnat, a prat, a bud, a bur, a pant, a cad, a jaap, a tapir, a lair, a cor, a mirador, a sial, a pallor, a door, a moor, a data, a plat, a camass, an aeon, a cassata, a crum, an agata, a tor, a boar, a knar, a liar, a ham, an agar, a dairyman, a gin, a waxer, a sunn, a panier, a vavasor, a saber, a drawer, a butat, a recall, a wafer, a pedalfer, a telfer, a coin, a manikin, a canon, a fakeer, a leer, a deer, a tenner, a pacer, a sprain, a basil, an acad, a raver, a lever, a supr, a call, a gamer, a sisal, a vomer, a lot, a manas, a mata-mata, a lud, a raser, a botaniser, a total, a batata, a dBm, a lapser, a torr, a capital, a saw, a ser, a tuna, a coir, a caper, a pull, a basalt, a napper, a gelder, a remital, a petal, a batt, an abl, a natl, an adder, a megameter, a begar, a gel, an amal, a kali, a ter, a bun, a tell, a gar, a decal, a barat, a local, a dun, a hair, a pas, a pun, a dir, a canap, a zakat, a nun, a vicar, a vaad, a gen, a farad, a ray, a kona, a tun, a fen, a poll, a gaol, a hausen, a ben, a diol, a haem, a lam, a gonad, a cen, a calamus, a monad, a mona, a ball, a waken, a krona, a mair, a cal, a gerah, an iman, a brocatel, a yen, a yell, an atoll, a baleen, a peen, a fil, an ait, a laggen, a sim, a tabor, a catena, a malam, a jalor, a patten, a red, a vena, a butanol, a ten, a marg, a men, a void, a racer, a valor, a casein, a pool, a sabin, a rennin, a sail, an aerocar, a boll, a sin, a hat, a lapin, a melena, a pin, a hall, a haar, a caracal, a tin, a kaon, a mural, a nat, a radon, an exon, a spina, a vil, a salina, a con, a trocar, a lamina, a pal, an amir, a haet, a ram, a mina, a tal, a bael, a talion, a ratton, a telamon, a tabaret, a daemon, a paragon, a sun, an abr, a waggon, a tenon, a sonatina, an ign, an aeron, a tonn, an att, a won, an acron, a rel, a tael, a saturater, a minaret, a rain, an astr, a damar, a hadron, a crotalin, an andron, a terr, a balas, an iron, a toman, a giron, a guan, a cir, a dayan, a retina, an ugali, a van, a citer, a paean, a woman, a deray, a war, a caps, a will, a ganoin, an afar, a damiana, a kal, a mana, a claret, a banat, a dan, a decan, a nadir, a can, a drain, a lapel, a satin, a mannan, a cain, a maar, a paal, a gamin, an ameer, a haemin, a namer, a halal, a salet, a rabban, a lagan, a lab, a tana, a cabana, a par, a carotin, a japan, an inn, a tarpan, a rot, a min, a nagana, a pan, a rattan, a kor, a tarot, a tan, an ikan, a manor, a banian, a tapas, a ban, an anat, a radian, a non-Uralian, a planarian, a mun, a cran, a scr, an agr, an aet, a n'gana, a flan, a lat, a raglan, a navar, a carer, a dallan, a tenor, a baht, a pollan, a dal, a sanies, a car, a passer, a caiman, an organa, a roman, a six, a tar, a parr, an avatar, a jaeger, a batwoman, an amt, an ana, a mon, a leman, a daman, a cit, a mor, an ataman, a bar, an areg, an atar, a stasis, a banana, a nan, a macerater, a canal, Panama\"" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str(p)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/pytudes/ipynb/xkcd1313-part2.ipynb b/pytudes/ipynb/xkcd1313-part2.ipynb new file mode 100644 index 0000000..63302a6 --- /dev/null +++ b/pytudes/ipynb/xkcd1313-part2.ipynb @@ -0,0 +1,3706 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "xkcd 1313: Regex Golf (Part 2: Infinite Problems)\n", + "====\n", + "\n", + "

Peter Norvig
with Stefan Pochmann
Feb 2014
revised Nov 2015

\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "This Again?\n", + "----\n", + "\n", + "Last month I demonstrated [a simple Regex Golf program](http://nbviewer.ipython.org/url/norvig.com/ipython/xkcd1313.ipynb?create=1). I thought that was the end of the topic, but [Stefan Pochmann](http://www.stefan-pochmann.info/spocc/) sent me a series of emails suggesting some impressive improvements. ([Davide Canton](https://plus.sandbox.google.com/108324296451294887432/posts) and [Thomas Breuel](https://plus.google.com/118190679520611168174/posts) also had good suggestions.) So this post is an exploration of some of Stefan's new ideas, and some of my own. It's a story about regex golf, and about using exploratory programming to test out ideas.\n", + "\n", + "To review, here's the program from [part 1](http://nbviewer.ipython.org/url/norvig.com/ipython/xkcd1313.ipynb?create=1), with some minor modifications:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from __future__ import division, print_function" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from collections import Counter, defaultdict\n", + "import re\n", + "import itertools\n", + "import random \n", + "\n", + "Set = frozenset # Data will be frozensets, so they can't be mutated.\n", + "\n", + "def words(text):\n", + " \"All space-separated words in text.\"\n", + " return Set(text.split())\n", + "\n", + "def phrases(text, sep='/'): \n", + " \"All sep-separated phrases in text, uppercased and stripped.\"\n", + " return Set(p.upper().strip() for p in text.split(sep))\n", + "\n", + "def mistakes(regex, winners, losers):\n", + " \"The set of mistakes made by this regex in classifying winners and losers.\"\n", + " return ({\"Should have matched: \" + W \n", + " for W in winners if not re.search(regex, W)} |\n", + " {\"Should not have matched: \" + L \n", + " for L in losers if re.search(regex, L)})\n", + "\n", + "def findregex(winners, losers, k=4):\n", + " \"Find a regex that matches all winners but no losers (sets of strings).\"\n", + " # Make a pool of regex parts, then pick from them to cover winners.\n", + " # On each iteration, add the 'best' part to 'solution',\n", + " # remove winners covered by best, and keep in 'pool' only parts\n", + " # that still match some winner.\n", + " pool = regex_parts(winners, losers)\n", + " solution = []\n", + " def score(p): return k * len(matches(p, winners)) - len(p)\n", + " while winners:\n", + " best = max(pool, key=score)\n", + " solution.append(best)\n", + " winners = winners - matches(best, winners)\n", + " pool = {p for p in pool if matches(p, winners)}\n", + " return OR(solution)\n", + "\n", + "def matches(regex, strings):\n", + " \"Return a set of all the strings that are matched by regex.\"\n", + " return {s for s in strings if re.search(regex, s)}\n", + "\n", + "OR = '|'.join # Join a sequence of strings with '|' between them\n", + "cat = ''.join # Join a sequence of strings with nothing between them\n", + "\n", + "def regex_parts(winners, losers):\n", + " \"Return parts that match at least one winner, but no loser.\"\n", + " wholes = {'^' + w + '$' for w in winners}\n", + " parts = {d for w in wholes for p in subparts(w) for d in dotify(p)}\n", + " return wholes | {p for p in parts if not matches(p, losers)}\n", + "\n", + "def subparts(word):\n", + " \"Return a set of subparts of word: consecutive characters up to length 4.\"\n", + " return set(word[i:i+n] for i in range(len(word)) for n in (1, 2, 3, 4)) \n", + " \n", + "def dotify(part):\n", + " \"Return all ways to replace a subset of chars in part with '.'.\"\n", + " choices = map(replacements, part)\n", + " return {cat(chars) for chars in itertools.product(*choices)}\n", + "\n", + "def replacements(c): \n", + " \"All ways to replace character c with something interesting: for now, 'c' or '.'.\"\n", + " return c if c in '^$' else c + '.'\n", + "\n", + "def report(winners, losers):\n", + " \"Find a regex to match A but not B, and vice-versa. Print summary.\"\n", + " solution = findregex(winners, losers)\n", + " assert not mistakes(solution, winners, losers)\n", + " print('Chars: {}, ratio: {:.1f}, inputs: {}:{}'.format(\n", + " len(solution), len(trivial(winners)) / len(solution) , len(winners), len(losers)))\n", + " return solution\n", + "\n", + "def trivial(winners): return '^(' + OR(winners) + ')$'" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here are some \"arbitrary lists\" (see panel two of the comic) which we will be using to test out the code. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "winners = words('''washington adams jefferson jefferson madison madison monroe \n", + " monroe adams jackson jackson van-buren harrison polk taylor pierce buchanan \n", + " lincoln lincoln grant grant hayes garfield cleveland harrison cleveland mckinley\n", + " mckinley roosevelt taft wilson wilson harding coolidge hoover roosevelt \n", + " roosevelt roosevelt roosevelt truman eisenhower eisenhower kennedy johnson nixon \n", + " nixon carter reagan reagan bush clinton clinton bush bush obama obama''')\n", + "losers = words('''clinton jefferson adams pinckney pinckney clinton king adams \n", + " jackson adams clay van-buren van-buren clay cass scott fremont breckinridge \n", + " mcclellan seymour greeley tilden hancock blaine cleveland harrison bryan bryan \n", + " parker bryan roosevelt hughes cox davis smith hoover landon wilkie dewey dewey \n", + " stevenson stevenson nixon goldwater humphrey mcgovern ford carter mondale \n", + " dukakis bush dole gore kerry mccain romney''') - winners\n", + "\n", + "boys = words('jacob mason ethan noah william liam jayden michael alexander aiden')\n", + "girls = words('sophia emma isabella olivia ava emily abigail mia madison elizabeth')\n", + "\n", + "pharma = words('lipitor nexium plavix advair ablify seroquel singulair crestor actos epogen')\n", + "cities = words('paris trinidad capetown riga zurich shanghai vancouver chicago adelaide auckland')\n", + "\n", + "foo = words('''afoot catfoot dogfoot fanfoot foody foolery foolish fooster footage foothot footle footpad footway \n", + " hotfoot jawfoot mafoo nonfood padfoot prefool sfoot unfool''')\n", + "bar = words('''Atlas Aymoro Iberic Mahran Ormazd Silipan altared chandoo crenel crooked fardo folksy forest \n", + " hebamic idgah manlike marly palazzi sixfold tarrock unfold''')\n", + "\n", + "nouns = words('''time year people way day man thing woman life child world school \n", + " state family student group country problem hand part place case week company \n", + " system program question work government number night point home water room \n", + " mother area money story fact month lot right study book eye job word business \n", + " issue side kind head house service friend father power hour game line end member \n", + " law car city community name president team minute idea kid body information \n", + " back parent face others level office door health person art war history party result \n", + " change morning reason research girl guy moment air teacher force education''')\n", + "adverbs = words('''all particularly just less indeed over soon course still yet before \n", + " certainly how actually better to finally pretty then around very early nearly now \n", + " always either where right often hard back home best out even away enough probably \n", + " ever recently never however here quite alone both about ok ahead of usually already \n", + " suddenly down simply long directly little fast there only least quickly much forward \n", + " today more on exactly else up sometimes eventually almost thus tonight as in close \n", + " clearly again no perhaps that when also instead really most why ago off \n", + " especially maybe later well together rather so far once''') - nouns \n", + "verbs = words('''ask believe borrow break bring buy can be able cancel change clean\n", + " comb complain cough count cut dance draw drink drive eat explain fall\n", + " fill find finish fit fix fly forget give go have hear hurt know learn\n", + " leave listen live look lose make do need open close shut organise pay\n", + " play put rain read reply run say see sell send sign sing sit sleep\n", + " smoke speak spell spend stand start begin study succeed swim take talk\n", + " teach tell think translate travel try turn off turn on type understand\n", + " use wait wake up want watch work worry write''') - nouns\n", + "\n", + "randoms = Set(vars(random))\n", + "builtins = Set(vars(__builtin__)) - randoms\n", + "\n", + "starwars = phrases('''The Phantom Menace / Attack of the Clones / Revenge of the Sith /\n", + " A New Hope / The Empire Strikes Back / Return of the Jedi''')\n", + "startrek = phrases('''The Wrath of Khan / The Search for Spock / The Voyage Home /\n", + " The Final Frontier / The Undiscovered Country / Generations / First Contact /\n", + " Insurrection / Nemesis''')\n", + "\n", + "dogs = phrases(''''Labrador Retrievers / German Shepherd Dogs / Golden Retrievers / Beagles / Bulldogs / \n", + " Yorkshire Terriers / Boxers / Poodles / Rottweilers / Dachshunds / Shih Tzu / Doberman Pinschers / \n", + " Miniature Schnauzers / French Bulldogs / German Shorthaired Pointers / Siberian Huskies / Great Danes / \n", + " Chihuahuas / Pomeranians / Cavalier King Charles Spaniels / Shetland Sheepdogs / Australian Shepherds / \n", + " Boston Terriers / Pembroke Welsh Corgis / Maltese / Mastiffs / Cocker Spaniels / Havanese / \n", + " English Springer Spaniels / Pugs / Brittanys / Weimaraners / Bernese Mountain Dogs / Vizslas / Collies / \n", + " West Highland White Terriers / Papillons / Bichons Frises / Bullmastiffs / Basset Hounds / \n", + " Rhodesian Ridgebacks / Newfoundlands / Russell Terriers / Border Collies / Akitas / \n", + " Chesapeake Bay Retrievers / Miniature Pinschers / Bloodhounds / St. Bernards / Shiba Inu / Bull Terriers / \n", + " Chinese Shar-Pei / Soft Coated Wheaten Terriers / Airedale Terriers / Portuguese Water Dogs / Whippets / \n", + " Alaskan Malamutes / Scottish Terriers / Australian Cattle Dogs / Cane Corso / Lhasa Apsos / \n", + " Chinese Crested / Cairn Terriers / English Cocker Spaniels / Dalmatians / Italian Greyhounds / \n", + " Dogues de Bordeaux / Samoyeds / Chow Chows / German Wirehaired Pointers / Belgian Malinois / \n", + " Great Pyrenees / Pekingese / Irish Setters / Cardigan Welsh Corgis / Staffordshire Bull Terriers / \n", + " Irish Wolfhounds / Old English Sheepdogs / American Staffordshire Terriers / Bouviers des Flandres / \n", + " Greater Swiss Mountain Dogs / Japanese Chin / Tibetan Terriers / Brussels Griffons / \n", + " Wirehaired Pointing Griffons / Border Terriers / English Setters / Basenjis / Standard Schnauzers / \n", + " Silky Terriers / Flat-Coated Retrievers / Norwich Terriers / Afghan Hounds / Giant Schnauzers / Borzois / \n", + " Wire Fox Terriers / Parson Russell Terriers / Schipperkes / Gordon Setters / Treeing Walker Coonhounds''')\n", + "cats = phrases('''Abyssinian / Aegean cat / Australian Mist / American Curl / American Bobtail / \n", + " American Polydactyl / American Shorthair / American Wirehair / Arabian Mau / Asian / Asian Semi-longhair / \n", + " Balinese / Bambino / Bengal / Birman / Bombay / Brazilian Shorthair / British Shorthair / British Longhair / \n", + " Burmese / Burmilla / California Spangled Cat / Chantilly/Tiffany / Chartreux / Chausie / Cheetoh / \n", + " Colorpoint Shorthair / Cornish Rex / Cymric / Cyprus cat / Devon Rex / Donskoy or Don Sphynx / Dragon Li / \n", + " Dwelf / Egyptian Mau / European Shorthair / Exotic Shorthair / German Rex / Havana Brown / Highlander / \n", + " Himalayan-Colorpoint Persian / Japanese Bobtail / Javanese / Khao Manee / Korat / Korn Ja / \n", + " Kurilian Bobtail / LaPerm / Maine Coon / Manx / Mekong bobtail / Minskin / Munchkin / Nebelung / Napoleon / \n", + " Norwegian Forest Cat / Ocicat / Ojos Azules / Oregon Rex / Oriental Bicolor / Oriental Shorthair / \n", + " Oriental Longhair / Persian / Peterbald / Pixie-bob / Ragamuffin / Ragdoll / Russian Blue / Russian Black / \n", + " Sam Sawet / Savannah / Scottish Fold / Selkirk Rex / Serengeti cat / Serrade petit / Siamese / Siberian / \n", + " Singapura / Snowshoe / Sokoke / Somali / Sphynx / Swedish forest cat / Thai / Tonkinese / Toyger / \n", + " Turkish Angora / Turkish Van / Ukrainian Levkoy / York Chocolate Cat''')\n", + "\n", + "movies = phrases('''Citizen Kane / The Godfather / Vertigo / 2001: A Space Odyssey / The Searchers / Sunrise / \n", + " Singin’ in the Rain / Psycho / Casablanca / The Godfather Part II / The Magnificent Ambersons / Chinatown / \n", + " North by Northwest / Nashville / The Best Years of Our Lives / McCabe & Mrs Miller / The Gold Rush / \n", + " City Lights / Taxi Driver / Goodfellas / Mulholland Drive / Greed / Annie Hall / The Apartment / \n", + " Do the Right Thing / Killer of Sheep / Barry Lyndon / Pulp Fiction / Raging Bull / Some Like It Hot / \n", + " A Woman Under the Influence / The Lady Eve / The Conversation / The Wizard of Oz / Double Indemnity / \n", + " Star Wars / Imitation of Life / Jaws / The Birth of a Nation / Meshes of the Afternoon / Rio Bravo / \n", + " Dr Strangelove / Letter from an Unknown Woman / Sherlock Jr / The Man Who Shot Liberty Valance / \n", + " It’s a Wonderful Life / Marnie / A Place in the Sun / Days of Heaven / His Girl Friday / Touch of Evil / \n", + " The Wild Bunch / Grey Gardens / Sunset Boulevard / The Graduate / Back to the Future / Crimes and Misdemeanors / \n", + " The Shop Around the Corner / One Flew Over the Cuckoo’s Nest / Blue Velvet / Eyes Wide Shut / The Shining / \n", + " Love Streams / Johnny Guitar / The Right Stuff / Red River / Modern Times / Notorious / Koyaanisqatsi / \n", + " The Band Wagon / Groundhog Day / The Shanghai Gesture / Network / Forrest Gump / \n", + " Close Encounters of the Third Kind / The Empire Strikes Back / Stagecoach / Schindler’s List / \n", + " The Tree of Life / Meet Me in St Louis / Thelma & Louise / Raiders of the Lost Ark / Bringing Up Baby / \n", + " Deliverance / Night of the Living Dead / The Lion King / Eternal Sunshine of the Spotless Mind / \n", + " West Side Story / In a Lonely Place / Apocalypse Now / ET: The Extra-Terrestrial / The Night of the Hunter / \n", + " Mean Streets / 25th Hour / Duck Soup / The Dark Knight / Gone With the Wind / Heaven’s Gate / 12 Years a Slave / \n", + " Ace in the Hole''')\n", + "tv = phrases('''The Abbott and Costello Show / ABC’s Wide World of Sports / Alfred Hitchcock Presents /\n", + " All in the Family / An American Family / American Idol / Arrested Development / Battlestar Galactica /\n", + " The Beavis and Butt-Head Show / The Bob Newhart Show / Brideshead Revisited / Buffalo Bill /\n", + " Buffy the Vampire Slayer / The Carol Burnett Show / The CBS Evening News with Walter Cronkite /\n", + " A Charlie Brown Christmas / Cheers / The Cosby Show / The Daily Show / Dallas / The Day After / \n", + " Deadwood / The Dick Van Dyke Show / Dragnet / The Ed Sullivan Show / The Ernie Kovacs Show /\n", + " Felicity / Freaks and Geeks / The French Chef / Friends / General Hospital /\n", + " The George Burns and Gracie Allen Show / Gilmore Girls / Gunsmoke / Hill Street Blues /\n", + " Homicide: Life on the Street / The Honeymooners / I, Claudius / I Love Lucy / King of the Hill /\n", + " The Larry Sanders Show / Late Night with David Letterman / Leave It to Beaver / Lost /\n", + " Married with Children / Mary Hartman, Mary Hartman / The Mary Tyler Moore Show / MASH / The Monkees /\n", + " Monty Python’s Flying Circus / Moonlighting / My So-Called Life / Mystery Science Theater 3000 /\n", + " The Odd Couple / The Office / The Oprah Winfrey Show / Pee Wee’s Playhouse / Playhouse 90 /\n", + " The Price Is Right / Prime Suspect / The Prisoner / The Real World / Rocky and His Friends / Roots /\n", + " Roseanne / Sanford and Son / Saturday Night Live / Second City Television / See It Now / Seinfeld /\n", + " Sesame Street / Sex and the City / The Shield / The Simpsons / The Singing Detective / Six Feet Under /\n", + " 60 Minutes / Soap / The Sopranos / South Park / SpongeBob SquarePants / SportsCenter / Star Trek /\n", + " St Elsewhere / The Super Bowl / Survivor / Taxi /The Tonight Show Starring Johnny Carson /\n", + " 24 / The Twilight Zone / Twin Peaks / The West Wing / What’s My Line / WKRP in Cincinnati /\n", + " The Wire / Wiseguy / The X-Files''')\n", + "\n", + "stars = phrases('''Humphrey Bogart / Cary Grant / James Stewart / Marlon Brando / Fred Astaire / Henry Fonda / \n", + " Clark Gable / James Cagney / Spencer Tracy / Charlie Chaplin / Gary Cooper / Gregory Peck / John Wayne / \n", + " Laurence Olivier / Gene Kelly / Orson Welles / Kirk Douglas / James Dean / Burt Lancaster / Marx Brothers / \n", + " Buster Keaton / Sidney Poitier / Robert Mitchum / Edward G. Robinson / William Holden / Katharine Hepburn / \n", + " Bette Davis / Audrey Hepburn / Ingrid Bergman / Greta Garbo / Marilyn Monroe / Elizabeth Taylor / Judy Garland / \n", + " Marlene Dietrich / Joan Crawford / Barbara Stanwyck / Claudette Colbert / Grace Kelly / Ginger Rogers / \n", + " Mae West / Vivien Leigh / Lillian Gish / Shirley Temple / Rita Hayworth / Lauren Bacall / Sophia Loren / \n", + " Jean Harlow / Carole Lombard / Mary Pickford / Ava Gardner''')\n", + "scientists = phrases('''Alain Aspect / Martin Karplus / David Baltimore / Donald Knuth / Allen Bard / \n", + " Robert Marks II / Timothy Berners-Lee / Craig Mello / John Tyler Bonner / Luc Montagnier / Dennis Bray / \n", + " Gordon Moore / Sydney Brenner / Kary Mullis / Pierre Chambon / C Nüsslein-Volhard / Simon Conway Morris / \n", + " Seiji Ogawa / Mildred Dresselhaus / Jeremiah Ostriker / Gerald M Edelman / Roger Penrose / Ronald Evans / \n", + " Stanley Prusiner / Anthony Fauci / Henry F Schaefer III / Anthony Fire / Thomas Südhof / Jean Frechet / \n", + " Jack Szostak / Margaret Geller / James Tour / Jane Goodall / Charles Townes / Alan Guth / Harold Varmus / \n", + " Lene Vestergaard Hau / Craig Venter / Stephen Hawking / James Watson / Peter Higgs / Steven Weinberg / \n", + " Leroy Hood / George Whitesides / Eric Kandel / Edward Wilson / Andrew Knoll / Edward Witten / Charles Kao / \n", + " Shinya Yamanaka''')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "And here we show how it works:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "' T|E.P|OP'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solution = findregex(starwars, startrek)\n", + "solution" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "not mistakes(solution, starwars, startrek) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Plan of Attack\n", + "----\n", + "\n", + "To improve the program, I'll take the following steps:\n", + "\n", + "- *Profiling:* Figure out where the program spends its time.\n", + "- *Speedup:* Make the program faster.\n", + "- *Benchmarking:* Run the program over pairs of arbitrary lists to see how fast it is and how short the solutions are. \n", + "- *Analyzing:* Learn something by looking at the benchmark results.\n", + "- *Searching:* Introduce a better search algorithm.\n", + "- *Eliminating Parts:* Get rid of parts that can't possibly be part of an optimal solution.\n", + "- *Adding Parts:* Add new types of parts to allow new, shorter solutions.\n", + "- *Randomizing Search:* Randomness allows us to explore different parts of the search space.\n", + "- *Speculating:* Think about what we could do next.\n", + "\n", + "Profiling \n", + "----\n", + "\n", + "Let's time how long it takes to separate the top 100 adverbs from top 100 nouns:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loops, best of 3: 5.4 s per loop\n" + ] + } + ], + "source": [ + "%timeit findregex(adverbs, nouns)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "On my computer it was 4 seconds. I have some ideas for how to make this faster, but I know that I shouldn't waste effort trying to speed up parts of a program that [don't take much of the total time](http://en.wikipedia.org/wiki/Amdahl's_law). I'll use the [`cProfile`](http://docs.python.org/2/library/profile.html#module-cProfile) module to see where the time goes:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 12220085 function calls in 7.748 seconds\n", + "\n", + " Ordered by: cumulative time\n", + "\n", + " ncalls tottime percall cumtime percall filename:lineno(function)\n", + " 1 0.000 0.000 7.748 7.748 {built-in method builtins.exec}\n", + " 1 0.000 0.000 7.748 7.748 :1()\n", + " 1 0.001 0.001 7.748 7.748 :23(findregex)\n", + " 54424 0.051 0.000 7.652 0.000 :39(matches)\n", + " 54424 1.052 0.000 7.601 0.000 :41()\n", + " 2841615 1.347 0.000 6.549 0.000 re.py:170(search)\n", + " 2841615 1.482 0.000 4.016 0.000 re.py:278(_compile)\n", + " 41 0.015 0.000 3.584 0.087 {built-in method builtins.max}\n", + " 25445 0.033 0.000 3.569 0.000 :31(score)\n", + " 41 0.021 0.001 3.335 0.081 :36()\n", + " 45055 0.223 0.000 2.459 0.000 sre_compile.py:531(compile)\n", + " 45055 0.169 0.000 1.206 0.000 sre_parse.py:819(parse)\n", + " 2841615 1.186 0.000 1.186 0.000 {method 'search' of '_sre.SRE_Pattern' objects}\n", + " 45055 0.080 0.000 0.911 0.000 sre_compile.py:516(_code)\n", + " 1 0.000 0.000 0.825 0.825 :46(regex_parts)\n", + " 45055 0.098 0.000 0.821 0.000 sre_parse.py:429(_parse_sub)\n", + " 1 0.003 0.003 0.809 0.809 :50()\n", + " 45055 0.281 0.000 0.660 0.000 sre_parse.py:491(_parse)\n", + " 45055 0.263 0.000 0.650 0.000 sre_compile.py:412(_compile_info)\n", + " 172941 0.076 0.000 0.246 0.000 sre_parse.py:247(get)\n", + " 217996 0.212 0.000 0.212 0.000 sre_parse.py:226(__next)\n", + " 45055 0.159 0.000 0.196 0.000 sre_parse.py:167(getwidth)\n", + " 45055 0.141 0.000 0.177 0.000 sre_compile.py:64(_compile)\n", + " 916825 0.129 0.000 0.129 0.000 {method 'append' of 'list' objects}\n", + " 45055 0.074 0.000 0.122 0.000 sre_parse.py:217(__init__)\n", + " 172941 0.067 0.000 0.091 0.000 sre_parse.py:165(append)\n", + " 28890 0.078 0.000 0.082 0.000 sre_compile.py:391(_generate_overlap_table)\n", + " 574427 0.058 0.000 0.058 0.000 {built-in method builtins.len}\n", + " 45055 0.046 0.000 0.054 0.000 sre_parse.py:797(fix_flags)\n", + " 90110 0.040 0.000 0.051 0.000 sre_compile.py:513(isstring)\n", + " 135163 0.050 0.000 0.050 0.000 {built-in method builtins.min}\n", + " 45055 0.048 0.000 0.048 0.000 {built-in method _sre.compile}\n", + " 225275 0.043 0.000 0.043 0.000 {built-in method builtins.isinstance}\n", + " 90110 0.032 0.000 0.042 0.000 sre_parse.py:75(groups)\n", + " 45055 0.041 0.000 0.041 0.000 sre_parse.py:70(__init__)\n", + " 45055 0.026 0.000 0.031 0.000 sre_parse.py:276(tell)\n", + " 45055 0.029 0.000 0.029 0.000 sre_parse.py:105(__init__)\n", + " 88 0.020 0.000 0.020 0.000 {method 'clear' of 'dict' objects}\n", + " 57782 0.017 0.000 0.017 0.000 {method 'extend' of 'list' objects}\n", + " 1 0.002 0.002 0.016 0.016 :49()\n", + " 45055 0.014 0.000 0.014 0.000 sre_parse.py:242(match)\n", + " 119455 0.013 0.000 0.013 0.000 {built-in method builtins.ord}\n", + " 2131 0.005 0.000 0.012 0.000 :56(dotify)\n", + " 45055 0.008 0.000 0.008 0.000 {method 'items' of 'dict' objects}\n", + " 2131 0.004 0.000 0.005 0.000 :59()\n", + " 14684 0.003 0.000 0.003 0.000 {method 'get' of 'dict' objects}\n", + " 11135 0.002 0.000 0.002 0.000 {method 'join' of 'str' objects}\n", + " 98 0.001 0.000 0.002 0.000 :52(subparts)\n", + " 4921 0.001 0.000 0.001 0.000 :61(replacements)\n", + " 2874 0.001 0.000 0.001 0.000 :54()\n", + " 1 0.000 0.000 0.000 0.000 :48()\n", + " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", + "\n", + "\n" + ] + } + ], + "source": [ + "import cProfile\n", + "\n", + "cProfile.run('findregex(adverbs, nouns)', sort='cumulative')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "About 99% of the time was spent in `matches`. And most of the time in `matches` goes to `re.search`. So my thoughts are: \n", + " \n", + "+ Can we make each call to `matches` run faster? \n", + "+ Can we make fewer calls to `matches`?\n", + "+ Can we use `re.search` more effectively? \n", + "+ Nothing else matters. 99% of the time is in `matches`; don't waste effort speeding up anything else.\n", + "\n", + "# Speedup: Faster `matches` by Compiling Regexes\n", + "\n", + "\n", + "The `re` package uses strings to specify regular expressions, but internally, when we call `re.search` on a string, that string is compiled, with the function `re.compile`, into an object that has a `search` method. If you need to search many times with the same regex, then it is faster to call `re.compile` once, and then call the `search` method of the compiled object, rather than calling `re.search` each time.\n", + "\n", + "Another trick: use the builtin function `filter` rather than a set comprehension. Builtins, written in C, are often faster." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def matches(regex, strings):\n", + " \"Return a set of all the strings that are matched by regex.\"\n", + " searcher = re.compile(regex).search\n", + " return set(filter(searcher, strings))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "One thing to be careful about: the `re` module manages a cache of recent compilations. I call `re.purge()` before each timing, to make sure that I'm not re-using any work that was done before the timing started." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loops, best of 3: 2.95 s per loop\n" + ] + } + ], + "source": [ + "re.purge()\n", + "\n", + "%timeit findregex(adverbs, nouns)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "*That was almost twice as fast!* Not bad for changing two lines. \n", + "\n", + "# Speedup: Fewer `matches` Against Losers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "In `regex_parts`, for each part, `p`, we test `if not matches(p, losers)`. This applies `searcher` to every loser and builds up a set of all those that match. It would be faster if we could *exit early*: as soon as we find one loser that matches, we don't need to apply `searcher` to the remaining losers. Stefan Pochmann came up with a great way to do this. If we concatenate the list of losers together into one big string, then we only need one call to `re.search` for each part `p`. If a part matches the big string anywhere, the call will return immediately, and we will know the part is no good. \n", + "\n", + "There is one catch: we have to make sure that the start of each loser matches `'^'` and the end matches `'$'`. We can do that by concatenating together the losers with a newline between them, and by using the `re.MULTILINE` option. (See the [`re` module documentation](http://docs.python.org/2/library/re.html) if this is unfamiliar.)\n", + "\n", + "Here is the change, with timing before and after:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loops, best of 3: 271 ms per loop\n" + ] + } + ], + "source": [ + "re.purge()\n", + "\n", + "%timeit regex_parts(adverbs, nouns)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def regex_parts(winners, losers):\n", + " \"Return parts that match at least one winner, but no loser.\"\n", + " losers_str = '\\n'.join(losers)\n", + " def no_losers(part): return not re.compile(part, re.MULTILINE).search(losers_str)\n", + " wholes = {'^' + w + '$' for w in winners}\n", + " parts = {d for w in wholes for p in subparts(w) for d in dotify(p)}\n", + " return wholes | set(filter(no_losers, parts))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 171 ms per loop\n" + ] + } + ], + "source": [ + "re.purge()\n", + "\n", + "%timeit regex_parts(adverbs, nouns)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We've made `regex_parts` almost two times faster.\n", + "\n", + "# Speedup: Fewer `matches` Against Winners\n", + "\n", + "Here's what `findregex` currently looks like:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def findregex(winners, losers, k=4):\n", + " \"Find a regex that matches all winners but no losers (sets of strings).\"\n", + " # Make a pool of regex parts, then pick from them to cover winners.\n", + " # On each iteration, add the 'best' part to 'solution',\n", + " # remove winners covered by best, and keep in 'pool' only parts\n", + " # that still match some winner.\n", + " pool = regex_parts(winners, losers)\n", + " solution = []\n", + " def score(p): return k * len(matches(p, winners)) - len(p)\n", + " while winners:\n", + " best = max(pool, key=score)\n", + " solution.append(best)\n", + " winners = winners - matches(best, winners)\n", + " pool = {p for p in pool if matches(p, winners)}\n", + " return OR(solution)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Notice that we call `matches` twice (once within `score`) for every part in the pool on every iteration of the main loop. If there are 50 iterations of the loop, and 1000 parts, that's 100,000 calls to `matches`. Instead of repeating all these calls, I propose that, for each part in the pool, we limit ourselves to this:\n", + "\n", + "- One `re.compile`.\n", + "- One `re.search` against each of the winners.\n", + "- One `re.search` against the big string of losers.\n", + "- Some cache lookups as needed.\n", + "\n", + "During initialization, we create a dict, called `covers`, that will serve as a cache: `covers[p]` is the set of all winners that match the part `p`. The new function `regex_covers` replaces the old function `regex_parts`. Here is the new `findregex`, with timing before and after:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loops, best of 3: 2.85 s per loop\n" + ] + } + ], + "source": [ + "re.purge()\n", + "\n", + "%timeit findregex(adverbs, nouns)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def findregex(winners, losers, k=4):\n", + " \"Find a regex that matches all winners but no losers (sets of strings).\"\n", + " # Initialize covers = {regex: {winner,...}} for a large set of regex components.\n", + " # On each iteration, add the 'best' component to 'solution',\n", + " # remove winners covered by best, and keep in 'pool' only components\n", + " # that still match some winner.\n", + " covers = regex_covers(winners, losers)\n", + " pool = list(covers)\n", + " solution = [] \n", + " def score(p): return k * len(covers[p] & winners) - len(p)\n", + " while winners:\n", + " best = max(pool, key=score)\n", + " solution.append(best)\n", + " winners = winners - covers[best]\n", + " pool = [p for p in pool \n", + " if not covers[p].isdisjoint(winners)]\n", + " return OR(solution)\n", + "\n", + "def regex_covers(winners, losers):\n", + " \"\"\"Generate regex parts and return a dict of {regex: {winner,...}}.\n", + " Each regex matches at least one winner and no loser.\"\"\"\n", + " losers_str = '\\n'.join(losers)\n", + " wholes = {'^' + w + '$' for w in winners}\n", + " parts = {d for w in wholes for p in subparts(w) for d in dotify(p)}\n", + " pool = wholes | parts\n", + " searchers = {p: re.compile(p, re.MULTILINE).search for p in pool}\n", + " return {p: Set(filter(searchers[p], winners)) \n", + " for p in pool\n", + " if not searchers[p](losers_str)}" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loops, best of 3: 251 ms per loop\n" + ] + } + ], + "source": [ + "re.purge()\n", + "\n", + "%timeit findregex(adverbs, nouns)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "*Wow!* That's a dozen times faster! But I don't want to draw too many conclusions from just this one example." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Benchmarking\n", + "\n", + "We will benchmark the program on a suite of 22 different problems (11 examples, run in both directions). The function `benchmark` finds a solution to each problem and prints the number of characters in the solution, and some other information. In the end it prints the total number of characters, and if we use the `%time` magic, we can see how long it took." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "EXAMPLES = [ex for example in [\n", + " (winners, 'win', 'lose', losers),\n", + " (boys, 'boy', 'girl', girls),\n", + " (pharma, 'drug', 'city', cities),\n", + " (foo, 'foo', 'bar', bar),\n", + " (starwars, 'wars', 'trek', startrek),\n", + " (nouns, 'noun', 'adj', adverbs),\n", + " (nouns, 'noun', 'verb', verbs),\n", + " (randoms, 'rand', 'built', builtins),\n", + " (dogs, 'dog', 'cat', cats),\n", + " (movies, 'movie', 'tv', tv),\n", + " (scientists, 'sci', 'star', stars)]\n", + " for ex in (example, example[::-1])] # Do each example both ways\n", + "\n", + "SOLUTION = {} # A cached table of solutions; SOLUTION[W, L] will hold a regex\n", + " \n", + "def benchmark(examples=EXAMPLES): \n", + " \"Run examples; print summaries; return total of solution lengths.\"\n", + " totalchars = 0\n", + " for (W, Wname, Lname, L) in examples:\n", + " re.purge()\n", + " solution = SOLUTION[W, L] = findregex(W, L)\n", + " assert not mistakes(solution, W, L)\n", + " legend = '{}({}):{}({})'.format(Wname, len(W), Lname, len(L))\n", + " print('{:20} {:3}: \"{}\"'.format(legend, len(solution), truncate(solution, 50)))\n", + " totalchars += len(solution)\n", + " print('Total characters: {:6}'.format(totalchars))\n", + " return totalchars\n", + "\n", + "def truncate(text, nchars, ellipsis=' ...'):\n", + " \"Return whole string, or version truncated to nchars.\"\n", + " return text if len(text) < nchars else text[:nchars-len(ellipsis)] + ellipsis" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 54: \"a.a|i..n|j|li|a.t|a..i|bu|oo|ay.|n.e|r.e$|ru|l ...\"\n", + "lose(34):win(34) 59: \"^d|^s|r.$|^.re|cc|hu|ld.|nd.|l.i|n.y|ya|ss|pa| ...\"\n", + "boy(10):girl(10) 11: \"e.$|a.$|a.o\"\n", + "girl(10):boy(10) 10: \"a$|^..i|is\"\n", + "drug(10):city(10) 15: \"o.$|x|ir|f|q|^e\"\n", + "city(10):drug(10) 11: \"ri|an|ca|id\"\n", + "foo(21):bar(21) 3: \"f.o\"\n", + "bar(21):foo(21) 28: \"r..$|k|.m|^..l|ld|c..n|id|or\"\n", + "wars(6):trek(9) 9: \" T|E.P|W \"\n", + "trek(9):wars(6) 15: \"TI|R.. |Y|RA|IS\"\n", + "noun(100):adj(98) 170: \"m.n|a.e$|m$|in.$|en.$|ch.|^w.r|id|^g|io|s.n|o. ...\"\n", + "adj(98):noun(100) 155: \"a.l|^..$|st$|et|re$|tl|en$|^al|ver$|nl|^a.o|ui ...\"\n", + "noun(100):verb(94) 174: \"m.n|er$|am|es|^.ar|ho|.on|or.$|id|f.c|o.l|..h. ...\"\n", + "verb(94):noun(100) 177: \"^..l|ak|ve$|^..$|s..n|a.n|^fi|^tr|ut$|.pe|o.g| ...\"\n", + "rand(58):built(147) 76: \"ia|and|^_.e|_s|_.o|.G|e_|P.$|_e|ets|lti|^_.c|^ ...\"\n", + "built(147):rand(58) 138: \"ro|Wa|as|^d|^i|r..i|li|^o|te.$|a.s$|m..$|up|tr ...\"\n", + "dog(100):cat(91) 73: \"E.S$|O.S$|DS|.AS|.HI|RD|.D.E|ANS|IES|G.S|N.S$| ...\"\n", + "cat(91):dog(100) 113: \"AI.$|T$|AN$|EX|A$|L$|Y$|A..B|NX|M.I|H$|R$|R.G| ...\"\n", + "movie(100):tv(97) 157: \"GO| . |^N|HIN|S O|E IN|A.NI|.A.C|TIO|RIV|U.K|E ...\"\n", + "tv(97):movie(100) 148: \"H.W|.CI|PR|R..$|D .E|A.ER|O..I|PE|^SE|^RO|T.C| ...\"\n", + "sci(50):star(50) 70: \"AL..|T..N|R.S|.KA|NN|VE|-|MU|^P|OD|OS|L.O|W.I| ...\"\n", + "star(50):sci(50) 77: \"CA|T. |LI..|F..D|GR|BU| GA|LO.|R..Y|UM| R| ST| ...\"\n", + "Total characters: 1743\n", + "CPU times: user 5.98 s, sys: 19.1 ms, total: 6 s\n", + "Wall time: 6 s\n" + ] + }, + { + "data": { + "text/plain": [ + "1743" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time benchmark()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "In 5 seconds we solved 22 problems, getting a score of 1749 for the total number of characters in all the solutions. \n", + "\n", + "(**Note:** if you run this, you might get a slightly different answer. Why? The algorithm has no random parts in it; shouldn't it return the same result every time? It will return the same results if you run it twice in the same Python. But when `findregex` evaluates `max(pool, key=score)` and two components are tied for the best score, Python chooses the one that comes first in the iteration of `pool`. And different versions of Python can iterate over `pool` in different orders.)\n", + "\n", + "# Analyzing\n", + "\n", + "What can we do to understand the program better? Let's start by analyzing what the regex parts look like. We cached the solutions in `SOLUTION`, and we can start to examine the solutions and the parts they are made of. For example, how long are the parts that appears in solutions?" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Counter({1: 17, 2: 192, 3: 179, 4: 84, 7: 1, 10: 1})" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "parts = [p for regex in SOLUTION.values() for p in regex.split('|')]\n", + "lengths = [len(p) for p in parts]\n", + "Counter(lengths)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "This says that there are 17 parts of length 1, 198 parts of length 2, etc. There's also one part of length 10; that's such an outlier, I wonder if it is an error? " + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'^HAVANESE$'" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(parts, key=len)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I happen to own [a Havanese](http://pn.smugmug.com/Family/Dobby-Idgie/i-2JPzBkL/A), but I don't think the program knew that. Rather, the issue is that in the set of `cats` we have `'HAVANA BROWN'` and `'JAVANESE'`, which means that any 4-letter-or-less subsequence of `'HAVANESE'` matches one of these two. So the only component that doesn't match one of these two cats is the whole, `'^HAVANESE$'`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "What about the individual characters that make up the parts? Which ones are popular? We can see:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('.', 205),\n", + " ('$', 71),\n", + " ('a', 58),\n", + " ('^', 54),\n", + " ('e', 48),\n", + " ('r', 46),\n", + " ('o', 44),\n", + " ('t', 37),\n", + " ('i', 37),\n", + " ('n', 37),\n", + " ('l', 35),\n", + " ('O', 31),\n", + " ('E', 31),\n", + " ('A', 30),\n", + " ('s', 28),\n", + " ('R', 27),\n", + " ('S', 26),\n", + " ('N', 24),\n", + " ('u', 23),\n", + " ('I', 23)]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Counter(cat(parts)).most_common(20)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I wonder if there are parts that appear in many solutions?" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('id', 4),\n", + " ('ru', 3),\n", + " ('hu', 3),\n", + " ('f.c', 2),\n", + " ('oo', 2),\n", + " ('f$', 2),\n", + " ('lt', 2),\n", + " ('m.n', 2),\n", + " ('vi', 2),\n", + " ('Y', 2),\n", + " ('^..$', 2),\n", + " ('N.S$', 2),\n", + " ('rc', 2),\n", + " ('^u', 2),\n", + " ('a$', 2),\n", + " ('j', 2),\n", + " ('ls', 2),\n", + " ('UG', 2),\n", + " ('^..l', 2),\n", + " ('YN', 2)]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Counter(parts).most_common(20)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Most parts appear in only 2 solutions or less.\n", + "\n", + "# Analyzing: Set Cover Theory\n", + "\n", + "Now I want to think about this as a [set cover problem](http://en.wikipedia.org/wiki/Set_cover_problem). Wikipedia shows this diagram to explain set cover:\n", + " \n", + "\n", + "\n", + "The idea is that each blue dot in set $u$ on the left represents a regex component, and each green dot in set $v$ represents a winner that is matched by the regex component. The problem is to pick some blue dots such that all the green dots are covered. In this example, we can see that picking the blue dots that are second and third from the top will do it.\n", + "\n", + "But in general, what do our graphs look like? How many blue and green dots are there? How many links between them? Let's build a little tool to find out. We'll list the $N$ \"most popular\" blue and green dots—the ones with the most links to the other side. Then we'll show histograms of all the nodes and their numbers of links.\n", + "\n", + "But first some explanation: I use the term *multimap* for a dictionary, like `covers = {regex: {winner,...}}`, that maps keys to collections. Then `invert_multimap(covers)` is of the form `{winner: {regex, ...}}`." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def show(W, L, N=10):\n", + " \"Summarize the links between the set of winners, W, and its parts.\"\n", + " covers = regex_covers(W, L)\n", + " inv = invert_multimap(covers)\n", + " for ((n1, w), (n2, r)) in zip(top(N, covers), top(N, inv)):\n", + " print(\"{:8} {:2} | {:3}| {}\".format(w, n1, n2, r))\n", + " print(\"TOTAL %5d | %3d TOTAL\" % (len(covers), len(W)))\n", + " plt.subplot(1, 2, 1); histmm(covers, \"parts\", \"winners\")\n", + " plt.subplot(1, 2, 2); histmm(inv, \"winners\", \"parts\")\n", + " \n", + "def top(N, multimap): \n", + " \"The top N longest items in a dict of {key: {val,...})\"\n", + " return sorted([(len(vals), key) for (key, vals) in multimap.items()], reverse=True)[:N]\n", + "\n", + "def histmm(multimap, key, val): \n", + " \"Display a histogram of how many values each key has.\"\n", + " plt.rcParams['figure.figsize'] = (8.0, 4.0)\n", + " plt.hist([len(v) for v in multimap.values()])\n", + " plt.xlabel('set size of {' + val + ',...}')\n", + " plt.ylabel('number of ' + key + ' mapping to that size')\n", + "\n", + "def invert_multimap(multimap):\n", + " \"Covert {key: {val,...}} to {val: [key,...]}.\"\n", + " result = defaultdict(set)\n", + " for key in multimap:\n", + " for val in multimap[key]:\n", + " result[val].add(key)\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "i..n 4 | 110| van-buren\n", + "a.a 4 | 98| washington\n", + "a..i 4 | 93| jefferson\n", + "r.i. 3 | 93| eisenhower\n", + "r.i 3 | 81| garfield\n", + "oo.. 3 | 78| roosevelt\n", + "oo. 3 | 72| buchanan\n", + "oo 3 | 61| obama\n", + "ma 3 | 61| kennedy\n", + "li.. 3 | 59| jackson\n", + "TOTAL 1615 | 34 TOTAL\n" + ] + }, + { + "data": { + "image/png": "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\ntaKdAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(winners, losers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "What does this say? First the table says that there are only three regexes that have 4 winners; all the rest have 3 or fewer winners. So the links going left-to-right are rather sparse. There are more links going the other direction; 110 to `van-buren`, for example. The histograms give the whole picture mapping set sizes to the number of keys that have that set size. So, on the left we see that over 1400 regexes have a set size of one winner, and 100 or fewer have set sizes of 2 and 3, and we saw that only 3 regexes have a set size of 4 winners. On the right, the histogram shows a wide spread of winners that have set sizes between 1 and 110 regexes.\n", + "\n", + "From looking at this I get two ideas:\n", + " \n", + "+ I notice that both `'oo..'` and `'oo.'` happen to match 3 winners. But even if I didn't know how many they matched, I would know that the winners matched by `'oo..'` must be a subset of the winners matched by `'oo.'` (remember that a set is a subset of itself). Furthermore, `'oo.'` is shorter. This suggests that we would *never* want to use `'oo..'` in a solution, because we could always make the solution one character shorter (and cover at least all the same winners) by substituting `'oo.'`. We say that * part A dominates B* if *A* is shorter and matches a superset of winners. We might as well throw out all dominated parts right at the start.\n", + "\n", + "+ It might be a good idea to pay special attention to the characters, like `'-'`, that appear in the winners but not the losers.\n", + "\n", + "Let's look at another example:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "E.S$ 41 | 186| SOFT COATED WHEATEN TERRIERS\n", + "RS$ 34 | 184| STAFFORDSHIRE BULL TERRIERS\n", + "ERS$ 34 | 175| GREATER SWISS MOUNTAIN DOGS\n", + ".RS$ 34 | 162| TREEING WALKER COONHOUNDS\n", + "IE.S 22 | 157| CAVALIER KING CHARLES SPANIELS\n", + "E.RI 21 | 149| AMERICAN STAFFORDSHIRE TERRIERS\n", + "T..R 20 | 147| WEST HIGHLAND WHITE TERRIERS\n", + "IER. 19 | 146| STANDARD SCHNAUZERS\n", + "IER 19 | 146| FLAT-COATED RETRIEVERS\n", + "I.R. 19 | 146| CHESAPEAKE BAY RETRIEVERS\n", + "TOTAL 4570 | 100 TOTAL\n" + ] + }, + { + "data": { + "image/png": "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\n2wAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(dogs, cats)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "My immediate reaction to this is \"there are a lot of retrievers and terriers.\" All ten of the parts in the table recognize this fact, but the left-hand histogram shows that almost all the parts match fewer than 5 dog breeds. In contrast, the right-hand histogram shows that most of the dog breeds have 9 or more parts that match them.\n", + "\n", + "Let's look at one more example:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a.l 12 | 94| especially\n", + "a.ly 11 | 83| eventually\n", + "a.l. 11 | 74| particularly\n", + ".a.l 11 | 67| actually\n", + "ll 9 | 65| quickly\n", + "^..$ 9 | 65| exactly\n", + ".ll 9 | 65| directly\n", + "..ll 8 | 63| certainly\n", + "all 7 | 61| usually\n", + "st$ 6 | 57| recently\n", + "TOTAL 2049 | 98 TOTAL\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show(adverbs, nouns)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The pattern looks similar here. Almost all the parts match only one winner, but most of the winners are matched by many parts. What can I conclude from this?\n", + "\n", + "+ It would be good to think of new types of parts that match more winners.\n", + "+ Most parts are 2 or 3 characters long and most match just 1 or 2 winners. That suggests that often we will have a tie in the `score` function, and greedy search will arbitrarily pick the one that comes first. But I'm worried that another choice might be better. Maybe we should replace greedy search with something that considers more than one choice.\n", + "\n", + "Given all we've seen, I will shift my attention to understanding the search algorithm we have, and thinking about how to improve it." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Analyzing: Understanding Greedy vs. Exhaustive Search\n", + "\n", + "`findregex` is a *greedy search* algorithm. In general, greedy search is used when you are trying to find a solution that is composed of parts. On each iteration you choose a part that looks good, and you never reconsider that choice; you just keep on adding parts until you get a complete solution. \n", + "\n", + "The pseudo-code for a general `greedy_search`, described as a recursive function, is given below. It takes two arguments: a set of parts, and a partial solution indicating parts that have previously been chosen. " + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "# Pseudocode \n", + "def greedy_search(parts, partial_solution=None):\n", + " if is_complete(partial_solution):\n", + " return partial_solution\n", + " else:\n", + " best = max(parts, key=score)\n", + " return greedy_search(parts - {best}, partial_solution + best)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "An *exhaustive search* considers *every* possible choice of parts, and selects the best solution. On each iteration exhaustive search picks a part (just like greedy search), but then it considers *both* using the part and not using the part. You can see that exhaustive search is almost identical to greedy search, except that it has *two* recursive calls (on lines 7 and 8) instead of *one* (on line 7). (*If you are viewing this in a iPython notebook, not just a web page, you can toggle line numbers by pressing 'ctrl-M L' within a cell.*) How do we choose between the results of the two calls? We need a cost function that we are trying to minimize. (For regex golf the cost of a solution is the length of the string.)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "# Pseudocode\n", + "def exhaustive_search(parts, partial_solution=None):\n", + " if is_complete(partial_solution):\n", + " return partial_solution\n", + " else:\n", + " best = max(parts, key=score)\n", + " return min(exhaustive_search(parts - {best}, partial_solution + best),\n", + " exhaustive_search(parts - {best}, partial_solution),\n", + " key=cost)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Here's an interesting piece of trivia: the first thing that exhaustive search does is a greedy search! Think about it: on each recursive call, `exhaustive_search` selects the best part, and then calls itself recursively with `best` chosen as part of the partial solution. It keeps going until it reaches a complete solution. That's exactly what greedy search does. But then exhaustive search does more: It also considers all the cases where it *didn't* choose the best part.\n", + "\n", + "Here's something else to ponder: why should we bother with selecting the \"best\" part? If we're going to explore *all* possibilities, wouldn't it be the same if we just selected *any* part, not the \"best\" one?\n", + "\n", + "# Searching: Computational Complexity of Greedy and Exhaustive Search\n", + "\n", + "\n", + "Greedy search only considers one path towards the goal of finding a solution. Exhaustive search considers two paths on *every* iteration. How much work is that all together? If there are *P* parts, then there are $2^P$ subsets of parts. Now, we don't have to consider every one of these subsets, because the search ends when we cover all the winners. If there are $W$ winners, than an upper bound on the number of combinations we have to consider is the number of ways we can pick $W$ parts from a pool of $P$, which in math we write as ($P$ choose $W$). For the presidential candidates $W$, is 34, and $P$ is 1615.\n", + "\n", + "So exhaustive search would have to consider roughly [(1615 choose 34)](https://www.google.com/search?q=1615+choose+34) = $10^{70}$ combinations, which is clearly too many. Don't even think about dogs versus cats, where $W$ = 100 and $P$ = 4570, so [(4570 choose 100)](https://www.google.com/search?q=4570+choose+100) = $10^{207}$. Fortunately, there is another way.\n", + "\n", + "# Searching: Branch and Bound Search\n", + "\n", + "[*Branch and bound*](http://en.wikipedia.org/wiki/Branch_and_bound) is a search strategy that gets the same answer as exhaustive search, but runs faster because it avoids considering many combinations that could not possibly lead to an optimal solution. Here's how and why it works:\n", + "\n", + "- The *branch* part of the name means that, just like exhaustive search, on each iteration it picks a part, and considers two branches, one where the part is in the solution, and one where it is not. \n", + "- The *bound* part of the name means that the algorithm continually keeps track of the lowest-cost solution it has found so far. This serves as a *bound* on what the optimal solution can be.\n", + "- The *trick* is to notice that the cost of a partial solution always *increases* as we add more parts to it. Therefore, if we ever get to a partial solution whose cost is more than the lowest-cost solution we have found so far, then we can *immediately* discard the partial solution, and *never consider* all the other combinations that would have come from continuing the partial solution. If there are $MP$ parts left to consider, that means we just eliminated $2^P$ potential combinations all at once. \"Eliminating potential combinations\" is also called \"pruning the search tree\"—\"[pruning](https://www.google.com/search?q=pruning)\" means cutting off unwanted branches.\n", + "\n", + "The pseudocode below uses a global variable called `CHEAPEST` to hold the lowest-cost solution found so far. Note that the two branches (two recursive calls in lines 7 and 8) communicate through this global variable. If the first branch sets `CHEAPEST` to an improved solution, then the second branch will see it. That is why it is important to choose good \"best\" parts—it means we are more likely to find a good solution early on, which makes it more likely that we can prune away branches. " + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "# Pseudocode\n", + "def branch_and_bound_search(parts, partial_solution=None):\n", + " if is_complete(partial_solution):\n", + " CHEAPEST = min(CHEAPEST, partial_solution, key=cost)\n", + " elif cost(partial_solution) < cost(CHEAPEST):\n", + " best = select_best(parts)\n", + " branch_and_bound_search(parts - {best}, partial_solution + best)\n", + " branch_and_bound_search(parts - {best}, partial_solution)\n", + " return CHEAPEST" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "# Searching: Anytime Branch and Bound Search\n", + "\n", + "Even with all this pruning, we still may be presented with problems that require trillions of recursive calls. [Who's got that kind of time?](http://www.gocomics.com/calvinandhobbes/1995/08/17#.UvSJImSwI8g) But if we stop the algorithm at any time, we still have our best solution stored in `CHEAPEST`. Algorithms that have the property that an answer is always available are called [*anytime algorithms*](http://en.wikipedia.org/wiki/Anytime_algorithm); let's do that.\n", + "\n", + "I can think of two easy ways to allow early stopping. We could use the [`threading.Timer`](http://docs.python.org/2/library/threading.html#timer-objects) class to run the search for a given number of seconds, then stop. Or we could have a counter which gets decremented every time we make a call, and when it hits zero, stop. I'll use the second approach.\n", + "\n", + "Enough pseudocode—here is a real implementation. Since global variables are [considered bad style](https://google.github.io/styleguide/pyguide.html#Global_variables), I decided to use a class, `BranchBound`, to hold the lowest-cost solution and the number of calls remaining. The class provides one method, `search`, which does the work." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "class BranchBound(object):\n", + " \"Hold state information for a branch and bound search.\"\n", + " def __init__(self, winners, max_num_calls, k=4):\n", + " self.cheapest = trivial(winners)\n", + " self.calls = max_num_calls\n", + " self.k = k\n", + " \n", + " def search(self, covers, partial=None):\n", + " \"\"\"Recursively extend partial regex until it matches all winners in covers.\n", + " Try all reasonable combinations until we run out of calls.\"\"\"\n", + " if self.calls <= 0: \n", + " return self.cheapest\n", + " self.calls -= 1\n", + " covers, partial = simplify_covers(covers, partial)\n", + " if not covers: # Nothing left to cover; solution is complete\n", + " self.cheapest = min(partial, self.cheapest, key=len)\n", + " elif len(OR(partial, min(covers, key=len))) < len(self.cheapest):\n", + " def score(p): return self.k * len(covers[p]) - len(p)\n", + " best = max(covers, key=score) # Best part\n", + " covered = covers[best] # Set of winners covered by best\n", + " covers.pop(best)\n", + " # Try with and without the greedy-best part\n", + " self.search({c:covers[c]-covered for c in covers}, OR(partial, best))\n", + " self.search(covers, partial)\n", + " return self.cheapest" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Simplifying Covers\n", + "\n", + "There's a new function introduced above, `simplify_covers`. The idea is that you pass it a `covers` dict and a partial regex, and it does a triage process to divide the components in `covers` into three categories:\n", + "\n", + "- *Useless components*: could never appear in an optimal solution.\n", + "- *Necessary components*: must appear in any solution (because no other component covers some winner).\n", + "- *Remaining components*: neither useless nor necessary.\n", + " \n", + "The necessary components are joined to the partial regex that is passed in, to yield a new partial regex that the function returns. The useless components are eliminated, and the remaining ones are returned in a new `covers` dict. \n", + "\n", + "`simplify_covers` works by first eliminating useless components, and then selecting necessary components. We keep repeating this process of eliminating and selecting until there are no more changes to `covers`:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def simplify_covers(covers, partial=None):\n", + " \"Eliminate dominated regexes, and select ones that uniquely cover a winner.\"\n", + " previous = None\n", + " while covers != previous:\n", + " previous = covers\n", + " covers = eliminate_dominated(covers)\n", + " covers, necessary = select_necessary(covers)\n", + " partial = OR(partial, necessary)\n", + " return covers, partial" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "For convenience we modified the function `OR` slightly; we made it work just like the function `max` in that you can call it two ways: either with a single argument, which is a collection of components, or with 2 or more arguments, each a component. We also made it ignore components that are `None`, so that `OR(None, 'a')` equals `'a'`, but `OR('a', 'b')` equals `'a|b'`, as does `OR(['a', 'b'])`" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def OR(*regexes):\n", + " \"\"\"OR together component regexes. Ignore 'None' components.\n", + " Allows both OR(a, b, c) and OR([a, b, c]), similar to max.\"\"\"\n", + " if len(regexes) == 1: \n", + " regexes = regexes[0]\n", + " return '|'.join(r for r in regexes if r)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Simplifying Covers: Eliminating Dominated Components\n", + "\n", + "We defined the notion of a regex being *dominated* if there is some other regex that is shorter (or at least not longer) and covers a superset of winners. How can we efficiently compute which parts are dominated? Here's one simple approach: go through each regex part, `p`, and every time we find one that is not dominated by any another regex part `p2`, add `p` (and its winners) to a new dict that we are building up. This approach works, but it is $O(n^2)$.\n", + "\n", + "Here's an alternative that is faster: First, sort all the regexes so that the ones that match more winners come first (in case of tie, put the shorter ones first). (In other words, \"best\" first.) Initialize a new dict to empty, and go through the sorted regexes, `p`, one at a time. For each `p`, compare it only to the regexes, `p2`, that we have already added to the new dict; if none of them dominate `p`, then add `p`. This is still $O(n^2)$, but if, say, 99 out of 100 regexes are eliminated, we will only need $n^2/100$ comparisons.\n", + "\n", + "The code for `eliminate_dominated` is a slight variant on the [version](https://github.com/pochmann/regex-golf) by Stefan Pochmann (because his version turned out to be better than my first version). Note that the function `signature` represents a regex as a pair of numbers, the negative of the number of winners and the length in characters. The smaller (in lexicographical order) this pair is, the \"better\" the regex is. Why is it important to put the regexes in sorted order? So that we know that the only possible dominators are the ones that came *before*, not ones that come after. Note that, as we are going through the component regexes, `p`, in sorted order, if we ever hit a `p` that covers no winners, then we know that all the remaining `p` will also cover no winners (because we're going in best-first order), so we can break out of the loop immediately. And one more thing: the expression `covers[p2] >= covers[p]` asks if `p2` covers a superset of the winners that `p` covers." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def eliminate_dominated(covers):\n", + " \"\"\"Given a dict of {regex: {winner...}}, make a new dict with only the regexes\n", + " that are not dominated by any others. A regex part p is dominated by p2 if p2 covers \n", + " a superset of the matches covered by p, and rp is shorter.\"\"\"\n", + " newcovers = {}\n", + " def signature(p): return (-len(covers[p]), len(p))\n", + " for p in sorted(covers, key=signature):\n", + " if not covers[p]: break # All remaining r must not cover anything\n", + " # r goes in newcache if it is not dominated by any other regex\n", + " if not any(covers[p2] >= covers[p] and len(p2) <= len(p) \n", + " for p2 in newcovers):\n", + " newcovers[p] = covers[p]\n", + " return newcovers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Simplifying Covers: Selecting Necessary Components\n", + "\n", + "\n", + "If some winner is covered by only one part, then we know that part must be part of the solution. The function `select_necessary` finds all such parts, `OR`s them together, and returns that, along with a dict of the remaining covers, after removing the necessary parts (and removing all the winners that are covered by the neccessary parts)." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def select_necessary(covers):\n", + " \"\"\"Select winners covered by only one part; remove from covers.\n", + " Return a pair of (covers, necessary).\"\"\"\n", + " counts = Counter(w for p in covers for w in covers[p])\n", + " necessary = {p for p in covers if any(counts[w] == 1 for w in covers[p])}\n", + " if necessary:\n", + " covered = {w for p in necessary for w in covers[p]}\n", + " covers = {p: covers[p] - covered \n", + " for p in covers if p not in necessary}\n", + " return covers, OR(necessary)\n", + " else:\n", + " return covers, None" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Testing and Benchmarking: Branch and Bound\n", + "\n", + "Let's make up a test suite (showing some examples of how these functions work). Then let's see if `findregex` works with the new branch and bound search. " + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'test_bb passes'" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_bb():\n", + " assert OR(['a', 'b', 'c']) == OR('a', 'b', 'c') == 'a|b|c'\n", + " assert OR(['a|b', 'c|d']) == OR('a|b', 'c|d') == 'a|b|c|d'\n", + " assert OR(None, 'c') == 'c'\n", + " covers1 = {'a': {'ann', 'abe'}, 'ab': {'abe'}}\n", + " assert eliminate_dominated(covers1) == {'a': {'ann', 'abe'}}\n", + " assert simplify_covers(covers1) == ({}, 'a')\n", + " covers2 = {'a': {'abe', 'cab'}, 'b': {'abe', 'cab', 'bee'}, \n", + " 'c': {'cab', 'cee'}, 'c.': {'cab', 'cee'}, 'abe': {'abe'},\n", + " 'ab': {'abe', 'cab'}, '.*b': {'abe', 'cab', 'bee'}, \n", + " 'e': {'abe', 'bee', 'cee'}, 'f': {}, 'g': {}}\n", + " assert eliminate_dominated(covers2) == simplify_covers(covers2)[0] == {\n", + " 'c': {'cab', 'cee'}, 'b': {'cab', 'abe', 'bee'}, 'e': {'cee', 'abe', 'bee'}}\n", + " covers3 = {'1': {'w1'}, '.1': {'w1'}, '2': {'w2'}}\n", + " assert eliminate_dominated(covers3) == {'1': {'w1'}, '2': {'w2'}}\n", + " assert simplify_covers(covers3) in (({}, '2|1'), ({}, '1|2'))\n", + " covers, nec = select_necessary({'a': {'abe'}, 'c': {'cee'}})\n", + " assert covers == {} and (nec == 'c|a' or nec == 'a|c')\n", + " assert {0, 1, 2} >= {1, 2}\n", + " assert {1, 2} >= {1, 2}\n", + " assert not ({1, 2, 4} >= {1, 3})\n", + " return 'test_bb passes'\n", + "\n", + "test_bb()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's investigate how much the cover simplification process is helping:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1615" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "covers = regex_covers(winners, losers)\n", + "len(covers)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "49" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "covers2, partial = simplify_covers(covers)\n", + "len(covers2)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.9696594427244583" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1 - len(covers2)/len(covers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We see that `simplify_covers` gives us a 97% reduction in the number of parts! What do the remaining covers look like?" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "({'-': frozenset({'van-buren'}),\n", + " '.b': frozenset({'obama', 'van-buren'}),\n", + " '.f': frozenset({'garfield', 'taft'}),\n", + " '.h.n': frozenset({'buchanan', 'washington'}),\n", + " '.se': frozenset({'eisenhower', 'roosevelt'}),\n", + " 'a..i': frozenset({'garfield', 'harding', 'harrison', 'washington'}),\n", + " 'a.a': frozenset({'adams', 'buchanan', 'obama', 'reagan'}),\n", + " 'a.t': frozenset({'carter', 'grant', 'taft'}),\n", + " 'ad': frozenset({'adams', 'madison'}),\n", + " 'am': frozenset({'adams', 'obama'}),\n", + " 'an.$': frozenset({'cleveland', 'grant'}),\n", + " 'ay.': frozenset({'hayes', 'taylor'}),\n", + " 'bu': frozenset({'buchanan', 'bush', 'van-buren'}),\n", + " 'di': frozenset({'harding', 'madison'}),\n", + " 'ed': frozenset({'kennedy'}),\n", + " 'el.$': frozenset({'garfield', 'roosevelt'}),\n", + " 'g..n': frozenset({'grant', 'washington'}),\n", + " 'ga': frozenset({'garfield', 'reagan'}),\n", + " 'h..e': frozenset({'eisenhower', 'hayes'}),\n", + " 'ho': frozenset({'eisenhower', 'hoover'}),\n", + " 'i..n': frozenset({'eisenhower', 'harrison', 'madison', 'nixon'}),\n", + " 'i..o': frozenset({'clinton', 'lincoln', 'wilson'}),\n", + " 'i.l': frozenset({'garfield', 'mckinley'}),\n", + " 'i.o': frozenset({'harrison', 'madison', 'nixon'}),\n", + " 'ie.': frozenset({'garfield', 'pierce'}),\n", + " 'is.': frozenset({'eisenhower', 'harrison', 'madison'}),\n", + " 'li': frozenset({'clinton', 'coolidge', 'lincoln'}),\n", + " 'ls': frozenset({'wilson'}),\n", + " 'm..i': frozenset({'madison', 'mckinley'}),\n", + " 'ma': frozenset({'madison', 'obama', 'truman'}),\n", + " 'n..o': frozenset({'nixon', 'washington'}),\n", + " 'n.e': frozenset({'kennedy', 'mckinley'}),\n", + " 'nl': frozenset({'mckinley'}),\n", + " 'oe': frozenset({'monroe'}),\n", + " 'oo': frozenset({'coolidge', 'hoover', 'roosevelt'}),\n", + " 'r..s': frozenset({'harrison', 'roosevelt'}),\n", + " 'r.e$': frozenset({'monroe', 'pierce'}),\n", + " 'r.i': frozenset({'garfield', 'harding', 'harrison'}),\n", + " 'r.n': frozenset({'grant', 'van-buren'}),\n", + " 'ra': frozenset({'grant'}),\n", + " 'rc': frozenset({'pierce'}),\n", + " 'rt': frozenset({'carter'}),\n", + " 'sh': frozenset({'bush', 'washington'}),\n", + " 'ta': frozenset({'taft', 'taylor'}),\n", + " 'to': frozenset({'clinton', 'washington'}),\n", + " 'u..n': frozenset({'truman', 'van-buren'}),\n", + " 'vel': frozenset({'cleveland', 'roosevelt'}),\n", + " 'xo': frozenset({'nixon'}),\n", + " 'ye': frozenset({'hayes'})},\n", + " 'j|po')" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simplify_covers(covers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + " Now let's benchmark branch and bound. I'm going to introduce a modified version of `benchmark`, called `bbenchmark`, to print the number of calls taken. The easiest way to do that is to introduce a new version of `findregex`, called `bb_findregex`, that returns the `BranchBound` object it creates, rather than returning the solution. (In general, I tend to introduce a new function when I change the call/return signature, but not when I just improve the mechanism.)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def bbenchmark(examples=EXAMPLES, calls=10**4): \n", + " \"Run these data sets; print summaries; return total of solution lengths.\"\n", + " totalchars = 0\n", + " for (W, Wname, Lname, L) in examples: # Do both ways\n", + " re.purge()\n", + " bb = bb_findregex(W, L, calls)\n", + " SOLUTION[W, L] = bb.cheapest\n", + " assert not mistakes(bb.cheapest, W, L)\n", + " legend = '{}({}):{}({})'.format(Wname, len(W), Lname, len(L))\n", + " print('{:20} {:6} calls, {:3}: \"{}\"'.format(\n", + " legend, (calls - bb.calls), len(bb.cheapest), truncate(bb.cheapest, 45)))\n", + " totalchars += len(bb.cheapest)\n", + " return totalchars\n", + "\n", + "def bb_findregex(winners, losers, calls=10**4):\n", + " \"Return a BranchBound object which contains the shortest regex that covers winners but not losers.\"\n", + " bb = BranchBound(winners, calls)\n", + " bb.search(regex_covers(winners, losers))\n", + " return bb\n", + "\n", + "def findregex(winners, losers): return bb_findregex(winners, losers).cheapest" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Remember, the old benchmark took about 5 seconds and totaled 1749 characters. Let's see how the branch and bound benchmark compares:" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 1000 calls, 52: \"j|po|a.a|a..i|bu|ma|li|ls|a.t|vel|ho|xo|a ...\"\n", + "lose(34):win(34) 1000 calls, 58: \"^s|ox|ss|^ki|^d|go|^.re|hu|ry|ai|k..$|n.y ...\"\n", + "boy(10):girl(10) 9 calls, 11: \"de|a.$|c|as\"\n", + "girl(10):boy(10) 13 calls, 10: \"a$|a.i|e.i\"\n", + "drug(10):city(10) 3 calls, 15: \"ir|^e|o.$|f|x|q\"\n", + "city(10):drug(10) 17 calls, 11: \"ri|an|h|a.e\"\n", + "foo(21):bar(21) 1 calls, 3: \"f.o\"\n", + "bar(21):foo(21) 205 calls, 24: \"k|ld|b|...n|ah|ar|or|z|A\"\n", + "wars(6):trek(9) 21 calls, 9: \" T|E..H|B\"\n", + "trek(9):wars(6) 9 calls, 13: \"IS|Y|RA|CT| F\"\n", + "noun(100):adj(98) 1000 calls, 167: \"f.t|^hea|aw$|^g|jo|rty|rt$|ot$|^wa|o.y|el ...\"\n", + "adj(98):noun(100) 721 calls, 146: \"r.t|re$|f$|st$|at$|rse|b.t|a.l|ui|far|u.h ...\"\n", + "noun(100):verb(94) 1000 calls, 168: \"am|er$|t.t|ir|po|ot|.as|^ar|^en|gu|.ne|ac ...\"\n", + "verb(94):noun(100) 1000 calls, 170: \"c.n|p.y|sw|r.ad|^tr|ru|^fi|un.$|it$|b.y|^ ...\"\n", + "rand(58):built(147) 1000 calls, 73: \"ia|_p|a.p|ee|_e|and|ets|^u|lti|^_.e|_s|_. ...\"\n", + "built(147):rand(58) 1000 calls, 130: \"^i|se.$|^range$|Y|..E|xe|Wa|bo|ev|w$|xt|^ ...\"\n", + "dog(100):cat(91) 1000 calls, 69: \"^HAVANESE$|E.S$|O.S$|N.S$|.AS|GS|.HI|RD|B ...\"\n", + "cat(91):dog(100) 539 calls, 104: \"J.V|NX|H$|AN$|EX|OE|BAL|^TH|Y$|T$|R$|MES| ...\"\n", + "movie(100):tv(97) 1000 calls, 154: \"^GR|R W|LAD|^CI|GO| . |AP.|^N|^RA|HIN|NC. ...\"\n", + "tv(97):movie(100) 1000 calls, 146: \"MAS|^.OS|WIR|EER|OAP|4|H.W|6|.CI|X.$|.MO| ...\"\n", + "sci(50):star(50) 1000 calls, 67: \"AL..|T..N|R.S| TO|.KA|KN|OS|MU|VE|NN|Ü|LE ...\"\n", + "star(50):sci(50) 1000 calls, 76: \"UM|WES|CA|T. | ST|YN|LI..|F..D|GR|BU| GA| ...\"\n", + "CPU times: user 8.05 s, sys: 23.4 ms, total: 8.07 s\n", + "Wall time: 8.07 s\n" + ] + }, + { + "data": { + "text/plain": [ + "1676" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=1000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "This is encouraging! We took about 2 seconds longer, but improved on the total number of characters by about 4%. For 10 of the 22 cases we didn't reach the cutoff of 1000 calls, which means that we searched every feasible combination of the parts we have. Let's try with 10,000 calls:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 1707 calls, 52: \"j|po|a.a|a..i|bu|ma|li|ls|a.t|vel|ho|xo|a ...\"\n", + "lose(34):win(34) 3075 calls, 57: \"^s|ox|ss|^ki|i.$|go|^f|de|br|hu|ker|le$|e ...\"\n", + "boy(10):girl(10) 9 calls, 11: \"de|a.$|c|as\"\n", + "girl(10):boy(10) 13 calls, 10: \"a$|a.i|e.i\"\n", + "drug(10):city(10) 3 calls, 15: \"ir|^e|o.$|f|x|q\"\n", + "city(10):drug(10) 17 calls, 11: \"ri|an|h|a.e\"\n", + "foo(21):bar(21) 1 calls, 3: \"f.o\"\n", + "bar(21):foo(21) 205 calls, 24: \"k|ld|b|...n|ah|ar|or|z|A\"\n", + "wars(6):trek(9) 21 calls, 9: \" T|E..H|B\"\n", + "trek(9):wars(6) 9 calls, 13: \"IS|Y|RA|CT| F\"\n", + "noun(100):adj(98) 2009 calls, 167: \"f.t|^hea|aw$|^g|jo|rty|rt$|ot$|^wa|o.y|el ...\"\n", + "adj(98):noun(100) 721 calls, 146: \"r.t|re$|f$|st$|at$|rse|b.t|a.l|ui|far|u.h ...\"\n", + "noun(100):verb(94) 10000 calls, 168: \"am|er$|t.t|ir|po|ot|.as|^ar|^en|gu|.ne|ac ...\"\n", + "verb(94):noun(100) 3285 calls, 170: \"c.n|p.y|sw|r.ad|^tr|ru|^fi|un.$|it$|b.y|^ ...\"\n", + "rand(58):built(147) 1427 calls, 73: \"ia|_p|a.p|ee|_e|and|ets|^u|lti|^_.e|_s|_. ...\"\n", + "built(147):rand(58) 10000 calls, 130: \"^i|se.$|^range$|Y|ro|Wa|bo|ev|w$|xt|^d|^o ...\"\n", + "dog(100):cat(91) 10000 calls, 69: \"^HAVANESE$|E.S$|O.S$|N.S$|.AS|GS|.HI|RD|B ...\"\n", + "cat(91):dog(100) 539 calls, 104: \"J.V|NX|H$|AN$|EX|OE|BAL|^TH|Y$|T$|R$|MES| ...\"\n", + "movie(100):tv(97) 10000 calls, 153: \"^GR|R W|LAD|^CI|GO| . |AP.|^N|^RA|HIN|NC. ...\"\n", + "tv(97):movie(100) 10000 calls, 146: \"MAS|^.OS|WIR|EER|OAP|4|H.W|6|.CI|X.$|.MO| ...\"\n", + "sci(50):star(50) 10000 calls, 67: \"AL..|T..N|R.S| TO|.KA|KN|OS|MU|NN|W.I|IG. ...\"\n", + "star(50):sci(50) 10000 calls, 76: \"UM|WES|CA|T. | ST|YN|F..D|GR| GA|H.P|LO.| ...\"\n", + "CPU times: user 20.2 s, sys: 40.4 ms, total: 20.3 s\n", + "Wall time: 20.3 s\n" + ] + }, + { + "data": { + "text/plain": [ + "1674" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=10000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We doubled the time and gained a few characters. How about 100,000 calls?" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 1707 calls, 52: \"j|po|a.a|a..i|bu|ma|li|ls|a.t|vel|ho|xo|a ...\"\n", + "lose(34):win(34) 3075 calls, 57: \"^s|ox|ss|^ki|i.$|go|^f|de|br|hu|ker|le$|e ...\"\n", + "boy(10):girl(10) 9 calls, 11: \"de|a.$|c|as\"\n", + "girl(10):boy(10) 13 calls, 10: \"a$|a.i|e.i\"\n", + "drug(10):city(10) 3 calls, 15: \"ir|^e|o.$|f|x|q\"\n", + "city(10):drug(10) 17 calls, 11: \"ri|an|h|a.e\"\n", + "foo(21):bar(21) 1 calls, 3: \"f.o\"\n", + "bar(21):foo(21) 205 calls, 24: \"k|ld|b|...n|ah|ar|or|z|A\"\n", + "wars(6):trek(9) 21 calls, 9: \" T|E..H|B\"\n", + "trek(9):wars(6) 9 calls, 13: \"IS|Y|RA|CT| F\"\n", + "noun(100):adj(98) 2009 calls, 167: \"f.t|^hea|aw$|^g|jo|rty|rt$|ot$|^wa|o.y|el ...\"\n", + "adj(98):noun(100) 721 calls, 146: \"r.t|re$|f$|st$|at$|rse|b.t|a.l|ui|far|u.h ...\"\n", + "noun(100):verb(94) 100000 calls, 167: \"am|er$|t.t|ir|po|ot|.as|^ar|^en|gu|.ne|ac ...\"\n", + "verb(94):noun(100) 3285 calls, 170: \"c.n|p.y|sw|r.ad|^tr|ru|^fi|un.$|it$|b.y|^ ...\"\n", + "rand(58):built(147) 1427 calls, 73: \"ia|_p|a.p|ee|_e|and|ets|^u|lti|^_.e|_s|_. ...\"\n", + "built(147):rand(58) 94795 calls, 127: \"^i|se.$|^range$|Y|ro|Wa|bo|ev|w$|xt|^d|^o ...\"\n", + "dog(100):cat(91) 100000 calls, 69: \"^HAVANESE$|E.S$|O.S$|N.S$|.AS|GS|.HI|RD|B ...\"\n", + "cat(91):dog(100) 539 calls, 104: \"J.V|NX|H$|AN$|EX|OE|BAL|^TH|Y$|T$|R$|MES| ...\"\n", + "movie(100):tv(97) 100000 calls, 153: \"^GR|R W|LAD|^CI|GO| . |AP.|^N|^RA|HIN|NC. ...\"\n", + "tv(97):movie(100) 100000 calls, 146: \"MAS|^.OS|WIR|EER|OAP|4|H.W|6|.CI|X.$|.MO| ...\"\n", + "sci(50):star(50) 100000 calls, 67: \"AL..|T..N|I$|.KA|KN|OS|VE|I.O| TO| .RE|LE ...\"\n", + "star(50):sci(50) 100000 calls, 75: \"UM|WES|CA|GR|LO.|F..D|^B|DEA| GA|H.P|I.L| ...\"\n", + "CPU times: user 3min 8s, sys: 333 ms, total: 3min 8s\n", + "Wall time: 3min 8s\n" + ] + }, + { + "data": { + "text/plain": [ + "1669" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=100000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We're slowly decreasing the total number of characters, but at the expense of increasing run time. I think if we want to make more progress, it is time to stop worrying about the search algorithm, and start worrying about what we're searching over.\n", + "\n", + "# New Parts: Repetition Characters\n", + "\n", + "Following a suggestion by Stefan Pochmann, I will generate two new classes of parts that use the repetition characters `'*'`, `'+'`, and `'?'`:\n", + "\n", + "- **pairs**: parts of the form `'A.*B'` where `'A'` and `'B'` are any two non-special characters that appear anywhere in any winner, the dot is always the second character, and the third character is one of the repetition characters. \n", + "\n", + "- **reps**: given a part such as `'a.c'`, insert any repetition character after any character in the part (yielding, for example, `'a*.c'`).\n", + "Don't insert after `'^'` or `'$'`, and don't allow redundant parts like `'..*c'`.\n", + "\n", + "\n", + "Here is a new version of `regex_covers` that adds the new parts:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def regex_covers(winners, losers):\n", + " \"\"\"Generate regex components and return a dict of {regex: {winner...}}.\n", + " Each regex matches at least one winner and no loser.\"\"\"\n", + " losers_str = '\\n'.join(losers)\n", + " wholes = {'^'+winner+'$' for winner in winners}\n", + " parts = {d for w in wholes for p in subparts(w) for d in dotify(p)}\n", + " reps = {r for p in parts for r in repetitions(p)}\n", + " pool = wholes | parts | pairs(winners) | reps \n", + " searchers = {p:re.compile(p, re.MULTILINE).search for p in pool}\n", + " return {p: Set(filter(searchers[p], winners)) \n", + " for p in pool\n", + " if not searchers[p](losers_str)}\n", + "\n", + "def pairs(winners, special_chars=Set('*+?^$.[](){}|\\\\')):\n", + " chars = Set(cat(winners)) - special_chars\n", + " return {A+'.'+q+B \n", + " for A in chars for B in chars for q in '*+?'}\n", + "\n", + "def repetitions(part):\n", + " \"\"\"Return a set of strings derived by inserting a single repetition character\n", + " ('+' or '*' or '?'), after each non-special character. \n", + " Avoid redundant repetition of dots.\"\"\"\n", + " splits = [(part[:i], part[i:]) for i in range(1, len(part)+1)]\n", + " return {A + q + B \n", + " for (A, B) in splits\n", + " # Don't allow '^*' nor '$*' nor '..*' nor '.*.'\n", + " if not (A[-1] in '^$')\n", + " if not A.endswith('..')\n", + " if not (A.endswith('.') and B.startswith('.'))\n", + " for q in '*+?'}" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'test_new_parts passes'" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_new_parts():\n", + " assert repetitions('a') == {'a+', 'a*', 'a?'}\n", + " assert repetitions('ab') == {'a+b', 'a*b', 'a?b', \n", + " 'ab+', 'ab*', 'ab?'}\n", + " assert repetitions('a.c') == {'a+.c', 'a*.c', 'a?.c',\n", + " 'a.c+', 'a.*c', 'a.?c',\n", + " 'a.+c', 'a.c*', 'a.c?'}\n", + " assert repetitions('^a..d$') == {'^a+..d$', '^a*..d$', '^a?..d$', \n", + " '^a..d+$', '^a..d*$', '^a..d?$'}\n", + " assert pairs({'ab', 'c'}) == {\n", + " 'a.*a', 'a.*b', 'a.*c',\n", + " 'a.+a', 'a.+b', 'a.+c',\n", + " 'a.?a', 'a.?b', 'a.?c',\n", + " 'b.*a', 'b.*b', 'b.*c',\n", + " 'b.+a', 'b.+b', 'b.+c',\n", + " 'b.?a', 'b.?b', 'b.?c',\n", + " 'c.*a', 'c.*b', 'c.*c',\n", + " 'c.+a', 'c.+b', 'c.+c',\n", + " 'c.?a', 'c.?b','c.?c'}\n", + " assert len(pairs({'1...2...3', '($2.34)', '42', '56', '7-11'})) == 8 * 8 * 3\n", + " covers = regex_covers({'one', 'on'}, {'won', 'wuan', 'juan'})\n", + " assert (eliminate_dominated(covers) == {'e': {'one'}, '^o': {'on', 'one'}})\n", + " return 'test_new_parts passes'\n", + "\n", + "test_new_parts()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's take our new parts out for a spin and see what they can do:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "' T|P.*E'" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "findregex(starwars, startrek)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Awesome!** \n", + "\n", + "Remember, Randall had a ten character regex in the strip (see below); we previously got it down to nine, but we now have it down to **seven** with `' T|P.*E'`!\n", + "\n", + "\n", + "\n", + "**Update(Nov 2015)**: There are two new movies in the works; let's see what they do to our golf score:" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "' T|P.*E|KE'" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "starwars = starwars | {'THE FORCE AWAKENS'}\n", + "startrek = startrek | {'BEYOND'}\n", + "\n", + "findregex(starwars, startrek)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Too bad; back to ten characters.\n", + "\n", + "How much more work are we doing with these additional parts? Before, `regex_covers(winners, losers)` gave 1615 regexes, which were reduced to 49 by `simplify_covers`. Now:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "13200" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "covers = regex_covers(winners, losers)\n", + "len(covers)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "90" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "covers2, partial = simplify_covers(covers)\n", + "len(covers2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "So the total number of regexes is increased almost 10-fold, but after simplification the number is only double what it was before. (To put it another way, `simplify_covers` eliminated 99.3% of the parts.) That's not too bad; let's add *more* components.\n", + "\n", + "# New Parts: Longer Ones\n", + "\n", + "Previously we generated parts of length up to 4 characters. Why not say \"[we're doing 5](http://www.theonion.com/articles/fuck-everything-were-doing-five-blades,11056/)\"? The implementation is easy:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "SUBPARTS = 5 # Maximum length of a subpart\n", + "\n", + "def subparts(word):\n", + " \"Return a set of subparts of word, consecutive characters up to length 5.\"\n", + " return set(word[i:i+1+s] for i in range(len(word)) for s in range(SUBPARTS)) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "But how many more regex components does this give us?" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "39537" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "covers = regex_covers(winners, losers)\n", + "len(covers)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "112" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "covers2, partial = simplify_covers(covers)\n", + "len(covers2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "In the end the longer parts add only 22 new components, rejecting nearly 40,000 other parts. It is time to benchmark again. Remember our previous best was Branch and Bound with 100,000 calls, which yielded 1669 total characters in 170 seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 1000 calls, 47: \"i.+o|o.*o|a.a|po|a.t|j|bu|ce|ay.|ma|r.i|n ...\"\n", + "lose(34):win(34) 1000 calls, 56: \"r.*y|i.e*$|^s|go|d..e|^f|n.*k|k.+g|hu|rk| ...\"\n", + "boy(10):girl(10) 29 calls, 11: \"a.$|de|c|as\"\n", + "girl(10):boy(10) 23 calls, 9: \"a$|^m*..i\"\n", + "drug(10):city(10) 85 calls, 15: \"o.$|x|ir|f|q|^e\"\n", + "city(10):drug(10) 45 calls, 11: \"ri|a.+e|h|k\"\n", + "foo(21):bar(21) 1 calls, 3: \"foo\"\n", + "bar(21):foo(21) 1000 calls, 23: \"^...a|k|...n|ld|b|ar|or\"\n", + "wars(6):trek(9) 23 calls, 7: \" T|P.*E\"\n", + "trek(9):wars(6) 169 calls, 12: \"I.?S|RA| F|Y\"\n", + "noun(100):adj(98) 1000 calls, 161: \"^wa|l.v|m.+n|me?$|.i.*d|....o|an*.e$|..k$ ...\"\n", + "adj(98):noun(100) 1000 calls, 140: \"e.+y|^..l*$|l.*s|rs?e$|a.l|ei?t|st$|en$|f ...\"\n", + "noun(100):verb(94) 1000 calls, 168: \"h.+g|mp*.n|p.*r|..h.|mb*e|ea?s|^k?i|.ne|. ...\"\n", + "verb(94):noun(100) 1000 calls, 162: \"rr|tar|o.b|^..p?l|^f?..$|buy|f$|^fi|as*k| ...\"\n", + "rand(58):built(147) 1000 calls, 72: \"ee|^_.*n|a.p|ia|an*d.|^_.?e|tst|e._+$|o.c ...\"\n", + "built(147):rand(58) 1000 calls, 130: \"^rang|r...$|c.*t|ra*.i|^l*i|al*s|ug|^m?a| ...\"\n", + "dog(100):cat(91) 1000 calls, 43: \"E.+S$|I.*S$|H.*N.S|.HI|G.?S|TES|.SO|W |O.D.\"\n", + "cat(91):dog(100) 1000 calls, 105: \"J.V|RA*$|R.*A.$|LD?$|N.*X|M$|M...$|E.*O.$ ...\"\n", + "movie(100):tv(97) 1000 calls, 148: \" TH.+N| A*. |R...R|GR?O|IS?.$|A.C*E$|^GR| ...\"\n", + "tv(97):movie(100) 1000 calls, 148: \"4|HT?.W|..CH*I|XI$|PO*R|R..AN|MAS|..AY.|O ...\"\n", + "sci(50):star(50) 1000 calls, 71: \"AN?L..|T.V?.N|RL?.S|N.*RE|.S.+H|LER|.KA|G ...\"\n", + "star(50):sci(50) 1000 calls, 74: \"U.*R.|GR|LO.|F.+D|I.Y*N| T*R|G.*Y|LES?$|E ...\"\n", + "CPU times: user 4min 23s, sys: 2 s, total: 4min 25s\n", + "Wall time: 4min 25s\n" + ] + }, + { + "data": { + "text/plain": [ + "1616" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=1000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We reduced the total characters by about 4%, although it did take longer, even with only 1,000 calls. And notice we no longer need `'^HAVANESE$'`; instead we have `'H.*N.S'`, which saves 4 characters, and, look how many breeds it matches:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'AFGHAN HOUNDS',\n", + " 'BASSET HOUNDS',\n", + " 'BLOODHOUNDS',\n", + " 'CHINESE CRESTED',\n", + " 'CHINESE SHAR-PEI',\n", + " 'DACHSHUNDS',\n", + " 'HAVANESE',\n", + " 'IRISH WOLFHOUNDS',\n", + " 'ITALIAN GREYHOUNDS',\n", + " 'TREEING WALKER COONHOUNDS'}" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matches('H.*N.S', dogs)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's continue benchmarking:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 10000 calls, 46: \"i.+o|j|bu|oo|a.t|n.o*e|ma|po|ie.|ay.|e.?a ...\"\n", + "lose(34):win(34) 10000 calls, 55: \"r.*y|i.e*$|^s|go|de|do|^f|la.$|al|n.*k|k. ...\"\n", + "boy(10):girl(10) 29 calls, 11: \"a.$|de|c|as\"\n", + "girl(10):boy(10) 23 calls, 9: \"a$|^m*..i\"\n", + "drug(10):city(10) 85 calls, 15: \"o.$|x|ir|f|q|^e\"\n", + "city(10):drug(10) 45 calls, 11: \"ri|a.+e|h|k\"\n", + "foo(21):bar(21) 1 calls, 3: \"foo\"\n", + "bar(21):foo(21) 6151 calls, 23: \"^...a|k|...n|ld|b|ar|or\"\n", + "wars(6):trek(9) 23 calls, 7: \" T|P.*E\"\n", + "trek(9):wars(6) 169 calls, 12: \"I.?S|RA| F|Y\"\n", + "noun(100):adj(98) 10000 calls, 160: \"^wa|l.v|m.+n|me?$|.i.*d|....o|an*.e$|..k$ ...\"\n", + "adj(98):noun(100) 10000 calls, 136: \"e.+y|^..l*$|l.*s|rs?e$|a.l|ei?t|st$|en$|f ...\"\n", + "noun(100):verb(94) 10000 calls, 167: \"h.+g|mp*.n|p.*r|..h.|mb*e|ea?s|^k?i|.ne|. ...\"\n", + "verb(94):noun(100) 10000 calls, 162: \"rr|tar|o.b|^..p?l|^f?..$|buy|f$|^fi|as*k| ...\"\n", + "rand(58):built(147) 10000 calls, 69: \"ee|^_.*n|a.p|ia|an*d.|^_.?e|tst|_s|.G|_.o ...\"\n", + "built(147):rand(58) 10000 calls, 124: \"^rang|r...$|c.*t|ra*.i|^l*i|al*s|ug|^m?a| ...\"\n", + "dog(100):cat(91) 10000 calls, 43: \"E.+S$|I.*S$|H.*N.S|.HI|G.?S|TES|.SO|W |O.D.\"\n", + "cat(91):dog(100) 10000 calls, 104: \"J.V|RA*$|R.*A.$|LD?$|N.*X|M$|M...$|E.*O.$ ...\"\n", + "movie(100):tv(97) 10000 calls, 148: \" TH.+N| A*. |R...R|GR?O|IS?.$|A.C*E$|^GR| ...\"\n", + "tv(97):movie(100) 10000 calls, 148: \"4|HT?.W|..CH*I|XI$|PO*R|R..AN|MAS|..AY.|O ...\"\n", + "sci(50):star(50) 10000 calls, 70: \"AN?L..|T.V?.N|RL?.S|N.*RE|.S.+H|LER|.KA|P ...\"\n", + "star(50):sci(50) 10000 calls, 73: \"U.*R.|GR|LO.|F.+D|I.Y*N| T*R|G.*Y|AE?.W|E ...\"\n", + "CPU times: user 4min 38s, sys: 2 s, total: 4min 40s\n", + "Wall time: 4min 40s\n" + ] + }, + { + "data": { + "text/plain": [ + "1596" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=10000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We're making good progress. What next? We now have so many parts, that many of the searches do not complete. Suppose one of our first choices was wrong, and the search took a part that does not belong in an optimal solution. We might well spend all our calls on the half of the search tree that keeps the part, never exploring a part of the tree without it. I'd like to alter the search algorithm to get us out of that rut.\n", + "\n", + "# Searching: Random Restart\n", + "\n", + "\n", + "One way out of the rut is to run the search for a while, then stop it, and run a different search, that explores a different part of the search space. This is called a *random restart search*. How do we get a *different* search when we restart? I can think of two easy things to vary:\n", + " \n", + "+ The '4' in the `score` function. That is, vary the tradeoff between number of winners matched and number of characters in a regex.\n", + "+ The tie-breaker. In case of a tie on `max(covers, key=score)`, Python always picks the first component. Let's make it choose a different one each time.\n", + "\n", + "The first of these is easy; we can use the `random.choice` function to choose an integer, K, to serve as the tradeoff factor. The second is easy too. We could write an alternative to the `max` function, say `max_random_tiebreaker`. That would work, but an easier approach is to build the tiebreaker into the `score` function. In addition to awarding points for matching winners, and subtracting a point for each character in the solution, we will have `score` add in a random number. We'll call this the \"fuzz factor\" and use the variable `F` to determine how big it is. If the fuzz factor is a random number between 0 and 1, then all it does is serve as a tiebreaker. But if it is a random number that can be larger than 1, then sometimes it will cause `max` to pick a best part that does not have quite the best score. We're not sure how much randomness is best, so we'll let the values of `K` and `F` vary from one choice to the next." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def bb_findregex(winners, losers, calls=10000, restarts=10):\n", + " \"Find the shortest disjunction of regex components that covers winners but not losers.\"\n", + " bb = BranchBoundRandomRestart(winners, calls)\n", + " covers = eliminate_dominated(regex_covers(winners, losers))\n", + " for _ in range(restarts):\n", + " bb.calls = calls\n", + " bb.search(covers.copy())\n", + " if bb.calls > 0: # If search was not cut off, we have optimal solution\n", + " return bb \n", + " return bb\n", + "\n", + "class BranchBoundRandomRestart(BranchBound):\n", + " def search(self, covers, partial=None):\n", + " \"\"\"Recursively extend partial regex until it matches all winners in covers.\n", + " Try all reasonable combinations until we run out of calls.\"\"\"\n", + " if self.calls <= 0: \n", + " return partial, covers\n", + " self.calls -= 1\n", + " covers, partial = simplify_covers(covers, partial)\n", + " if not covers: # Nothing left to cover; solution is complete\n", + " self.cheapest = min(partial, self.cheapest, key=len)\n", + " elif len(OR(partial, min(covers, key=len))) < len(self.cheapest):\n", + " # Try with and without the greedy-best component\n", + " K = random.choice((2, 3, 4, 4, 4, 5, 6))\n", + " F = random.choice((0.1, 0.1, 2.0))\n", + " def score(c): return K * len(covers[c]) - len(c) + random.uniform(0., F)\n", + " best = max(covers, key=score) # Best component\n", + " covered = covers[best] # Set of winners covered by r\n", + " covers.pop(best)\n", + " self.search({c:covers[c]-covered for c in covers}, OR(partial, best))\n", + " self.search(covers, partial)\n", + " return self.cheapest" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 100 calls, 49: \"i.+o|o.*o|.f|ce|a.a|po|bu|ay.|ma|n.e|j|an ...\"\n", + "lose(34):win(34) 100 calls, 52: \"r.*y|^d|^s|go|m.+a|^f|....k|^.?la|ki*..$| ...\"\n", + "boy(10):girl(10) 29 calls, 11: \"a.$|c|de|as\"\n", + "girl(10):boy(10) 21 calls, 9: \"a$|^m*..i\"\n", + "drug(10):city(10) 91 calls, 15: \"o.$|x|ir|f|q|^e\"\n", + "city(10):drug(10) 49 calls, 11: \"ri|h|a.+e|k\"\n", + "foo(21):bar(21) 1 calls, 3: \"foo\"\n", + "bar(21):foo(21) 100 calls, 23: \"..r..|^...a|k|A|ld|...n\"\n", + "wars(6):trek(9) 23 calls, 7: \" T|P.*E\"\n", + "trek(9):wars(6) 100 calls, 12: \"I.?S|TI|H |Y\"\n", + "noun(100):adj(98) 100 calls, 160: \"^wa|l.v|m.+n|me?$|....o|.i.*d|ar*c.$|wo|. ...\"\n", + "adj(98):noun(100) 100 calls, 128: \"e.+y|^o*..$|l.*s|ll|rs?e$|ei?t|en$|st$|fa ...\"\n", + "noun(100):verb(94) 100 calls, 163: \"h.+g|mo?.n|p.*r|..h.|mb*e|t.*o|.ne|^k?i|f ...\"\n", + "verb(94):noun(100) 100 calls, 161: \"rr|tar|o.b|^..p?l|^s*..$|f$|buy|as*k|r.ad ...\"\n", + "rand(58):built(147) 100 calls, 69: \"ee|^_.*n|a.p|ia|an*d.|^_.?e|tst|_s|_a?.o| ...\"\n", + "built(147):rand(58) 100 calls, 119: \"^rang|r...$|c.*t|Wa|^d?i|al*s|ug|^m?a|o.* ...\"\n", + "dog(100):cat(91) 100 calls, 43: \"E.+S$|I.*S$|H.*N.S|.HI|G.?S|.SO|W |TES|O.D.\"\n", + "cat(91):dog(100) 100 calls, 97: \"J.V|RA*$|T$|LI*$|AN?$|N.*X|M$|F$|S.+E$|E. ...\"\n", + "movie(100):tv(97) 100 calls, 144: \" TH.+N|R...R| A*. |GO|UC*. |^N|A.C*E$|^GR ...\"\n", + "tv(97):movie(100) 100 calls, 148: \"4|HT?.W|..CH*I|XI$|PO*R|R..AN|MAS| .E.?E| ...\"\n", + "sci(50):star(50) 100 calls, 67: \"AN?L..|T.V?.N|.S.+H|.KA|IL?.O|N.*RE|OS|LE ...\"\n", + "star(50):sci(50) 100 calls, 73: \"U.*R.|GR|LO.|F.+D|I.Y*N| T*R|G.*Y| M*.T|E ...\"\n", + "CPU times: user 4min 39s, sys: 2.33 s, total: 4min 41s\n", + "Wall time: 4min 41s\n" + ] + }, + { + "data": { + "text/plain": [ + "1564" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=100) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Remember, when it says \"100 calls\" here, it really means 1,000 calls, because we are doing 10 random restarts. This looks very promising; even with only 100 calls per restart, we're doing better than 100,000 calls without restarts. Let's continue:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 1000 calls, 46: \"i.+o|o.*o|bu|a.t|j|ma|po|ie.|n.e|ay.|ar*d ...\"\n", + "lose(34):win(34) 1000 calls, 55: \"r.*y|i.e*$|^s|go|de|^f|do|la.$|al|k.+g|hu ...\"\n", + "boy(10):girl(10) 31 calls, 11: \"a.$|de|c|as\"\n", + "girl(10):boy(10) 21 calls, 9: \"a$|^m*..i\"\n", + "drug(10):city(10) 89 calls, 15: \"o.$|x|ir|f|q|^e\"\n", + "city(10):drug(10) 41 calls, 11: \"ri|a.+e|h|k\"\n", + "foo(21):bar(21) 1 calls, 3: \"foo\"\n", + "bar(21):foo(21) 1000 calls, 23: \"^...a|k|...n|ld|b|or|ar\"\n", + "wars(6):trek(9) 33 calls, 7: \" T|P.*E\"\n", + "trek(9):wars(6) 153 calls, 12: \"I.?S|RA| F|Y\"\n", + "noun(100):adj(98) 1000 calls, 159: \"^wa|l.v|m.+n|me?$|....o|.i.*d|an*.e$|..k$ ...\"\n", + "adj(98):noun(100) 1000 calls, 128: \"e.+y|^o*..$|l.*s|ll|rs?e$|ei?t|st$|en$|fa ...\"\n", + "noun(100):verb(94) 1000 calls, 162: \"h.+g|mp*.n|p.*r|..h.|mb*e|^k?i|.ne|or.?$| ...\"\n", + "verb(94):noun(100) 1000 calls, 159: \"rr|tar|o.b|^..p?l|^s*..$|f$|buy|as*k|r.ad ...\"\n", + "rand(58):built(147) 1000 calls, 69: \"ee|ia|^_.*n|a.p|an*d.|^_.?e|tst|_a?.o|ga| ...\"\n", + "built(147):rand(58) 1000 calls, 119: \"^rang|r...$|c.*t|Wa|^d?i|al*s|ug|o.*p..|Y ...\"\n", + "dog(100):cat(91) 1000 calls, 43: \"E.+S$|I.*S$|H.*N.S|.HI|G.?S|TES|.SO|W |O.D.\"\n", + "cat(91):dog(100) 1000 calls, 96: \"J.V|RA*$|T$|LD?$|AN?$|N.*X|M$|Y$|S.+E$|M. ...\"\n", + "movie(100):tv(97) 1000 calls, 139: \" TH.+N| A*. |R...R|GO|UC*. |^N|NC.$|A.NI| ...\"\n", + "tv(97):movie(100) 1000 calls, 148: \"4|HT?.W|..CH*I|XI$|PO*R|..AY.|O.+L.$|R..A ...\"\n", + "sci(50):star(50) 1000 calls, 67: \"AN?L..|T.V?.N|.S.+H|.KA|IL?.O|N.*RE|OS|NN ...\"\n", + "star(50):sci(50) 1000 calls, 73: \"U.*R.|GR|LO.|F.+D|I.+H$| T*R|G.*NE| M*.T| ...\"\n", + "CPU times: user 4min 56s, sys: 3.13 s, total: 4min 59s\n", + "Wall time: 4min 59s\n" + ] + }, + { + "data": { + "text/plain": [ + "1554" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=1000)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "win(34):lose(34) 10000 calls, 46: \"i.+o|o.*o|bu|a.t|j|ma|po|n.e|ay.|ar*d|e.? ...\"\n", + "lose(34):win(34) 10000 calls, 52: \"^d|r.*y|^s|go|m.+a|^f|^.?la|....k|ki*..$| ...\"\n", + "boy(10):girl(10) 29 calls, 11: \"a.$|de|c|as\"\n", + "girl(10):boy(10) 21 calls, 9: \"a$|^m*..i\"\n", + "drug(10):city(10) 105 calls, 15: \"x|o.$|ir|f|q|^e\"\n", + "city(10):drug(10) 39 calls, 11: \"ri|a.+e|h|k\"\n", + "foo(21):bar(21) 1 calls, 3: \"foo\"\n", + "bar(21):foo(21) 6049 calls, 23: \"^...a|k|...n|ld|b|ar|or\"\n", + "wars(6):trek(9) 23 calls, 7: \" T|P.*E\"\n", + "trek(9):wars(6) 147 calls, 12: \"I.?S|TI|H |Y\"\n", + "noun(100):adj(98) 10000 calls, 158: \"^wa|l.v|m.+n|me?$|....o|.i.*d|a.e$|..k$|^ ...\"\n", + "adj(98):noun(100) 10000 calls, 128: \"e.+y|^o*..$|ll|l.*s|rs?e$|ei?t|en$|i..l|l ...\"\n", + "noun(100):verb(94) 10000 calls, 163: \"h.+g|mp*.n|p.*r|..h.|mb*e|^k?i|.ne|.t.*y| ...\"\n", + "verb(94):noun(100) 10000 calls, 157: \"rr|tar|o.b|^..p?l|^s*..$|f$|buy|as*k|r.ad ...\"\n", + "rand(58):built(147) 10000 calls, 67: \"ee|ia|^_.*n|a.p|and|^_.?e|tst|_a?.o|ga|.G ...\"\n", + "built(147):rand(58) 10000 calls, 121: \"^rang|r...$|c.*t|Wa|al*s|ug|^l*i|o.*p..|Y ...\"\n", + "dog(100):cat(91) 10000 calls, 43: \"E.+S$|I.*S$|H.*N.S|.HI|G.?S|TES|.SO|W |O.D.\"\n", + "cat(91):dog(100) 10000 calls, 96: \"J.V|RA*$|T$|LD?$|AN?$|N.*X|M$|M...$|Y$|M. ...\"\n", + "movie(100):tv(97) 10000 calls, 141: \" TH.+N| A*. |R...R|GR?O|UC*. |A.C*E$|^GR| ...\"\n", + "tv(97):movie(100) 10000 calls, 148: \"4|HT?.W|..CH*I|XI$|PO*R|..AY.|R..AN|MAS|O ...\"\n", + "sci(50):star(50) 10000 calls, 67: \"AN?L..|T.V?.N|.S.+H|.KA|OS|NN|I.O|OD|^P|N ...\"\n", + "star(50):sci(50) 10000 calls, 72: \"U.*R.|GR|LO.|I.+H$|F.+D| T*R|G.*Y|YN|^B|I ...\"\n", + "CPU times: user 8min 3s, sys: 11.9 s, total: 8min 15s\n", + "Wall time: 8min 15s\n" + ] + }, + { + "data": { + "text/plain": [ + "1550" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time bbenchmark(calls=10000)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Just One More Thing: Negative Lookahead\n", + "----\n", + "\n", + "In the `foo` versus `bar` example, we have a big asymmetry in the solution lengths: three letter for `'foo'` compared to 23 characters in the other direction. But if you are a real [regular expression superhero](https://xkcd.com/208/), then you might know about [*negative lookahead assertions*](http://docs.python.org/2/howto/regex.html#lookahead-assertions) and you could solve `bar` versus `foo` like this: " + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "not_foo = '^(?!.*foo)'\n", + "not mistakes(not_foo, bar, foo)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Whoa—what just happened there? The form `'^(?!.*foo)'` means \"starting from the beginning of the line, look ahead for `'.*foo'` (that is, any number of characters followed by `'foo'`). If it is there, then fail, else succeeed.\" That's just what we need to match all the non-foo strings in the `bar` collection. Let's apply this idea to the complete benchmark and see how many characters we save. We'll use the `SOLUTION` dict that was compiled by the previous call to `benchmark`:" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15.8 ms, sys: 291 µs, total: 16.1 ms\n", + "Wall time: 16 ms\n" + ] + }, + { + "data": { + "text/plain": [ + "1429" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def consider_negative_lookahead(W, L): \n", + " \"Return either SOLUTION[W, L] or negative lookup of SOLUTION[L, W], whichever is shorter.\"\n", + " solution = min(SOLUTION[W, L], '^(?!.*(' + SOLUTION[L, W] + '))',\n", + " key=len)\n", + " assert not mistakes(solution, W, L)\n", + " return solution\n", + " \n", + "%time sum(len(consider_negative_lookahead(W, L)) for (W, _, _, L) in EXAMPLES)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Very nice! Almost a 10% improvement, and it took almost no additional time at all. \n", + "\n", + "# Summary of Results\n", + "\n", + "Here is a plot of results. Note that every time you re-run this notebook, the timing and the exact number of characters will vary a little; these numbers reflect rrsults from a previous run.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "image/png": "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\naaJjx44ttL6EhAS977778qX95z//0Ro1auiRI0c0NTVVR44cqY0aNdKQkBCNjIzUBQsWqKrqM888\no6k4Gp4AABn+SURBVA0bNtTAwEBt3ry5vvPOO6463nzzTa1fv77WrFlTP/74Yz18+LBGR0drYGCg\ntm7dWt966y318fHRnJwcVVWNjo7W9957L187vvrqK23VqpWGhobq448/7rb9y5cv19tuu821vn//\nfhURFRH18fFREdGIiAhVVZ0+fbqOGjUq3/YTJkxwlc9dJk6c6Mr//PPPtU2bNurv76833nijHjhw\nQFVVd+7cqR06dMhX19q1awvs+8Ybb3TlJyUlaXR0tPr7+2ubNm10zZo1+bafO3euNmnSRAMCAnTw\n4MGakpLiyrvw+zl+/Lh27txZf/vb3+q5c+d08uTJ+uSTT7r9jsrDpfybMaYyW7t2bb7znPO3WuJz\ntKgX3/vtfASwVFU7ikhH4HPglDO7EY4r+m6qevSC7dYCTwLJwBeq/7+9e4/P6UoXOP57ookmEpK4\nNUJQHa26H5cWbQUd7QyqqNvUrZzWMLTTqVsrmTIdzmhLT9Gehipl1JSpYTDV4gg6p8O0LiGUSpMg\njLZEmsQgkuf88e68zZu8IeqNNPJ8P598vO9aa6+99kq2vfbaa6+lTZzwwUBnVf2ll32pt2Oxtc3L\nl/vuu4833njDYxS9Nz169GD8+PFeH4Vcq5dffpmzZ8/+KCbfuXjxIq1atWLHjh3utzduNDtnjCkf\nnHP16pOsFOOGPQJQ1f2A+/01EUkG2qjqWRGpAaSraq6I3A78BPhKVc+JyHcicg+wCxgKFH2HzNw0\nPvnkkxKli46OLtGI/ZJo2LAhvXv39kle16ty5cocOnSorIthjKkASq0HQERWAJ2B6sDXwG9VdXGB\n+K+Atk4DoC/wOyAHyHPSbnDStQGWAIHA31S16CwyWA+AMb5i54wx5cP19gCU6iOAG8kaAMb4hp0z\nxpQP19sAsJkAjTHGmArIGgDGGGNMBWQNAGOMMaYCsgaAMcYYUwFZA8CYHyh/lcOSOnjwIO3atSvF\nEpVMQkICnTp1KutiGGPKmDUAylCDBg0ICgoiJCSE8PBwevbsyYkT3898PGLECCpXrkxISAhVq1al\nbdu27uV5vZk2bRr+/v6EhIQQGhrKvffey44dO667nH5+fnz11VfXlUd0dDSLFi0qNj4lJQU/P78i\n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\nD6cAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Algorithm Style Times Total character counts\n", + "DATA = [('Greedy', 'gD-', [6], [1740]),\n", + " ('BB (1/10/100K)', 'bo-', [8, 21, 196], [1676, 1674, 1669]),\n", + " ('BB + Parts (1/10K)', 'kd-', [272, 288], [1595, 1587]),\n", + " ('BB Restart (1/10/100K)', 'rs-', [289, 303, 493], [1560, 1556, 1547]),\n", + " ('BB Restart NegLook (100K)','m*-', [493], [1426])]\n", + "\n", + "def display(data=DATA):\n", + " fig = plt.figure()\n", + " ax = fig.add_subplot(111)\n", + " for (label, line, times, counts) in data:\n", + " plt.plot(times, counts, line, label=label)\n", + " x, y = times[-1], counts[-1]\n", + " offset = (-22, -15) if line in ('rs-', 'm*-') else (10, -5)\n", + " ax.annotate(str(y), xy=(x, y), xytext=offset, textcoords='offset points')\n", + " plt.xlabel('Time (seconds)'); plt.ylabel('Solution size (total chars)')\n", + " plt.legend(loc='lower left');\n", + "\n", + "display()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We've made great strides, decreasing the total solution length by 20%. (It is up to you whether that 20% improvement is worth the increase in time from 6 seconds to 8 minutes.)\n", + "\n", + "# Profiling Again\n", + "\n", + "Now where does the time go? Let's check again:" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 59623899 function calls (59278679 primitive calls) in 36.067 seconds\n", + "\n", + " Ordered by: cumulative time\n", + "\n", + " ncalls tottime percall cumtime percall filename:lineno(function)\n", + " 1 0.000 0.000 36.067 36.067 {built-in method builtins.exec}\n", + " 1 0.000 0.000 36.067 36.067 :1()\n", + " 1 0.002 0.002 36.067 36.067 :21(findregex)\n", + " 1 0.072 0.072 36.066 36.066 :1(bb_findregex)\n", + "100178/10 0.781 0.000 24.877 2.488 :13(search)\n", + " 100000 0.593 0.000 20.145 0.000 :1(simplify_covers)\n", + " 209152 2.074 0.000 11.561 0.000 :1(eliminate_dominated)\n", + " 1 0.007 0.007 10.413 10.413 :1(regex_covers)\n", + " 4047977 2.941 0.000 8.916 0.000 {built-in method builtins.any}\n", + " 1 0.104 0.104 8.110 8.110 :9()\n", + " 209151 0.747 0.000 8.080 0.000 :1(select_necessary)\n", + " 89666 0.043 0.000 8.006 0.000 re.py:222(compile)\n", + " 89666 0.533 0.000 7.963 0.000 re.py:278(_compile)\n", + " 89666 0.449 0.000 7.330 0.000 sre_compile.py:531(compile)\n", + " 18054570 4.510 0.000 4.745 0.000 :10()\n", + " 89666 0.335 0.000 3.693 0.000 sre_parse.py:819(parse)\n", + " 209151 0.801 0.000 3.453 0.000 __init__.py:505(__init__)\n", + " 209151 1.187 0.000 3.322 0.000 :5()\n", + " 89666 0.161 0.000 2.947 0.000 sre_compile.py:516(_code)\n", + " 89666 0.187 0.000 2.930 0.000 sre_parse.py:429(_parse_sub)\n", + " 50084 0.587 0.000 2.783 0.000 {built-in method builtins.max}\n", + " 209152 1.339 0.000 2.649 0.000 {built-in method builtins.sorted}\n", + " 209151 0.408 0.000 2.626 0.000 __init__.py:574(update)\n", + " 89666 1.184 0.000 2.626 0.000 sre_parse.py:491(_parse)\n", + " 636500 0.910 0.000 2.196 0.000 :26(score)\n", + " 1 1.683 1.683 2.164 2.164 :10()\n", + " 89666 0.472 0.000 1.407 0.000 sre_compile.py:412(_compile_info)\n", + "171350/89666 0.873 0.000 1.369 0.000 sre_compile.py:64(_compile)\n", + " 426948 0.469 0.000 1.331 0.000 :1(OR)\n", + " 2167485 0.983 0.000 1.311 0.000 :6(signature)\n", + " 209151 0.622 0.000 1.310 0.000 {built-in method _collections._count_elements}\n", + " 4734318 1.287 0.000 1.287 0.000 :5()\n", + " 636500 1.118 0.000 1.180 0.000 random.py:342(uniform)\n", + " 1147585 0.351 0.000 1.049 0.000 {built-in method builtins.isinstance}\n", + "11387014/11305330 0.956 0.000 0.980 0.000 {built-in method builtins.len}\n", + " 444972 0.606 0.000 0.818 0.000 {method 'join' of 'str' objects}\n", + " 209151 0.416 0.000 0.698 0.000 abc.py:178(__instancecheck__)\n", + " 2988397 0.688 0.000 0.688 0.000 :4()\n", + "253034/171350 0.566 0.000 0.684 0.000 sre_parse.py:167(getwidth)\n", + " 480786 0.209 0.000 0.605 0.000 sre_parse.py:247(get)\n", + " 89666 0.481 0.000 0.481 0.000 {method 'search' of '_sre.SRE_Pattern' objects}\n", + " 490104 0.334 0.000 0.478 0.000 sre_parse.py:157(__getitem__)\n", + " 570452 0.474 0.000 0.474 0.000 sre_parse.py:226(__next)\n", + " 532234 0.368 0.000 0.368 0.000 {built-in method builtins.min}\n", + " 2239948 0.317 0.000 0.317 0.000 {method 'append' of 'list' objects}\n", + " 418302 0.282 0.000 0.282 0.000 _weakrefset.py:70(__contains__)\n", + " 100168 0.097 0.000 0.270 0.000 random.py:250(choice)\n", + " 76784 0.248 0.000 0.248 0.000 :8()\n", + " 81684 0.148 0.000 0.241 0.000 sre_compile.py:386(_simple)\n", + " 399102 0.153 0.000 0.234 0.000 sre_parse.py:165(append)\n", + " 89666 0.145 0.000 0.233 0.000 sre_parse.py:217(__init__)\n", + " 1102830 0.213 0.000 0.213 0.000 :6()\n", + " 50084 0.195 0.000 0.195 0.000 :30()\n", + " 100168 0.111 0.000 0.164 0.000 random.py:220(_randbelow)\n", + " 89666 0.098 0.000 0.111 0.000 sre_parse.py:797(fix_flags)\n", + " 1 0.018 0.018 0.109 0.109 :7()\n", + " 171350 0.107 0.000 0.107 0.000 sre_parse.py:105(__init__)\n", + " 171350 0.088 0.000 0.107 0.000 sre_parse.py:276(tell)\n", + " 89666 0.102 0.000 0.102 0.000 {built-in method _sre.compile}\n", + " 245052 0.080 0.000 0.102 0.000 sre_parse.py:153(__len__)\n", + " 38126 0.095 0.000 0.100 0.000 sre_compile.py:391(_generate_overlap_table)\n", + " 179332 0.076 0.000 0.096 0.000 sre_compile.py:513(isstring)\n", + " 7902 0.016 0.000 0.091 0.000 :19(repetitions)\n", + " 89666 0.085 0.000 0.085 0.000 sre_parse.py:70(__init__)\n", + " 179332 0.064 0.000 0.082 0.000 sre_parse.py:75(groups)\n", + " 636500 0.062 0.000 0.062 0.000 {method 'random' of '_random.Random' objects}\n", + " 7902 0.047 0.000 0.061 0.000 :24()\n", + " 171350 0.048 0.000 0.048 0.000 sre_parse.py:242(match)\n", + " 76784 0.047 0.000 0.047 0.000 :7()\n", + " 123976 0.042 0.000 0.042 0.000 {method 'getrandbits' of '_random.Random' objects}\n", + " 246020 0.028 0.000 0.028 0.000 {built-in method builtins.ord}\n", + " 81684 0.023 0.000 0.023 0.000 sre_parse.py:161(__setitem__)\n", + " 1 0.003 0.003 0.022 0.022 :6()\n", + " 76384 0.022 0.000 0.022 0.000 {method 'extend' of 'list' objects}\n", + " 2433 0.006 0.000 0.016 0.000 :56(dotify)\n", + " 89666 0.016 0.000 0.016 0.000 {method 'items' of 'dict' objects}\n", + " 7902 0.014 0.000 0.014 0.000 :23()\n", + " 61211 0.012 0.000 0.012 0.000 {method 'endswith' of 'str' objects}\n", + " 100168 0.011 0.000 0.011 0.000 {method 'bit_length' of 'int' objects}\n", + " 50084 0.009 0.000 0.009 0.000 {method 'pop' of 'dict' objects}\n", + " 49204 0.009 0.000 0.009 0.000 {method 'get' of 'dict' objects}\n", + " 2433 0.006 0.000 0.009 0.000 :59()\n", + " 176 0.008 0.000 0.008 0.000 {method 'clear' of 'dict' objects}\n", + " 98 0.001 0.000 0.002 0.000 :3(subparts)\n", + " 9029 0.002 0.000 0.002 0.000 {method 'startswith' of 'str' objects}\n", + " 6431 0.002 0.000 0.002 0.000 :61(replacements)\n", + " 3568 0.001 0.000 0.001 0.000 :5()\n", + " 1 0.000 0.000 0.001 0.001 :14(pairs)\n", + " 1 0.001 0.001 0.001 0.001 :16()\n", + " 10 0.000 0.000 0.000 0.000 {method 'copy' of 'dict' objects}\n", + " 1 0.000 0.000 0.000 0.000 :3(__init__)\n", + " 1 0.000 0.000 0.000 0.000 :73(trivial)\n", + " 1 0.000 0.000 0.000 0.000 :5()\n", + " 1 0.000 0.000 0.000 0.000 weakref.py:102(remove)\n", + " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", + "\n", + "\n" + ] + } + ], + "source": [ + "cProfile.run('findregex(adverbs, nouns)', sort='cumulative')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We see that the majority of the time is in `simplify_covers`, and within that, half the time goes to `eliminate_dominated`. That gives us some ideas of where speedups could be made, but gains will be harder now than before." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "# Speculating: Other Ideas\n", + "\n", + "I'm going to stop here, but I'll briefly mention some other ideas that I didn't get to investigate. Perhaps you can play with some of these, or with other ideas.\n", + "\n", + "- *Completely different approach*: [Thomas Breuel](https://plus.google.com/118190679520611168174/posts) suggested doing [minimization](http://en.wikipedia.org/wiki/DFA_minimization) of [weighted finite state transducers](http://nbviewer.ipython.org/url/nlpa.iupr.com/resources/nlpa-openfst.ipynb?attredirects=0&create=1).\n", + "- *Character classes*: We never considered character classes, such as `'[abc]'`. It is not obvious they would help, but it is possible. Consider the fragment `'ld|la'`, which shows up in one of the solutions. We could replace that with a single component, `'l[da]'`. But we haven't gained anything; both are 5 characters long. If we had had `'l.d|l.c|l.b|l.a'` then the replacement `'l.[a-d]'` would save 8 characters, but I don't see many opportunities like that. It might also be possible to use *negative* character classes, like `l[^y]` to explicitly avoid something in the losers set.\n", + "\n", + "- *Prefilter parts*: Currently, `regex_covers` generates a huge set of components, then eliminates the ones that match losers (or don't match winners), and then eliminates the ones that are dominated. We could make `regex_covers` faster by not generating components that can't possibly contribute. Suppose we're considering a subpart, say `'ab'`. If it matches no losers, then there is no reason to extend it to a longer subpart, such as `'abc'`, because we know that `'abc'` is dominated by `'ab'`. By filtering out dominated parts before we have to check them, I estimate we should be able to cut the time for `regex_covers` in half, maybe better.\n", + "- *Better component choice*: We pick the \"best\" component based on how many winners it covers and how many characters it takes. Maybe we could have a better measure; perhaps taking into account whether it covers winners that are \"easy\" to cover by other regexes, or \"hard\" to cover.\n", + "- *Tuning*: We have the two parameters `K` and `F`, which are randomly chosen from a fairly arbitrary distribution. We could measure which values of the parameters perform better and pick those values more often.\n", + "- *Post-editing*: We concentrated on the task of generating a solution from scratch; another task is to improve an existing solution. For example, take the set of components in a solution, and see if one component could be dropped—it is possible that all the winners covered by that component might accidentally have been covered by other components, making it unnecessary. Or take all pairs of components, and see if they could be replaced by a shorter set of components.\n", + "- *Better bounds*: Branch and Bound search works best if the bounds are tight. If we can recognize early that the path we are on cannot possibly be as good as the best solution found so far then we can cut off search early and save time. But the bound estimate we are using now is a poor one. We estimate the cost of a solution as the cost of the partial solution plus the cost of the shortest component remaining. We use this estimate because all we know for sure is that we need at least one more component. Here's one way to get a better bound by recognizing that in many cases we will need more than one more component. We'll define the following quantities:\n", + "\n", + " + *P* = the length of the partial solution, plus the \"|\", if needed. So if the partial solution is `None`, then *P* = 0, else *P* is the length plus 1.\n", + " + *S* = the length of the shortest regex component in `covers`.\n", + " + *W* = the number of winners still in `covers`.\n", + " + *C* = the largest number of winners covered by any regex in `covers`.\n", + " \n", + " The current estimate is *P* + *S*. We can see that a better estimate is *P* + *S* × ceil(*W* / *C*).\n", + "\n", + "\n", + "I hope you had fun seeing how I (and Stefan) attacked this problem; now go out and solve some problems of your own." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "
\n", + "[*Peter Norvig*](http://norvig.com), Feb. 2014" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/xkcd1313.ipynb b/pytudes/ipynb/xkcd1313.ipynb new file mode 100644 index 0000000..aba9c4d --- /dev/null +++ b/pytudes/ipynb/xkcd1313.ipynb @@ -0,0 +1,1220 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# xkcd 1313: Regex Golf\n", + "\n", + "

Peter Norvig
January 2014
revised November 2015

\n", + "\n", + "I ♡ [xkcd](http://xkcd.com)! It reliably provides top-rate [insights](http://xkcd.com/285/), [humor](http://xkcd.com/612/), or [both](http://xkcd.com/627/). I was thrilled when I got to [introduce Randall Monroe](http://www.youtube.com/watch?v=zJOS0sV2a24) for a talk in 2007. But in [xkcd #1313](http://xkcd.com/1313), \n", + "\n", + "\n", + "\n", + "I found that the hover text, \"/bu|[rn]t|[coy]e|[mtg]a|j|iso|n[hl]|[ae]d|lev|sh|[lnd]i|[po]o|ls/ matches the last names of elected US presidents but not their opponents\", contains a confusing contradiction. I'm old enough to remember that Jimmy Carter won one term and lost a second. No regular expression could both match and not match \"Carter\". \n", + "\n", + "But this got me thinking: can I come up with an algorithm to match or beat Randall's regex golf scores? The game is on.\n", + "\n", + "# Presidents\n", + " \n", + "I started by finding a [listing](http://www.anesi.com/presname.htm) of presidential elections, giving me these winners and losers:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "from __future__ import division, print_function\n", + "import re\n", + "import itertools\n", + "\n", + "def words(text): return set(text.split())\n", + "\n", + "winners = words('''washington adams jefferson jefferson madison madison monroe \n", + " monroe adams jackson jackson van-buren harrison polk taylor pierce buchanan \n", + " lincoln lincoln grant grapartnt hayes garfield cleveland harrison cleveland mckinley\n", + " mckinley roosevelt taft wilson wilson harding coolidge hoover roosevelt \n", + " roosevelt roosevelt roosevelt truman eisenhower eisenhower kennedy johnson nixon \n", + " nixon carter reagan reagan bush clinton clinton bush bush obama obama''')\n", + "\n", + "losers = words('''clinton jefferson adams pinckney pinckney clinton king adams \n", + " jackson adams clay van-buren van-buren clay cass scott fremont breckinridge \n", + " mcclellan seymour greeley tilden hancock blaine cleveland harrison bryan bryan \n", + " parker bryan roosevelt hughes cox davis smith hoover landon willkie dewey dewey \n", + " stevenson stevenson nixon goldwater humphrey mcgovern ford carter mondale \n", + " dukakis bush dole gore kerry mccain romney''')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "We can see that there are multiple names that are both winners and losers:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'adams',\n", + " 'bush',\n", + " 'carter',\n", + " 'cleveland',\n", + " 'clinton',\n", + " 'harrison',\n", + " 'hoover',\n", + " 'jackson',\n", + " 'jefferson',\n", + " 'nixon',\n", + " 'roosevelt',\n", + " 'van-buren'}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "winners & losers" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Clinton? He won both his elections, didn't he? Yes, *Bill* Clinton did, but *George* Clinton (the Revolutionary War leader, not the Funkadelic leader) was a losing opponent in 1792 and 1812. To avoid the contradiction, I decided to eliminate all winners from the set of losers (and in fact Randall later confirmed that that was his intent):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "losers = losers - winners" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Defining the Problem\n", + "\n", + "\n", + "Let's be clear exactly what we're trying to achieve. We're looking for a Python regular expression which, when used with the `re.search` function, will match all of the winners but none of the losers. We can define the function `mistakes` to return a set of misclassifications; if `mistakes` is empty then the regular expression is verified correct:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def mistakes(regex, winners, losers):\n", + " \"The set of mistakes made by this regex in classifying winners and losers.\"\n", + " return ({\"Should have matched: \" + W \n", + " for W in winners if not re.search(regex, W)} |\n", + " {\"Should not have matched: \" + L \n", + " for L in losers if re.search(regex, L)})\n", + "\n", + "def verify(regex, winners, losers): \n", + " assert not mistakes(regex, winners, losers)\n", + " return True" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Let's check the xkcd regex:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Should not have matched: fremont'}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "xkcd = \"bu|[rn]t|[coy]e|[mtg]a|j|iso|n[hl]|[ae]d|lev|sh|[lnd]i|[po]o|ls\"\n", + "\n", + "mistakes(xkcd, winners, losers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The xkcd regex incorrectly matches `\"fremont\"`, representing John C. Frémont, the Republican candidate who lost to James Buchanan in 1856. Could Randall Monroe have made an error? Is someone **[wrong](http://xkcd.com/386/)** on the Internet? Investigating the [1856 election](http://en.wikipedia.org/wiki/United_States_presidential_election,_1856), I see that Randall must have had Millard Fillmore, the third-party candidate, as the opponent. Fillmore is more famous, having served as the 13th president (although he never won an election; he became president when Taylor died in office). But Fillmore only got 8 electoral votes in 1856 while Fremont got 114, so I will stick with Fremont in *my* list of losers. \n", + "\n", + "We can verify that Randall got it right under the interpretation that Fillmore, not Fremont, was the loser: " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alternative_losers = {'fillmore'} | losers - {'fremont'}\n", + "\n", + "verify(xkcd, winners, alternative_losers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Strategy for Finding a Regex\n", + "\n", + "\n", + "We need a strategy to find a regex that matches all the winners but none of the losers. I came up with this approach:\n", + " \n", + "- Generate a pool of regex *parts*: small regexes of a few characters, such as `\"bu\"` or `\"r.e$\"` or `\"j\"`.\n", + "- Consider only parts that match at least one winner, but no losers.\n", + "- Our solution will be formed by \"or\"-ing together some of these parts (e.g. `\"bu|n.e|j\"`).\n", + "- This is a [set cover problem](http://en.wikipedia.org/wiki/Set_cover_problem): pick some of the parts so that they cover all the winners.\n", + "- Set cover is an NP-hard problem, so I feel justified in using an approximation approach that finds a small but not necessarily smallest solution.\n", + "- For many NP-hard problems a good approximation can be had with a [greedy algorithm](http://en.wikipedia.org/wiki/Greedy_algorithm): Pick the \"best\" part first (the one that covers the most winners with the fewest characters), and repeat, choosing the \"best\" each time until there are no more winners to cover.\n", + "- To guarantee that we will find a solution, make sure that each winner has at least one part that matches it.\n", + "\n", + "There are three ways this strategy can fail to find the shortest possible regex:\n", + "\n", + "- The shortest regex might not be a disjunction. Our strategy can only find disjunctions (of the form `\"a|b|c|...\"`). \n", + "- The shortest regex might be a disjunction formed with different parts. For example, `\"[rn]t\"` is not in our pool of parts.\n", + "- The greedy algorithm isn't guaranteed to find the shortest solution. We might have all the right parts, but pick the wrong ones.\n", + "\n", + "The algorithm is below. Our pool of parts is a set of strings created with `regex_parts(winners, losers)`. We accumulate parts into the list `solution`, which starts empty. On each iteration choose the best part: the one with a maximum score. (I decided by default to score 4 points for each winner matched, minus one point for each character in the part.) We then add the best part to `solution`, and remove from winners all the strings that are matched by `best`. Finally, we update the pool, keeping only those parts that still match one or more of the remaining winners. When there are no more winners left, OR together all the solution parts to give the final regular expression string." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def findregex(winners, losers, k=4):\n", + " \"Find a regex that matches all winners but no losers (sets of strings).\"\n", + " # Make a pool of regex parts, then pick from them to cover winners.\n", + " # On each iteration, add the 'best' part to 'solution',\n", + " # remove winners covered by best, and keep in 'pool' only parts\n", + " # that still match some winner.\n", + " pool = regex_parts(winners, losers)\n", + " solution = []\n", + " def score(part): return k * len(matches(part, winners)) - len(part)\n", + " while winners:\n", + " best = max(pool, key=score)\n", + " solution.append(best)\n", + " winners = winners - matches(best, winners)\n", + " pool = {r for r in pool if matches(r, winners)}\n", + " return OR(solution)\n", + "\n", + "def matches(regex, strings):\n", + " \"Return a set of all the strings that are matched by regex.\"\n", + " return {s for s in strings if re.search(regex, s)}\n", + "\n", + "OR = '|'.join # Join a sequence of strings with '|' between them" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Glossary\n", + "\n", + "\n", + "Just to be clear, I define the terms I will be using:\n", + "\n", + "- *winners:* A set of strings; our solution is required to match each of them.\n", + "- *losers:* A set of strings; our solution is not allowed to match any of them.\n", + "- *part:* A small regular expression, a string, such as `'bu'` or `'a.a'`.\n", + "- *pool:* A set of parts from which we will pick a subset to form the solution.\n", + "- *regex:* A [regular expression](http://docs.python.org/2/library/re.html); a pattern used to match against a string. \n", + "- *solution:* A regular expression that matches all winners but no losers.\n", + "- *whole:* A part that matches a whole word (and nothing else): `'^word$'`\n", + "\n", + " \n", + "# Regex Parts\n", + "\n", + "\n", + "\n", + "Now we need to define what the `regex_parts` are. Here's what I came up with:\n", + "\n", + "- For each winner, include a regex that matches the entire string exactly. I call this regex a *whole*.\n", + "
Example: for `'word'`, include `'^word$'`\n", + "- For each whole, generate *subparts* consisting of 1 to 4 consecutive characters.\n", + "
Example: `subparts('^it$')` == `{'^', 'i', 't', '$', '^i', 'it', 't$', '^it', 'it$', '^it$'}`\n", + "- For each subpart, generate all ways to replace any of the letters with a dot (the \"match any\" character).\n", + "
Example: `dotify('it')` == `{'it', 'i.', '.t', '..'}`\n", + "- Keep only the dotified subparts that do not match any of the losers.\n", + "\n", + "Note that I only used a few of the regular expression mechanisms: `'.'`, `'^'`, and `'$'`. I didn't try to use character classes (`[a-z]`), nor any of the repetition operators, nor other advanced mechanisms. Why? I thought that the advanced features usually take too many characters. For example, I don't allow the part `'[rn]t'`, but I can achieve the same effect with the same number of characters by combining two parts: `'rt|nt'`. I could add more complicated mechanisms later, but for now, [YAGNI](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it). Here is the code:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [ + "def regex_parts(winners, losers):\n", + " \"Return parts that match at least one winner, but no loser.\"\n", + " wholes = {'^' + w + '$' for w in winners}\n", + " parts = {d for w in wholes for p in subparts(w) for d in dotify(p)}\n", + " return wholes | {p for p in parts if not matches(p, losers)}\n", + "\n", + "def subparts(word, N=4):\n", + " \"Return a set of subparts of word: consecutive characters up to length N (default 4).\"\n", + " return set(word[i:i+n+1] for i in range(len(word)) for n in range(N)) \n", + " \n", + "def dotify(part):\n", + " \"Return all ways to replace a subset of chars in part with '.'.\"\n", + " choices = map(replacements, part)\n", + " return {cat(chars) for chars in itertools.product(*choices)}\n", + "\n", + "def replacements(c): return c if c in '^$' else c + '.'\n", + "\n", + "cat = ''.join" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Our program is complete! We can run `findregex`, verify the solution, and compare the length of our solution to Randall's:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(53, 'a.a|i..n|j|oo|a.t|i..o|a..i|bu|n.e|ay.|r.e$|po|ma|nd$')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solution = findregex(winners, losers)\n", + "verify(solution, winners, losers)\n", + "\n", + "len(solution), solution" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(63, 'bu|[rn]t|[coy]e|[mtg]a|j|iso|n[hl]|[ae]d|lev|sh|[lnd]i|[po]o|ls')" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(xkcd), xkcd" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Our regex is 15% shorter than Randall's—success!\n", + "\n", + "# Tests\n", + "\n", + "Here's a test suite to give us more confidence in (and familiarity with) our functions:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'tests pass'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def tests():\n", + " assert subparts('^it$') == {'^', 'i', 't', '$', '^i', 'it', 't$', '^it', 'it$', '^it$'}\n", + " assert subparts('this') == {'t', 'h', 'i', 's', 'th', 'hi', 'is', 'thi', 'his', 'this'}\n", + " subparts('banana') == {'a', 'an', 'ana', 'anan', 'b', 'ba', 'ban', 'bana', \n", + " 'n', 'na', 'nan', 'nana'}\n", + " \n", + " assert dotify('it') == {'it', 'i.', '.t', '..'}\n", + " assert dotify('^it$') == {'^it$', '^i.$', '^.t$', '^..$'}\n", + " assert dotify('this') == {'this', 'thi.', 'th.s', 'th..', 't.is', 't.i.', 't..s', 't...',\n", + " '.his', '.hi.', '.h.s', '.h..', '..is', '..i.', '...s', '....'}\n", + " assert regex_parts({'win'}, {'losers', 'bin', 'won'}) == {\n", + " '^win$', '^win', '^wi.', 'wi.', 'wi', '^wi', 'win$', 'win', 'wi.$'}\n", + " assert regex_parts({'win'}, {'bin', 'won', 'wine', 'wit'}) == {'^win$', 'win$'}\n", + " regex_parts({'boy', 'coy'}, \n", + " {'ahoy', 'toy', 'book', 'cook', 'boycott', 'cowboy', 'cod', 'buy', 'oy', \n", + " 'foil', 'coyote'}) == {'^boy$', '^coy$', 'c.y$', 'coy$'}\n", + " \n", + " assert matches('a|b|c', {'a', 'b', 'c', 'd', 'e'}) == {'a', 'b', 'c'}\n", + " assert matches('a|b|c', {'any', 'bee', 'succeed', 'dee', 'eee!'}) == {\n", + " 'any', 'bee', 'succeed'}\n", + " \n", + " assert OR(['a', 'b', 'c']) == 'a|b|c'\n", + " assert OR(['a']) == 'a'\n", + " \n", + " assert words('this is a test this is') == {'this', 'is', 'a', 'test'}\n", + " \n", + " assert findregex({\"ahahah\", \"ciao\"}, {\"ahaha\", \"bye\"}) == 'a.$'\n", + " assert findregex({\"this\", \"that\", \"the other\"}, {\"one\", \"two\", \"here\", \"there\"}) == 'h..$'\n", + " assert findregex({'boy', 'coy', 'toy', 'joy'}, {'ahoy', 'buy', 'oy', 'foil'}) == '^.oy'\n", + " \n", + " assert not mistakes('a|b|c', {'ahoy', 'boy', 'coy'}, {'joy', 'toy'})\n", + " assert not mistakes('^a|^b|^c', {'ahoy', 'boy', 'coy'}, {'joy', 'toy', 'kickback'})\n", + " assert mistakes('^.oy', {'ahoy', 'boy', 'coy'}, {'joy', 'ploy'}) == {\n", + " \"Should have matched: ahoy\", \n", + " \"Should not have matched: joy\"}\n", + " return 'tests pass'\n", + "\n", + "tests()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# Regex Golf with Arbitrary Lists\n", + "\n", + "Let's move on to arbitrary lists. I define `report`, to call `findregex`, verify the solution, and print the number of characters in the solution, the number of parts, the *competitive ratio* (the ratio between the lengths of a trivial solution and the actual solution), and the number of winners and losers." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 53, Parts: 14, Competitive ratio: 5.2, Winners: 35, Losers: 34\n" + ] + }, + { + "data": { + "text/plain": [ + "'a.a|i..n|j|oo|a.t|i..o|a..i|bu|n.e|ay.|r.e$|po|ma|nd$'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def report(winners, losers):\n", + " \"Find a regex to match A but not B, and vice-versa. Print summary.\"\n", + " solution = findregex(winners, losers)\n", + " verify(solution, winners, losers)\n", + " trivial = '^(' + OR(winners) + ')$'\n", + " print('Characters: {}, Parts: {}, Competitive ratio: {:.1f}, Winners: {}, Losers: {}'.format(\n", + " len(solution), solution.count('|') + 1, len(trivial) / len(solution) , len(winners), len(losers)))\n", + " return solution\n", + "\n", + "report(winners, losers)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The top 10 [boys and girls names](http://www.ssa.gov/oact/babynames/) for 2012:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 11, Parts: 3, Competitive ratio: 6.4, Winners: 10, Losers: 10\n" + ] + }, + { + "data": { + "text/plain": [ + "'e.$|a.$|a.o'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "boys = words('jacob mason ethan noah william liam jayden michael alexander aiden')\n", + "girls = words('sophia emma isabella olivia ava emily abigail mia madison elizabeth')\n", + "\n", + "report(boys, girls)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "This is interesting because `'a.$|e.$|a.o'` is an example of something that could be re-written in a shorter form if we allowed more complex parts. The following would save one character:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "verify('[ae].(o|$)', boys, girls)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "We have now fulfilled panel two of the strip. Let's try another example, separating \n", + "the top ten best-selling drugs from the top 10 cities to visit:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 15, Parts: 6, Competitive ratio: 5.3, Winners: 10, Losers: 10\n" + ] + }, + { + "data": { + "text/plain": [ + "'o.$|x|ir|q|f|po'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "drugs = words('lipitor nexium plavix advair ablify seroquel singulair crestor actos epogen')\n", + "cities = words('paris trinidad capetown riga zurich shanghai vancouver chicago adelaide auckland')\n", + "\n", + "report(drugs, cities)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "\n", + "We can answer the challenge from panel one of the strip:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 9, Parts: 3, Competitive ratio: 13.0, Winners: 6, Losers: 9\n" + ] + }, + { + "data": { + "text/plain": [ + "' T|E.P|OP'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def phrases(text, sep='/'): return {line.upper().strip() for line in text.split(sep)}\n", + "\n", + "starwars = phrases('''The Phantom Menace / Attack of the Clones / Revenge of the Sith /\n", + " A New Hope / The Empire Strikes Back / Return of the Jedi''')\n", + "\n", + "startrek = phrases('''The Wrath of Khan / The Search for Spock / The Voyage Home /\n", + " The Final Frontier / The Undiscovered Country / Generations / \n", + " First Contact / Insurrection / Nemesis''')\n", + "\n", + "report(starwars, startrek)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "Neat—our solution is one character shorter than Randall's. We can verify that Randall's solution is also correct:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "verify('M | [TN]|B', starwars, startrek)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "**Update (Nov 2015): There are two new movies in the works! **\n", + "\n", + "
\n", + "\n", + "\n", + "\n", + "
\n", + "\n", + "Let's add them:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "' T|CE| ..P'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "starwars.add('THE FORCE AWAKENS')\n", + "startrek.add('BEYOND')\n", + "\n", + "findregex(starwars, startrek)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The two movies cost us one more character.\n", + "\n", + "There are lots of examples to play with over at [regex.alf.nu](http://regex.alf.nu), like this one:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 3, Parts: 1, Competitive ratio: 53.7, Winners: 21, Losers: 21\n" + ] + }, + { + "data": { + "text/plain": [ + "'foo'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "foo = words('''afoot catfoot dogfoot fanfoot foody foolery foolish fooster \n", + " footage foothot footle footpad footway hotfoot jawfoot mafoo nonfood padfoot \n", + " prefool sfoot unfool''')\n", + "\n", + "bar = words('''Atlas Aymoro Iberic Mahran Ormazd Silipan altared chandoo crenel \n", + " crooked fardo folksy forest hebamic idgah manlike marly palazzi sixfold \n", + " tarrock unfold''')\n", + "\n", + "report(foo, bar)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "The answer varies with different runs; sometimes it is `'foo'` and sometimes `'f.o'`. Both have 3 characters, but `'f.o'` is smaller in terms of the total amount of ink/pixels needed to render it. (How can the answer vary, when there are no calls to any `random` function? Because when `max` iterates over a set and several elements have the same best score, it is *unspecified* which one will be selected.)\n", + "\n", + "Of course, we can run any of these examples in the other direction:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 26, Parts: 8, Competitive ratio: 6.0, Winners: 21, Losers: 21\n" + ] + }, + { + "data": { + "text/plain": [ + "'r..$|k|.m|...n|ld|la|dg|or'" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "report(bar, foo)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "# What To Do Next? \n", + "\n", + "I see two options:\n", + "\n", + "- Stop here and declare victory! *Yay!*\n", + "- Try to make the program faster and capable of finding shorter regexes. \n", + "\n", + "My first inclination was \"stop here\", and that's what this notebook will shortly do. But several correspondents offered very interesting suggestions, so I returned to the problem in [a second notebook](http://nbviewer.ipython.org/url/norvig.com/ipython/xkcd1313-part2.ipynb?create=1). \n", + "\n", + "I was asked whether Randall was **[wrong](http://xkcd.com/386/)** to come up with \"only\" a 10-character Star Wars regex, whereas I showed there is a 9-character version. I would say that, given his role as a cartoonist, author, public speaker, educator, and entertainer, he has [chosen ... wisely](https://www.youtube.com/watch?v=puo1Enh9h5k&feature=youtu.be&t=294). He wrote a program that was good enough to allow him to make a great webcomic. A 9-character regex would not improve the comic. Randall stated that he used a genetic algorithm to find his regexes, and it has been said that genetic algorithms are often the second (or was it the third?) best method to solve any problem, and that's all he needed. But if you consider that in addition to all those roles, Randall is also still a practicing computer scientist, you could say\n", + "[he chose ... poorly](https://www.youtube.com/watch?v=Ubw5N8iVDHI). Genetic algorithms are good when you want to combine the structure of two solutions to yield a better solution, so they would work well if the best regexes had a complicated tree structure. But they don't! The best solutions are disjunctions of small parts. So the genetic algorithm is trying to combine the first half of one disjunction with the second half of another—but that isn't useful, because the components of a disjunction are unordered; imposing an ordering on them doesn't help.\n", + "\n", + "# Summary\n", + "\n", + "That was fun! I hope this page gives you an idea of how to think about problems like this. Let's review what we did:\n", + "\n", + "- Found an interesting problem (in a comic strip) and realized that it would not be hard to program a solution.\n", + "- Wrote the function `mistakes` to prove that we really understand exactly what the problem is.\n", + "- Came up with an approach: create lots of regex parts, and \"or\" together a subset of them.\n", + "- Realized that this is an instance of a known problem, *set cover*.\n", + "- Since set cover is computationally expensive, decide to use a *greedy algorithm*, which will be efficient (although not optimal).\n", + "- Decided what goes into the pool of regex parts.\n", + "- Implemented an algorithm to greedily pick parts from the pool (the function `findregex`).\n", + "- Tried the algorithm on some examples.\n", + "- Declared victory!\n", + "\n", + " \n", + "# Thanks!\n", + "\n", + "\n", + "Thanks especially to [Randall Monroe](http://xkcd.com/) for inspiring me to do this, to [regex.alf.nu](http://regex.alf.nu) for inspiring Randall, to Sean Lip for correcting \"Wilkie\" to \"Willkie,\" and to [Davide Canton](https://plus.sandbox.google.com/108324296451294887432/posts), [Thomas Breuel](https://plus.google.com/118190679520611168174/posts), and [Stefan Pochmann](http://www.stefan-pochmann.info/spocc/) for providing suggestions to improve my code.\n", + "\n", + "\n", + "\n", + "
\n", + "[*Peter Norvig*](http://norvig.com), Jan. 2014" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "button": false, + "collapsed": false, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Characters: 44, Parts: 12, Competitive ratio: 4.8, Winners: 21, Losers: 21\n" + ] + }, + { + "data": { + "text/plain": [ + "'.17|4.2|1.4|06|55|009|37|0.2|00$|191|015|003'" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "report(words(\"\"\" 000000000\n", + " 000000003\n", + " 000000006\n", + " 000000009\n", + " 000000012\n", + " 000000015\n", + " 066990060\n", + " 140091876\n", + " 173655750\n", + " 312440187\n", + " 321769005\n", + " 368542278\n", + " 390259104\n", + " 402223947\n", + " 443512431\n", + " 714541758\n", + " 747289572\n", + " 819148602\n", + " 878531775\n", + " 905586303\n", + " 9537348\"\"\"), words(\"\"\"000000005\n", + " 000000008\n", + " 000000010\n", + " 000000011\n", + " 000000014\n", + " 018990130\n", + " 112057285\n", + " 159747125\n", + " 176950268\n", + " 259108903\n", + " 333162608\n", + " 388401457\n", + " 477848777\n", + " 478621693\n", + " 531683939\n", + " 704168662\n", + " 759282218\n", + " 769340942\n", + " 851936815\n", + " 973816159\n", + " 979204403\"\"\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "button": false, + "collapsed": true, + "deletable": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/ipynb/xkxd-part3.ipynb b/pytudes/ipynb/xkxd-part3.ipynb new file mode 100644 index 0000000..e2388b4 --- /dev/null +++ b/pytudes/ipynb/xkxd-part3.ipynb @@ -0,0 +1,428 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def partition(covers):\n", + " # covers: {w: {r,...}}\n", + " # invcovers: {r: {w,...}}\n", + " pass\n", + "\n", + "def connected(w, covers, invcovers, result):\n", + " if w not in result:\n", + " result.add(w)\n", + " for r in covers[w]:\n", + " for w2 in invcovers[r]:\n", + " connected(w2, covers, invcovers, result)\n", + " return result\n", + "\n", + "for (W, L, legend) in ALL:\n", + " covers = eliminate_dominated(regex_covers(W, L))\n", + " invcovers = invert_multimap(covers)\n", + " start = list(covers)[2]\n", + " P = connected(start, covers, invcovers, set())\n", + " print legend, len(P), len(covers), len(covers)-len(P)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finding Shorter Regexes: Trying Multiple Times\n", + "----\n", + " \n", + "Why run just two versions of `findregex`? Why not run 1000 variations, and then pick the best solution? Of course, I don't want to write 1000 different functions by hand; I want an automated way of varying each run. I can think of three easy things to vary:\n", + " \n", + "* The number '4' in the `score` function. That is, vary the tradeoff between number of winners matched and number of characters.\n", + "* The tie-breaker. In case of a tie, Python's `max` function always picks the first one. Let's make it choose a different 'best' regex from among all those that tie.\n", + "* The greediness. Don't be so greedy (picking the best) every time. Occasionally pick a not-quite-best component, and see if that works out better.\n", + " \n", + "The first of these is easy; we just use the `random.choice` function to choose an integer, `K`, to serve as the tradeoff factor. \n", + "\n", + "The second is easy too. We could write an alternative to the `max` function, say `max_random_tiebreaker`. That would work, but an easier approach is to build the tiebreaker into the `score` function. In addition to awarding points for matching winners and the number of characters, we will have add in a tiebreaker: a random number between 0 and 1. Since all the scores are otherwise integers, this will not change the order of the scores, but it will break ties.\n", + "\n", + "The third we can accomplish by allowing the random factor to be larger than 1 (allowing us to pick a component that is not the shortest) or even larger than `K` (allowing us to pick a component that does not cover the most winners). \n", + " \n", + "I will factor out the function `greedy_search` to do a single computation oof a covering regex, while keeping the name `findregex` for the top level function that now calls `greedy_search` 1000 times and chooses the best (shortest length) result." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "def findregex(winners, losers, tries=1000):\n", + " \"Find a regex that matches all winners but no losers (sets of strings).\"\n", + " # Repeatedly call 'findregex1' the given number of tries; pick the shortest result\n", + " covers = regex_covers(winners, losers)\n", + " results = [greedy_search(winners, covers) for _ in range(tries)]\n", + " return min(results, key=len)\n", + "\n", + "def greedy_search(winners, covers):\n", + " # On each iteration, add the 'best' component in covers to 'result',\n", + " # remove winners covered by best, and remove from 'pool' any components\n", + " # that no longer match any remaining winners.\n", + " winners = set(winners) # Copy input so as not to modify it.\n", + " pool = set(covers)\n", + " result = []\n", + " \n", + " def matches(regex, strings): return {w for w in covers[regex] if w in strings}\n", + " \n", + " K = random.choice((2, 3, 4, 4, 5, 6))\n", + " T = random.choice((1., 1.5, 2., K+1., K+2.))\n", + " def score(c): \n", + " return K * len(matches(c, winners)) - len(c) + random.uniform(0., T)\n", + " \n", + " while winners:\n", + " best = max(pool, key=score)\n", + " result.append(best)\n", + " winners -= covers[best]\n", + " pool -= {c for c in pool if covers[c].isdisjoint(winners)}\n", + " return OR(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def factorial1(n):\n", + " if (n <= 1):\n", + " return 1\n", + " else:\n", + " return n * factorial1(n-1)\n", + "\n", + "def factorial2(n, partial_solution=1):\n", + " if (n <= 1):\n", + " return partial_solution\n", + " else:\n", + " return factorial2(n-1, n * partial_solution)\n", + " \n", + "assert factorial1(6) == factorial2(6) == 720" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def findregex(winners, losers, calls=100000):\n", + " \"Find the shortest disjunction of regex components that covers winners but not losers.\"\n", + " covers = regex_covers(winners, losers)\n", + " best = '^(' + OR(winners) + ')$'\n", + " state = Struct(best=best, calls=calls)\n", + " return bb_search('', covers, state).best\n", + "\n", + "def bb_search(regex, covers, state):\n", + " \"\"\"Recursively build a shortest regex from the components in covers.\"\"\"\n", + " if state.calls > 0:\n", + " state.calls -= 1\n", + " regex, covers = simplify_covers(regex, covers)\n", + " if not covers:\n", + " state.best = min(regex, state.best, key=len)\n", + " elif len(OR2(regex, min(covers, key=len))) < len(state.best):\n", + " # Try with and without the greedy-best component\n", + " def score(c): return 4 * len(covers[c]) - len(c)\n", + " best = max(covers, key=score)\n", + " covered = covers[best]\n", + " covers.pop(best)\n", + " bb_search(OR2(regex, best), {c:covers[c]-covered for c in covers}, state)\n", + " bb_search(regex, covers, state)\n", + " return state\n", + "\n", + "class Struct(object):\n", + " \"A mutable structure with specified fields and values.\"\n", + " def __init__(self, **kwds): vars(self).update(kwds)\n", + " def __repr__(self): return '<%s>' % vars(self)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def findregex(winners, losers, calls=100000):\n", + " \"Find the shortest disjunction of regex components that covers winners but not losers.\"\n", + " covers = regex_covers(winners, losers)\n", + " solution = '^(' + OR(winners) + ')$'\n", + " solution, calls = bb_search('', covers, solution, calls)\n", + " return solution\n", + "\n", + "def bb_search(regex, covers, solution, calls):\n", + " \"\"\"Recursively build a shortest regex from the components in covers.\"\"\"\n", + " if calls > 0:\n", + " calls -= 1\n", + " regex, covers = simplify_covers(regex, covers)\n", + " if not covers: # Solution is complete\n", + " solution = min(regex, solution, key=len)\n", + " elif len(OR2(regex, min(covers, key=len))) < len(solution):\n", + " # Try with and without the greedy-best component\n", + " def score(c): return 4 * len(covers[c]) - len(c)\n", + " r = max(covers, key=score) # Best component\n", + " covered = covers[r] # Set of winners covered by r\n", + " covers.pop(r)\n", + " solution, calls = bb_search(OR2(regex, r), \n", + " {c:covers[c]-covered for c in covers}, \n", + " solution, calls)\n", + " solution, calls = bb_search(regex, covers, solution, calls)\n", + " return solution, calls" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def findregex(winners, losers, calls=100000):\n", + " \"Find the shortest disjunction of regex components that covers winners but not losers.\"\n", + " global SOLUTION, CALLS\n", + " SOLUTION = '^(' + OR(winners) + ')$'\n", + " CALLS = calls\n", + " return bb_search(None, regex_covers(winners, losers))\n", + "\n", + "def bb_search(regex, covers):\n", + " \"\"\"Recursively build a shortest regex from the components in covers.\"\"\"\n", + " global SOLUTION, CALLS\n", + " CALLS -= 1\n", + " regex, covers = simplify_covers(regex, covers)\n", + " if not covers: # Solution is complete\n", + " SOLUTION = min(regex, SOLUTION, key=len)\n", + " elif CALLS >= 0 and len(OR(regex, min(covers, key=len))) < len(SOLUTION):\n", + " # Try with and without the greedy-best component\n", + " def score(c): return 4 * len(covers[c]) - len(c)\n", + " r = max(covers, key=score) # Best component\n", + " covered = covers[r] # Set of winners covered by r\n", + " covers.pop(r)\n", + " bb_search(OR(regex, r), {c:covers[c]-covered for c in covers})\n", + " bb_search(regex, covers)\n", + " return SOLUTION\n", + " \n", + "def OR(*regexes):\n", + " \"OR together regexes. Ignore 'None' components.\"\n", + " return '|'.join(r for r in regexes if r is not None)\n", + "\n", + "\n", + "def invert_multimap(multimap):\n", + " result = collections.defaultdict(list)\n", + " for key in multimap:\n", + " for val in multimap[key]:\n", + " result[val].append(key)\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "## For debugging\n", + "\n", + "def findregex(winners, losers, calls=100000):\n", + " \"Find the shortest disjunction of regex components that covers winners but not losers.\"\n", + " solution = '^(' + OR(winners) + ')$'\n", + " covers = regex_covers(winners, losers)\n", + " b = BranchBound(solution, calls)\n", + " b.search(None, covers)\n", + " print b.calls, 'calls', len(b.solution), 'len'\n", + " return b.solution\n", + "\n", + "\n", + "def triage_covers(partial, covers):\n", + " \"Simplify covers by eliminating dominated regexes, and picking ones that uniquely cover a winner.\"\n", + " previous = None\n", + " while covers != previous:\n", + " previous = covers\n", + " # Eliminate regexes that are dominated by another regex\n", + " covers = eliminate_dominated(covers) # covers = {regex: {winner,...}}\n", + " coverers = invert_multimap(covers) # coverers = {winner: {regex,...}}\n", + " # For winners covered by only one component, move winner from covers to regex\n", + " singletons = {coverers[w][0] for w in coverers if len(coverers[w]) == 1}\n", + " if singletons:\n", + " partial = OR(partial, OR(singletons))\n", + " covered = {w for c in singletons for w in covers[c]}\n", + " covers = {c:covers[c]-covered for c in covers if c not in singletons}\n", + " return partial, covers\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ", and to , who suggested looking at [WFSTs](http://www.openfst.org/twiki/bin/view/FST/WebHome)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def regex_covers(winners, losers):\n", + " \"\"\"Generate regex components and return a dict of {regex: {winner...}}.\n", + " Each regex matches at least one winner and no loser.\"\"\"\n", + " losers_str = '\\n'.join(losers)\n", + " wholes = {'^'+winner+'$' for winner in winners}\n", + " parts = {d for w in wholes for p in subparts(w) for d in dotify(p)}\n", + " chars = set(cat(winners))\n", + " pairs = {A+'.'+rep_char+B for A in chars for B in chars for rep_char in '+*?'}\n", + " reps = {r for p in parts for r in repetitions(p)}\n", + " pool = wholes | parts | pairs | reps \n", + " searchers = [re.compile(c, re.MULTILINE).search for c in pool]\n", + " covers = {r: set(filter(searcher, winners)) \n", + " for (r, searcher) in zip(pool, searchers)\n", + " if not searcher(losers_str)}\n", + " covers = eliminate_dominated(covers)\n", + " return covers\n", + " return add_character_class_components(covers)\n", + "\n", + "def add_character_class_components(covers):\n", + " for (B, Ms, E) in combine_splits(covers):\n", + " N = len(Ms)\n", + " or_size = N*len(B+'.'+E) + N-1 # N=3 => 'B1E|B2E|B3E'\n", + " class_size = len(B+'[]'+E) + N # N=3 => 'B[123]E'\n", + " winners = {w for m in Ms for w in Ms[m]}\n", + " if class_size < or_size:\n", + " covers[B + make_char_class(Ms) + E] = winners\n", + " return covers\n", + "\n", + "def split3(word):\n", + " \"Splits a word into 3 parts, all ways, with middle part having 0 or 1 character.\"\n", + " return [(word[:i], word[i:i+L], word[i+L:]) \n", + " for i in range(len(word)+1) for L in (0, 1)\n", + " if not word[i:i+L].startswith(('.', '+', '*', '?'))]\n", + "\n", + "def combine_splits(covers):\n", + " \"Convert covers = {BME: {w...}} into a list of [(B, {M...}, E, {w...}].\"\n", + " table = collections.defaultdict(dict) # table = {(B, E): {M: {w...}}}\n", + " for r in covers:\n", + " for (B, M, E) in split3(r):\n", + " table[B, E][M] = covers[r]\n", + " return [(B, Ms, E) for ((B, E), Ms) in table.items()\n", + " if len(Ms) > 1]\n", + "\n", + "def make_char_class(chars):\n", + " chars = set(chars)\n", + " return '[%s]%s' % (cat(chars), ('?' if '' in chars else ''))\n", + "\n", + "covers = regex_covers(boys, girls)\n", + "old = set(covers)\n", + "print len(covers)\n", + "covers = add_character_class_components(covers)\n", + "print len(covers)\n", + "print set(covers) - old\n", + "\n", + "print dict(combine_splits({'..a': {1,2,3}, '..b': {4,5,6}, '..c':{7}}))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consider the two components `'..a'` and `'..b'`. If we wanted to cover all the winners that both of these match, we could use `'..a|..b'`, or we could share the common prefix and introduce a *character class* to get `'..[ab]'`. Since the former is 7 characters and the later is only 6, the later would be preferred. It would be an even bigger win to replace `'..az|..bz|..cz'` with `'..[abc]z'`; that reduces the count from 14 to 8. Similarly, replacing `'..az|..bz|..z'` with `'..[ab]?z'` saves 5 characters.\n", + "\n", + "There seems to be potential savings with character classes. But how do we know which characters from which components to combine into classes? To keep things from getting out of control, I'm going to only look at components that are left after we eliminate dominated. That is not an ideal approach—there may well be some components that are dominated on their own, but could be part of an optimal solution when combined with other components into a character class. But I'm going to keep it simple." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "Searching: Better Bounds\n", + "----\n", + "\n", + "Branch and bound prunes the search tree whenever it is on a branch that is guaranteed to result in a solution that is no better than the best solution found so far. Currently we estimate the best possible solution along the current branch by taking the length of the partial solution and adding the length of the shortest component in `covers`. We do that because we know for sure that we need at least one component, but we don't know for sure how many components we'll need (nor how long each of them will be. So our estimate is often severely underestimates the true answer, which means we don't cut off search some places where we could, if only we had a better estimate.\n", + " \n", + "Here's one way to get a better bound. We'll define the following quantities:\n", + "\n", + "+ *P* = the length of the partial solution, plus the \"|\", if needed. So if the partial solution is `None`, then *P* will be zero, otherwise *P* is the length plus 1.\n", + "+ *S* = the length of the shortest regex component in `covers`.\n", + "+ *W* = the number of winners still in `covers`.\n", + "+ *C* = the largest number of winners covered by any regex in `covers`.\n", + "\n", + "If we assume The current estimate is *P* + *S*. We can see that a better estimate is *P* + *S* × ceil(*W* / *C*)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import math\n", + "\n", + "class BranchBound(object):\n", + " \"Hold state information for a branch and bound search.\"\n", + " def __init__(self, solution, calls):\n", + " self.solution, self.calls = solution, calls\n", + " \n", + " def search(self, covers, partial=None):\n", + " \"Recursively extend partial regex until it matches all winners in covers.\"\n", + " if self.calls <= 0: \n", + " return self.solution\n", + " self.calls -= 1\n", + " covers, partial = simplify_covers(covers, partial)\n", + " if not covers: # Nothing left to cover; solution is complete\n", + " self.solution = min(partial, self.solution, key=len)\n", + " else:\n", + " P = 0 if not partial else len(partial) + 1\n", + " S = len(min(covers, key=len))\n", + " C = max(len(covers[r]) for r in covers)\n", + " W = len(set(w for r in covers for w in covers[r]))\n", + " if P + S * math.ceil(W / C) < len(self.solution):\n", + " # Try with and without the greedy-best component\n", + " def score(r): return 4 * len(covers[r]) - len(r)\n", + " r = max(covers, key=score) # Best component\n", + " covered = covers[r] # Set of winners covered by r\n", + " covers.pop(r)\n", + " self.search({c:covers[c]-covered for c in covers}, OR(partial, r))\n", + " self.search(covers, partial)\n", + " return self.solution" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pytudes/py/SET.py b/pytudes/py/SET.py new file mode 100644 index 0000000..5349c4c --- /dev/null +++ b/pytudes/py/SET.py @@ -0,0 +1,134 @@ +import random +import collections +import itertools + +""" +Game of Set (Peter Norvig 2010-2015) + +How often do sets appear when we deal an array of cards? +How often in the course of playing out the game? + +Here are the data types we will use: + + card: A string, such as '3R=0', meaning "three red striped ovals". + deck: A list of cards, initially of length 81. + layout: A list of cards, initially of length 12. + set: A tuple of 3 cards. + Tallies: A dict: {12: {True: 33, False: 1}}} means a layout of size 12 + tallied 33 sets and 1 non-set. +""" + +#### Cards, dealing cards, and defining the notion of sets. + +CARDS = [number + color + shade + symbol + for number in '123' + for color in 'RGP' + for shade in '@O=' + for symbol in '0SD'] + +def deal(n, deck): + "Deal n cards from the deck." + return [deck.pop() for _ in range(n)] + +def is_set(cards): + "Are these 3 cards a set? No if any feature has 2 values." + for f in range(4): + values = {card[f] for card in cards} + if len(values) == 2: + return False + return True + +def find_set(layout): + "Return a set found from this layout, if there is one." + for cards in itertools.combinations(layout, 3): + if is_set(cards): + return cards + return () + +#### Tallying set:no-set ratio + +def Tallies(): + "A data structure to keep track, for each size, the number of sets and no-sets." + return collections.defaultdict(lambda: {True: 0, False: 0}) + +def tally(tallies, layout): + "Record that a set was found or not found in a layout of given size; return the set." + s = find_set(layout) + tallies[len(layout)][bool(s)] += 1 + return s + +#### Three experiments + +def tally_initial_layout(N, sizes=(12, 15)): + "Record tallies for N initial deals." + tallies = Tallies() + deck = list(CARDS) + for deal in range(N): + random.shuffle(deck) + for size in sizes: + tally(tallies, deck[:size]) + return tallies + +def tally_initial_layout_no_prior_sets(N, sizes=(12, 15)): + """Simulate N initial deals for each size, keeping tallies for Sets and NoSets, + but only when there was no set with 3 fewer cards.""" + tallies = Tallies() + deck = list(CARDS) + for deal in range(N): + random.shuffle(deck) + for size in sizes: + if not find_set(deck[:size-3]): + tally(tallies, deck[:size]) + return tallies + +def tally_game_play(N): + "Record tallies for the play of N complete games." + tallies = Tallies() + for game in range(N): + deck = list(CARDS) + random.shuffle(deck) + layout = deal(12, deck) + while deck: + s = tally(tallies, layout) + # Pick up the cards in the set, if any + for card in s: layout.remove(card) + # Deal new cards + if len(layout) < 12 or not s: + layout += deal(3, deck) + return tallies + +def experiments(N): + show({12: [1, 33], 15: [1, 2500]}, + 'the instruction booklet') + show(tally_initial_layout(N), + 'initial layout') + show(tally_game_play(N // 25), + 'game play') + show(tally_initial_layout_no_prior_sets(N), + 'initial layout, but no sets before dealing last 3 cards') + + +def show(tallies, label): + "Print out the counts." + print() + print('Size | Sets | NoSets | Set:NoSet ratio for', label) + print('-----+--------+--------+----------------') + for size in sorted(tallies): + y, n = tallies[size][True], tallies[size][False] + ratio = ('inft' if n==0 else int(round(float(y)/n))) + print('{:4d} |{:7,d} |{:7,d} | {:4}:1' + .format(size, y, n, ratio)) + +def test(): + assert len(CARDS) == 81 == len(set(CARDS)) + assert is_set(('3R=O', '2R=S', '1R=D')) + assert not is_set(('3R=0', '2R=S', '1R@D')) + assert find_set(['1PO0', '2G=D', '3R=0', '2R=S', '1R=D']) == ('3R=0', '2R=S', '1R=D') + assert not find_set(['1PO0', '2G=D', '3R=0', '2R=S', '1R@D']) + photo = '2P=0 3P=D 2R=0 3GO0 2POD 3R@D 2RO0 2ROS 1P@S 2P@0 3ROS 2GOD 2P@D 1GOD 3GOS'.split() + assert not find_set(photo) + assert set(itertools.combinations([1, 2, 3, 4], 3)) == {(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)} + print('All tests pass.') + +test() +experiments(100000) diff --git a/pytudes/py/beal.py b/pytudes/py/beal.py new file mode 100644 index 0000000..ebe4dd8 --- /dev/null +++ b/pytudes/py/beal.py @@ -0,0 +1,159 @@ +"""Search for counterexamples to Beal's conjecture +See http://norvig.com/beal.html and http://www.bealconjecture.com""" + +from __future__ import division, print_function +from math import log +from itertools import combinations, product +from collections import defaultdict +try: + from math import gcd # For Python 3.6 and up +except ImportError: + from fractions import gcd # For older versions (works in 2.7 as well) + +def beal(max_A, max_x): + """See if any A ** x + B ** y equals some C ** z, with gcd(A, B) == 1. + Consider any 1 <= A,B <= max_A and x,y <= max_x, with x,y prime or 4.""" + Apowers = make_Apowers(max_A, max_x) + Czroots = make_Czroots(Apowers) + for (A, B) in combinations(Apowers, 2): + if gcd(A, B) == 1: + for (Ax, By) in product(Apowers[A], Apowers[B]): + Cz = Ax + By + if Cz in Czroots: + C = Czroots[Cz] + x, y, z = exponent(Ax, A), exponent(By, B), exponent(Cz, C) + print('{} ** {} + {} ** {} == {} ** {} == {}' + .format(A, x, B, y, C, z, C ** z)) + +def make_Apowers(max_A, max_x): + "A dict of {A: [A**3, A**4, ...], ...}." + exponents = exponents_upto(max_x) + return {A: [A ** x for x in (exponents if (A != 1) else [3])] + for A in range(1, max_A+1)} + +def make_Czroots(Apowers): return {Cz: C for C in Apowers for Cz in Apowers[C]} + +def exponents_upto(max_x): + "Return all odd primes up to max_x, as well as 4." + exponents = [3, 4] if max_x >= 4 else [3] if max_x == 3 else [] + for x in range(5, max_x, 2): + if not any(x % p == 0 for p in exponents): + exponents.append(x) + return exponents + +def exponent(Cz, C): + """Recover z such that C ** z == Cz (or equivalently z = log Cz base C). + For exponent(1, 1), arbitrarily choose to return 3.""" + return 3 if (Cz == C == 1) else int(round(log(Cz, C))) + +############################################################################## + +def tests(): + assert make_Apowers(6, 10) == { + 1: [1], + 2: [8, 16, 32, 128], + 3: [27, 81, 243, 2187], + 4: [64, 256, 1024, 16384], + 5: [125, 625, 3125, 78125], + 6: [216, 1296, 7776, 279936]} + + assert make_Czroots(make_Apowers(5, 8)) == { + 1: 1, 8: 2, 16: 2, 27: 3, 32: 2, 64: 4, 81: 3, + 125: 5, 128: 2, 243: 3, 256: 4, 625: 5, 1024: 4, + 2187: 3, 3125: 5, 16384: 4, 78125: 5} + Czroots = make_Czroots(make_Apowers(100, 100)) + assert 3 ** 3 + 6 ** 3 in Czroots + assert 99 ** 97 in Czroots + assert 101 ** 100 not in Czroots + assert Czroots[99 ** 97] == 99 + + assert exponent(10 ** 5, 10) == 5 + assert exponent(7 ** 3, 7) == 3 + assert exponent(1234 ** 999, 1234) == 999 + assert exponent(12345 ** 6789, 12345) == 6789 + assert exponent(3 ** 10000, 3) == 10000 + assert exponent(1, 1) == 3 + + assert exponents_upto(2) == [] + assert exponents_upto(3) == [3] + assert exponents_upto(4) == [3, 4] + assert exponents_upto(40) == [3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37] + assert exponents_upto(100) == [ + 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, + 67, 71, 73, 79, 83, 89, 97] + + assert gcd(3, 6) == 3 + assert gcd(3, 7) == 1 + assert gcd(861591083269373931, 94815872265407) == 97 + assert gcd(2*3*5*(7**10)*(11**12), 3*(7**5)*(11**13)*17) == 3*(7**5)*(11**12) + return 'tests pass' + +############################################################################## + +def beal_modp(max_A, max_x, p=2**31-1): + """See if any A ** x + B ** y equals some C ** z (mod p), with gcd(A, B) == 1. + If so, verify that the equation works without the (mod p). + Consider any 1 <= A,B <= max_A and x,y <= max_x, with x,y prime or 4.""" + assert p >= max_A + Apowers = make_Apowers_modp(max_A, max_x, p) + Czroots = make_Czroots_modp(Apowers) + for (A, B) in combinations(Apowers, 2): + if gcd(A, B) == 1: + for (Axp, x), (Byp, y) in product(Apowers[A], Apowers[B]): + Czp = (Axp + Byp) % p + if Czp in Czroots: + lhs = A ** x + B ** y + for (C, z) in Czroots[Czp]: + if lhs == C ** z: + print('{} ** {} + {} ** {} == {} ** {} == {}' + .format(A, x, B, y, C, z, C ** z)) + + +def make_Apowers_modp(max_A, max_x, p): + "A dict of {A: [(A**3 (mod p), 3), (A**4 (mod p), 4), ...]}." + exponents = exponents_upto(max_x) + return {A: [(pow(A, x, p), x) for x in (exponents if (A != 1) else [3])] + for A in range(1, max_A+1)} + +def make_Czroots_modp(Apowers): + "A dict of {C**z (mod p): [(C, z),...]}" + Czroots = defaultdict(list) + for A in Apowers: + for (Axp, x) in Apowers[A]: + Czroots[Axp].append((A, x)) + return Czroots + +############################################################################## + +def simpsons(bases, powers): + """Find the integers (A, B, C, n) that come closest to solving + Fermat's equation, A ** n + B ** n == C ** n. + Let A, B range over all pairs of bases and n over all powers.""" + equations = ((A, B, iroot(A ** n + B ** n, n), n) + for A, B in combinations(bases, 2) + for n in powers) + return min(equations, key=relative_error) + +def iroot(i, n): + "The integer closest to the nth root of i." + return int(round(i ** (1./n))) + +def relative_error(equation): + "Error between LHS and RHS of equation, relative to RHS." + (A, B, C, n) = equation + LHS = A ** n + B ** n + RHS = C ** n + return abs(LHS - RHS) / RHS + +if __name__ == '__main__': + print(tests()) + print("Searching beal(500, 100)") + print(beal(500, 100)) + print("Finding Simpson-esque near-solutions to Fermat's Equation") + def s(b, p): print('{0}^{3} + {1}^{3} = {2}^{3}'.format(*simpsons(b, p))) + s(range(1000, 2000), [11, 12, 13]) + s(range(3000, 5000), [12]) + print("Searching beal_modp(500, 100)") + print(beal_modp(500, 100)) + + diff --git a/pytudes/py/docex.py b/pytudes/py/docex.py new file mode 100644 index 0000000..cbffe2a --- /dev/null +++ b/pytudes/py/docex.py @@ -0,0 +1,238 @@ +"""A framework for running unit tests and examples, written in docstrings. + +This lets you write "Ex: sqrt(4) ==> 2; sqrt(-1) raises ValueError" in a +docstring, and then execute the examples as unit tests. + +This functionality is similar to the doctest module. The major +differences between docex and doctest are: + +(1) Brevity. With docex you write the one-line comment + "Ex: len('abc') ==> 3; len([]) ==> 0; len(5) raises TypeError" + With doctest you would need 9 lines for the same thing: + '''>>> len('abc') + 3 + >>> len([]) + 0 + >>> len(5)) + Traceback (most recent call last): + ... + TypeError: len() of unsized object + ''' + +(2) Docex handles both examples and unit tests. + It took me a while to recognize this distinction: when I write + "sqrt(4) ==> 2" it has two purposes -- to serve as a unit test + and to serve as an example of how to use the sqrt function. + When I write "random.choice('abc')" it serves as an example of + how to use the choice function, but it is not a unit test. + docex lets you do both; doctest only supports tests. Of course + you can coerce this into a test in doctest, with something like + >>> random.choice('abc') in 'abc' + True + +(3) Eval-based rather than string-comparison based. The docex string + "dict(zip([1,4,9], [1,2,3])) ==> {1: 1, 4: 2, 9: 3}" works even + when a different version of Python decides to print the dict as + "{9: 3, 4: 2, 1: 1}" because docex evals the right-hand-side and + checks to see if it is equal. That's good for dicts, its good for + writing "1+1==2 ==> True" and having it work in versions of Python + where True prints as "1" rather than as "True", and so on, + but doctest has the edge if you want to compare against something + that doesn't have an eval-able output, or if you want to test + printed output. + +(4) Doctest has many more features, and is better supported. + I wrote docex before doctest was an official part of Python, but + with the refactoring of doctest in Python 2.4, I decided to switch + my code over to doctest, even though I prefer the brevity of docex. + I still offer docex for those who want it. + +From Python, when you want to test modules m1, m2, ... do: + docex.Docex([m1, m2, ...]) +From the shell, when you want to test files *.py, do: + python docex.py [log-file] *.py +If log file ends in .htm or .html, it will be written in HTML. +If log file is -, or if it is missing, then standard output is used. + +For each module, Docex looks at the __doc__ and _docex strings of the +module itself, and of each member, and recursively for each member +class. If a line in a docstring starts with r'^\s*Ex: ' (a line with +blanks, then 'Ex: '), then the remainder of the string after the colon +is treated as examples. Each line of the examples should conform to +one of the following formats: + + (1) Blank line or a comment; these just get echoed verbatim to the log. + (2) Of the form example1 ; example2 ; ... + (3) Of the form 'x ==> y' for any expressions x and y. + x is evaled and assigned to _, then y is evaled. + If x != y, an error message is printed. + (4) Of the form 'x raises y', for any statement x and expression y. + First y is evaled to yield an exception type, then x is execed. + If x doesn't raise the right exception, an error msg is printed. + (5) Of the form 'statement'. Statement is execed for side effect. + (6) Of the form 'expression'. Expression is evaled for side effect. +""" + +import re, sys, types + +class Docex: + """A class to run test examples written in docstrings or in _docex.""" + + def __init__(self, modules=None, html=0, out=None, + title='Docex Example Output'): + if modules is None: + modules = sys.modules.values() + self.passed = self.failed = 0; + self.dictionary = {} + self.already_seen = {} + self.html = html + try: + if out: sys.stdout = out + self.writeln(title, '

', '

')
+            for module in modules:
+                self.run_module(module)
+            self.writeln(str(self), '
\n

', '

\n') + finally: + if out: + sys.stdout = sys.__stdout__ + out.close() + + def __repr__(self): + if self.failed: + return ('' + % (self.failed, self.passed)) + else: + return '' % self.passed + + def run_module(self, object): + """Run the docstrings, and then all members of the module.""" + if not self.seen(object): + self.dictionary.update(vars(object)) # import module into self + name = object.__name__ + self.writeln('## Module %s ' % name, + '\n

' % name, + '

')
+            self.run_docstring(object)
+            names = object.__dict__.keys()
+            names.sort()
+            for name in names:
+                val = object.__dict__[name]
+                if isinstance(val, types.ClassType):
+                    self.run_class(val)
+                elif isinstance(val, types.ModuleType):
+                    pass
+                elif not self.seen(val):
+                    self.run_docstring(val)
+
+    def run_class(self, object):
+        """Run the docstrings, and then all members of the class."""
+        if not self.seen(object):
+            self.run_docstring(object)
+            names = object.__dict__.keys()
+            names.sort()
+            for name in names:
+                self.run_docstring(object.__dict__[name])
+
+    def run_docstring(self, object, search=re.compile(r'(?m)^\s*Ex: ').search):
+        "Run the __doc__ and _docex attributes, if the object has them."
+        if hasattr(object, '__doc__'):
+            s = object.__doc__
+            if isinstance(s, str):
+                match = search(s)
+                if match: self.run_string(s[match.end():])
+        if hasattr(object, '_docex'):
+                self.run_string(object._docex)
+        
+    def run_string(self, teststr):
+        """Run a test string, printing inputs and results."""
+        if not teststr: return
+        teststr = teststr.strip()
+        if teststr.find('\n') > -1:
+            map(self.run_string, teststr.split('\n'))
+        elif teststr == '' or teststr.startswith('#'):
+            self.writeln(teststr)
+        elif teststr.find('; ') > -1:
+            for substr in teststr.split('; '): self.run_string(substr)
+        elif teststr.find('==>') > -1:
+            teststr, result = teststr.split('==>')
+            self.evaluate(teststr, result)
+        elif teststr.find(' raises ') > -1:
+            teststr, exception = teststr.split(' raises ')
+            self.raises(teststr, exception)
+        else: ## Try to eval, but if it is a statement, exec
+            try:
+                self.evaluate(teststr)
+            except SyntaxError:
+                exec teststr in self.dictionary
+
+    def evaluate(self, teststr, resultstr=None):
+        "Eval teststr and check if resultstr (if given) evals to the same."
+        self.writeln('>>> ' +  teststr.strip())
+        result = eval(teststr, self.dictionary)
+        self.dictionary['_'] = result
+        self.writeln(repr(result))
+        if resultstr == None:
+          return
+        elif result == eval(resultstr, self.dictionary):
+          self.passed += 1
+        else:
+          self.fail(teststr, resultstr)
+    
+    def raises(self, teststr, exceptionstr):
+        teststr = teststr.strip()
+        self.writeln('>>> ' + teststr)
+        except_class = eval(exceptionstr, self.dictionary)
+        try:
+            exec teststr in self.dictionary
+        except except_class:
+            self.writeln('# raises %s as expected' % exceptionstr)
+            self.passed += 1
+            return
+        self.fail(teststr, exceptionstr)
+
+    def fail(self, teststr, resultstr):
+        self.writeln('###### ERROR, TEST FAILED: expected %s for %s' 
+                     % (resultstr, teststr),
+                     '', '')
+        self.failed += 1
+
+    def writeln(self, s, before='', after=''):
+        "Write s, html escaped, and wrapped with html code before and after."
+        s = str(s)
+        if self.html:
+            s = s.replace('&','&').replace('<','<').replace('>','>')
+            print '%s%s%s' % (before, s, after)
+        else:
+            print s
+
+    def seen(self, object):
+        """Return true if this object has been seen before.
+        In any case, record that we have seen it."""
+        result = self.already_seen.has_key(id(object))
+        self.already_seen[id(object)] = 1
+        return result
+
+def main(args):
+    """Run Docex.  args should be a list of python filenames.  
+    If the first arg is a non-python filename, it is taken as the
+    name of a log file to which output is written.  If it ends in
+    ".htm" or ".html", then the output is written as html.  If the
+    first arg is "-", then standard output is used as the log file."""
+    import glob
+    out = None
+    html = 0
+    if args[0] != "-" and not args[0].endswith(".py"):
+        out = open(args[0], 'w')
+        if args[0].endswith(".html") or args[0].endswith(".htm"):
+            html = 1
+    modules = []
+    for arg in args:
+        for file in glob.glob(arg):
+            if file.endswith('.py'):
+                modules.append(__import__(file[:-3]))
+    print Docex(modules, html=html, out=out)
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
+
+
diff --git a/pytudes/py/ibol.py b/pytudes/py/ibol.py
new file mode 100644
index 0000000..d2490a6
--- /dev/null
+++ b/pytudes/py/ibol.py
@@ -0,0 +1,193 @@
+from collections import defaultdict
+
+def get_genomes(fname="byronbayseqs.fas.txt"):
+    "Return a list of genomes, and a list of their corresponding names."
+    import re
+    names, species, genomes = [], [], []
+    for name, g in re.findall('>(.*?)\r([^\r]*)\r*', file(fname).read()):
+        names.append(name)
+        species.append(name.split('|')[-1])
+        genomes.append(g)
+    return names, species, genomes
+
+def get_neighbors(fname="editdistances.txt"):
+    "Return dict: neighbors[i][j] = neighbors[j][i] = d means i,j are d apart."
+    ## Read the data pre-computed from the Java program
+    neighbors = dict((i, {}) for i in range(n))
+    for line in file(fname):
+        i,j,d = map(int, line.split())
+        neighbors[i][j] = neighbors[j][i] = d
+    return neighbors
+        
+def cluster(neighbors, d, dc):
+    """Return a list of clusters, each cluster element is within d of another
+    and within dc of every other cluster element."""
+    unclustered = set(neighbors) ## set of g's not yet clustered
+    return [closure(g, set(), unclustered, d, dc)
+            for g in neighbors if g in unclustered]
+
+def closure(g, s, unclustered, d, dc):
+    "Accumulate in set s the transitive closure of 'near', starting at g"
+    if g not in s and g in unclustered and near(g, s, d, dc):
+        s.add(g); unclustered.remove(g)
+        for g2 in neighbors[g]:
+            closure(g2, s, unclustered, d, dc)
+    return s
+
+def dist(i, j):
+    "Distance between two genomes."
+    if i == j: return 0
+    return neighbors[min(i, j)].get(max(i, j), max_distance)
+
+def near(g, cluster, d, dc):
+    "Is g within d of some member of c, and within dc of every member of c?"
+    distances = [dist(g, g2) for g2 in cluster] or [0]
+    return min(distances) <= d and max(distances) <= dc
+
+def diameter(cluster):
+    "The largest distance between two elements of the cluster"
+    return max([dist(i, j) for i in cluster for j in cluster] or [0])
+
+def margin(cluster):
+    "The distance from a cluster to the nearest g2 outside this cluster."
+    return min([d for g in cluster for g2,d in neighbors[g].items()
+                if g2 not in cluster] or [max_distance])
+
+################################################################ Analysis
+
+def pct(num, den):
+    "Return a string representing the percentage. "
+    if '__len__' in dir(den): den = len(den)
+    if num==den: return ' 100%'
+    return '%.1f%%' % (num*100.0/den)
+
+def histo(items):
+    "Make a histogram from a sequence of items or (item, count) tuples."
+    D = defaultdict(int)
+    for item in items:
+        if isinstance(item, tuple): D[item[0]] += item[1]
+        else: D[item] += 1
+    return D
+
+def showh(d):
+    "Show a histogram"
+    if not isinstance(d, dict): d = histo(d)
+    return ' '.join('%s:%s' % i for i in sorted(d.items()))
+
+def greport(genomes):
+    print "Number of genomes: %d (%d distinct)" % (len(genomes), len(set(genomes)))
+    G = dict((g, set()) for g in genomes)
+    for i in range(n):
+        G[genomes[i]].add(species[i])
+    print "Multi-named genomes:", (
+        len([s for s in G.values() if len(s) > 1]))
+    lens = map(len, genomes)
+    print "Genome lengths: min=%d, max=%d" % (min(lens), max(lens))
+    print "Character counts: ", showh(c for g in genomes for c in g)
+    
+def nreport(neighbors):
+    NN, NumN = defaultdict(int), defaultdict(int) ## Nearest, Number of neighbors
+    for n in neighbors:
+        nn = min(neighbors[n].values() or ['>25'])
+        NN[nn] += 1
+        for d2 in neighbors[n].values():
+            NumN[d2] += 1 
+    print
+    print "Nearest neighbor counts:", showh(NN)
+    print "Number of neighbors at each distance:", showh(NumN)
+
+def nspecies(c): return len(set(species[g] for g in c))
+
+def showc(c):
+    return "N=%d, D=%d, M=%d: %s %s" % (
+        len(c), diameter(c), margin(c), list(c), showh(species[g] for g in c))
+
+def creport(drange, dcrange):
+    def table(what, fn):
+        print "\n" + what
+        print ' '*8, ' '.join([' '+pct(dc, glen) for dc in dcrange])
+        for d in drange:
+            print '%s (%2d)' % (pct(d, glen), d),
+            for dc in dcrange:
+                print '%5s' % fn(cluster(neighbors, d, dc)),
+            print
+    print '\nNearest neighbor must be closer than this percentage (places). '
+    print 'Each column: all genomes in cluster within this percentage of each other.'
+    table("Number of clusters", len)
+    cluster1 = cluster(neighbors, 8, 15) ## splits Cleora
+    print '\nNumber of clusters of different sizes:', showh(len(c) for c in cluster1)
+    M, T = defaultdict(int), defaultdict(int)
+    for c in cluster1:
+        M[margin(c)] += 1; T[margin(c)] += len(c)
+    for x in M: print '%d\t%d\t%d'% (x,M[x],T[x])
+    print '\nMargins', showh(M)
+    for c in cluster1:
+        if margin(c) <= 16:
+            print showc(c)
+    print '\nScatter plot of cluster diameter vs. margin.'
+    for c in cluster1:
+        if diameter(c) > 0:
+            pass
+            #print '%d\t%d' % (diameter(c), margin(c))
+    print '\nDifference from cluster(neighbors, 11, 14):'
+    #table(lambda cl: pct(len(cluster1)-compare(cluster1, cl),max(len(cluster1),len(cl))))
+    print '\nNumber of clusters witth more than one species name:'
+    #table(lambda cl: sum(nspecies(c) > 1 for c in cl))
+    def pct_near_another(clusters, P=1.25):
+        total = 0
+        for c in clusters:
+            d = diameter(c)
+            for g in c:
+                for g2 in neighbors[g]:
+                    if g2 not in c and dist(g, g2) < P*d:
+                        total += 1
+        return pct(total, n)
+    def f(P):
+        print '\nPercent of individuals within %.2f*diameter of another cluster.'%P
+        table(lambda cl: pct_near_another(cl, P))
+    #map(f, [1.2, 1.33, 1.5])
+
+def sreport(species):
+    SS = defaultdict(int)
+    print
+    for s in set(species):
+        c = [g for g in range(n) if species[g] == s]
+        d = diameter(c)
+        if d > 14:
+            if d==glen: d = '>25'
+            print 'diameter %s for %s (%d elements)' % (d, s, len(c))
+        SS[d] += 1
+    print 'Diameters of %d labeled clusters: %s' % (len(set(species)), showh(SS))
+    
+def compare(cl1, cl2):
+    "Compare two lists of clusters"
+    return sum(c1==c2 or 0.5*(abs(len(c1)-len(c2))==1 and
+                              (c1.issubset(c2) or c2.issubset(c1)))
+               for c1 in cl1 for c2 in cl2)
+
+def unit_tests():
+    assert set(len(g) for g in genomes) == set([glen])
+    clusters = cluster(neighbors, 11, 11)
+    assert sum(len(c) for c in clusters) == len(genomes)
+    assert len(set(g for c in clusters for g in c)) == len(genomes)
+    assert dist(17, 42) == dist(42, 17)
+    assert diameter(set()) == 0
+    assert diameter([17, 42]) == dist(17, 42)
+    assert pct(1, 2) == '50.0%'
+    print '\nAll tests pass.\n'
+
+    
+
+################################################################ Main body
+ 
+max_distance = 26
+names, species, genomes = get_genomes() ## genomes = ['ACT...', ...]
+n = len(genomes)
+glen = len(genomes[0])
+neighbors = get_neighbors() ## neighbor[g] = {g2:d2, g3:g3, ...}
+greport(genomes)
+nreport(neighbors)
+creport(range(6, 15), [glen,16,15,14,13, 12, 11])
+#sreport(species)
+
+unit_tests()
diff --git a/pytudes/py/lettercount.py b/pytudes/py/lettercount.py
new file mode 100644
index 0000000..3c6db88
--- /dev/null
+++ b/pytudes/py/lettercount.py
@@ -0,0 +1,443 @@
+"""
+Code to support http://norvig.com/mayzner.html
+Read files in the Google Books ngram format, and convert them to a simpler format.
+The original format looks like this:
+
+    word     \t year \t word_count \t book_count
+    word_POS \t year \t word_count \t book_count
+
+for example,
+
+    accreted_VERB	1846	7	4
+    accreted_VERB	1847	1	1
+    accreted_VERB	1848	1	1
+
+The function 'read_year_file' will convert a file of this form into a dict of
+{WORD: count} pairs, where the WORD is uppercased, and the count is the total
+over all years (you have the option to specify a starting year) and all
+capitalizations.  Then 'read_dict' and 'write_dict' convert between a dict and
+an external file format that looks like this:
+
+    ACCRETED	9
+
+"""
+
+from __future__ import division
+from collections import Counter, defaultdict
+
+#### Read files in Books-Ngram format; convert to a dict
+
+def read_year_file(filename, dic=None):
+    """Read a file of 'word year word_count book_count' lines and convert to a dict
+    {WORD: totalcount}. Uppercase all words, and only include all-alphabetic words."""
+    if dic is None: dic = {}
+    for line in file(filename):
+        word, year, c1, c2 = line.split('\t')
+        if '_' in word:
+            word = word[:word.index('_')]
+        if word.isalpha():
+            word = word.upper()
+            dic[word] = dic.get(word, 0) + int(c1)
+    return dic
+
+#### Read and write files of the form 'WORD \t count \n'
+
+def write_dict(dic, filename):
+    "Write a {word:count} dict as 'word \t count' lines in filename."
+    out = file(filename, 'w')
+    for key in sorted(dic):
+        out.write('%s\t%s\n' % (key, dic[key]))
+    return out.close()
+        
+def read_dict(filename, sep='\t'):
+    "Read 'word \t count' lines from file and make them into a dict of {word:count}."
+    pairs = (line.split(sep) for line in file(filename))
+    return {word: int(count) for (word, count) in pairs}
+
+#### Convert a bunch of year files into dict file format.
+
+def convert_files(filenames, mincount=1e5):
+    def report(filename, D, adj):
+        import time
+        N = len(D)
+        W = sum(v for v in D.itervalues())
+        print '%s: %s %s words (%s tokens) at %s' % (
+            filename, adj, format(W, ',d'), format(N, ',d'),
+            time.strftime("%H:%M:%S", time.gmtime()))
+    for f in filenames:
+        report(f, {}, 'starting')
+        D = read_year_file(f)
+        report(f, D, 'total')
+        for key in list(D):
+            if D[key] < mincount:
+                del D[key]
+        write_dict(D, 'WORD-' + f[-1].upper())
+        report(f, D, 'popular')
+
+def load(filename='top-words.txt'):
+    "Load file of 'word \t count' lines into D (a dict), W (length of D) and M (total number of words)."
+    global D, W, M
+    D = read_dict(filename)
+    W = len(D)
+    M = sum(D.values())
+    
+#### Compute letter counts and save as HTML files.
+
+def histogram(items):
+    "Return a Counter of the number of times each key occurs in (key, val) pairs."
+    C = Counter()
+    for (key, val) in items:
+        C[key] += val
+    return C
+
+def end(name): return '/' + name
+
+def tag(name, **kwds): return '<' + name + keywords(kwds) + '>'
+
+def row(cells, **kwds):
+    return '' + ''
+    
+def ngram_tables(dic, N, pos=[0, 1, 2, 3, 4, -5, -4, -3, -2, -1]):
+    """Return three dicts of letter N-grams of length N: counts, counts1, counts2.
+    counts is a dict of {'AB': 123} that counts how often 'AB' occurs.
+    counts1[i] is a dict of {'AB': 123} that counts how often 'AB' occurs at position i.
+    counts2[i][j] is a dict of {'AB': 123} that counts how often 'AB' occurs at position i."""
+    L = len(max(D, key=len))
+    counts = Counter()
+    counts1 = [Counter() for _ in range(L)]
+    counts2 = [[Counter() for i in range(L)]]
+
+def counter(pairs):
+    "Make a Counter from an iterable of (value, count) pairs."
+    c = Counter()
+    for (value, count) in pairs:
+        c[value] += count
+    return c
+
+def ngrams(word, N):
+    return [word[i:i+N] for i in range(len(word)+1-N)]
+
+
+import glob
+#convert_files(glob.glob('book?'))
+              
+#DB = [[letter_counts() for length in range(length)] for length in range(maxlen)]
+      
+
+## Unused ???
+
+def letter_counts(wc):
+    """From word_counts dictionary wc, Create a dictionary of {(s, i, L): count}
+    where s is a letter n-gram, i is the starting position, and L is the length
+    of the word in which it appears."""
+    result = defaultdict(int)
+    for (word, count) in wc.iteritems():
+        for p in pieces(word):
+            result[p] += count
+    return result
+
+def pieces(word):
+    "Yield the 1- and 2-letter grams in (s, i, L) format."
+    L = len(word)
+    for i in range(L):
+        yield (word[i], i, L)
+        if i+1 < L:
+            yield (word[i:i+2], i, L)
+
+def getcount(counts, s, pos, length):
+    """The count for letter sequence s (one or two letters) starting at
+    position i of words of length length.  If any argument is all, sum them up."""
+    if length == all:
+        return sum(getcount(counts, s, pos, L) for L in all_lengths)
+    elif pos == all:
+        return sum(getcount(counts, s, i, length) for i in range(length))
+    else:
+        return counts[s, pos, length]
+
+
+print 'start'
+#wc = word_counts('count_100K.txt')
+#counts = letter_counts(wc)
+print 'end'
+
+
+
+def test():
+    D = {'the': 100, 'of': 70, 'and': 60, 'to': 50, 'a': 40}
+
+def num(ch):
+    "Translate 'a' or 'A' to 0, ... 'z' or 'Z' to 25."
+    return 'abcdefghijklmnopqrstuvwxyz'.index(ch.lower())
+    
+
+def stats(D, NS = (1, 2, 3, 4, 5, 6)):
+    counts = {n: Counter() for n in NS}
+    print 'words ' + ' '.join('   %d-grams  ' % n for n in NS)
+    for (i, word) in enumerate(sortedby(D), 1):
+        for n in NS:
+            for ng in ngrams(word, n):
+                counts[n][ng] += 1
+        if i % 5000 == 0 or i == len(D):
+            print "%4dK" % (i/1000),
+            for n in NS:
+                c = len(counts[n])
+                field = "%5d (%d%%)" % (c, int(round(c*100/(26**n))))
+                print '%12s' % field,
+            print
+
+letters = 'ETAOINSRHLDCUMFPGWYBVKXJQZ'
+alphabet = ''.join(sorted(letters))
+
+from itertools import cycle, izip
+
+colors = 'ygobp'
+
+def bar(text, color, count, N, pixels, height=16):
+    width = int(round(pixels * count / N))
+    if width < 2: width = 3
+    title = '{}: {:.3f}%; {:,}'.format(text, count*100./N, count)
+    return '%s' % (
+        title, color, height, width, -width+2, text) # -int(width/2+5)
+
+def letter_bar(LC, N=None, factor='', pixels=700):
+    if N is None: N = sum(LC.values())
+    #divisor = {'':1., 'K':1e3, 'M':1e6, 'B':1e9}[factor]
+    return ''.join(
+        bar(L.lower(), color, LC[L], N, pixels)
+        for (L, color) in izip(letters, cycle(colors)))
+        
+
+def singleton(x): return [x]
+
+positions = [0, 1, 2, 3, 4, 5, 6, -7, -6, -5, -4, -3, -2, -1]
+
+def substr(word, pos, length):
+    """Return the substr of word of given length starting/ending at pos; or None."""
+    W = len(word)
+    if pos >= 0 and pos+length <= W:
+        return word[pos:pos+length]
+    elif pos < 0 and abs(pos)+length-1 <= W:
+        return word[W+pos+1-length:W+pos+1]
+    else:
+        return None
+        
+def lettercount(D, pos):
+    LC = histogram((substr(w, pos, 1), D[w]) for w in D)
+    del LC[None]
+    print LC
+    pos_name = (str(pos)+'+' if isinstance(pos, tuple) else
+                pos if pos < 0 else
+                pos+1)
+    return '\n
\n%-3s %s' % (pos_name, letter_bar(LC)) + +def ngramcount(D, n=2): + return histogram((ng, D[w]) for w in D for ng in ngrams(w, n)) + +def twograms(D2): + N = sum(D2.values()) + header = '' + rows = [tr([cell(A+B, D2, N) for A in alphabet]) for B in alphabet] + return '\n'.join([header] + rows + ['
']) + +def cell(text, D2, N, height=16, maxwidth=25, scale=27): + count = D2.get(text, 0) + width = int(round(maxwidth * count * scale * 1. / N)) + if width < 1: width = 1 + title = '{}: {:.3f}%; {:,}'.format(text, count*100./N, count) + return '%s' % ( + title, height, width, -width+2, text) + +def cell(text, D2, N, height=16, maxwidth=25, scale=27): + count = D2.get(text, 0) + width = int(round(maxwidth * count * scale * 1. / N)) + if width < 1: width = 1 + title = '{}: {:.3f}%; {:,}'.format(text, count*100./N, count) + return '%s' % ( + title, height, width, text) + +def tr(cells): + return '' + ''.join(cells) + +def comma(n): return '{:,}'.format(n) + +def ngram_stats(D, n, k=5): + DN = ngramcount(D, n) + topk = ', '.join(sortedby(DN)[:k]) + return '%d-grams%s%s
counts-%d.csvcounts-%d.html%s' % ( + n, comma(len(DN)), comma(sum(DN.values())), n, n, n, n, topk) + +#### Tables + +def sortedby(D): + return sorted(D, key=lambda x: -D[x]) + +ANY = '*' + +wordlengths = range(1, 10) + +def col(*args): return args + +def columns(n, wordlengths=wordlengths): + lengths = [k for k in wordlengths if k >= n] + return ([col(ANY, ANY)] + + [col(k, ANY) for k in lengths] + + [col(k, start, start+n-1) for k in lengths for start in range(1, 2+k-n)] + + [col(ANY, start, start+n-1) for start in wordlengths] + + [col(ANY, -k, -k+n-1) for k in reversed(lengths) if -k+n-1 < 0]) + +def colname(col): + fmt = '%s/%s' if (len(col) == 2) else '%s/%d:%d' + return fmt % col + +def csvline(first, rest): + return '\t'.join([first] + map(str, rest)) + +def makecsv(n, D=D): + out = file('ngrams%d.csv' % n, 'w') + cols = columns(n) + Dng = defaultdict(lambda: defaultdict(int)) + for w in D: + for (start, ng) in enumerate(ngrams(w, n), 1): + entry = Dng[ng] + N = D[w] + wlen = len(w) + entry[ANY, ANY] += N + entry[wlen, ANY] += N + if start <= 9: + entry[wlen, start, start+n-1] += N + entry[ANY, start, start+n-1] += N + from_end = wlen-start+1 + if from_end <= 9: + entry[ANY, -from_end, -from_end+n-1] += N + # enumerate ngrams from word and increment counts for each one + print >> out, csvline('%d-gram' % n, map(colname, cols)) + for ng in sorted(Dng, key=lambda ng: -Dng[ng][(ANY, ANY)]): + print >> out, csvline(ng, [Dng[ng].get(col, 0) for col in cols]) + out.close() + return Dng + +### Tests + +""" +>>> for w in words: + print '%-6s %6.2f B (%4.2f%%) ' % (w.lower(), D[w]/1e9, D[w]*100./N, int(round(D[w]*4000./N))) +... +the 53.10 B (7.14%) +of 30.97 B (4.16%) +and 22.63 B (3.04%) +to 19.35 B (2.60%) +in 16.89 B (2.27%) +a 15.31 B (2.06%) +is 8.38 B (1.13%) +that 8.00 B (1.08%) +for 6.55 B (0.88%) +it 5.74 B (0.77%) +as 5.70 B (0.77%) +was 5.50 B (0.74%) +with 5.18 B (0.70%) +be 4.82 B (0.65%) +by 4.70 B (0.63%) +on 4.59 B (0.62%) +not 4.52 B (0.61%) +he 4.11 B (0.55%) +i 3.88 B (0.52%) +this 3.83 B (0.51%) +are 3.70 B (0.50%) +or 3.67 B (0.49%) +his 3.61 B (0.49%) +from 3.47 B (0.47%) +at 3.41 B (0.46%) +which 3.14 B (0.42%) +but 2.79 B (0.38%) +have 2.78 B (0.37%) +an 2.73 B (0.37%) +had 2.62 B (0.35%) +they 2.46 B (0.33%) +you 2.34 B (0.31%) +were 2.27 B (0.31%) +their 2.15 B (0.29%) +one 2.15 B (0.29%) +all 2.06 B (0.28%) +we 2.06 B (0.28%) +can 1.67 B (0.22%) +her 1.63 B (0.22%) +has 1.63 B (0.22%) +there 1.62 B (0.22%) +been 1.62 B (0.22%) +if 1.56 B (0.21%) +more 1.55 B (0.21%) +when 1.52 B (0.20%) +will 1.49 B (0.20%) +would 1.47 B (0.20%) +who 1.46 B (0.20%) +so 1.45 B (0.19%) +no 1.40 B (0.19%) + +>>> for n in sorted(H): + print '%2d %9.2f M (%6.3f%%) %d' % (n, H[n]/1e6, H[n]*100./NN, H[n]*3000./NN, n) +... + 1 22301.22 M ( 2.998%) 1 + 2 131293.85 M (17.651%) 2 + 3 152568.38 M (20.511%) 3 + 4 109988.33 M (14.787%) 4 + 5 79589.32 M (10.700%) 5 + 6 62391.21 M ( 8.388%) 6 + 7 59052.66 M ( 7.939%) 7 + 8 44207.29 M ( 5.943%) 8 + 9 33006.93 M ( 4.437%) 9 +10 22883.84 M ( 3.076%) 10 +11 13098.06 M ( 1.761%) 11 +12 7124.15 M ( 0.958%) 12 +13 3850.58 M ( 0.518%) 13 +14 1653.08 M ( 0.222%) 14 +15 565.24 M ( 0.076%) 15 +16 151.22 M ( 0.020%) 16 +17 72.81 M ( 0.010%) 17 +18 28.62 M ( 0.004%) 18 +19 8.51 M ( 0.001%) 19 +20 6.35 M ( 0.001%) 20 +21 0.13 M ( 0.000%) 21 +22 0.81 M ( 0.000%) 22 +23 0.32 M ( 0.000%) 23 + +>>> NL = sum(LC.values()) + +>>> for L in sorted(LC, key=lambda L: -LC[L]): + print '%s %8.1f B (%5.2f%%) ' % (L, LC[L]/1e9, LC[L]*100./NL, LC[L]*3000./NL) +... +E 445.2 B (12.49%) +T 330.5 B ( 9.28%) +A 286.5 B ( 8.04%) +O 272.3 B ( 7.64%) +I 269.7 B ( 7.57%) +N 257.8 B ( 7.23%) +S 232.1 B ( 6.51%) +R 223.8 B ( 6.28%) +H 180.1 B ( 5.05%) +L 145.0 B ( 4.07%) +D 136.0 B ( 3.82%) +C 119.2 B ( 3.34%) +U 97.3 B ( 2.73%) +M 89.5 B ( 2.51%) +F 85.6 B ( 2.40%) +P 76.1 B ( 2.14%) +G 66.6 B ( 1.87%) +W 59.7 B ( 1.68%) +Y 59.3 B ( 1.66%) +B 52.9 B ( 1.48%) +V 37.5 B ( 1.05%) +K 19.3 B ( 0.54%) +X 8.4 B ( 0.23%) +J 5.7 B ( 0.16%) +Q 4.3 B ( 0.12%) +Z 3.2 B ( 0.09%) + +>>> D2 = ngramcount(D, 2) + +>>> for ng in sorted(D2, key=lambda L: -D2[L])[:50]: print '%s %8.1f B (%5.2f%%) ' % (ng, D2[ng]/1e9, D2[ng]*100./N2, D2[ng]*15000./N2) + +def doit(k=25): + counts = [sortedby(ngramcount(D, n))[:k] for n in range(2, 10)] + for i in range(k): + print (' '.join(count[i] for count in counts)).lower() +""" diff --git a/pytudes/py/lis.py b/pytudes/py/lis.py new file mode 100644 index 0000000..2d031ad --- /dev/null +++ b/pytudes/py/lis.py @@ -0,0 +1,145 @@ +################ Lispy: Scheme Interpreter in Python + +## (c) Peter Norvig, 2010-16; See http://norvig.com/lispy.html + +from __future__ import division +import math +import operator as op + +################ Types + +Symbol = str # A Lisp Symbol is implemented as a Python str +List = list # A Lisp List is implemented as a Python list +Number = (int, float) # A Lisp Number is implemented as a Python int or float + +################ Parsing: parse, tokenize, and read_from_tokens + +def parse(program): + "Read a Scheme expression from a string." + return read_from_tokens(tokenize(program)) + +def tokenize(s): + "Convert a string into a list of tokens." + return s.replace('(',' ( ').replace(')',' ) ').split() + +def read_from_tokens(tokens): + "Read an expression from a sequence of tokens." + if len(tokens) == 0: + raise SyntaxError('unexpected EOF while reading') + token = tokens.pop(0) + if '(' == token: + L = [] + while tokens[0] != ')': + L.append(read_from_tokens(tokens)) + tokens.pop(0) # pop off ')' + return L + elif ')' == token: + raise SyntaxError('unexpected )') + else: + return atom(token) + +def atom(token): + "Numbers become numbers; every other token is a symbol." + try: return int(token) + except ValueError: + try: return float(token) + except ValueError: + return Symbol(token) + +################ Environments + +def standard_env(): + "An environment with some Scheme standard procedures." + env = Env() + env.update(vars(math)) # sin, cos, sqrt, pi, ... + env.update({ + '+':op.add, '-':op.sub, '*':op.mul, '/':op.truediv, + '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, + 'abs': abs, + 'append': op.add, + 'apply': apply, + 'begin': lambda *x: x[-1], + 'car': lambda x: x[0], + 'cdr': lambda x: x[1:], + 'cons': lambda x,y: [x] + y, + 'eq?': op.is_, + 'equal?': op.eq, + 'length': len, + 'list': lambda *x: list(x), + 'list?': lambda x: isinstance(x,list), + 'map': map, + 'max': max, + 'min': min, + 'not': op.not_, + 'null?': lambda x: x == [], + 'number?': lambda x: isinstance(x, Number), + 'procedure?': callable, + 'round': round, + 'symbol?': lambda x: isinstance(x, Symbol), + }) + return env + +class Env(dict): + "An environment: a dict of {'var':val} pairs, with an outer Env." + def __init__(self, parms=(), args=(), outer=None): + self.update(zip(parms, args)) + self.outer = outer + def find(self, var): + "Find the innermost Env where var appears." + return self if (var in self) else self.outer.find(var) + +global_env = standard_env() + +################ Interaction: A REPL + +def repl(prompt='lis.py> '): + "A prompt-read-eval-print loop." + while True: + val = eval(parse(raw_input(prompt))) + if val is not None: + print(lispstr(val)) + +def lispstr(exp): + "Convert a Python object back into a Lisp-readable string." + if isinstance(exp, List): + return '(' + ' '.join(map(lispstr, exp)) + ')' + else: + return str(exp) + +################ Procedures + +class Procedure(object): + "A user-defined Scheme procedure." + def __init__(self, parms, body, env): + self.parms, self.body, self.env = parms, body, env + def __call__(self, *args): + return eval(self.body, Env(self.parms, args, self.env)) + +################ eval + +def eval(x, env=global_env): + "Evaluate an expression in an environment." + if isinstance(x, Symbol): # variable reference + return env.find(x)[x] + elif not isinstance(x, List): # constant literal + return x + elif x[0] == 'quote': # (quote exp) + (_, exp) = x + return exp + elif x[0] == 'if': # (if test conseq alt) + (_, test, conseq, alt) = x + exp = (conseq if eval(test, env) else alt) + return eval(exp, env) + elif x[0] == 'define': # (define var exp) + (_, var, exp) = x + env[var] = eval(exp, env) + elif x[0] == 'set!': # (set! var exp) + (_, var, exp) = x + env.find(var)[var] = eval(exp, env) + elif x[0] == 'lambda': # (lambda (var...) body) + (_, parms, body) = x + return Procedure(parms, body, env) + else: # (proc arg...) + proc = eval(x[0], env) + args = [eval(exp, env) for exp in x[1:]] + return proc(*args) \ No newline at end of file diff --git a/pytudes/py/lispy.py b/pytudes/py/lispy.py new file mode 100644 index 0000000..08923c1 --- /dev/null +++ b/pytudes/py/lispy.py @@ -0,0 +1,318 @@ +################ Scheme Interpreter in Python + +## (c) Peter Norvig, 2010; See http://norvig.com/lispy2.html + +################ Symbol, Procedure, classes + +from __future__ import division +import re, sys, StringIO + +class Symbol(str): pass + +def Sym(s, symbol_table={}): + "Find or create unique Symbol entry for str s in symbol table." + if s not in symbol_table: symbol_table[s] = Symbol(s) + return symbol_table[s] + +_quote, _if, _set, _define, _lambda, _begin, _definemacro, = map(Sym, +"quote if set! define lambda begin define-macro".split()) + +_quasiquote, _unquote, _unquotesplicing = map(Sym, +"quasiquote unquote unquote-splicing".split()) + +class Procedure(object): + "A user-defined Scheme procedure." + def __init__(self, parms, exp, env): + self.parms, self.exp, self.env = parms, exp, env + def __call__(self, *args): + return eval(self.exp, Env(self.parms, args, self.env)) + +################ parse, read, and user interaction + +def parse(inport): + "Parse a program: read and expand/error-check it." + # Backwards compatibility: given a str, convert it to an InPort + if isinstance(inport, str): inport = InPort(StringIO.StringIO(inport)) + return expand(read(inport), toplevel=True) + +eof_object = Symbol('#') # Note: uninterned; can't be read + +class InPort(object): + "An input port. Retains a line of chars." + tokenizer = r"""\s*(,@|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,;)]*)(.*)""" + def __init__(self, file): + self.file = file; self.line = '' + def next_token(self): + "Return the next token, reading new text into line buffer if needed." + while True: + if self.line == '': self.line = self.file.readline() + if self.line == '': return eof_object + token, self.line = re.match(InPort.tokenizer, self.line).groups() + if token != '' and not token.startswith(';'): + return token + +def readchar(inport): + "Read the next character from an input port." + if inport.line != '': + ch, inport.line = inport.line[0], inport.line[1:] + return ch + else: + return inport.file.read(1) or eof_object + +def read(inport): + "Read a Scheme expression from an input port." + def read_ahead(token): + if '(' == token: + L = [] + while True: + token = inport.next_token() + if token == ')': return L + else: L.append(read_ahead(token)) + elif ')' == token: raise SyntaxError('unexpected )') + elif token in quotes: return [quotes[token], read(inport)] + elif token is eof_object: raise SyntaxError('unexpected EOF in list') + else: return atom(token) + # body of read: + token1 = inport.next_token() + return eof_object if token1 is eof_object else read_ahead(token1) + +quotes = {"'":_quote, "`":_quasiquote, ",":_unquote, ",@":_unquotesplicing} + +def atom(token): + 'Numbers become numbers; #t and #f are booleans; "..." string; otherwise Symbol.' + if token == '#t': return True + elif token == '#f': return False + elif token[0] == '"': return token[1:-1].decode('string_escape') + try: return int(token) + except ValueError: + try: return float(token) + except ValueError: + try: return complex(token.replace('i', 'j', 1)) + except ValueError: + return Sym(token) + +def to_string(x): + "Convert a Python object back into a Lisp-readable string." + if x is True: return "#t" + elif x is False: return "#f" + elif isa(x, Symbol): return x + elif isa(x, str): return '"%s"' % x.encode('string_escape').replace('"',r'\"') + elif isa(x, list): return '('+' '.join(map(to_string, x))+')' + elif isa(x, complex): return str(x).replace('j', 'i') + else: return str(x) + +def load(filename): + "Eval every expression from a file." + repl(None, InPort(open(filename)), None) + +def repl(prompt='lispy> ', inport=InPort(sys.stdin), out=sys.stdout): + "A prompt-read-eval-print loop." + sys.stderr.write("Lispy version 2.0\n") + while True: + try: + if prompt: sys.stderr.write(prompt) + x = parse(inport) + if x is eof_object: return + val = eval(x) + if val is not None and out: print >> out, to_string(val) + except Exception as e: + print '%s: %s' % (type(e).__name__, e) + +################ Environment class + +class Env(dict): + "An environment: a dict of {'var':val} pairs, with an outer Env." + def __init__(self, parms=(), args=(), outer=None): + # Bind parm list to corresponding args, or single parm to list of args + self.outer = outer + if isa(parms, Symbol): + self.update({parms:list(args)}) + else: + if len(args) != len(parms): + raise TypeError('expected %s, given %s, ' + % (to_string(parms), to_string(args))) + self.update(zip(parms,args)) + def find(self, var): + "Find the innermost Env where var appears." + if var in self: return self + elif self.outer is None: raise LookupError(var) + else: return self.outer.find(var) + +def is_pair(x): return x != [] and isa(x, list) +def cons(x, y): return [x]+y + +def callcc(proc): + "Call proc with current continuation; escape only" + ball = RuntimeWarning("Sorry, can't continue this continuation any longer.") + def throw(retval): ball.retval = retval; raise ball + try: + return proc(throw) + except RuntimeWarning as w: + if w is ball: return ball.retval + else: raise w + +def add_globals(self): + "Add some Scheme standard procedures." + import math, cmath, operator as op + self.update(vars(math)) + self.update(vars(cmath)) + self.update({ + '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_, + '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, + 'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons, + 'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add, + 'list':lambda *x:list(x), 'list?': lambda x:isa(x,list), + 'null?':lambda x:x==[], 'symbol?':lambda x: isa(x, Symbol), + 'boolean?':lambda x: isa(x, bool), 'pair?':is_pair, + 'port?': lambda x:isa(x,file), 'apply':lambda proc,l: proc(*l), + 'eval':lambda x: eval(expand(x)), 'load':lambda fn: load(fn), 'call/cc':callcc, + 'open-input-file':open,'close-input-port':lambda p: p.file.close(), + 'open-output-file':lambda f:open(f,'w'), 'close-output-port':lambda p: p.close(), + 'eof-object?':lambda x:x is eof_object, 'read-char':readchar, + 'read':read, 'write':lambda x,port=sys.stdout:port.write(to_string(x)), + 'display':lambda x,port=sys.stdout:port.write(x if isa(x,str) else to_string(x))}) + return self + +isa = isinstance + +global_env = add_globals(Env()) + +################ eval (tail recursive) + +def eval(x, env=global_env): + "Evaluate an expression in an environment." + while True: + if isa(x, Symbol): # variable reference + return env.find(x)[x] + elif not isa(x, list): # constant literal + return x + elif x[0] is _quote: # (quote exp) + (_, exp) = x + return exp + elif x[0] is _if: # (if test conseq alt) + (_, test, conseq, alt) = x + x = (conseq if eval(test, env) else alt) + elif x[0] is _set: # (set! var exp) + (_, var, exp) = x + env.find(var)[var] = eval(exp, env) + return None + elif x[0] is _define: # (define var exp) + (_, var, exp) = x + env[var] = eval(exp, env) + return None + elif x[0] is _lambda: # (lambda (var*) exp) + (_, vars, exp) = x + return Procedure(vars, exp, env) + elif x[0] is _begin: # (begin exp+) + for exp in x[1:-1]: + eval(exp, env) + x = x[-1] + else: # (proc exp*) + exps = [eval(exp, env) for exp in x] + proc = exps.pop(0) + if isa(proc, Procedure): + x = proc.exp + env = Env(proc.parms, exps, proc.env) + else: + return proc(*exps) + +################ expand + +def expand(x, toplevel=False): + "Walk tree of x, making optimizations/fixes, and signaling SyntaxError." + require(x, x!=[]) # () => Error + if not isa(x, list): # constant => unchanged + return x + elif x[0] is _quote: # (quote exp) + require(x, len(x)==2) + return x + elif x[0] is _if: + if len(x)==3: x = x + [None] # (if t c) => (if t c None) + require(x, len(x)==4) + return map(expand, x) + elif x[0] is _set: + require(x, len(x)==3); + var = x[1] # (set! non-var exp) => Error + require(x, isa(var, Symbol), "can set! only a symbol") + return [_set, var, expand(x[2])] + elif x[0] is _define or x[0] is _definemacro: + require(x, len(x)>=3) + _def, v, body = x[0], x[1], x[2:] + if isa(v, list) and v: # (define (f args) body) + f, args = v[0], v[1:] # => (define f (lambda (args) body)) + return expand([_def, f, [_lambda, args]+body]) + else: + require(x, len(x)==3) # (define non-var/list exp) => Error + require(x, isa(v, Symbol), "can define only a symbol") + exp = expand(x[2]) + if _def is _definemacro: + require(x, toplevel, "define-macro only allowed at top level") + proc = eval(exp) + require(x, callable(proc), "macro must be a procedure") + macro_table[v] = proc # (define-macro v proc) + return None # => None; add v:proc to macro_table + return [_define, v, exp] + elif x[0] is _begin: + if len(x)==1: return None # (begin) => None + else: return [expand(xi, toplevel) for xi in x] + elif x[0] is _lambda: # (lambda (x) e1 e2) + require(x, len(x)>=3) # => (lambda (x) (begin e1 e2)) + vars, body = x[1], x[2:] + require(x, (isa(vars, list) and all(isa(v, Symbol) for v in vars)) + or isa(vars, Symbol), "illegal lambda argument list") + exp = body[0] if len(body) == 1 else [_begin] + body + return [_lambda, vars, expand(exp)] + elif x[0] is _quasiquote: # `x => expand_quasiquote(x) + require(x, len(x)==2) + return expand_quasiquote(x[1]) + elif isa(x[0], Symbol) and x[0] in macro_table: + return expand(macro_table[x[0]](*x[1:]), toplevel) # (m arg...) + else: # => macroexpand if m isa macro + return map(expand, x) # (f arg...) => expand each + +def require(x, predicate, msg="wrong length"): + "Signal a syntax error if predicate is false." + if not predicate: raise SyntaxError(to_string(x)+': '+msg) + +_append, _cons, _let = map(Sym, "append cons let".split()) + +def expand_quasiquote(x): + """Expand `x => 'x; `,x => x; `(,@x y) => (append x y) """ + if not is_pair(x): + return [_quote, x] + require(x, x[0] is not _unquotesplicing, "can't splice here") + if x[0] is _unquote: + require(x, len(x)==2) + return x[1] + elif is_pair(x[0]) and x[0][0] is _unquotesplicing: + require(x[0], len(x[0])==2) + return [_append, x[0][1], expand_quasiquote(x[1:])] + else: + return [_cons, expand_quasiquote(x[0]), expand_quasiquote(x[1:])] + +def let(*args): + args = list(args) + x = cons(_let, args) + require(x, len(args)>1) + bindings, body = args[0], args[1:] + require(x, all(isa(b, list) and len(b)==2 and isa(b[0], Symbol) + for b in bindings), "illegal binding list") + vars, vals = zip(*bindings) + return [[_lambda, list(vars)]+map(expand, body)] + map(expand, vals) + +macro_table = {_let:let} ## More macros can go here + +eval(parse("""(begin + +(define-macro and (lambda args + (if (null? args) #t + (if (= (length args) 1) (car args) + `(if ,(car args) (and ,@(cdr args)) #f))))) + +;; More macros can also go here + +)""")) + +if __name__ == '__main__': + repl() + diff --git a/pytudes/py/lispytest.py b/pytudes/py/lispytest.py new file mode 100644 index 0000000..bed5307 --- /dev/null +++ b/pytudes/py/lispytest.py @@ -0,0 +1,121 @@ + +################ Tests for lis.py and lispy.py + +lis_tests = [ + ("(quote (testing 1 (2.0) -3.14e159))", ['testing', 1, [2.0], -3.14e159]), + ("(+ 2 2)", 4), + ("(+ (* 2 100) (* 1 10))", 210), + ("(if (> 6 5) (+ 1 1) (+ 2 2))", 2), + ("(if (< 6 5) (+ 1 1) (+ 2 2))", 4), + ("(define x 3)", None), ("x", 3), ("(+ x x)", 6), + ("(begin (define x 1) (set! x (+ x 1)) (+ x 1))", 3), + ("((lambda (x) (+ x x)) 5)", 10), + ("(define twice (lambda (x) (* 2 x)))", None), ("(twice 5)", 10), + ("(define compose (lambda (f g) (lambda (x) (f (g x)))))", None), + ("((compose list twice) 5)", [10]), + ("(define repeat (lambda (f) (compose f f)))", None), + ("((repeat twice) 5)", 20), ("((repeat (repeat twice)) 5)", 80), + ("(define fact (lambda (n) (if (<= n 1) 1 (* n (fact (- n 1))))))", None), + ("(fact 3)", 6), + ("(fact 50)", 30414093201713378043612608166064768844377641568960512000000000000), + ("(define abs (lambda (n) ((if (> n 0) + -) 0 n)))", None), + ("(list (abs -3) (abs 0) (abs 3))", [3, 0, 3]), + ("""(define combine (lambda (f) + (lambda (x y) + (if (null? x) (quote ()) + (f (list (car x) (car y)) + ((combine f) (cdr x) (cdr y)))))))""", None), + ("(define zip (combine cons))", None), + ("(zip (list 1 2 3 4) (list 5 6 7 8))", [[1, 5], [2, 6], [3, 7], [4, 8]]), + ("""(define riff-shuffle (lambda (deck) (begin + (define take (lambda (n seq) (if (<= n 0) (quote ()) (cons (car seq) (take (- n 1) (cdr seq)))))) + (define drop (lambda (n seq) (if (<= n 0) seq (drop (- n 1) (cdr seq))))) + (define mid (lambda (seq) (/ (length seq) 2))) + ((combine append) (take (mid deck) deck) (drop (mid deck) deck)))))""", None), + ("(riff-shuffle (list 1 2 3 4 5 6 7 8))", [1, 5, 2, 6, 3, 7, 4, 8]), + ("((repeat riff-shuffle) (list 1 2 3 4 5 6 7 8))", [1, 3, 5, 7, 2, 4, 6, 8]), + ("(riff-shuffle (riff-shuffle (riff-shuffle (list 1 2 3 4 5 6 7 8))))", [1,2,3,4,5,6,7,8]), + ] + +lispy_tests = [ + ("()", SyntaxError), ("(set! x)", SyntaxError), + ("(define 3 4)", SyntaxError), + ("(quote 1 2)", SyntaxError), ("(if 1 2 3 4)", SyntaxError), + ("(lambda 3 3)", SyntaxError), ("(lambda (x))", SyntaxError), + ("""(if (= 1 2) (define-macro a 'a) + (define-macro a 'b))""", SyntaxError), + ("(define (twice x) (* 2 x))", None), ("(twice 2)", 4), + ("(twice 2 2)", TypeError), + ("(define lyst (lambda items items))", None), + ("(lyst 1 2 3 (+ 2 2))", [1,2,3,4]), + ("(if 1 2)", 2), + ("(if (= 3 4) 2)", None), + ("(define ((account bal) amt) (set! bal (+ bal amt)) bal)", None), + ("(define a1 (account 100))", None), + ("(a1 0)", 100), ("(a1 10)", 110), ("(a1 10)", 120), + ("""(define (newton guess function derivative epsilon) + (define guess2 (- guess (/ (function guess) (derivative guess)))) + (if (< (abs (- guess guess2)) epsilon) guess2 + (newton guess2 function derivative epsilon)))""", None), + ("""(define (square-root a) + (newton 1 (lambda (x) (- (* x x) a)) (lambda (x) (* 2 x)) 1e-8))""", None), + ("(> (square-root 200.) 14.14213)", True), + ("(< (square-root 200.) 14.14215)", True), + ("(= (square-root 200.) (sqrt 200.))", True), + ("""(define (sum-squares-range start end) + (define (sumsq-acc start end acc) + (if (> start end) acc (sumsq-acc (+ start 1) end (+ (* start start) acc)))) + (sumsq-acc start end 0))""", None), + ("(sum-squares-range 1 3000)", 9004500500), ## Tests tail recursion + ("(call/cc (lambda (throw) (+ 5 (* 10 (throw 1))))) ;; throw", 1), + ("(call/cc (lambda (throw) (+ 5 (* 10 1)))) ;; do not throw", 15), + ("""(call/cc (lambda (throw) + (+ 5 (* 10 (call/cc (lambda (escape) (* 100 (escape 3)))))))) ; 1 level""", 35), + ("""(call/cc (lambda (throw) + (+ 5 (* 10 (call/cc (lambda (escape) (* 100 (throw 3)))))))) ; 2 levels""", 3), + ("""(call/cc (lambda (throw) + (+ 5 (* 10 (call/cc (lambda (escape) (* 100 1))))))) ; 0 levels""", 1005), + ("(* 1i 1i)", -1), ("(sqrt -1)", 1j), + ("(let ((a 1) (b 2)) (+ a b))", 3), + ("(let ((a 1) (b 2 3)) (+ a b))", SyntaxError), + ("(and 1 2 3)", 3), ("(and (> 2 1) 2 3)", 3), ("(and)", True), + ("(and (> 2 1) (> 2 3))", False), + ("(define-macro unless (lambda args `(if (not ,(car args)) (begin ,@(cdr args))))) ; test `", None), + ("(unless (= 2 (+ 1 1)) (display 2) 3 4)", None), + (r'(unless (= 4 (+ 1 1)) (display 2) (display "\n") 3 4)', 4), + ("(quote x)", 'x'), + ("(quote (1 2 three))", [1, 2, 'three']), + ("'x", 'x'), + ("'(one 2 3)", ['one', 2, 3]), + ("(define L (list 1 2 3))", None), + ("`(testing ,@L testing)", ['testing',1,2,3,'testing']), + ("`(testing ,L testing)", ['testing',[1,2,3],'testing']), + ("`,@L", SyntaxError), + ("""'(1 ;test comments ' + ;skip this line + 2 ; more ; comments ; ) ) + 3) ; final comment""", [1,2,3]), + ] + +def test(tests, name=''): + "For each (exp, expected) test case, see if eval(parse(exp)) == expected." + fails = 0 + for (x, expected) in tests: + try: + result = eval(parse(x)) + print x, '=>', to_string(result) + ok = (result == expected) + except Exception as e: + print x, '=raises=>', type(e).__name__, e + ok = issubclass(expected, Exception) and isinstance(e, expected) + if not ok: + fails += 1 + print 'FAIL!!! Expected', expected + print '%s %s: %d out of %d tests fail.' % ('*'*45, name, fails, len(tests)) + +if __name__ == '__main__': + from lis import * + test(lis_tests, 'lis.py') + from lispy import * + test(lis_tests+lispy_tests, 'lispy.py') + diff --git a/pytudes/py/pal.py b/pytudes/py/pal.py new file mode 100644 index 0000000..db8f509 --- /dev/null +++ b/pytudes/py/pal.py @@ -0,0 +1,154 @@ +import string, random, os, re, bisect + +"""Produce Panama-ish Palindromes. Copyright (C) 2002, Peter Norvig. +See http://www.norvig.com/license.html and http://www.norvig.com/pal-alg.html""" + +def is_panama(p): + "Test if p is a Panama-ish palindrome." + def is_unique(seq): return len(seq) == len(dict(zip(seq, seq))) + return (p.endswith('Panama') and is_palindrome(p) + and is_unique([s.strip() for s in p.split(',')])) + +def is_palindrome(phrase): + "Test if a phrase is a palindrome." + cphrase = canonical(phrase) + return cphrase == reverse(cphrase) + +def canonical(word, sub=re.compile('[^A-Za-z0-9]').sub): + "The canonical form for comparing: lowercase alphanumerics." + return sub('', word).lower() + +def read_dict(filename='npdict.txt'): + "Read the file into global variables _fw and _bw and _truename." + global _fw, _bw, _truename + _fw, _bw, _truename = [], [], {'': ''} + for word in open(filename).read().splitlines(): + w = canonical(word) + _fw.append(w) + _bw.append(reverse(w)) + _truename[w] = word + _fw.sort(); _bw.sort() + return len(_fw), len(_bw), len(_truename) + +def update(obj, **entries): obj.__dict__.update(entries); return obj + +class PalDict: + """A dictionary from which you can find canonical words that start or end + with a given canonical substring, and find the true name of a + canonical word.""" + def __init__(self, fw=None, bw=None, truename=None): + update(self, fw=fw or _fw, bw=bw or _bw, truename=truename or _truename) + + def startswith(self, prefix, k=100): + """Return up to k canonical words that start with prefix. + If there are more than k, choose from them at random.""" + return k_startingwith(k, self.fw, prefix) + + def endswith(self, suffix, k=100): + """Return up to k canonical words that end with suffix. + If there are more than k, choose from them at random. + Both the suffix and the word returned are reversed.""" + return k_startingwith(k, self.bw, suffix) + +def k_startingwith(k, words, prefix): + """Choose up to k words that match the prefix (choose randomly if > k).""" + start = bisect.bisect(words, prefix) + end = bisect.bisect(words, prefix + 'zzzz') + n = end - start + if k >= n: + results = words[start:end] + random.shuffle(results) + else: # Should really try to avoid duplicates + results = [words[random.randrange(start, end)] for i in range(k)] + return results + +class Panama: + def __init__(self, L='A man, a plan', R='a canal, Panama', dict=None): + left = [canonical(w) for w in L.split(', ')] + right = [canonical(reverse(w)) for w in reverse(R.split(', '))] + update(self, left=left, right=right, dict=dict or PalDict(), best=0, + seen={}, diff=len(''.join(left)) - len(''.join(right))) + for word in left + map(reverse, right): + self.seen[word] = 1 + + def missing(self, k=20): + """Return the substring that is missing, and candidate words.""" + if self.diff >= 0: # Left is longer, missing on right + substr = self.left[-1][-self.diff:] + return substr, self.dict.endswith(substr, k) + else: # Right is longer, missing on left + substr = self.right[-1][self.diff:] + return substr, self.dict.startswith(substr, k) + + def search(self, k=200): + "Search for palindromes; consider at most k words at each level." + self.stack = [self.missing(k)] + while self.stack: + substr, words = self.stack[-1] + if is_palindrome(substr): + self.report() + if words: + self.extend(words.pop(), k) + elif not self.backtrack(): + return + + def extend(self, word, k): + "Add a new word (unless we've already seen it)." + if self.diff >= 0: # Left is longer, add to right + fword = reverse(word) + if fword in self.seen: return + self.diff -= len(fword) + self.seen[fword] = 1 + self.right.append(word) + self.stack.append(self.missing(k)) + else: # Right is longer, add to left + if word in self.seen: return + self.diff += len(word) + self.seen[word] = 1 + self.left.append(word) + self.stack.append(self.missing(k)) + + def backtrack(self): + "Remove the last word added; return 0 if can't backtrack" + if self.diff >= 0: # Left is longer, pop from left + if not self.left: return 0 + word = self.left.pop() + self.diff -= len(word) + del self.seen[word] + else: # Right is longer, pop from right + if not self.right: return 0 + word = self.right.pop() + self.diff += len(word) + del self.seen[reverse(word)] + self.stack.pop() + return 1 + + def report(self): + "Write current state to log file." + if len(self) > self.best + 200: + self.best = len(self) + print self.best + self.bestphrase = str(self) + assert is_panama(self.bestphrase) + f = open('pallog%d.txt' % os.getpid(), 'w') + f.write(self.bestphrase + '\n') + f.close() + + def __len__(self): + return len(self.left) + len(self.right) + + def __str__(self): + truename = self.dict.truename + lefts = [truename[w] for w in self.left] + rights = [truename[reverse(w)] for w in reverse(self.right[:])] + return ', '.join(lefts + ['*****'] + rights) + +def reverse(x): + "Reverse a list or string." + if type(x) == type(''): + return ''.join(reverse(list(x))) + else: + x.reverse() + return x + +if __name__ == '__main__': read_dict(); p = Panama(); p.search() diff --git a/pytudes/py/pal2.py b/pytudes/py/pal2.py new file mode 100644 index 0000000..9436ead --- /dev/null +++ b/pytudes/py/pal2.py @@ -0,0 +1,262 @@ +import random, re, bisect, time + +"""Produce Panama-ish Palindromes. Copyright (C) 2002-2008, Peter Norvig.""" + +################ Checking for Palindromes + +def is_panama(s): + "Test if string s is a Panama-ish palindrome." + return is_palindrome(s) and is_unique(phrases(s)) + +def is_palindrome(s): + "Test if a string is a palindrome." + s1 = canonical(s) + return s1 == reversestr(s1) + +def phrases(s): + "Break a string s into comma-separated phrases." + return [phrase.strip() for phrase in s.split(',')] + +def canonical(word, sub=re.compile('''[-* \t\n\r.,;!?:()`"']''').sub): + "The canonical form for comparing: lowercase, no blanks or punctuation." + return sub('', word).lower() + +################ Utilities + +def reversestr(x): + "Reverse a string." + return x[::-1] + +def is_unique(seq): + "Return true if seq has no duplicate elements." + return len(seq) == len(set(seq)) + +def update(obj, **entries): + "Change attributes of obj, according to the keyword args." + obj.__dict__.update(entries) + return obj + +################ Reading in a dictionary + +class PalDict: + """A dictionary from which you can find canonical words that start or end + with a given canonical substring, and find the true name of a + canonical word with d.truename[canonicalword].""" + + def __init__(self, k=1000, filename='npdict.txt'): + words, rwords, truename = [], [], {'': '', 'panama': 'Panama!'} + for tword in open(filename).read().splitlines(): + word = canonical(tword) + words.append(word) + rwords.append(reversestr(word)) + truename[word] = tword + words.sort() + rwords.sort() + update(self, k=k, words=words, rwords=rwords, truename=truename, + reversibles={}, rangek=range(k), tryharder=False) + + def startswith(self, prefix): + """Return up to k canonical words that start with prefix. + If there are more than k, choose from them at random.""" + return self._k_startingwith(self.words, prefix) + + def endswith(self, rsuffix): + """Return up to k canonical words that end with the reversed suffix. + If you want words ending in 'ing', ask for d.endswith('gni'). + If there are more than k, choose from them at random.""" + return map(reversestr, self._k_startingwith(self.rwords, rsuffix)) + + def __contains__(self, word): + return word in self.truename + + def reversible_words(self): + "Find words that have a reverse in the dict, like {'Camus': 'Sumac'}" + if not self.reversibles: + reversibles = self.reversibles + for rw in self.rwords: + if rw in self: + w = reversestr(rw) + if w != rw and w not in reversibles: + reversibles[w] = rw + self.reversibles = reversibles + return self.reversibles + + def _k_startingwith(self, words, prefix): + start = bisect.bisect_left(words, prefix) + end = bisect.bisect(words, prefix + 'zzzz') + n = end - start + if self.k >= n: # get all the words that start with prefix + results = words[start:end] + else: # sample from words starting with prefix + indexes = random.sample(xrange(start, end), self.k) + results = [words[i] for i in indexes] + random.shuffle(results) + ## Consider words that are prefixes of the prefix. + ## This is very slow, so don't use it until late in the game. + if self.tryharder: + for i in range(3, len(prefix)): + w = prefix[0:i] + if ((words == self.words and w in self.truename) or + (words == self.rwords and reversestr(w) in self.truename)): + results.append(w) + return results + +paldict = PalDict() + +def anpdictshort(): + "Find the words that are valid when every phrase must start with 'a'" + def segment(word): return [s for s in word.split('a') if s] + def valid(word): return all(reversestr(s) in segments for s in segment(word)) + words = map(canonical, file('anpdict.txt')) + segments = set(s for w in words for s in segment(canonical(w))) + valid_words = [paldict.truename[w] for w in words if valid(w)] + file('anpdict-short.txt', 'w').write('\n'.join(valid_words)) + +################ Search for a palindrome + +class Panama: + def __init__(self, L='A man, a plan', R='a canal, Panama', dict=paldict): + ## .left and .right hold lists of canonical words + ## .diff holds the number of characters that are not matched, + ## positive for words on left, negative for right. + ## .stack holds (action, side, arg) tuples + update(self, left=[], right=[], best=0, seen={}, diff=0, stack=[], + used_reversibles=False, starttime=time.clock(), dict=dict) + for word in L.split(','): + self.add('left', canonical(word)) + for rword in reversestr(R).split(','): + self.add('right', canonical(reversestr(rword))) + self.consider_candidates() + + def search(self, steps=50000000): + "Search for palindromes." + for _ in xrange(steps): + if not self.stack: + return 'done' + action, dir, substr, arg = self.stack[-1] + if action == 'added': # undo the last word added + self.remove(dir, arg) + elif action == 'trying' and arg: # try the next word if there is one + self.add(dir, arg.pop()) and self.consider_candidates() + elif action == 'trying' and not arg: # otherwise backtrack + self.stack.pop() + else: + raise ValueError(action) + + def add(self, dir, word): + "add a word" + if word in self.seen: + return False + else: + getattr(self, dir).append(word) + self.diff += factor[dir] * len(word) + self.seen[word] = True + self.stack.append(('added', dir, '?', word)) + return True + + def remove(self, dir, word): + "remove a word" + oldword = getattr(self, dir).pop() + assert word == oldword + self.diff -= factor[dir] * len(word) + del self.seen[word] + self.stack.pop() + + def consider_candidates(self): + """Push a new state with a set of candidate words onto stack.""" + if self.diff > 0: # Left is longer, consider adding on right + dir = 'right' + substr = self.left[-1][-self.diff:] + candidates = self.dict.endswith(substr) + elif self.diff < 0: # Right is longer, consider adding on left + dir = 'left' + substr = reversestr(self.right[-1][0:-self.diff]) + candidates = self.dict.startswith(substr) + else: # Both sides are same size + dir = 'left' + if not self.used_reversibles: + self.report() + self.add_reversibles() + substr = '' + candidates = self.dict.startswith('') + if substr == reversestr(substr): + self.report() + self.stack.append(('trying', dir, substr, candidates)) + + def add_reversibles(self): + "Add in reversible words." + print 'using reversibles ...' + for (word, rword) in self.dict.reversible_words().items(): + if word not in self.seen and rword not in self.seen: + self.add('left', word) + self.add('right', rword) + self.used_reversibles = True + self.stack = [] + print '...done' + + def report(self): + "Report a new palindrome to log file (if it is sufficiently big)." + N = len(self) + if N > 13333: + self.dict.tryharder = True + if N > self.best and (N > 12500 or N > self.best+500): + self.best = len(self) + self.bestphrase = str(self) + print '%5d phrases (%5d words) in %3d seconds' % ( + self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime) + assert is_panama(self.bestphrase) + f = open('pallog%d.txt' % (id(self) % 10000), 'w') + f.write(self.bestphrase + '\n') + f.close() + + def __len__(self): + return len(self.left) + len(self.right) + + def __str__(self): + truename = self.dict.truename + lefts = [truename[w] for w in self.left] + rights =[truename[w] for w in self.right] + return ', '.join(lefts + rights[::-1]) + +factor = {'left': +1, 'right': -1} + +# Note that we only allow one truename per canonical name. Occasionally +# this means we miss a good word (as in "a node" vs. "an ode"), but there +# are only 665 of these truename collisions, and most of them are of the +# form "a mark-up" vs. "a markup" so it seemed better to disallow them. + +################ Unit Tests + +def tests(p=Panama()): + assert is_panama('A man, a plan, a canal, Panama.') + assert is_panama('''A (man), a plan,,;, a ```canal?'' -- Panama!''') + assert not is_panama('A man, a plan, a radar, a canal, Panama.') + assert is_palindrome('A man, a plan, a canal, Panama.') + assert is_palindrome('radar, radar? radar!') + assert not is_palindrome('radars') + assert phrases('A man, a plan, Panama') == ['A man', 'a plan', 'Panama'] + assert canonical('A man, a plan, a canal, Panama') == 'amanaplanacanalpanama' + assert reversestr('foo') == 'oof' + assert is_unique([1, 2, 3]) + assert not is_unique([1, 2, 2]) + d = p.dict + def sameset(a, b): return set(a) == set(b) + assert 'panama' in d + assert d.words[0] in d + assert d.words[-1] in d + assert sameset(d.startswith('aword'), ['awording', 'awordbreak', + 'awordiness', 'awordage', 'awordplay', 'awordlore', 'awordbook', + 'awordlessness', 'aword', 'awordsmith']) + assert sameset(d.endswith('ytisob'), ['aglobosity', 'averbosity', + 'asubglobosity', 'anonverbosity', 'agibbosity']) + d.tryharder = True + assert sameset(d.startswith('oklahoma'), ['oklahoma', 'okla']) + d.tryharder = False + assert d.startswith('oklahoma') == ['oklahoma'] + assert d.startswith('fsfdsfdsfds') == [] + print 'all tests pass' + +if __name__ == '__main__': + p = Panama(); + tests(p) + p.search() diff --git a/pytudes/py/pal3.py b/pytudes/py/pal3.py new file mode 100644 index 0000000..89e8571 --- /dev/null +++ b/pytudes/py/pal3.py @@ -0,0 +1,170 @@ +from collections import Counter, deque +import re + +class PhraseDict(dict): + """A dictionary of {letters: phrase}, such as {'donaldeknuth': 'Donald E. Knuth'}, with: + .prefixes: Counter of {'pre': n} where n is the number of keys that start with 'pre' + .suffixes: Counter of {'xes': n} where n is the number of keys that end with 'xes'""" + def __init__(self, phrases): + for phrase in phrases: + phrase = phrase.strip() + self[letters(phrase)] = phrase + self.prefixes = Counter(x for p in self for x in prefixes(p)) + self.suffixes = Counter(x for p in self for x in suffixes(p)) + +def prefixes(phrase): return [phrase[:i] for i in range(1, len(phrase) + 1)] + +def suffixes(phrase): return [phrase[-i:] for i in range(1, len(phrase) + 1)] + +def letters(phrase, sub=re.compile(r'[\W]+').sub): + "Remove all the non-letters from phrase; return lowercase version." + return sub('', phrase).lower() + +DICT = PhraseDict(open('npdict.txt')) + +class Panama: + """Panama represents a palindrome, or a state in searching for one. + It has .left and .right to hold the phrases that are chosen, + and .L and .R to hold the current partial phrases in the middle (still working on these). + Also, a .set of all complete phrases, and the .dict of allowable phrases to choose from.""" + + def __init__(self, left=['aman', 'aplan'], L='aca', R='', right=['acanal', 'panama'], dict=DICT): + assert cat(left + [L]) == cat([R] + right)[::-1] + self.left = list(left) # list of complete phrases on left + self.L = L # an incomplete phrase on left + self.R = R # an incomplete phrase on right + self.right = deque(right) # deque of complete phrases on right + self.dict = dict # a {letters: actual_phrase} mapping + self.set = set(left + right) # a set of all complete phrases in palindrome + self.best = [] # list of phrases in longest palindrome found + self.Nshown = 0 # the number of phrases shown in the previous printout + self.i = 0 # the number of steps taken in the search + self.check() + + def __str__(self): return self.original_phrases(self.best) + + def original_phrases(self, phrases): return ', '.join(self.dict[phrase] for phrase in phrases) + + def search(self, steps=10**5): + """Depth-first search for palindromes. From the current state, find all applicable actions. + Do the first one, and put on the stack reminders to undo it and try the others, + but first search deeper from the result of the first action.""" + stack = [self.applicable_actions()] + for self.i in range(steps): + if not stack: + return + command = stack.pop() + if isinstance(command, UndoCommand): + self.undo(command) + elif command: + act = command.pop() + self.do(act) + self.check() + stack.extend([command, UndoCommand(act), self.applicable_actions()]) + + def do(self, act): + "Modify the current state by adding a letter, or finishing a phrase." + if act == ',': # finish phrase on left + self.set.add(self.L) + self.left.append(self.L) + self.L = '' + elif act == ';': # finish phrase on right + self.set.add(self.R) + self.right.appendleft(self.R) + self.R = '' + else: # add a letter + self.L = self.L + act + self.R = act + self.R + + def undo(self, act): + "Modify the current state by undoing an action that was previously done." + if act == ',': # unfinish phrase on left + assert self.L == '' + self.L = self.left.pop() + self.set.remove(self.L) + elif act == ';': # unfinish phrase on right + assert self.R == '' + self.R = self.right.popleft() + self.set.remove(self.R) + else: # remove a letter + self.L = self.L[:-1] + self.R = self.R[1:] + + def check(self): + "Check to see if current state is a palindrome, and if so, record it and maybe print." + if not self.is_palindrome(): return + N = len(self.left) + len(self.right) + if N > len(self.best): + self.best = self.left + list(self.right) + if N - self.Nshown > 1000 or (N > 14000 and N - self.Nshown > 100) or N > 14500: + self.Nshown = N + print(self.report()) + + def report(self): + N = len(self.best) + nwords = N + sum(self.dict[p].count(' ') for p in self.best) + nletters = sum(len(p) for p in self.best) + return ('Pal: {:6,d} phrases, {:6,d} words, {:6,d} letters (at step {:,d})' + .format(N, nwords, nletters, self.i+1)) + + def applicable_actions(self): + L, R, D = self.L, self.R, self.dict + actions = [] + + def score(A): return D.prefixes[L+A] * D.suffixes[A+R] + if self.is_allowed(L): + actions.append(',') + if self.is_allowed(R): + actions.append(';') + for A in sorted(alphabet, key=score): + if score(A) > 0: + actions.append(A) + + return actions + + def is_allowed(self, phrase): return phrase in self.dict and phrase not in self.set + + def is_palindrome(self): + "Is this a palindrome? (Does any extra .L or .R match the other side?)" + return ((self.L == '' and self.left[-1].endswith(self.R)) or + (self.R == '' and self.right[0].startswith(self.L))) + +alphabet = 'abcdefghijklmnopqrstuvwxyz' +cat = ''.join +UndoCommand = str +DoCommand = list + +################ Unit Tests + +def test1(): + assert prefixes('hello') == ['h', 'he', 'hel', 'hell', 'hello'] + assert suffixes('hello') == ['o', 'lo', 'llo', 'ello', 'hello'] + assert letters('a man') == 'aman' + assert letters('an elk') == 'anelk' + assert letters('Mr. T') == 'mrt' + assert letters('Donald E. Knuth') == 'donaldeknuth' + assert len(DICT) == 125512 + assert 'panama' in DICT + assert 'aman' in DICT + assert 'threemen' not in DICT + assert DICT['acanal'] == 'a canal' + return 'ok' + +def test2(): + p1 = Panama() + assert p1.is_palindrome() + assert str(p1) == 'a man, a plan, a canal, Panama' + p2 = Panama(['aman','aplan'], 'acadd','dd', ['acanal', 'panama']) + assert not p2.is_palindrome() + p3 = Panama(['maya'], '', '', ['ayam']) + assert p3.is_palindrome() + assert str(p3) == 'Maya, a yam' + return 'ok' + +if __name__ == '__main__': + p = Panama(); + test1() + test2() + p.search(10**6) + print(p.report()) + print(str(p)) diff --git a/pytudes/py/parse.py b/pytudes/py/parse.py new file mode 100644 index 0000000..8c7e4ea --- /dev/null +++ b/pytudes/py/parse.py @@ -0,0 +1,52 @@ +grammar = { + 'Noun': ['stench', 'wumpus'], + 'Verb': ['is', 'smell'], + 'Adjective': ['dead', 'smelly'], + 'Adverb': ['left', 'back'], + 'Pronoun': ['me', 'you'], + 'Name': ['John', 'Mary'], + 'Article': ['the', 'a'], + 'Preposition': ['to', 'in'], + 'Conjunction': ['and', 'or'], + 'Digit': ['0', '1'], + + 'S': [['NP', 'VP'], ['S', 'Comjunction', 'S']], + 'NP': ['Pronoun', 'Noun', ['Article', 'Noun'], ['Digit', 'Digit'], + ['NP', 'PP'], ['NP', 'RelClause']], + 'VP': ['Verb', ['VP', 'NP'], ['VP', 'Adjective'], ['VP', 'PP'], + ['VP', 'Adverb']], + 'PP': [['Preposition', 'NP']], + 'RelClause': [['that', 'VP']] + } + + +def parse(forest, grammar): + if len(forest) == 1 and category(forest[0]) == 'S': + return forest[0] + for i in range(len(forest)): + for lhs in grammar.keys(): + for rhs in grammar[lhs]: + rhs = mklist(rhs) + n = len(rhs) + subsequence = forest[i:i+n] + if match(subsequence, rhs): + print subsequence, lhs, '=>', rhs + forest2 = forest[:] + forest2[i:i+n] = [(lhs, subsequence)] + result = parse(forest2, grammar) + if result != None: + return result + return None + +def mklist(x): + if type(x) == type([]): return x + else: return [x] + +def match(forest, rhs): + for i in range(len(rhs)): + if category(forest[i]) != rhs[i] and forest[i] != rhs[i]: return 0 + return 1 + +def category(forest): + if type(forest) == type(()): return forest[0] + else: return 'word' diff --git a/pytudes/py/py2html.py b/pytudes/py/py2html.py new file mode 100644 index 0000000..896d0de --- /dev/null +++ b/pytudes/py/py2html.py @@ -0,0 +1,110 @@ +"""Pretty-print Python code to colorized, hyperlinked html. + +In python, do: + py2html.convert_files(['file1.py', 'file2.py', ...]) +From the shell, do: + python py2html.py *.py""" + +import re, string, time, os + + +id = r'[a-zA-Z_][a-zA-Z_0-9]*' ## RE for a Python identifier +g1, g2, g3, g4 = r'\1 \2 \3 \4'.split() ## groups for re.matches +def b(text): return '%s' % text +def i(text): return '%s' % text +def color(rgb, text): return '%s' % (rgb, text) +def link(url, anchor): return '%s' % (url, anchor) +def hilite(text, bg="ffff00"): + return '%s' % ( + bg, text, text) + +def modulelink(module, baseurl=''): + """Hyperlink to a module, either locally or on python.org""" + if module+'.py' not in local_files: + baseurl = 'http://www.python.org/doc/current/lib/module-' + return link(baseurl+module+'.html', module) + +def importer(m): + "Turn text such as 'utils, math, re' into a string of HTML links." + modules = [modulelink(mod.strip()) for mod in m.group(2).split(',')] + return (m.group(1) + ', '.join(modules) + m.group(3)) + +def find1(regex, str): + return (re.findall(regex, str) or [' '])[0] + +def convert_files(filenames, local_filenames=None, tblfile='readme.htm'): + "Convert files of python code to colorized HTML." + global local_files + local_files = local_filenames or filenames + summary_table = {} + for f in filenames: + fulltext = '\n'.join(map(string.rstrip, open(f).readlines())) + text = fulltext + for (pattern, repl) in replacements: + text = re.sub(pattern, repl, text) + text = '<>
%s
<

' % name, - '

')
-            self.run_docstring(object)
-            names = object.__dict__.keys()
-            names.sort()
-            for name in names:
-                val = object.__dict__[name]
-                if isinstance(val, types.ClassType):
-                    self.run_class(val)
-                elif isinstance(val, types.ModuleType):
-                    pass
-                elif not self.seen(val):
-                    self.run_docstring(val)
-
-    def run_class(self, object):
-        """Run the docstrings, and then all members of the class."""
-        if not self.seen(object):
-            self.run_docstring(object)
-            names = object.__dict__.keys()
-            names.sort()
-            for name in names:
-                self.run_docstring(object.__dict__[name])
-
-    def run_docstring(self, object, search=re.compile(r'(?m)^\s*Ex: ').search):
-        "Run the __doc__ and _docex attributes, if the object has them."
-        if hasattr(object, '__doc__'):
-            s = object.__doc__
-            if isinstance(s, str):
-                match = search(s)
-                if match: self.run_string(s[match.end():])
-        if hasattr(object, '_docex'):
-                self.run_string(object._docex)
-        
-    def run_string(self, teststr):
-        """Run a test string, printing inputs and results."""
-        if not teststr: return
-        teststr = teststr.strip()
-        if teststr.find('\n') > -1:
-            map(self.run_string, teststr.split('\n'))
-        elif teststr == '' or teststr.startswith('#'):
-            self.writeln(teststr)
-        elif teststr.find('; ') > -1:
-            for substr in teststr.split('; '): self.run_string(substr)
-        elif teststr.find('==>') > -1:
-            teststr, result = teststr.split('==>')
-            self.evaluate(teststr, result)
-        elif teststr.find(' raises ') > -1:
-            teststr, exception = teststr.split(' raises ')
-            self.raises(teststr, exception)
-        else: ## Try to eval, but if it is a statement, exec
-            try:
-                self.evaluate(teststr)
-            except SyntaxError:
-                exec teststr in self.dictionary
-
-    def evaluate(self, teststr, resultstr=None):
-        "Eval teststr and check if resultstr (if given) evals to the same."
-        self.writeln('>>> ' +  teststr.strip())
-        result = eval(teststr, self.dictionary)
-        self.dictionary['_'] = result
-        self.writeln(repr(result))
-        if resultstr == None:
-          return
-        elif result == eval(resultstr, self.dictionary):
-          self.passed += 1
-        else:
-          self.fail(teststr, resultstr)
-    
-    def raises(self, teststr, exceptionstr):
-        teststr = teststr.strip()
-        self.writeln('>>> ' + teststr)
-        except_class = eval(exceptionstr, self.dictionary)
-        try:
-            exec teststr in self.dictionary
-        except except_class:
-            self.writeln('# raises %s as expected' % exceptionstr)
-            self.passed += 1
-            return
-        self.fail(teststr, exceptionstr)
-
-    def fail(self, teststr, resultstr):
-        self.writeln('###### ERROR, TEST FAILED: expected %s for %s' 
-                     % (resultstr, teststr),
-                     '', '')
-        self.failed += 1
-
-    def writeln(self, s, before='', after=''):
-        "Write s, html escaped, and wrapped with html code before and after."
-        s = str(s)
-        if self.html:
-            s = s.replace('&','&').replace('<','<').replace('>','>')
-            print '%s%s%s' % (before, s, after)
-        else:
-            print s
-
-    def seen(self, object):
-        """Return true if this object has been seen before.
-        In any case, record that we have seen it."""
-        result = self.already_seen.has_key(id(object))
-        self.already_seen[id(object)] = 1
-        return result
-
-def main(args):
-    """Run Docex.  args should be a list of python filenames.  
-    If the first arg is a non-python filename, it is taken as the
-    name of a log file to which output is written.  If it ends in
-    ".htm" or ".html", then the output is written as html.  If the
-    first arg is "-", then standard output is used as the log file."""
-    import glob
-    out = None
-    html = 0
-    if args[0] != "-" and not args[0].endswith(".py"):
-        out = open(args[0], 'w')
-        if args[0].endswith(".html") or args[0].endswith(".htm"):
-            html = 1
-    modules = []
-    for arg in args:
-        for file in glob.glob(arg):
-            if file.endswith('.py'):
-                modules.append(__import__(file[:-3]))
-    print Docex(modules, html=html, out=out)
-
-if __name__ == '__main__':
-    main(sys.argv[1:])
-
-
diff --git a/pytudes/py/ibol.py b/pytudes/py/ibol.py
deleted file mode 100644
index d2490a6..0000000
--- a/pytudes/py/ibol.py
+++ /dev/null
@@ -1,193 +0,0 @@
-from collections import defaultdict
-
-def get_genomes(fname="byronbayseqs.fas.txt"):
-    "Return a list of genomes, and a list of their corresponding names."
-    import re
-    names, species, genomes = [], [], []
-    for name, g in re.findall('>(.*?)\r([^\r]*)\r*', file(fname).read()):
-        names.append(name)
-        species.append(name.split('|')[-1])
-        genomes.append(g)
-    return names, species, genomes
-
-def get_neighbors(fname="editdistances.txt"):
-    "Return dict: neighbors[i][j] = neighbors[j][i] = d means i,j are d apart."
-    ## Read the data pre-computed from the Java program
-    neighbors = dict((i, {}) for i in range(n))
-    for line in file(fname):
-        i,j,d = map(int, line.split())
-        neighbors[i][j] = neighbors[j][i] = d
-    return neighbors
-        
-def cluster(neighbors, d, dc):
-    """Return a list of clusters, each cluster element is within d of another
-    and within dc of every other cluster element."""
-    unclustered = set(neighbors) ## set of g's not yet clustered
-    return [closure(g, set(), unclustered, d, dc)
-            for g in neighbors if g in unclustered]
-
-def closure(g, s, unclustered, d, dc):
-    "Accumulate in set s the transitive closure of 'near', starting at g"
-    if g not in s and g in unclustered and near(g, s, d, dc):
-        s.add(g); unclustered.remove(g)
-        for g2 in neighbors[g]:
-            closure(g2, s, unclustered, d, dc)
-    return s
-
-def dist(i, j):
-    "Distance between two genomes."
-    if i == j: return 0
-    return neighbors[min(i, j)].get(max(i, j), max_distance)
-
-def near(g, cluster, d, dc):
-    "Is g within d of some member of c, and within dc of every member of c?"
-    distances = [dist(g, g2) for g2 in cluster] or [0]
-    return min(distances) <= d and max(distances) <= dc
-
-def diameter(cluster):
-    "The largest distance between two elements of the cluster"
-    return max([dist(i, j) for i in cluster for j in cluster] or [0])
-
-def margin(cluster):
-    "The distance from a cluster to the nearest g2 outside this cluster."
-    return min([d for g in cluster for g2,d in neighbors[g].items()
-                if g2 not in cluster] or [max_distance])
-
-################################################################ Analysis
-
-def pct(num, den):
-    "Return a string representing the percentage. "
-    if '__len__' in dir(den): den = len(den)
-    if num==den: return ' 100%'
-    return '%.1f%%' % (num*100.0/den)
-
-def histo(items):
-    "Make a histogram from a sequence of items or (item, count) tuples."
-    D = defaultdict(int)
-    for item in items:
-        if isinstance(item, tuple): D[item[0]] += item[1]
-        else: D[item] += 1
-    return D
-
-def showh(d):
-    "Show a histogram"
-    if not isinstance(d, dict): d = histo(d)
-    return ' '.join('%s:%s' % i for i in sorted(d.items()))
-
-def greport(genomes):
-    print "Number of genomes: %d (%d distinct)" % (len(genomes), len(set(genomes)))
-    G = dict((g, set()) for g in genomes)
-    for i in range(n):
-        G[genomes[i]].add(species[i])
-    print "Multi-named genomes:", (
-        len([s for s in G.values() if len(s) > 1]))
-    lens = map(len, genomes)
-    print "Genome lengths: min=%d, max=%d" % (min(lens), max(lens))
-    print "Character counts: ", showh(c for g in genomes for c in g)
-    
-def nreport(neighbors):
-    NN, NumN = defaultdict(int), defaultdict(int) ## Nearest, Number of neighbors
-    for n in neighbors:
-        nn = min(neighbors[n].values() or ['>25'])
-        NN[nn] += 1
-        for d2 in neighbors[n].values():
-            NumN[d2] += 1 
-    print
-    print "Nearest neighbor counts:", showh(NN)
-    print "Number of neighbors at each distance:", showh(NumN)
-
-def nspecies(c): return len(set(species[g] for g in c))
-
-def showc(c):
-    return "N=%d, D=%d, M=%d: %s %s" % (
-        len(c), diameter(c), margin(c), list(c), showh(species[g] for g in c))
-
-def creport(drange, dcrange):
-    def table(what, fn):
-        print "\n" + what
-        print ' '*8, ' '.join([' '+pct(dc, glen) for dc in dcrange])
-        for d in drange:
-            print '%s (%2d)' % (pct(d, glen), d),
-            for dc in dcrange:
-                print '%5s' % fn(cluster(neighbors, d, dc)),
-            print
-    print '\nNearest neighbor must be closer than this percentage (places). '
-    print 'Each column: all genomes in cluster within this percentage of each other.'
-    table("Number of clusters", len)
-    cluster1 = cluster(neighbors, 8, 15) ## splits Cleora
-    print '\nNumber of clusters of different sizes:', showh(len(c) for c in cluster1)
-    M, T = defaultdict(int), defaultdict(int)
-    for c in cluster1:
-        M[margin(c)] += 1; T[margin(c)] += len(c)
-    for x in M: print '%d\t%d\t%d'% (x,M[x],T[x])
-    print '\nMargins', showh(M)
-    for c in cluster1:
-        if margin(c) <= 16:
-            print showc(c)
-    print '\nScatter plot of cluster diameter vs. margin.'
-    for c in cluster1:
-        if diameter(c) > 0:
-            pass
-            #print '%d\t%d' % (diameter(c), margin(c))
-    print '\nDifference from cluster(neighbors, 11, 14):'
-    #table(lambda cl: pct(len(cluster1)-compare(cluster1, cl),max(len(cluster1),len(cl))))
-    print '\nNumber of clusters witth more than one species name:'
-    #table(lambda cl: sum(nspecies(c) > 1 for c in cl))
-    def pct_near_another(clusters, P=1.25):
-        total = 0
-        for c in clusters:
-            d = diameter(c)
-            for g in c:
-                for g2 in neighbors[g]:
-                    if g2 not in c and dist(g, g2) < P*d:
-                        total += 1
-        return pct(total, n)
-    def f(P):
-        print '\nPercent of individuals within %.2f*diameter of another cluster.'%P
-        table(lambda cl: pct_near_another(cl, P))
-    #map(f, [1.2, 1.33, 1.5])
-
-def sreport(species):
-    SS = defaultdict(int)
-    print
-    for s in set(species):
-        c = [g for g in range(n) if species[g] == s]
-        d = diameter(c)
-        if d > 14:
-            if d==glen: d = '>25'
-            print 'diameter %s for %s (%d elements)' % (d, s, len(c))
-        SS[d] += 1
-    print 'Diameters of %d labeled clusters: %s' % (len(set(species)), showh(SS))
-    
-def compare(cl1, cl2):
-    "Compare two lists of clusters"
-    return sum(c1==c2 or 0.5*(abs(len(c1)-len(c2))==1 and
-                              (c1.issubset(c2) or c2.issubset(c1)))
-               for c1 in cl1 for c2 in cl2)
-
-def unit_tests():
-    assert set(len(g) for g in genomes) == set([glen])
-    clusters = cluster(neighbors, 11, 11)
-    assert sum(len(c) for c in clusters) == len(genomes)
-    assert len(set(g for c in clusters for g in c)) == len(genomes)
-    assert dist(17, 42) == dist(42, 17)
-    assert diameter(set()) == 0
-    assert diameter([17, 42]) == dist(17, 42)
-    assert pct(1, 2) == '50.0%'
-    print '\nAll tests pass.\n'
-
-    
-
-################################################################ Main body
- 
-max_distance = 26
-names, species, genomes = get_genomes() ## genomes = ['ACT...', ...]
-n = len(genomes)
-glen = len(genomes[0])
-neighbors = get_neighbors() ## neighbor[g] = {g2:d2, g3:g3, ...}
-greport(genomes)
-nreport(neighbors)
-creport(range(6, 15), [glen,16,15,14,13, 12, 11])
-#sreport(species)
-
-unit_tests()
diff --git a/pytudes/py/lettercount.py b/pytudes/py/lettercount.py
deleted file mode 100644
index 3c6db88..0000000
--- a/pytudes/py/lettercount.py
+++ /dev/null
@@ -1,443 +0,0 @@
-"""
-Code to support http://norvig.com/mayzner.html
-Read files in the Google Books ngram format, and convert them to a simpler format.
-The original format looks like this:
-
-    word     \t year \t word_count \t book_count
-    word_POS \t year \t word_count \t book_count
-
-for example,
-
-    accreted_VERB	1846	7	4
-    accreted_VERB	1847	1	1
-    accreted_VERB	1848	1	1
-
-The function 'read_year_file' will convert a file of this form into a dict of
-{WORD: count} pairs, where the WORD is uppercased, and the count is the total
-over all years (you have the option to specify a starting year) and all
-capitalizations.  Then 'read_dict' and 'write_dict' convert between a dict and
-an external file format that looks like this:
-
-    ACCRETED	9
-
-"""
-
-from __future__ import division
-from collections import Counter, defaultdict
-
-#### Read files in Books-Ngram format; convert to a dict
-
-def read_year_file(filename, dic=None):
-    """Read a file of 'word year word_count book_count' lines and convert to a dict
-    {WORD: totalcount}. Uppercase all words, and only include all-alphabetic words."""
-    if dic is None: dic = {}
-    for line in file(filename):
-        word, year, c1, c2 = line.split('\t')
-        if '_' in word:
-            word = word[:word.index('_')]
-        if word.isalpha():
-            word = word.upper()
-            dic[word] = dic.get(word, 0) + int(c1)
-    return dic
-
-#### Read and write files of the form 'WORD \t count \n'
-
-def write_dict(dic, filename):
-    "Write a {word:count} dict as 'word \t count' lines in filename."
-    out = file(filename, 'w')
-    for key in sorted(dic):
-        out.write('%s\t%s\n' % (key, dic[key]))
-    return out.close()
-        
-def read_dict(filename, sep='\t'):
-    "Read 'word \t count' lines from file and make them into a dict of {word:count}."
-    pairs = (line.split(sep) for line in file(filename))
-    return {word: int(count) for (word, count) in pairs}
-
-#### Convert a bunch of year files into dict file format.
-
-def convert_files(filenames, mincount=1e5):
-    def report(filename, D, adj):
-        import time
-        N = len(D)
-        W = sum(v for v in D.itervalues())
-        print '%s: %s %s words (%s tokens) at %s' % (
-            filename, adj, format(W, ',d'), format(N, ',d'),
-            time.strftime("%H:%M:%S", time.gmtime()))
-    for f in filenames:
-        report(f, {}, 'starting')
-        D = read_year_file(f)
-        report(f, D, 'total')
-        for key in list(D):
-            if D[key] < mincount:
-                del D[key]
-        write_dict(D, 'WORD-' + f[-1].upper())
-        report(f, D, 'popular')
-
-def load(filename='top-words.txt'):
-    "Load file of 'word \t count' lines into D (a dict), W (length of D) and M (total number of words)."
-    global D, W, M
-    D = read_dict(filename)
-    W = len(D)
-    M = sum(D.values())
-    
-#### Compute letter counts and save as HTML files.
-
-def histogram(items):
-    "Return a Counter of the number of times each key occurs in (key, val) pairs."
-    C = Counter()
-    for (key, val) in items:
-        C[key] += val
-    return C
-
-def end(name): return '/' + name
-
-def tag(name, **kwds): return '<' + name + keywords(kwds) + '>'
-
-def row(cells, **kwds):
-    return '' + ''
-    
-def ngram_tables(dic, N, pos=[0, 1, 2, 3, 4, -5, -4, -3, -2, -1]):
-    """Return three dicts of letter N-grams of length N: counts, counts1, counts2.
-    counts is a dict of {'AB': 123} that counts how often 'AB' occurs.
-    counts1[i] is a dict of {'AB': 123} that counts how often 'AB' occurs at position i.
-    counts2[i][j] is a dict of {'AB': 123} that counts how often 'AB' occurs at position i."""
-    L = len(max(D, key=len))
-    counts = Counter()
-    counts1 = [Counter() for _ in range(L)]
-    counts2 = [[Counter() for i in range(L)]]
-
-def counter(pairs):
-    "Make a Counter from an iterable of (value, count) pairs."
-    c = Counter()
-    for (value, count) in pairs:
-        c[value] += count
-    return c
-
-def ngrams(word, N):
-    return [word[i:i+N] for i in range(len(word)+1-N)]
-
-
-import glob
-#convert_files(glob.glob('book?'))
-              
-#DB = [[letter_counts() for length in range(length)] for length in range(maxlen)]
-      
-
-## Unused ???
-
-def letter_counts(wc):
-    """From word_counts dictionary wc, Create a dictionary of {(s, i, L): count}
-    where s is a letter n-gram, i is the starting position, and L is the length
-    of the word in which it appears."""
-    result = defaultdict(int)
-    for (word, count) in wc.iteritems():
-        for p in pieces(word):
-            result[p] += count
-    return result
-
-def pieces(word):
-    "Yield the 1- and 2-letter grams in (s, i, L) format."
-    L = len(word)
-    for i in range(L):
-        yield (word[i], i, L)
-        if i+1 < L:
-            yield (word[i:i+2], i, L)
-
-def getcount(counts, s, pos, length):
-    """The count for letter sequence s (one or two letters) starting at
-    position i of words of length length.  If any argument is all, sum them up."""
-    if length == all:
-        return sum(getcount(counts, s, pos, L) for L in all_lengths)
-    elif pos == all:
-        return sum(getcount(counts, s, i, length) for i in range(length))
-    else:
-        return counts[s, pos, length]
-
-
-print 'start'
-#wc = word_counts('count_100K.txt')
-#counts = letter_counts(wc)
-print 'end'
-
-
-
-def test():
-    D = {'the': 100, 'of': 70, 'and': 60, 'to': 50, 'a': 40}
-
-def num(ch):
-    "Translate 'a' or 'A' to 0, ... 'z' or 'Z' to 25."
-    return 'abcdefghijklmnopqrstuvwxyz'.index(ch.lower())
-    
-
-def stats(D, NS = (1, 2, 3, 4, 5, 6)):
-    counts = {n: Counter() for n in NS}
-    print 'words ' + ' '.join('   %d-grams  ' % n for n in NS)
-    for (i, word) in enumerate(sortedby(D), 1):
-        for n in NS:
-            for ng in ngrams(word, n):
-                counts[n][ng] += 1
-        if i % 5000 == 0 or i == len(D):
-            print "%4dK" % (i/1000),
-            for n in NS:
-                c = len(counts[n])
-                field = "%5d (%d%%)" % (c, int(round(c*100/(26**n))))
-                print '%12s' % field,
-            print
-
-letters = 'ETAOINSRHLDCUMFPGWYBVKXJQZ'
-alphabet = ''.join(sorted(letters))
-
-from itertools import cycle, izip
-
-colors = 'ygobp'
-
-def bar(text, color, count, N, pixels, height=16):
-    width = int(round(pixels * count / N))
-    if width < 2: width = 3
-    title = '{}: {:.3f}%; {:,}'.format(text, count*100./N, count)
-    return '%s' % (
-        title, color, height, width, -width+2, text) # -int(width/2+5)
-
-def letter_bar(LC, N=None, factor='', pixels=700):
-    if N is None: N = sum(LC.values())
-    #divisor = {'':1., 'K':1e3, 'M':1e6, 'B':1e9}[factor]
-    return ''.join(
-        bar(L.lower(), color, LC[L], N, pixels)
-        for (L, color) in izip(letters, cycle(colors)))
-        
-
-def singleton(x): return [x]
-
-positions = [0, 1, 2, 3, 4, 5, 6, -7, -6, -5, -4, -3, -2, -1]
-
-def substr(word, pos, length):
-    """Return the substr of word of given length starting/ending at pos; or None."""
-    W = len(word)
-    if pos >= 0 and pos+length <= W:
-        return word[pos:pos+length]
-    elif pos < 0 and abs(pos)+length-1 <= W:
-        return word[W+pos+1-length:W+pos+1]
-    else:
-        return None
-        
-def lettercount(D, pos):
-    LC = histogram((substr(w, pos, 1), D[w]) for w in D)
-    del LC[None]
-    print LC
-    pos_name = (str(pos)+'+' if isinstance(pos, tuple) else
-                pos if pos < 0 else
-                pos+1)
-    return '\n
\n%-3s %s' % (pos_name, letter_bar(LC)) - -def ngramcount(D, n=2): - return histogram((ng, D[w]) for w in D for ng in ngrams(w, n)) - -def twograms(D2): - N = sum(D2.values()) - header = '' - rows = [tr([cell(A+B, D2, N) for A in alphabet]) for B in alphabet] - return '\n'.join([header] + rows + ['
']) - -def cell(text, D2, N, height=16, maxwidth=25, scale=27): - count = D2.get(text, 0) - width = int(round(maxwidth * count * scale * 1. / N)) - if width < 1: width = 1 - title = '{}: {:.3f}%; {:,}'.format(text, count*100./N, count) - return '%s' % ( - title, height, width, -width+2, text) - -def cell(text, D2, N, height=16, maxwidth=25, scale=27): - count = D2.get(text, 0) - width = int(round(maxwidth * count * scale * 1. / N)) - if width < 1: width = 1 - title = '{}: {:.3f}%; {:,}'.format(text, count*100./N, count) - return '%s' % ( - title, height, width, text) - -def tr(cells): - return '' + ''.join(cells) - -def comma(n): return '{:,}'.format(n) - -def ngram_stats(D, n, k=5): - DN = ngramcount(D, n) - topk = ', '.join(sortedby(DN)[:k]) - return '%d-grams%s%s
counts-%d.csvcounts-%d.html%s' % ( - n, comma(len(DN)), comma(sum(DN.values())), n, n, n, n, topk) - -#### Tables - -def sortedby(D): - return sorted(D, key=lambda x: -D[x]) - -ANY = '*' - -wordlengths = range(1, 10) - -def col(*args): return args - -def columns(n, wordlengths=wordlengths): - lengths = [k for k in wordlengths if k >= n] - return ([col(ANY, ANY)] - + [col(k, ANY) for k in lengths] - + [col(k, start, start+n-1) for k in lengths for start in range(1, 2+k-n)] - + [col(ANY, start, start+n-1) for start in wordlengths] - + [col(ANY, -k, -k+n-1) for k in reversed(lengths) if -k+n-1 < 0]) - -def colname(col): - fmt = '%s/%s' if (len(col) == 2) else '%s/%d:%d' - return fmt % col - -def csvline(first, rest): - return '\t'.join([first] + map(str, rest)) - -def makecsv(n, D=D): - out = file('ngrams%d.csv' % n, 'w') - cols = columns(n) - Dng = defaultdict(lambda: defaultdict(int)) - for w in D: - for (start, ng) in enumerate(ngrams(w, n), 1): - entry = Dng[ng] - N = D[w] - wlen = len(w) - entry[ANY, ANY] += N - entry[wlen, ANY] += N - if start <= 9: - entry[wlen, start, start+n-1] += N - entry[ANY, start, start+n-1] += N - from_end = wlen-start+1 - if from_end <= 9: - entry[ANY, -from_end, -from_end+n-1] += N - # enumerate ngrams from word and increment counts for each one - print >> out, csvline('%d-gram' % n, map(colname, cols)) - for ng in sorted(Dng, key=lambda ng: -Dng[ng][(ANY, ANY)]): - print >> out, csvline(ng, [Dng[ng].get(col, 0) for col in cols]) - out.close() - return Dng - -### Tests - -""" ->>> for w in words: - print '%-6s %6.2f B (%4.2f%%) ' % (w.lower(), D[w]/1e9, D[w]*100./N, int(round(D[w]*4000./N))) -... -the 53.10 B (7.14%) -of 30.97 B (4.16%) -and 22.63 B (3.04%) -to 19.35 B (2.60%) -in 16.89 B (2.27%) -a 15.31 B (2.06%) -is 8.38 B (1.13%) -that 8.00 B (1.08%) -for 6.55 B (0.88%) -it 5.74 B (0.77%) -as 5.70 B (0.77%) -was 5.50 B (0.74%) -with 5.18 B (0.70%) -be 4.82 B (0.65%) -by 4.70 B (0.63%) -on 4.59 B (0.62%) -not 4.52 B (0.61%) -he 4.11 B (0.55%) -i 3.88 B (0.52%) -this 3.83 B (0.51%) -are 3.70 B (0.50%) -or 3.67 B (0.49%) -his 3.61 B (0.49%) -from 3.47 B (0.47%) -at 3.41 B (0.46%) -which 3.14 B (0.42%) -but 2.79 B (0.38%) -have 2.78 B (0.37%) -an 2.73 B (0.37%) -had 2.62 B (0.35%) -they 2.46 B (0.33%) -you 2.34 B (0.31%) -were 2.27 B (0.31%) -their 2.15 B (0.29%) -one 2.15 B (0.29%) -all 2.06 B (0.28%) -we 2.06 B (0.28%) -can 1.67 B (0.22%) -her 1.63 B (0.22%) -has 1.63 B (0.22%) -there 1.62 B (0.22%) -been 1.62 B (0.22%) -if 1.56 B (0.21%) -more 1.55 B (0.21%) -when 1.52 B (0.20%) -will 1.49 B (0.20%) -would 1.47 B (0.20%) -who 1.46 B (0.20%) -so 1.45 B (0.19%) -no 1.40 B (0.19%) - ->>> for n in sorted(H): - print '%2d %9.2f M (%6.3f%%) %d' % (n, H[n]/1e6, H[n]*100./NN, H[n]*3000./NN, n) -... - 1 22301.22 M ( 2.998%) 1 - 2 131293.85 M (17.651%) 2 - 3 152568.38 M (20.511%) 3 - 4 109988.33 M (14.787%) 4 - 5 79589.32 M (10.700%) 5 - 6 62391.21 M ( 8.388%) 6 - 7 59052.66 M ( 7.939%) 7 - 8 44207.29 M ( 5.943%) 8 - 9 33006.93 M ( 4.437%) 9 -10 22883.84 M ( 3.076%) 10 -11 13098.06 M ( 1.761%) 11 -12 7124.15 M ( 0.958%) 12 -13 3850.58 M ( 0.518%) 13 -14 1653.08 M ( 0.222%) 14 -15 565.24 M ( 0.076%) 15 -16 151.22 M ( 0.020%) 16 -17 72.81 M ( 0.010%) 17 -18 28.62 M ( 0.004%) 18 -19 8.51 M ( 0.001%) 19 -20 6.35 M ( 0.001%) 20 -21 0.13 M ( 0.000%) 21 -22 0.81 M ( 0.000%) 22 -23 0.32 M ( 0.000%) 23 - ->>> NL = sum(LC.values()) - ->>> for L in sorted(LC, key=lambda L: -LC[L]): - print '%s %8.1f B (%5.2f%%) ' % (L, LC[L]/1e9, LC[L]*100./NL, LC[L]*3000./NL) -... -E 445.2 B (12.49%) -T 330.5 B ( 9.28%) -A 286.5 B ( 8.04%) -O 272.3 B ( 7.64%) -I 269.7 B ( 7.57%) -N 257.8 B ( 7.23%) -S 232.1 B ( 6.51%) -R 223.8 B ( 6.28%) -H 180.1 B ( 5.05%) -L 145.0 B ( 4.07%) -D 136.0 B ( 3.82%) -C 119.2 B ( 3.34%) -U 97.3 B ( 2.73%) -M 89.5 B ( 2.51%) -F 85.6 B ( 2.40%) -P 76.1 B ( 2.14%) -G 66.6 B ( 1.87%) -W 59.7 B ( 1.68%) -Y 59.3 B ( 1.66%) -B 52.9 B ( 1.48%) -V 37.5 B ( 1.05%) -K 19.3 B ( 0.54%) -X 8.4 B ( 0.23%) -J 5.7 B ( 0.16%) -Q 4.3 B ( 0.12%) -Z 3.2 B ( 0.09%) - ->>> D2 = ngramcount(D, 2) - ->>> for ng in sorted(D2, key=lambda L: -D2[L])[:50]: print '%s %8.1f B (%5.2f%%) ' % (ng, D2[ng]/1e9, D2[ng]*100./N2, D2[ng]*15000./N2) - -def doit(k=25): - counts = [sortedby(ngramcount(D, n))[:k] for n in range(2, 10)] - for i in range(k): - print (' '.join(count[i] for count in counts)).lower() -""" diff --git a/pytudes/py/lis.py b/pytudes/py/lis.py deleted file mode 100644 index 2d031ad..0000000 --- a/pytudes/py/lis.py +++ /dev/null @@ -1,145 +0,0 @@ -################ Lispy: Scheme Interpreter in Python - -## (c) Peter Norvig, 2010-16; See http://norvig.com/lispy.html - -from __future__ import division -import math -import operator as op - -################ Types - -Symbol = str # A Lisp Symbol is implemented as a Python str -List = list # A Lisp List is implemented as a Python list -Number = (int, float) # A Lisp Number is implemented as a Python int or float - -################ Parsing: parse, tokenize, and read_from_tokens - -def parse(program): - "Read a Scheme expression from a string." - return read_from_tokens(tokenize(program)) - -def tokenize(s): - "Convert a string into a list of tokens." - return s.replace('(',' ( ').replace(')',' ) ').split() - -def read_from_tokens(tokens): - "Read an expression from a sequence of tokens." - if len(tokens) == 0: - raise SyntaxError('unexpected EOF while reading') - token = tokens.pop(0) - if '(' == token: - L = [] - while tokens[0] != ')': - L.append(read_from_tokens(tokens)) - tokens.pop(0) # pop off ')' - return L - elif ')' == token: - raise SyntaxError('unexpected )') - else: - return atom(token) - -def atom(token): - "Numbers become numbers; every other token is a symbol." - try: return int(token) - except ValueError: - try: return float(token) - except ValueError: - return Symbol(token) - -################ Environments - -def standard_env(): - "An environment with some Scheme standard procedures." - env = Env() - env.update(vars(math)) # sin, cos, sqrt, pi, ... - env.update({ - '+':op.add, '-':op.sub, '*':op.mul, '/':op.truediv, - '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, - 'abs': abs, - 'append': op.add, - 'apply': apply, - 'begin': lambda *x: x[-1], - 'car': lambda x: x[0], - 'cdr': lambda x: x[1:], - 'cons': lambda x,y: [x] + y, - 'eq?': op.is_, - 'equal?': op.eq, - 'length': len, - 'list': lambda *x: list(x), - 'list?': lambda x: isinstance(x,list), - 'map': map, - 'max': max, - 'min': min, - 'not': op.not_, - 'null?': lambda x: x == [], - 'number?': lambda x: isinstance(x, Number), - 'procedure?': callable, - 'round': round, - 'symbol?': lambda x: isinstance(x, Symbol), - }) - return env - -class Env(dict): - "An environment: a dict of {'var':val} pairs, with an outer Env." - def __init__(self, parms=(), args=(), outer=None): - self.update(zip(parms, args)) - self.outer = outer - def find(self, var): - "Find the innermost Env where var appears." - return self if (var in self) else self.outer.find(var) - -global_env = standard_env() - -################ Interaction: A REPL - -def repl(prompt='lis.py> '): - "A prompt-read-eval-print loop." - while True: - val = eval(parse(raw_input(prompt))) - if val is not None: - print(lispstr(val)) - -def lispstr(exp): - "Convert a Python object back into a Lisp-readable string." - if isinstance(exp, List): - return '(' + ' '.join(map(lispstr, exp)) + ')' - else: - return str(exp) - -################ Procedures - -class Procedure(object): - "A user-defined Scheme procedure." - def __init__(self, parms, body, env): - self.parms, self.body, self.env = parms, body, env - def __call__(self, *args): - return eval(self.body, Env(self.parms, args, self.env)) - -################ eval - -def eval(x, env=global_env): - "Evaluate an expression in an environment." - if isinstance(x, Symbol): # variable reference - return env.find(x)[x] - elif not isinstance(x, List): # constant literal - return x - elif x[0] == 'quote': # (quote exp) - (_, exp) = x - return exp - elif x[0] == 'if': # (if test conseq alt) - (_, test, conseq, alt) = x - exp = (conseq if eval(test, env) else alt) - return eval(exp, env) - elif x[0] == 'define': # (define var exp) - (_, var, exp) = x - env[var] = eval(exp, env) - elif x[0] == 'set!': # (set! var exp) - (_, var, exp) = x - env.find(var)[var] = eval(exp, env) - elif x[0] == 'lambda': # (lambda (var...) body) - (_, parms, body) = x - return Procedure(parms, body, env) - else: # (proc arg...) - proc = eval(x[0], env) - args = [eval(exp, env) for exp in x[1:]] - return proc(*args) \ No newline at end of file diff --git a/pytudes/py/lispy.py b/pytudes/py/lispy.py deleted file mode 100644 index 08923c1..0000000 --- a/pytudes/py/lispy.py +++ /dev/null @@ -1,318 +0,0 @@ -################ Scheme Interpreter in Python - -## (c) Peter Norvig, 2010; See http://norvig.com/lispy2.html - -################ Symbol, Procedure, classes - -from __future__ import division -import re, sys, StringIO - -class Symbol(str): pass - -def Sym(s, symbol_table={}): - "Find or create unique Symbol entry for str s in symbol table." - if s not in symbol_table: symbol_table[s] = Symbol(s) - return symbol_table[s] - -_quote, _if, _set, _define, _lambda, _begin, _definemacro, = map(Sym, -"quote if set! define lambda begin define-macro".split()) - -_quasiquote, _unquote, _unquotesplicing = map(Sym, -"quasiquote unquote unquote-splicing".split()) - -class Procedure(object): - "A user-defined Scheme procedure." - def __init__(self, parms, exp, env): - self.parms, self.exp, self.env = parms, exp, env - def __call__(self, *args): - return eval(self.exp, Env(self.parms, args, self.env)) - -################ parse, read, and user interaction - -def parse(inport): - "Parse a program: read and expand/error-check it." - # Backwards compatibility: given a str, convert it to an InPort - if isinstance(inport, str): inport = InPort(StringIO.StringIO(inport)) - return expand(read(inport), toplevel=True) - -eof_object = Symbol('#') # Note: uninterned; can't be read - -class InPort(object): - "An input port. Retains a line of chars." - tokenizer = r"""\s*(,@|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,;)]*)(.*)""" - def __init__(self, file): - self.file = file; self.line = '' - def next_token(self): - "Return the next token, reading new text into line buffer if needed." - while True: - if self.line == '': self.line = self.file.readline() - if self.line == '': return eof_object - token, self.line = re.match(InPort.tokenizer, self.line).groups() - if token != '' and not token.startswith(';'): - return token - -def readchar(inport): - "Read the next character from an input port." - if inport.line != '': - ch, inport.line = inport.line[0], inport.line[1:] - return ch - else: - return inport.file.read(1) or eof_object - -def read(inport): - "Read a Scheme expression from an input port." - def read_ahead(token): - if '(' == token: - L = [] - while True: - token = inport.next_token() - if token == ')': return L - else: L.append(read_ahead(token)) - elif ')' == token: raise SyntaxError('unexpected )') - elif token in quotes: return [quotes[token], read(inport)] - elif token is eof_object: raise SyntaxError('unexpected EOF in list') - else: return atom(token) - # body of read: - token1 = inport.next_token() - return eof_object if token1 is eof_object else read_ahead(token1) - -quotes = {"'":_quote, "`":_quasiquote, ",":_unquote, ",@":_unquotesplicing} - -def atom(token): - 'Numbers become numbers; #t and #f are booleans; "..." string; otherwise Symbol.' - if token == '#t': return True - elif token == '#f': return False - elif token[0] == '"': return token[1:-1].decode('string_escape') - try: return int(token) - except ValueError: - try: return float(token) - except ValueError: - try: return complex(token.replace('i', 'j', 1)) - except ValueError: - return Sym(token) - -def to_string(x): - "Convert a Python object back into a Lisp-readable string." - if x is True: return "#t" - elif x is False: return "#f" - elif isa(x, Symbol): return x - elif isa(x, str): return '"%s"' % x.encode('string_escape').replace('"',r'\"') - elif isa(x, list): return '('+' '.join(map(to_string, x))+')' - elif isa(x, complex): return str(x).replace('j', 'i') - else: return str(x) - -def load(filename): - "Eval every expression from a file." - repl(None, InPort(open(filename)), None) - -def repl(prompt='lispy> ', inport=InPort(sys.stdin), out=sys.stdout): - "A prompt-read-eval-print loop." - sys.stderr.write("Lispy version 2.0\n") - while True: - try: - if prompt: sys.stderr.write(prompt) - x = parse(inport) - if x is eof_object: return - val = eval(x) - if val is not None and out: print >> out, to_string(val) - except Exception as e: - print '%s: %s' % (type(e).__name__, e) - -################ Environment class - -class Env(dict): - "An environment: a dict of {'var':val} pairs, with an outer Env." - def __init__(self, parms=(), args=(), outer=None): - # Bind parm list to corresponding args, or single parm to list of args - self.outer = outer - if isa(parms, Symbol): - self.update({parms:list(args)}) - else: - if len(args) != len(parms): - raise TypeError('expected %s, given %s, ' - % (to_string(parms), to_string(args))) - self.update(zip(parms,args)) - def find(self, var): - "Find the innermost Env where var appears." - if var in self: return self - elif self.outer is None: raise LookupError(var) - else: return self.outer.find(var) - -def is_pair(x): return x != [] and isa(x, list) -def cons(x, y): return [x]+y - -def callcc(proc): - "Call proc with current continuation; escape only" - ball = RuntimeWarning("Sorry, can't continue this continuation any longer.") - def throw(retval): ball.retval = retval; raise ball - try: - return proc(throw) - except RuntimeWarning as w: - if w is ball: return ball.retval - else: raise w - -def add_globals(self): - "Add some Scheme standard procedures." - import math, cmath, operator as op - self.update(vars(math)) - self.update(vars(cmath)) - self.update({ - '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_, - '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, - 'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons, - 'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add, - 'list':lambda *x:list(x), 'list?': lambda x:isa(x,list), - 'null?':lambda x:x==[], 'symbol?':lambda x: isa(x, Symbol), - 'boolean?':lambda x: isa(x, bool), 'pair?':is_pair, - 'port?': lambda x:isa(x,file), 'apply':lambda proc,l: proc(*l), - 'eval':lambda x: eval(expand(x)), 'load':lambda fn: load(fn), 'call/cc':callcc, - 'open-input-file':open,'close-input-port':lambda p: p.file.close(), - 'open-output-file':lambda f:open(f,'w'), 'close-output-port':lambda p: p.close(), - 'eof-object?':lambda x:x is eof_object, 'read-char':readchar, - 'read':read, 'write':lambda x,port=sys.stdout:port.write(to_string(x)), - 'display':lambda x,port=sys.stdout:port.write(x if isa(x,str) else to_string(x))}) - return self - -isa = isinstance - -global_env = add_globals(Env()) - -################ eval (tail recursive) - -def eval(x, env=global_env): - "Evaluate an expression in an environment." - while True: - if isa(x, Symbol): # variable reference - return env.find(x)[x] - elif not isa(x, list): # constant literal - return x - elif x[0] is _quote: # (quote exp) - (_, exp) = x - return exp - elif x[0] is _if: # (if test conseq alt) - (_, test, conseq, alt) = x - x = (conseq if eval(test, env) else alt) - elif x[0] is _set: # (set! var exp) - (_, var, exp) = x - env.find(var)[var] = eval(exp, env) - return None - elif x[0] is _define: # (define var exp) - (_, var, exp) = x - env[var] = eval(exp, env) - return None - elif x[0] is _lambda: # (lambda (var*) exp) - (_, vars, exp) = x - return Procedure(vars, exp, env) - elif x[0] is _begin: # (begin exp+) - for exp in x[1:-1]: - eval(exp, env) - x = x[-1] - else: # (proc exp*) - exps = [eval(exp, env) for exp in x] - proc = exps.pop(0) - if isa(proc, Procedure): - x = proc.exp - env = Env(proc.parms, exps, proc.env) - else: - return proc(*exps) - -################ expand - -def expand(x, toplevel=False): - "Walk tree of x, making optimizations/fixes, and signaling SyntaxError." - require(x, x!=[]) # () => Error - if not isa(x, list): # constant => unchanged - return x - elif x[0] is _quote: # (quote exp) - require(x, len(x)==2) - return x - elif x[0] is _if: - if len(x)==3: x = x + [None] # (if t c) => (if t c None) - require(x, len(x)==4) - return map(expand, x) - elif x[0] is _set: - require(x, len(x)==3); - var = x[1] # (set! non-var exp) => Error - require(x, isa(var, Symbol), "can set! only a symbol") - return [_set, var, expand(x[2])] - elif x[0] is _define or x[0] is _definemacro: - require(x, len(x)>=3) - _def, v, body = x[0], x[1], x[2:] - if isa(v, list) and v: # (define (f args) body) - f, args = v[0], v[1:] # => (define f (lambda (args) body)) - return expand([_def, f, [_lambda, args]+body]) - else: - require(x, len(x)==3) # (define non-var/list exp) => Error - require(x, isa(v, Symbol), "can define only a symbol") - exp = expand(x[2]) - if _def is _definemacro: - require(x, toplevel, "define-macro only allowed at top level") - proc = eval(exp) - require(x, callable(proc), "macro must be a procedure") - macro_table[v] = proc # (define-macro v proc) - return None # => None; add v:proc to macro_table - return [_define, v, exp] - elif x[0] is _begin: - if len(x)==1: return None # (begin) => None - else: return [expand(xi, toplevel) for xi in x] - elif x[0] is _lambda: # (lambda (x) e1 e2) - require(x, len(x)>=3) # => (lambda (x) (begin e1 e2)) - vars, body = x[1], x[2:] - require(x, (isa(vars, list) and all(isa(v, Symbol) for v in vars)) - or isa(vars, Symbol), "illegal lambda argument list") - exp = body[0] if len(body) == 1 else [_begin] + body - return [_lambda, vars, expand(exp)] - elif x[0] is _quasiquote: # `x => expand_quasiquote(x) - require(x, len(x)==2) - return expand_quasiquote(x[1]) - elif isa(x[0], Symbol) and x[0] in macro_table: - return expand(macro_table[x[0]](*x[1:]), toplevel) # (m arg...) - else: # => macroexpand if m isa macro - return map(expand, x) # (f arg...) => expand each - -def require(x, predicate, msg="wrong length"): - "Signal a syntax error if predicate is false." - if not predicate: raise SyntaxError(to_string(x)+': '+msg) - -_append, _cons, _let = map(Sym, "append cons let".split()) - -def expand_quasiquote(x): - """Expand `x => 'x; `,x => x; `(,@x y) => (append x y) """ - if not is_pair(x): - return [_quote, x] - require(x, x[0] is not _unquotesplicing, "can't splice here") - if x[0] is _unquote: - require(x, len(x)==2) - return x[1] - elif is_pair(x[0]) and x[0][0] is _unquotesplicing: - require(x[0], len(x[0])==2) - return [_append, x[0][1], expand_quasiquote(x[1:])] - else: - return [_cons, expand_quasiquote(x[0]), expand_quasiquote(x[1:])] - -def let(*args): - args = list(args) - x = cons(_let, args) - require(x, len(args)>1) - bindings, body = args[0], args[1:] - require(x, all(isa(b, list) and len(b)==2 and isa(b[0], Symbol) - for b in bindings), "illegal binding list") - vars, vals = zip(*bindings) - return [[_lambda, list(vars)]+map(expand, body)] + map(expand, vals) - -macro_table = {_let:let} ## More macros can go here - -eval(parse("""(begin - -(define-macro and (lambda args - (if (null? args) #t - (if (= (length args) 1) (car args) - `(if ,(car args) (and ,@(cdr args)) #f))))) - -;; More macros can also go here - -)""")) - -if __name__ == '__main__': - repl() - diff --git a/pytudes/py/lispytest.py b/pytudes/py/lispytest.py deleted file mode 100644 index bed5307..0000000 --- a/pytudes/py/lispytest.py +++ /dev/null @@ -1,121 +0,0 @@ - -################ Tests for lis.py and lispy.py - -lis_tests = [ - ("(quote (testing 1 (2.0) -3.14e159))", ['testing', 1, [2.0], -3.14e159]), - ("(+ 2 2)", 4), - ("(+ (* 2 100) (* 1 10))", 210), - ("(if (> 6 5) (+ 1 1) (+ 2 2))", 2), - ("(if (< 6 5) (+ 1 1) (+ 2 2))", 4), - ("(define x 3)", None), ("x", 3), ("(+ x x)", 6), - ("(begin (define x 1) (set! x (+ x 1)) (+ x 1))", 3), - ("((lambda (x) (+ x x)) 5)", 10), - ("(define twice (lambda (x) (* 2 x)))", None), ("(twice 5)", 10), - ("(define compose (lambda (f g) (lambda (x) (f (g x)))))", None), - ("((compose list twice) 5)", [10]), - ("(define repeat (lambda (f) (compose f f)))", None), - ("((repeat twice) 5)", 20), ("((repeat (repeat twice)) 5)", 80), - ("(define fact (lambda (n) (if (<= n 1) 1 (* n (fact (- n 1))))))", None), - ("(fact 3)", 6), - ("(fact 50)", 30414093201713378043612608166064768844377641568960512000000000000), - ("(define abs (lambda (n) ((if (> n 0) + -) 0 n)))", None), - ("(list (abs -3) (abs 0) (abs 3))", [3, 0, 3]), - ("""(define combine (lambda (f) - (lambda (x y) - (if (null? x) (quote ()) - (f (list (car x) (car y)) - ((combine f) (cdr x) (cdr y)))))))""", None), - ("(define zip (combine cons))", None), - ("(zip (list 1 2 3 4) (list 5 6 7 8))", [[1, 5], [2, 6], [3, 7], [4, 8]]), - ("""(define riff-shuffle (lambda (deck) (begin - (define take (lambda (n seq) (if (<= n 0) (quote ()) (cons (car seq) (take (- n 1) (cdr seq)))))) - (define drop (lambda (n seq) (if (<= n 0) seq (drop (- n 1) (cdr seq))))) - (define mid (lambda (seq) (/ (length seq) 2))) - ((combine append) (take (mid deck) deck) (drop (mid deck) deck)))))""", None), - ("(riff-shuffle (list 1 2 3 4 5 6 7 8))", [1, 5, 2, 6, 3, 7, 4, 8]), - ("((repeat riff-shuffle) (list 1 2 3 4 5 6 7 8))", [1, 3, 5, 7, 2, 4, 6, 8]), - ("(riff-shuffle (riff-shuffle (riff-shuffle (list 1 2 3 4 5 6 7 8))))", [1,2,3,4,5,6,7,8]), - ] - -lispy_tests = [ - ("()", SyntaxError), ("(set! x)", SyntaxError), - ("(define 3 4)", SyntaxError), - ("(quote 1 2)", SyntaxError), ("(if 1 2 3 4)", SyntaxError), - ("(lambda 3 3)", SyntaxError), ("(lambda (x))", SyntaxError), - ("""(if (= 1 2) (define-macro a 'a) - (define-macro a 'b))""", SyntaxError), - ("(define (twice x) (* 2 x))", None), ("(twice 2)", 4), - ("(twice 2 2)", TypeError), - ("(define lyst (lambda items items))", None), - ("(lyst 1 2 3 (+ 2 2))", [1,2,3,4]), - ("(if 1 2)", 2), - ("(if (= 3 4) 2)", None), - ("(define ((account bal) amt) (set! bal (+ bal amt)) bal)", None), - ("(define a1 (account 100))", None), - ("(a1 0)", 100), ("(a1 10)", 110), ("(a1 10)", 120), - ("""(define (newton guess function derivative epsilon) - (define guess2 (- guess (/ (function guess) (derivative guess)))) - (if (< (abs (- guess guess2)) epsilon) guess2 - (newton guess2 function derivative epsilon)))""", None), - ("""(define (square-root a) - (newton 1 (lambda (x) (- (* x x) a)) (lambda (x) (* 2 x)) 1e-8))""", None), - ("(> (square-root 200.) 14.14213)", True), - ("(< (square-root 200.) 14.14215)", True), - ("(= (square-root 200.) (sqrt 200.))", True), - ("""(define (sum-squares-range start end) - (define (sumsq-acc start end acc) - (if (> start end) acc (sumsq-acc (+ start 1) end (+ (* start start) acc)))) - (sumsq-acc start end 0))""", None), - ("(sum-squares-range 1 3000)", 9004500500), ## Tests tail recursion - ("(call/cc (lambda (throw) (+ 5 (* 10 (throw 1))))) ;; throw", 1), - ("(call/cc (lambda (throw) (+ 5 (* 10 1)))) ;; do not throw", 15), - ("""(call/cc (lambda (throw) - (+ 5 (* 10 (call/cc (lambda (escape) (* 100 (escape 3)))))))) ; 1 level""", 35), - ("""(call/cc (lambda (throw) - (+ 5 (* 10 (call/cc (lambda (escape) (* 100 (throw 3)))))))) ; 2 levels""", 3), - ("""(call/cc (lambda (throw) - (+ 5 (* 10 (call/cc (lambda (escape) (* 100 1))))))) ; 0 levels""", 1005), - ("(* 1i 1i)", -1), ("(sqrt -1)", 1j), - ("(let ((a 1) (b 2)) (+ a b))", 3), - ("(let ((a 1) (b 2 3)) (+ a b))", SyntaxError), - ("(and 1 2 3)", 3), ("(and (> 2 1) 2 3)", 3), ("(and)", True), - ("(and (> 2 1) (> 2 3))", False), - ("(define-macro unless (lambda args `(if (not ,(car args)) (begin ,@(cdr args))))) ; test `", None), - ("(unless (= 2 (+ 1 1)) (display 2) 3 4)", None), - (r'(unless (= 4 (+ 1 1)) (display 2) (display "\n") 3 4)', 4), - ("(quote x)", 'x'), - ("(quote (1 2 three))", [1, 2, 'three']), - ("'x", 'x'), - ("'(one 2 3)", ['one', 2, 3]), - ("(define L (list 1 2 3))", None), - ("`(testing ,@L testing)", ['testing',1,2,3,'testing']), - ("`(testing ,L testing)", ['testing',[1,2,3],'testing']), - ("`,@L", SyntaxError), - ("""'(1 ;test comments ' - ;skip this line - 2 ; more ; comments ; ) ) - 3) ; final comment""", [1,2,3]), - ] - -def test(tests, name=''): - "For each (exp, expected) test case, see if eval(parse(exp)) == expected." - fails = 0 - for (x, expected) in tests: - try: - result = eval(parse(x)) - print x, '=>', to_string(result) - ok = (result == expected) - except Exception as e: - print x, '=raises=>', type(e).__name__, e - ok = issubclass(expected, Exception) and isinstance(e, expected) - if not ok: - fails += 1 - print 'FAIL!!! Expected', expected - print '%s %s: %d out of %d tests fail.' % ('*'*45, name, fails, len(tests)) - -if __name__ == '__main__': - from lis import * - test(lis_tests, 'lis.py') - from lispy import * - test(lis_tests+lispy_tests, 'lispy.py') - diff --git a/pytudes/py/pal.py b/pytudes/py/pal.py deleted file mode 100644 index db8f509..0000000 --- a/pytudes/py/pal.py +++ /dev/null @@ -1,154 +0,0 @@ -import string, random, os, re, bisect - -"""Produce Panama-ish Palindromes. Copyright (C) 2002, Peter Norvig. -See http://www.norvig.com/license.html and http://www.norvig.com/pal-alg.html""" - -def is_panama(p): - "Test if p is a Panama-ish palindrome." - def is_unique(seq): return len(seq) == len(dict(zip(seq, seq))) - return (p.endswith('Panama') and is_palindrome(p) - and is_unique([s.strip() for s in p.split(',')])) - -def is_palindrome(phrase): - "Test if a phrase is a palindrome." - cphrase = canonical(phrase) - return cphrase == reverse(cphrase) - -def canonical(word, sub=re.compile('[^A-Za-z0-9]').sub): - "The canonical form for comparing: lowercase alphanumerics." - return sub('', word).lower() - -def read_dict(filename='npdict.txt'): - "Read the file into global variables _fw and _bw and _truename." - global _fw, _bw, _truename - _fw, _bw, _truename = [], [], {'': ''} - for word in open(filename).read().splitlines(): - w = canonical(word) - _fw.append(w) - _bw.append(reverse(w)) - _truename[w] = word - _fw.sort(); _bw.sort() - return len(_fw), len(_bw), len(_truename) - -def update(obj, **entries): obj.__dict__.update(entries); return obj - -class PalDict: - """A dictionary from which you can find canonical words that start or end - with a given canonical substring, and find the true name of a - canonical word.""" - def __init__(self, fw=None, bw=None, truename=None): - update(self, fw=fw or _fw, bw=bw or _bw, truename=truename or _truename) - - def startswith(self, prefix, k=100): - """Return up to k canonical words that start with prefix. - If there are more than k, choose from them at random.""" - return k_startingwith(k, self.fw, prefix) - - def endswith(self, suffix, k=100): - """Return up to k canonical words that end with suffix. - If there are more than k, choose from them at random. - Both the suffix and the word returned are reversed.""" - return k_startingwith(k, self.bw, suffix) - -def k_startingwith(k, words, prefix): - """Choose up to k words that match the prefix (choose randomly if > k).""" - start = bisect.bisect(words, prefix) - end = bisect.bisect(words, prefix + 'zzzz') - n = end - start - if k >= n: - results = words[start:end] - random.shuffle(results) - else: # Should really try to avoid duplicates - results = [words[random.randrange(start, end)] for i in range(k)] - return results - -class Panama: - def __init__(self, L='A man, a plan', R='a canal, Panama', dict=None): - left = [canonical(w) for w in L.split(', ')] - right = [canonical(reverse(w)) for w in reverse(R.split(', '))] - update(self, left=left, right=right, dict=dict or PalDict(), best=0, - seen={}, diff=len(''.join(left)) - len(''.join(right))) - for word in left + map(reverse, right): - self.seen[word] = 1 - - def missing(self, k=20): - """Return the substring that is missing, and candidate words.""" - if self.diff >= 0: # Left is longer, missing on right - substr = self.left[-1][-self.diff:] - return substr, self.dict.endswith(substr, k) - else: # Right is longer, missing on left - substr = self.right[-1][self.diff:] - return substr, self.dict.startswith(substr, k) - - def search(self, k=200): - "Search for palindromes; consider at most k words at each level." - self.stack = [self.missing(k)] - while self.stack: - substr, words = self.stack[-1] - if is_palindrome(substr): - self.report() - if words: - self.extend(words.pop(), k) - elif not self.backtrack(): - return - - def extend(self, word, k): - "Add a new word (unless we've already seen it)." - if self.diff >= 0: # Left is longer, add to right - fword = reverse(word) - if fword in self.seen: return - self.diff -= len(fword) - self.seen[fword] = 1 - self.right.append(word) - self.stack.append(self.missing(k)) - else: # Right is longer, add to left - if word in self.seen: return - self.diff += len(word) - self.seen[word] = 1 - self.left.append(word) - self.stack.append(self.missing(k)) - - def backtrack(self): - "Remove the last word added; return 0 if can't backtrack" - if self.diff >= 0: # Left is longer, pop from left - if not self.left: return 0 - word = self.left.pop() - self.diff -= len(word) - del self.seen[word] - else: # Right is longer, pop from right - if not self.right: return 0 - word = self.right.pop() - self.diff += len(word) - del self.seen[reverse(word)] - self.stack.pop() - return 1 - - def report(self): - "Write current state to log file." - if len(self) > self.best + 200: - self.best = len(self) - print self.best - self.bestphrase = str(self) - assert is_panama(self.bestphrase) - f = open('pallog%d.txt' % os.getpid(), 'w') - f.write(self.bestphrase + '\n') - f.close() - - def __len__(self): - return len(self.left) + len(self.right) - - def __str__(self): - truename = self.dict.truename - lefts = [truename[w] for w in self.left] - rights = [truename[reverse(w)] for w in reverse(self.right[:])] - return ', '.join(lefts + ['*****'] + rights) - -def reverse(x): - "Reverse a list or string." - if type(x) == type(''): - return ''.join(reverse(list(x))) - else: - x.reverse() - return x - -if __name__ == '__main__': read_dict(); p = Panama(); p.search() diff --git a/pytudes/py/pal2.py b/pytudes/py/pal2.py deleted file mode 100644 index 9436ead..0000000 --- a/pytudes/py/pal2.py +++ /dev/null @@ -1,262 +0,0 @@ -import random, re, bisect, time - -"""Produce Panama-ish Palindromes. Copyright (C) 2002-2008, Peter Norvig.""" - -################ Checking for Palindromes - -def is_panama(s): - "Test if string s is a Panama-ish palindrome." - return is_palindrome(s) and is_unique(phrases(s)) - -def is_palindrome(s): - "Test if a string is a palindrome." - s1 = canonical(s) - return s1 == reversestr(s1) - -def phrases(s): - "Break a string s into comma-separated phrases." - return [phrase.strip() for phrase in s.split(',')] - -def canonical(word, sub=re.compile('''[-* \t\n\r.,;!?:()`"']''').sub): - "The canonical form for comparing: lowercase, no blanks or punctuation." - return sub('', word).lower() - -################ Utilities - -def reversestr(x): - "Reverse a string." - return x[::-1] - -def is_unique(seq): - "Return true if seq has no duplicate elements." - return len(seq) == len(set(seq)) - -def update(obj, **entries): - "Change attributes of obj, according to the keyword args." - obj.__dict__.update(entries) - return obj - -################ Reading in a dictionary - -class PalDict: - """A dictionary from which you can find canonical words that start or end - with a given canonical substring, and find the true name of a - canonical word with d.truename[canonicalword].""" - - def __init__(self, k=1000, filename='npdict.txt'): - words, rwords, truename = [], [], {'': '', 'panama': 'Panama!'} - for tword in open(filename).read().splitlines(): - word = canonical(tword) - words.append(word) - rwords.append(reversestr(word)) - truename[word] = tword - words.sort() - rwords.sort() - update(self, k=k, words=words, rwords=rwords, truename=truename, - reversibles={}, rangek=range(k), tryharder=False) - - def startswith(self, prefix): - """Return up to k canonical words that start with prefix. - If there are more than k, choose from them at random.""" - return self._k_startingwith(self.words, prefix) - - def endswith(self, rsuffix): - """Return up to k canonical words that end with the reversed suffix. - If you want words ending in 'ing', ask for d.endswith('gni'). - If there are more than k, choose from them at random.""" - return map(reversestr, self._k_startingwith(self.rwords, rsuffix)) - - def __contains__(self, word): - return word in self.truename - - def reversible_words(self): - "Find words that have a reverse in the dict, like {'Camus': 'Sumac'}" - if not self.reversibles: - reversibles = self.reversibles - for rw in self.rwords: - if rw in self: - w = reversestr(rw) - if w != rw and w not in reversibles: - reversibles[w] = rw - self.reversibles = reversibles - return self.reversibles - - def _k_startingwith(self, words, prefix): - start = bisect.bisect_left(words, prefix) - end = bisect.bisect(words, prefix + 'zzzz') - n = end - start - if self.k >= n: # get all the words that start with prefix - results = words[start:end] - else: # sample from words starting with prefix - indexes = random.sample(xrange(start, end), self.k) - results = [words[i] for i in indexes] - random.shuffle(results) - ## Consider words that are prefixes of the prefix. - ## This is very slow, so don't use it until late in the game. - if self.tryharder: - for i in range(3, len(prefix)): - w = prefix[0:i] - if ((words == self.words and w in self.truename) or - (words == self.rwords and reversestr(w) in self.truename)): - results.append(w) - return results - -paldict = PalDict() - -def anpdictshort(): - "Find the words that are valid when every phrase must start with 'a'" - def segment(word): return [s for s in word.split('a') if s] - def valid(word): return all(reversestr(s) in segments for s in segment(word)) - words = map(canonical, file('anpdict.txt')) - segments = set(s for w in words for s in segment(canonical(w))) - valid_words = [paldict.truename[w] for w in words if valid(w)] - file('anpdict-short.txt', 'w').write('\n'.join(valid_words)) - -################ Search for a palindrome - -class Panama: - def __init__(self, L='A man, a plan', R='a canal, Panama', dict=paldict): - ## .left and .right hold lists of canonical words - ## .diff holds the number of characters that are not matched, - ## positive for words on left, negative for right. - ## .stack holds (action, side, arg) tuples - update(self, left=[], right=[], best=0, seen={}, diff=0, stack=[], - used_reversibles=False, starttime=time.clock(), dict=dict) - for word in L.split(','): - self.add('left', canonical(word)) - for rword in reversestr(R).split(','): - self.add('right', canonical(reversestr(rword))) - self.consider_candidates() - - def search(self, steps=50000000): - "Search for palindromes." - for _ in xrange(steps): - if not self.stack: - return 'done' - action, dir, substr, arg = self.stack[-1] - if action == 'added': # undo the last word added - self.remove(dir, arg) - elif action == 'trying' and arg: # try the next word if there is one - self.add(dir, arg.pop()) and self.consider_candidates() - elif action == 'trying' and not arg: # otherwise backtrack - self.stack.pop() - else: - raise ValueError(action) - - def add(self, dir, word): - "add a word" - if word in self.seen: - return False - else: - getattr(self, dir).append(word) - self.diff += factor[dir] * len(word) - self.seen[word] = True - self.stack.append(('added', dir, '?', word)) - return True - - def remove(self, dir, word): - "remove a word" - oldword = getattr(self, dir).pop() - assert word == oldword - self.diff -= factor[dir] * len(word) - del self.seen[word] - self.stack.pop() - - def consider_candidates(self): - """Push a new state with a set of candidate words onto stack.""" - if self.diff > 0: # Left is longer, consider adding on right - dir = 'right' - substr = self.left[-1][-self.diff:] - candidates = self.dict.endswith(substr) - elif self.diff < 0: # Right is longer, consider adding on left - dir = 'left' - substr = reversestr(self.right[-1][0:-self.diff]) - candidates = self.dict.startswith(substr) - else: # Both sides are same size - dir = 'left' - if not self.used_reversibles: - self.report() - self.add_reversibles() - substr = '' - candidates = self.dict.startswith('') - if substr == reversestr(substr): - self.report() - self.stack.append(('trying', dir, substr, candidates)) - - def add_reversibles(self): - "Add in reversible words." - print 'using reversibles ...' - for (word, rword) in self.dict.reversible_words().items(): - if word not in self.seen and rword not in self.seen: - self.add('left', word) - self.add('right', rword) - self.used_reversibles = True - self.stack = [] - print '...done' - - def report(self): - "Report a new palindrome to log file (if it is sufficiently big)." - N = len(self) - if N > 13333: - self.dict.tryharder = True - if N > self.best and (N > 12500 or N > self.best+500): - self.best = len(self) - self.bestphrase = str(self) - print '%5d phrases (%5d words) in %3d seconds' % ( - self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime) - assert is_panama(self.bestphrase) - f = open('pallog%d.txt' % (id(self) % 10000), 'w') - f.write(self.bestphrase + '\n') - f.close() - - def __len__(self): - return len(self.left) + len(self.right) - - def __str__(self): - truename = self.dict.truename - lefts = [truename[w] for w in self.left] - rights =[truename[w] for w in self.right] - return ', '.join(lefts + rights[::-1]) - -factor = {'left': +1, 'right': -1} - -# Note that we only allow one truename per canonical name. Occasionally -# this means we miss a good word (as in "a node" vs. "an ode"), but there -# are only 665 of these truename collisions, and most of them are of the -# form "a mark-up" vs. "a markup" so it seemed better to disallow them. - -################ Unit Tests - -def tests(p=Panama()): - assert is_panama('A man, a plan, a canal, Panama.') - assert is_panama('''A (man), a plan,,;, a ```canal?'' -- Panama!''') - assert not is_panama('A man, a plan, a radar, a canal, Panama.') - assert is_palindrome('A man, a plan, a canal, Panama.') - assert is_palindrome('radar, radar? radar!') - assert not is_palindrome('radars') - assert phrases('A man, a plan, Panama') == ['A man', 'a plan', 'Panama'] - assert canonical('A man, a plan, a canal, Panama') == 'amanaplanacanalpanama' - assert reversestr('foo') == 'oof' - assert is_unique([1, 2, 3]) - assert not is_unique([1, 2, 2]) - d = p.dict - def sameset(a, b): return set(a) == set(b) - assert 'panama' in d - assert d.words[0] in d - assert d.words[-1] in d - assert sameset(d.startswith('aword'), ['awording', 'awordbreak', - 'awordiness', 'awordage', 'awordplay', 'awordlore', 'awordbook', - 'awordlessness', 'aword', 'awordsmith']) - assert sameset(d.endswith('ytisob'), ['aglobosity', 'averbosity', - 'asubglobosity', 'anonverbosity', 'agibbosity']) - d.tryharder = True - assert sameset(d.startswith('oklahoma'), ['oklahoma', 'okla']) - d.tryharder = False - assert d.startswith('oklahoma') == ['oklahoma'] - assert d.startswith('fsfdsfdsfds') == [] - print 'all tests pass' - -if __name__ == '__main__': - p = Panama(); - tests(p) - p.search() diff --git a/pytudes/py/pal3.py b/pytudes/py/pal3.py deleted file mode 100644 index 89e8571..0000000 --- a/pytudes/py/pal3.py +++ /dev/null @@ -1,170 +0,0 @@ -from collections import Counter, deque -import re - -class PhraseDict(dict): - """A dictionary of {letters: phrase}, such as {'donaldeknuth': 'Donald E. Knuth'}, with: - .prefixes: Counter of {'pre': n} where n is the number of keys that start with 'pre' - .suffixes: Counter of {'xes': n} where n is the number of keys that end with 'xes'""" - def __init__(self, phrases): - for phrase in phrases: - phrase = phrase.strip() - self[letters(phrase)] = phrase - self.prefixes = Counter(x for p in self for x in prefixes(p)) - self.suffixes = Counter(x for p in self for x in suffixes(p)) - -def prefixes(phrase): return [phrase[:i] for i in range(1, len(phrase) + 1)] - -def suffixes(phrase): return [phrase[-i:] for i in range(1, len(phrase) + 1)] - -def letters(phrase, sub=re.compile(r'[\W]+').sub): - "Remove all the non-letters from phrase; return lowercase version." - return sub('', phrase).lower() - -DICT = PhraseDict(open('npdict.txt')) - -class Panama: - """Panama represents a palindrome, or a state in searching for one. - It has .left and .right to hold the phrases that are chosen, - and .L and .R to hold the current partial phrases in the middle (still working on these). - Also, a .set of all complete phrases, and the .dict of allowable phrases to choose from.""" - - def __init__(self, left=['aman', 'aplan'], L='aca', R='', right=['acanal', 'panama'], dict=DICT): - assert cat(left + [L]) == cat([R] + right)[::-1] - self.left = list(left) # list of complete phrases on left - self.L = L # an incomplete phrase on left - self.R = R # an incomplete phrase on right - self.right = deque(right) # deque of complete phrases on right - self.dict = dict # a {letters: actual_phrase} mapping - self.set = set(left + right) # a set of all complete phrases in palindrome - self.best = [] # list of phrases in longest palindrome found - self.Nshown = 0 # the number of phrases shown in the previous printout - self.i = 0 # the number of steps taken in the search - self.check() - - def __str__(self): return self.original_phrases(self.best) - - def original_phrases(self, phrases): return ', '.join(self.dict[phrase] for phrase in phrases) - - def search(self, steps=10**5): - """Depth-first search for palindromes. From the current state, find all applicable actions. - Do the first one, and put on the stack reminders to undo it and try the others, - but first search deeper from the result of the first action.""" - stack = [self.applicable_actions()] - for self.i in range(steps): - if not stack: - return - command = stack.pop() - if isinstance(command, UndoCommand): - self.undo(command) - elif command: - act = command.pop() - self.do(act) - self.check() - stack.extend([command, UndoCommand(act), self.applicable_actions()]) - - def do(self, act): - "Modify the current state by adding a letter, or finishing a phrase." - if act == ',': # finish phrase on left - self.set.add(self.L) - self.left.append(self.L) - self.L = '' - elif act == ';': # finish phrase on right - self.set.add(self.R) - self.right.appendleft(self.R) - self.R = '' - else: # add a letter - self.L = self.L + act - self.R = act + self.R - - def undo(self, act): - "Modify the current state by undoing an action that was previously done." - if act == ',': # unfinish phrase on left - assert self.L == '' - self.L = self.left.pop() - self.set.remove(self.L) - elif act == ';': # unfinish phrase on right - assert self.R == '' - self.R = self.right.popleft() - self.set.remove(self.R) - else: # remove a letter - self.L = self.L[:-1] - self.R = self.R[1:] - - def check(self): - "Check to see if current state is a palindrome, and if so, record it and maybe print." - if not self.is_palindrome(): return - N = len(self.left) + len(self.right) - if N > len(self.best): - self.best = self.left + list(self.right) - if N - self.Nshown > 1000 or (N > 14000 and N - self.Nshown > 100) or N > 14500: - self.Nshown = N - print(self.report()) - - def report(self): - N = len(self.best) - nwords = N + sum(self.dict[p].count(' ') for p in self.best) - nletters = sum(len(p) for p in self.best) - return ('Pal: {:6,d} phrases, {:6,d} words, {:6,d} letters (at step {:,d})' - .format(N, nwords, nletters, self.i+1)) - - def applicable_actions(self): - L, R, D = self.L, self.R, self.dict - actions = [] - - def score(A): return D.prefixes[L+A] * D.suffixes[A+R] - if self.is_allowed(L): - actions.append(',') - if self.is_allowed(R): - actions.append(';') - for A in sorted(alphabet, key=score): - if score(A) > 0: - actions.append(A) - - return actions - - def is_allowed(self, phrase): return phrase in self.dict and phrase not in self.set - - def is_palindrome(self): - "Is this a palindrome? (Does any extra .L or .R match the other side?)" - return ((self.L == '' and self.left[-1].endswith(self.R)) or - (self.R == '' and self.right[0].startswith(self.L))) - -alphabet = 'abcdefghijklmnopqrstuvwxyz' -cat = ''.join -UndoCommand = str -DoCommand = list - -################ Unit Tests - -def test1(): - assert prefixes('hello') == ['h', 'he', 'hel', 'hell', 'hello'] - assert suffixes('hello') == ['o', 'lo', 'llo', 'ello', 'hello'] - assert letters('a man') == 'aman' - assert letters('an elk') == 'anelk' - assert letters('Mr. T') == 'mrt' - assert letters('Donald E. Knuth') == 'donaldeknuth' - assert len(DICT) == 125512 - assert 'panama' in DICT - assert 'aman' in DICT - assert 'threemen' not in DICT - assert DICT['acanal'] == 'a canal' - return 'ok' - -def test2(): - p1 = Panama() - assert p1.is_palindrome() - assert str(p1) == 'a man, a plan, a canal, Panama' - p2 = Panama(['aman','aplan'], 'acadd','dd', ['acanal', 'panama']) - assert not p2.is_palindrome() - p3 = Panama(['maya'], '', '', ['ayam']) - assert p3.is_palindrome() - assert str(p3) == 'Maya, a yam' - return 'ok' - -if __name__ == '__main__': - p = Panama(); - test1() - test2() - p.search(10**6) - print(p.report()) - print(str(p)) diff --git a/pytudes/py/parse.py b/pytudes/py/parse.py deleted file mode 100644 index 8c7e4ea..0000000 --- a/pytudes/py/parse.py +++ /dev/null @@ -1,52 +0,0 @@ -grammar = { - 'Noun': ['stench', 'wumpus'], - 'Verb': ['is', 'smell'], - 'Adjective': ['dead', 'smelly'], - 'Adverb': ['left', 'back'], - 'Pronoun': ['me', 'you'], - 'Name': ['John', 'Mary'], - 'Article': ['the', 'a'], - 'Preposition': ['to', 'in'], - 'Conjunction': ['and', 'or'], - 'Digit': ['0', '1'], - - 'S': [['NP', 'VP'], ['S', 'Comjunction', 'S']], - 'NP': ['Pronoun', 'Noun', ['Article', 'Noun'], ['Digit', 'Digit'], - ['NP', 'PP'], ['NP', 'RelClause']], - 'VP': ['Verb', ['VP', 'NP'], ['VP', 'Adjective'], ['VP', 'PP'], - ['VP', 'Adverb']], - 'PP': [['Preposition', 'NP']], - 'RelClause': [['that', 'VP']] - } - - -def parse(forest, grammar): - if len(forest) == 1 and category(forest[0]) == 'S': - return forest[0] - for i in range(len(forest)): - for lhs in grammar.keys(): - for rhs in grammar[lhs]: - rhs = mklist(rhs) - n = len(rhs) - subsequence = forest[i:i+n] - if match(subsequence, rhs): - print subsequence, lhs, '=>', rhs - forest2 = forest[:] - forest2[i:i+n] = [(lhs, subsequence)] - result = parse(forest2, grammar) - if result != None: - return result - return None - -def mklist(x): - if type(x) == type([]): return x - else: return [x] - -def match(forest, rhs): - for i in range(len(rhs)): - if category(forest[i]) != rhs[i] and forest[i] != rhs[i]: return 0 - return 1 - -def category(forest): - if type(forest) == type(()): return forest[0] - else: return 'word' diff --git a/pytudes/py/py2html.py b/pytudes/py/py2html.py deleted file mode 100644 index 896d0de..0000000 --- a/pytudes/py/py2html.py +++ /dev/null @@ -1,110 +0,0 @@ -"""Pretty-print Python code to colorized, hyperlinked html. - -In python, do: - py2html.convert_files(['file1.py', 'file2.py', ...]) -From the shell, do: - python py2html.py *.py""" - -import re, string, time, os - - -id = r'[a-zA-Z_][a-zA-Z_0-9]*' ## RE for a Python identifier -g1, g2, g3, g4 = r'\1 \2 \3 \4'.split() ## groups for re.matches -def b(text): return '%s' % text -def i(text): return '%s' % text -def color(rgb, text): return '%s' % (rgb, text) -def link(url, anchor): return '%s' % (url, anchor) -def hilite(text, bg="ffff00"): - return '%s' % ( - bg, text, text) - -def modulelink(module, baseurl=''): - """Hyperlink to a module, either locally or on python.org""" - if module+'.py' not in local_files: - baseurl = 'http://www.python.org/doc/current/lib/module-' - return link(baseurl+module+'.html', module) - -def importer(m): - "Turn text such as 'utils, math, re' into a string of HTML links." - modules = [modulelink(mod.strip()) for mod in m.group(2).split(',')] - return (m.group(1) + ', '.join(modules) + m.group(3)) - -def find1(regex, str): - return (re.findall(regex, str) or [' '])[0] - -def convert_files(filenames, local_filenames=None, tblfile='readme.htm'): - "Convert files of python code to colorized HTML." - global local_files - local_files = local_filenames or filenames - summary_table = {} - for f in filenames: - fulltext = '\n'.join(map(string.rstrip, open(f).readlines())) - text = fulltext - for (pattern, repl) in replacements: - text = re.sub(pattern, repl, text) - text = '<>
%s
<