├── .gitignore ├── aima ├── agents.py ├── csp.py ├── doctests.py ├── games.py ├── images │ ├── .svn │ │ ├── all-wcprops │ │ ├── entries │ │ ├── prop-base │ │ │ ├── dirt05-icon.jpg.svn-base │ │ │ ├── vacuum-icon.jpg.svn-base │ │ │ └── wall-icon.jpg.svn-base │ │ └── text-base │ │ │ ├── IMAGE-CREDITS.svn-base │ │ │ ├── dirt.svg.svn-base │ │ │ ├── dirt05-icon.jpg.svn-base │ │ │ ├── makefile.svn-base │ │ │ ├── vacuum-icon.jpg.svn-base │ │ │ ├── vacuum.svg.svn-base │ │ │ └── wall-icon.jpg.svn-base │ ├── IMAGE-CREDITS │ ├── dirt.svg │ ├── dirt05-icon.jpg │ ├── makefile │ ├── vacuum-icon.jpg │ ├── vacuum.svg │ └── wall-icon.jpg ├── learning.py ├── logic.py ├── mdp.py ├── nlp.py ├── planning.py ├── probability.doctest ├── probability.py ├── rl.py ├── search.py ├── searchprob.py ├── text.py └── utils.py ├── cs101-Introduction-to-Computer-Science ├── collatz.py ├── final4.py ├── final5.py ├── final6.py ├── final_star2.py ├── final_star3.py ├── finaly6.py ├── hw2-4.py ├── hw2-5.py ├── hw2-6.py ├── hw2-7.py ├── hw2.2.py ├── hw2.3.py ├── hw2.6.py ├── hw2.7.py ├── hw3.1.py ├── hw3.2.py ├── hw3.3.py ├── hw3.4.py ├── hw3.5.py ├── hw3.6.py ├── hw3.7.py ├── hw3.8.py ├── hw4_5.py ├── hw4_6.py └── hw4_7.py ├── cs212-Design-of-Computer-Programs ├── final-1.py ├── final-2.py ├── final-3.py ├── final-4.py ├── final-5.py ├── final-6.py ├── hw1-1-rev2.py ├── hw1-1.py ├── hw1-1a-rev2.py ├── hw1-1a.py ├── hw1-2-rev2.py ├── hw1-2.py ├── hw2-1--cryptarithmatic-compiled.py ├── hw2-2--apartment-puzzle.py ├── hw2-3--subpalindome.py ├── hw3-1--json-grammar.py ├── quiz │ ├── q1-24--evaluate_poker_hand_rank.py │ ├── q1-27--deal-deck.py │ ├── q2-19--zebra-puzzle.py │ ├── q2-19.py │ ├── q2-32--cryptarithmatic.py │ ├── q2-34--cryptarithmatic-examples.py │ ├── q2_3_cryptographic_formula.py │ ├── q3-29--trace.py │ ├── q3-6--matchset.py │ └── q3-8--match-and-search.py └── wiki-code │ ├── bridge.py │ ├── cannibals.py │ ├── conditional.py │ ├── cryptarithmatic.py │ ├── decorators.py │ ├── grammar.py │ ├── pig.py │ ├── poker.py │ ├── pour.py │ ├── regex_compiler.py │ ├── regex_generator.py │ ├── regex_interpreter.py │ ├── scrabble.py │ ├── search.py │ ├── words4k.txt │ └── zebra.py ├── cs253-Web-Application-Engineering ├── app.yaml └── guestbook.py ├── cs262-Programming-Languages ├── cs262--Norvig Answers │ ├── CS262 Unit 1-v24 Parsing, Regular Expressions, Finite State Machines.pdf │ ├── CS262 Unit 3-v4 Grammar.pdf │ ├── final1-bowling.py │ ├── final1-poly.py │ ├── final3-polynomial.py │ └── parsing-code.py └── final-1.py ├── cs344-Introduction-to-Parallel-Programming ├── README.html ├── README.md ├── pip_install_numpy.py ├── pip_install_pyopencl.sh └── pyopencl_example.py ├── cs373-Programming-a-Robotic-Car ├── ai-hw2.py ├── ai_hw9.py ├── cs373 SLAM algorithm office hours.txt ├── final1.py ├── final16.py ├── final20.py ├── final3.py ├── final5.py ├── final6.py ├── final6.py.old ├── final8.py ├── hw1-4.py ├── hw1-4_submital.py ├── hw1.4.py ├── hw1.4submital.py ├── hw1.py ├── hw2-2.py ├── hw2.6.py ├── hw3.2.py ├── hw3.6.py ├── hw3.6gui.py ├── hw3_6.py ├── hw3_6orig.py ├── hw4.7.py ├── hw4_7.py ├── hw4_7_submit.py ├── hw6_1.py ├── hw6_3.py ├── quiz2-19.py ├── quiz2.19.py ├── quiz4.19.py ├── quiz4_19.py ├── quiz5_5.py ├── quiz6_21.py └── quiz6_22.py ├── cs387-Applied-Cryptography ├── hw1-4-probability-3.py └── hw1-5-one-time-pad.py ├── practice.sublime-workspace ├── practice ├── baseballcard_collection.py ├── decorators.py ├── hashtable.py ├── hosh.cpp ├── hosh.py ├── pc101.cpp ├── plotutil.py └── sort.py └── rosetta ├── heapsort.py └── quicksort.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | *.o 4 | *.exe 5 | 6 | -------------------------------------------------------------------------------- /aima/doctests.py: -------------------------------------------------------------------------------- 1 | """Run all doctests from modules on the command line. Use -v for verbose. 2 | 3 | Example usages: 4 | 5 | python doctests.py *.py 6 | python doctests.py -v *.py 7 | 8 | You can add more module-level tests with 9 | __doc__ += "..." 10 | You can add stochastic tests with 11 | __doc__ += random_tests("...") 12 | """ 13 | 14 | if __name__ == "__main__": 15 | import sys, glob, doctest 16 | args = [arg for arg in sys.argv[1:] if arg != '-v'] 17 | if not args: args = ['*.py'] 18 | modules = [__import__(name.replace('.py','')) 19 | for arg in args for name in glob.glob(arg)] 20 | for module in modules: 21 | doctest.testmod(module, report=1, optionflags=doctest.REPORT_UDIFF) 22 | summary = doctest.master.summarize() if modules else (0, 0) 23 | print '%d failed out of %d' % summary 24 | -------------------------------------------------------------------------------- /aima/images/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 28 4 | /svn/!svn/ver/8/trunk/images 5 | END 6 | dirt.svg 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 37 10 | /svn/!svn/ver/4/trunk/images/dirt.svg 11 | END 12 | wall-icon.jpg 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 42 16 | /svn/!svn/ver/8/trunk/images/wall-icon.jpg 17 | END 18 | vacuum-icon.jpg 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 44 22 | /svn/!svn/ver/8/trunk/images/vacuum-icon.jpg 23 | END 24 | dirt05-icon.jpg 25 | K 25 26 | svn:wc:ra_dav:version-url 27 | V 44 28 | /svn/!svn/ver/8/trunk/images/dirt05-icon.jpg 29 | END 30 | IMAGE-CREDITS 31 | K 25 32 | svn:wc:ra_dav:version-url 33 | V 42 34 | /svn/!svn/ver/8/trunk/images/IMAGE-CREDITS 35 | END 36 | makefile 37 | K 25 38 | svn:wc:ra_dav:version-url 39 | V 37 40 | /svn/!svn/ver/8/trunk/images/makefile 41 | END 42 | vacuum.svg 43 | K 25 44 | svn:wc:ra_dav:version-url 45 | V 39 46 | /svn/!svn/ver/8/trunk/images/vacuum.svg 47 | END 48 | -------------------------------------------------------------------------------- /aima/images/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 201 5 | http://aima-python.googlecode.com/svn/trunk/images 6 | http://aima-python.googlecode.com/svn 7 | 8 | 9 | 10 | 2007-07-13T21:57:40.824150Z 11 | 8 12 | spottedMetal 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 2679dc44-f919-0410-802c-91c6f4a87680 28 | 29 | dirt.svg 30 | file 31 | 32 | 33 | 34 | 35 | 2013-05-20T22:15:02.000000Z 36 | 2d812a1f67b4cac5a2ce115eb8b14679 37 | 2007-07-13T21:04:35.396946Z 38 | 4 39 | spottedMetal 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 14472 62 | 63 | wall-icon.jpg 64 | file 65 | 66 | 67 | 68 | 69 | 2013-05-20T22:15:02.000000Z 70 | a1c898297918bb2deb0da2c53bcfc231 71 | 2007-07-13T21:57:40.824150Z 72 | 8 73 | spottedMetal 74 | has-props 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 35979 96 | 97 | vacuum-icon.jpg 98 | file 99 | 100 | 101 | 102 | 103 | 2013-05-20T22:15:02.000000Z 104 | ac395318e94cb03026020993e55e6404 105 | 2007-07-13T21:57:40.824150Z 106 | 8 107 | spottedMetal 108 | has-props 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 1428 130 | 131 | dirt05-icon.jpg 132 | file 133 | 134 | 135 | 136 | 137 | 2013-05-20T22:15:02.000000Z 138 | cb14f61a30f8c62623f728d78c307b71 139 | 2007-07-13T21:57:40.824150Z 140 | 8 141 | spottedMetal 142 | has-props 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 1772 164 | 165 | IMAGE-CREDITS 166 | file 167 | 168 | 169 | 170 | 171 | 2013-05-20T22:15:02.000000Z 172 | 1e59f80d8c319a5542ad633c085b1acf 173 | 2007-07-13T21:57:40.824150Z 174 | 8 175 | spottedMetal 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 377 198 | 199 | makefile 200 | file 201 | 202 | 203 | 204 | 205 | 2013-05-20T22:15:02.000000Z 206 | 48a4239493d4d680104772bf24b54a2f 207 | 2007-07-13T21:57:40.824150Z 208 | 8 209 | spottedMetal 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 562 232 | 233 | vacuum.svg 234 | file 235 | 236 | 237 | 238 | 239 | 2013-05-20T22:15:02.000000Z 240 | c1b25ac1426f4a86a8f53695eeeb76df 241 | 2007-07-13T21:57:40.824150Z 242 | 8 243 | spottedMetal 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 5945 266 | 267 | -------------------------------------------------------------------------------- /aima/images/.svn/prop-base/dirt05-icon.jpg.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mime-type 3 | V 24 4 | application/octet-stream 5 | END 6 | -------------------------------------------------------------------------------- /aima/images/.svn/prop-base/vacuum-icon.jpg.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mime-type 3 | V 24 4 | application/octet-stream 5 | END 6 | -------------------------------------------------------------------------------- /aima/images/.svn/prop-base/wall-icon.jpg.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mime-type 3 | V 24 4 | application/octet-stream 5 | END 6 | -------------------------------------------------------------------------------- /aima/images/.svn/text-base/IMAGE-CREDITS.svn-base: -------------------------------------------------------------------------------- 1 | PHOTO CREDITS 2 | 3 | Image After http://www.imageafter.com/ 4 | 5 | b15woods003.jpg 6 | (Cropped to 764x764 and scaled to 50x50 to make wall-icon.jpg 7 | by Gregory Weber) 8 | 9 | Noctua Graphics, http://www.noctua-graphics.de/english/fraset_e.htm 10 | 11 | dirt05.jpg 512x512 12 | (Scaled to 50x50 to make dirt05-icon.jpg by Gregory Weber) 13 | 14 | Gregory Weber 15 | 16 | dirt.svg, dirt.png 17 | vacuum.svg, vacuum.png 18 | -------------------------------------------------------------------------------- /aima/images/.svn/text-base/dirt05-icon.jpg.svn-base: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/aima/images/.svn/text-base/dirt05-icon.jpg.svn-base -------------------------------------------------------------------------------- /aima/images/.svn/text-base/makefile.svn-base: -------------------------------------------------------------------------------- 1 | # makefile for images 2 | 3 | Sources = dirt.svg vacuum.svg 4 | 5 | Targets = $(Sources:.svg=.png) 6 | 7 | ImageScale = 50x50 8 | 9 | Temporary = tmp.jpg 10 | 11 | .PHONY: all 12 | 13 | all: $(Targets) 14 | 15 | .PHONY: clean 16 | 17 | clean: 18 | rm -f $(Targets) $(Temporary) 19 | 20 | %.png: %.svg 21 | convert -scale $(ImageScale) $< $@ 22 | 23 | %-icon.jpg: %.svg 24 | convert -scale $(ImageScale) $< $@ 25 | 26 | %-icon.jpg: %.jpg 27 | convert -scale $(ImageScale) $< $@ 28 | 29 | wall-icon.jpg: b15woods003.jpg 30 | convert -crop 764x764+0+0 $< tmp.jpg 31 | convert -resize 50x50+0+0 tmp.jpg $@ 32 | 33 | vacuum-icon.jpg: vacuum.svg 34 | convert -scale $(ImageScale) -transparent white $< $@ 35 | -------------------------------------------------------------------------------- /aima/images/.svn/text-base/vacuum-icon.jpg.svn-base: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/aima/images/.svn/text-base/vacuum-icon.jpg.svn-base -------------------------------------------------------------------------------- /aima/images/.svn/text-base/wall-icon.jpg.svn-base: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/aima/images/.svn/text-base/wall-icon.jpg.svn-base -------------------------------------------------------------------------------- /aima/images/IMAGE-CREDITS: -------------------------------------------------------------------------------- 1 | PHOTO CREDITS 2 | 3 | Image After http://www.imageafter.com/ 4 | 5 | b15woods003.jpg 6 | (Cropped to 764x764 and scaled to 50x50 to make wall-icon.jpg 7 | by Gregory Weber) 8 | 9 | Noctua Graphics, http://www.noctua-graphics.de/english/fraset_e.htm 10 | 11 | dirt05.jpg 512x512 12 | (Scaled to 50x50 to make dirt05-icon.jpg by Gregory Weber) 13 | 14 | Gregory Weber 15 | 16 | dirt.svg, dirt.png 17 | vacuum.svg, vacuum.png 18 | -------------------------------------------------------------------------------- /aima/images/dirt05-icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/aima/images/dirt05-icon.jpg -------------------------------------------------------------------------------- /aima/images/makefile: -------------------------------------------------------------------------------- 1 | # makefile for images 2 | 3 | Sources = dirt.svg vacuum.svg 4 | 5 | Targets = $(Sources:.svg=.png) 6 | 7 | ImageScale = 50x50 8 | 9 | Temporary = tmp.jpg 10 | 11 | .PHONY: all 12 | 13 | all: $(Targets) 14 | 15 | .PHONY: clean 16 | 17 | clean: 18 | rm -f $(Targets) $(Temporary) 19 | 20 | %.png: %.svg 21 | convert -scale $(ImageScale) $< $@ 22 | 23 | %-icon.jpg: %.svg 24 | convert -scale $(ImageScale) $< $@ 25 | 26 | %-icon.jpg: %.jpg 27 | convert -scale $(ImageScale) $< $@ 28 | 29 | wall-icon.jpg: b15woods003.jpg 30 | convert -crop 764x764+0+0 $< tmp.jpg 31 | convert -resize 50x50+0+0 tmp.jpg $@ 32 | 33 | vacuum-icon.jpg: vacuum.svg 34 | convert -scale $(ImageScale) -transparent white $< $@ 35 | -------------------------------------------------------------------------------- /aima/images/vacuum-icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/aima/images/vacuum-icon.jpg -------------------------------------------------------------------------------- /aima/images/wall-icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/aima/images/wall-icon.jpg -------------------------------------------------------------------------------- /aima/planning.py: -------------------------------------------------------------------------------- 1 | """Planning (Chapters 10-11) 2 | """ 3 | 4 | from __future__ import generators 5 | from utils import * 6 | import agents 7 | import math, random, sys, time, bisect, string 8 | -------------------------------------------------------------------------------- /aima/probability.doctest: -------------------------------------------------------------------------------- 1 | 2 | >>> cpt = burglary.variable_node('Alarm').cpt 3 | >>> parents = ['Burglary', 'Earthquake'] 4 | >>> event = {'Burglary': True, 'Earthquake': True} 5 | >>> print '%4.2f' % cpt.p(True, parents, event) 6 | 0.95 7 | >>> event = {'Burglary': False, 'Earthquake': True} 8 | >>> print '%4.2f' % cpt.p(False, parents, event) 9 | 0.71 10 | >>> BoolCPT({T: 0.2, F: 0.625}).p(False, ['Burglary'], event) 11 | 0.375 12 | >>> BoolCPT(0.75).p(False, [], {}) 13 | 0.25 14 | 15 | (fixme: The following test p_values which has been folded into p().) 16 | >>> cpt = BoolCPT(0.25) 17 | >>> cpt.p_values(F, ()) 18 | 0.75 19 | >>> cpt = BoolCPT({T: 0.25, F: 0.625}) 20 | >>> cpt.p_values(T, (T,)) 21 | 0.25 22 | >>> cpt.p_values(F, (F,)) 23 | 0.375 24 | >>> cpt = BoolCPT({(T, T): 0.2, (T, F): 0.31, 25 | ... (F, T): 0.5, (F, F): 0.62}) 26 | >>> cpt.p_values(T, (T, F)) 27 | 0.31 28 | >>> cpt.p_values(F, (F, F)) 29 | 0.38 30 | 31 | 32 | >>> cpt = BoolCPT({True: 0.2, False: 0.7}) 33 | >>> cpt.rand(['A'], {'A': True}) in [True, False] 34 | True 35 | >>> cpt = BoolCPT({(True, True): 0.1, (True, False): 0.3, 36 | ... (False, True): 0.5, (False, False): 0.7}) 37 | >>> cpt.rand(['A', 'B'], {'A': True, 'B': False}) in [True, False] 38 | True 39 | 40 | 41 | >>> enumeration_ask('Earthquake', {}, burglary).show_approx() 42 | 'False: 0.998, True: 0.002' 43 | 44 | 45 | >>> s = prior_sample(burglary) 46 | >>> s['Burglary'] in [True, False] 47 | True 48 | >>> s['Alarm'] in [True, False] 49 | True 50 | >>> s['JohnCalls'] in [True, False] 51 | True 52 | >>> len(s) 53 | 5 54 | 55 | 56 | >>> s = {'A': True, 'B': False, 'C': True, 'D': False} 57 | >>> consistent_with(s, {}) 58 | True 59 | >>> consistent_with(s, s) 60 | True 61 | >>> consistent_with(s, {'A': False}) 62 | False 63 | >>> consistent_with(s, {'D': True}) 64 | False 65 | 66 | >>> seed(21); p = rejection_sampling('Earthquake', {}, burglary, 1000) 67 | >>> [p[True], p[False]] 68 | [0.001, 0.999] 69 | 70 | >>> seed(71); p = likelihood_weighting('Earthquake', {}, burglary, 1000) 71 | >>> [p[True], p[False]] 72 | [0.002, 0.998] 73 | -------------------------------------------------------------------------------- /aima/rl.py: -------------------------------------------------------------------------------- 1 | """Reinforcement Learning (Chapter 21) 2 | """ 3 | 4 | from utils import * 5 | import agents 6 | 7 | class PassiveADPAgent(agents.Agent): 8 | """Passive (non-learning) agent that uses adaptive dynamic programming 9 | on a given MDP and policy. [Fig. 21.2]""" 10 | NotImplemented 11 | 12 | class PassiveTDAgent(agents.Agent): 13 | """Passive (non-learning) agent that uses temporal differences to learn 14 | utility estimates. [Fig. 21.4]""" 15 | NotImplemented 16 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/collatz.py: -------------------------------------------------------------------------------- 1 | # the collatz conjecture is that this always terminates? 2 | 3 | def collatz_steps(n): 4 | # n = any positive integer 5 | n=abs(int(n)) 6 | i=0 7 | while n != 1: 8 | i += 1 9 | if n % 2 == 0: # the % means remainder, so this tests if n is even 10 | n = n / 2 11 | else: 12 | n = 3 * n + 1 13 | return i 14 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/final4.py: -------------------------------------------------------------------------------- 1 | # the collatz conjecture is that this always terminates? 2 | 3 | def collatz_steps(n): 4 | # n = any positive integer 5 | n=abs(int(n)) 6 | i=0 7 | while n != 1: 8 | i += 1 9 | if n % 2 == 0: # the % means remainder, so this tests if n is even 10 | n = n / 2 11 | else: 12 | n = 3 * n + 1 13 | return i 14 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/final5.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | def tricky_loop(p): 5 | i=0 6 | while True: 7 | i +=1 8 | if len(p) == 0: 9 | break 10 | else: 11 | #print 'len(p)',len(p) 12 | if p[-1] == 0: 13 | #print 'p[-1]',p[-1] 14 | p.pop() # assume pop is a constant time operation 15 | else: 16 | p[-1] = 0 17 | #print 'setting p[-1] to 0' 18 | return i 19 | 20 | for N in range(100): 21 | p = [1.1*i for i in range(5,N+6)] 22 | print tricky_loop(p) 23 | 24 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/final6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def explode_list(p,n): 4 | explosion = [] 5 | for i in range(len(p)): 6 | explosion.extend([p[i]]*n) 7 | return explosion 8 | 9 | assert(explode_list([1, 2, 3], 2) == [1, 1, 2, 2, 3, 3]) 10 | 11 | assert(explode_list([1, 0, 1], 0) == []) 12 | 13 | assert(explode_list(["super","man"], 5) == ["super", "super", "super", "super", "super","man", "man", "man", "man", "man"] ) 14 | 15 | print explode_list(["super","man"], 5) 16 | 17 | assert(explode_list(["super","man"], 0) == [] ) 18 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/final_star2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.6 2 | 3 | #Spelling Correction 4 | 5 | #Double Gold Star 6 | 7 | #For this question, your goal is to build a step towards a spelling corrector, 8 | #similarly to the way Google used to respond, 9 | 10 | # "Did you mean: audacity" 11 | 12 | 13 | #when you searched for "udacity" (but now considers "udacity" a real word!). 14 | 15 | #One way to do spelling correction is to measure the edit distance between the 16 | #entered word and other words in the dictionary. Edit distance is a measure of 17 | #the number of edits required to transform one word into another word. An edit 18 | #is either: (a) replacing one letter with a different letter, (b) removing a 19 | #letter, or (c) inserting a letter. The edit distance between two strings s and 20 | #t, is the minimum number of edits needed to transform s into t. 21 | 22 | #Define a procedure, edit_distance(s, t), that takes two strings as its inputs, 23 | #and returns a number giving the edit distance between those strings. 24 | 25 | #Note: it is okay if your edit_distance procedure is very expensive, and does 26 | #not work on strings longer than the ones shown here. 27 | 28 | #The built-in python function min() returns the mininum of all its arguments. 29 | 30 | #print min(1,2,3) 31 | #>>> 1 32 | 33 | def edit_distance(s,t): 34 | N,M=len(s),len(t) 35 | cm = [range(M+1)]+[[i]+[0]*(M) for i in range(1,N+1)] 36 | #import pprint 37 | #pprint.pprint(cm) 38 | for i in range(N): 39 | for j in range(M): 40 | #print i,j 41 | cm[i+1][j+1] = min(cm[i][j+1]+1, # del s[i] 42 | cm[i][j]+(s[i]!=t[j]), # replace cs w/ ct if ne 43 | cm[i+1][j]+1) # del t[i] 44 | #pprint.pprint(cm) 45 | return cm[N][M] 46 | 47 | print edit_distance("A man, a plan, a canal - Panama!", "Doc, note: I dissent. A fast never prevents a fatness. I diet on cod.") 48 | 49 | #For example: 50 | 51 | # Delete the 'a' 52 | #print edit_distance('audacity', 'udacity') 53 | #>>> 1 54 | 55 | # Delete the 'a', replace the 'u' with 'U' 56 | #print edit_distance('audacity', 'Udacity') 57 | #>>> 2 58 | 59 | # Five replacements 60 | #print edit_distance('peter', 'sarah') 61 | #>>> 5 62 | 63 | # One deletion 64 | #print edit_distance('pete', 'peter') 65 | #>>> 1 66 | 67 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/finaly6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def explode_list(p,n): 4 | explosion = [] 5 | for i in range(len(p)): 6 | explosion.extend([p[i]]*n) 7 | return explosion 8 | 9 | assert(explode_list([1, 2, 3], 2) == [1, 1, 2, 2, 3, 3]) 10 | 11 | assert(explode_list([1, 0, 1], 0) == []) 12 | 13 | assert(explode_list(["super","man"], 5) == ["super", "super", "super", "super", "super","man", "man", "man", "man", "man"] ) 14 | 15 | assert(explode_list(["super","man"], 0) == [] ) 16 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2-4.py: -------------------------------------------------------------------------------- 1 | def countdown(N): 2 | """ 3 | Examples: 4 | >>> countdown(3) 5 | 3 6 | 2 7 | 1 8 | Blastoff! 9 | """ 10 | for i in range(N,0,-1): 11 | print i 12 | print 'Blastoff!' 13 | 14 | def _test(): 15 | import doctest 16 | doctest.testmod(verbose=True) 17 | 18 | if __name__ == "__main__": 19 | _test() 20 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2-5.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | # 0 is neither positive nor negative, http://en.wikipedia.org/wiki/Integer 4 | 5 | N=random.randint(1,1e7) 6 | 7 | 8 | I=[] 9 | I+=[0] 10 | #I+=[[0,0,0]] 11 | for N in range(1,int(1e7)): 12 | I+=[0] 13 | # I+=[[0,0,0]] 14 | # n=N 15 | # i = 0 16 | # while i <= n: 17 | # i = i+1 18 | # I[N][0]=i 19 | # #print 'loop 1 concluded with N={N:6d} \ti={i:6d} \tn={n:6d}'.format(N=N,i=i,n=n) 20 | 21 | # n=N 22 | # i = 1 23 | # while True: 24 | # i = i*2 25 | # n = n+1 26 | # if i > n: 27 | # break 28 | # I[N][1]=i 29 | # #print 'loop 2 N={N:6d} \ti={i:6d} \tn={n:6d}'.format(N=N,i=i,n=n) 30 | 31 | n=N 32 | i=1 33 | while n != 1: 34 | i+=1 35 | if n % 2 == 0: # n is even 36 | n = n/2 37 | else: 38 | n = 3*n + 1 39 | # I[N][0]=i 40 | I[N]=i 41 | if N%1000==0: 42 | print 'loop 3 N={N:6d} \ti={i:6d} \tn={n:6d}'.format(N=N,i=i,n=n) 43 | 44 | 45 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2-6.py: -------------------------------------------------------------------------------- 1 | def find_last(t,s): 2 | """ 3 | Example: 4 | >>> find_last('aaaa','a') 5 | 3 6 | >>> find_last('hello world','war') 7 | -1 8 | """ 9 | return t.rfind(s) 10 | 11 | def _test(): 12 | import doctest 13 | doctest.testmod(verbose=True) 14 | 15 | if __name__ == "__main__": 16 | _test() 17 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2-7.py: -------------------------------------------------------------------------------- 1 | def print_multiplication_table(N): 2 | """ 3 | Example: 4 | >>> print_multiplication_table(2) 5 | 1*1=1 6 | 1*2=2 7 | 2*1=2 8 | 2*2=4 9 | >>> print_multiplication_table(3) 10 | 1*1=1 11 | 1*2=2 12 | 1*3=3 13 | 2*1=2 14 | 2*2=4 15 | 2*3=6 16 | 3*1=3 17 | 3*2=6 18 | 3*3=9 19 | """ 20 | for i in range(1,N+1): 21 | for j in range(1,N+1): 22 | print '{0}*{1}={2}'.format(i,j,i*j) 23 | 24 | def _test(): 25 | import doctest 26 | doctest.testmod(verbose=True) 27 | 28 | if __name__ == "__main__": 29 | _test() 30 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2.2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | def test(x): 4 | if x>0.: 5 | return True 6 | return False 7 | 8 | def proc(a,b): 9 | if test(a): 10 | return b 11 | return a 12 | 13 | def proc1(x,y): 14 | if test(x): 15 | return y 16 | else: 17 | return x 18 | 19 | def proc2(a,b): 20 | if not test(b): 21 | return a 22 | else: 23 | return b 24 | 25 | def proc3(a,b): 26 | result = a 27 | if test(a): 28 | result = b 29 | return result 30 | 31 | def proc4(a,b): 32 | if not test(a): 33 | b = 'udacity' 34 | else: 35 | return b 36 | return a 37 | 38 | A = [-.1,0,1.9] 39 | B = [-.1,0,1.9] 40 | 41 | Aa = [[0,0,0],[0,0,0],[0,0,0]] 42 | Aa1 = [[0,0,0],[0,0,0],[0,0,0]] 43 | Aa2 = [[0,0,0],[0,0,0],[0,0,0]] 44 | Aa3 = [[0,0,0],[0,0,0],[0,0,0]] 45 | Aa4 = [[0,0,0],[0,0,0],[0,0,0]] 46 | e1 = [[0,0,0],[0,0,0],[0,0,0]] 47 | e2 = [[0,0,0],[0,0,0],[0,0,0]] 48 | e3 = [[0,0,0],[0,0,0],[0,0,0]] 49 | e4 = [[0,0,0],[0,0,0],[0,0,0]] 50 | 51 | for i,a in enumerate(A): 52 | for j,b in enumerate(B): 53 | Aa[i][j] = proc(a,b) 54 | Aa1[i][j] = proc1(a,b) 55 | Aa2[i][j] = proc2(a,b) 56 | Aa3[i][j] = proc3(a,b) 57 | Aa4[i][j] = proc4(a,b) 58 | e1[i][j] = (Aa[i][j] == Aa1[i][j]) 59 | e2[i][j] = (Aa[i][j] == Aa2[i][j]) 60 | e3[i][j] = (Aa[i][j] == Aa3[i][j]) 61 | e4[i][j] = (Aa[i][j] == Aa4[i][j]) 62 | 63 | 64 | print 'proc1' 65 | print e1 66 | print 'proc2' 67 | print e2 68 | print 'proc3' 69 | print e3 70 | print 'proc4' 71 | print e4 72 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2.3.py: -------------------------------------------------------------------------------- 1 | def median(a,b,c): 2 | """ 3 | Examples: 4 | >>> median(1,2,3) 5 | 2 6 | >>> median(9,3,6) 7 | 6 8 | >>> median(7,8,7) 9 | 7 10 | """ 11 | if a<=b<=c or c<=b<=a: 12 | return b 13 | elif a<=c<=b or b<=c<=a: 14 | return c 15 | else: 16 | return a 17 | 18 | def _test(): 19 | import doctest 20 | doctest.testmod() 21 | 22 | if __name__ == "__main__": 23 | _test() 24 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2.6.py: -------------------------------------------------------------------------------- 1 | def print_multiplication_table(N): 2 | """ 3 | Example: 4 | >>> print_multiplication_table(2) 5 | 1*1=1 6 | 1*2=2 7 | 2*1=2 8 | 2*2=4 9 | >>> print_multiplication_table(3) 10 | 1*1=1 11 | 1*2=2 12 | 1*3=3 13 | 2*1=2 14 | 2*2=4 15 | 2*3=6 16 | 3*1=3 17 | 3*2=6 18 | 3*3=9 19 | """ 20 | for i in range(1,N+1): 21 | for j in range(1,N+1): 22 | print '{0}*{1}={2}'.format(i,j,i*j) 23 | 24 | def _test(): 25 | import doctest 26 | doctest.testmod(verbose=True) 27 | 28 | if __name__ == "__main__": 29 | _test() 30 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw2.7.py: -------------------------------------------------------------------------------- 1 | def print_multiplication_table(N): 2 | """ 3 | Example: 4 | >>> print_multiplication_table(2) 5 | 1*1=1 6 | 1*2=2 7 | 2*1=2 8 | 2*2=4 9 | >>> print_multiplication_table(3) 10 | 1*1=1 11 | 1*2=2 12 | 1*3=3 13 | 2*1=2 14 | 2*2=4 15 | 2*3=6 16 | 3*1=3 17 | 3*2=6 18 | 3*3=9 19 | """ 20 | for i in range(1,N+1): 21 | for j in range(1,N+1): 22 | print '{0}*{1}={2}'.format(i,j,i*j) 23 | 24 | def _test(): 25 | import doctest 26 | doctest.testmod(verbose=True) 27 | 28 | if __name__ == "__main__": 29 | _test() 30 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw3.1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | p = [1, 0, 1] 4 | p[0] = p[0]+p[1] 5 | p[1]=p[0]+p[2] 6 | p[2]=p[0]+p[1] 7 | print p == [1,2,3] 8 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw3.2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | def proc1(p): 4 | p[0]=p[1] 5 | 6 | def proc2(p): 7 | p=p+[1] 8 | 9 | def proc3(p): 10 | q=p 11 | p.append(3) 12 | q.pop() # surprisingly this undoes the change 13 | 14 | def proc4(p): 15 | q=[] 16 | while p: 17 | q.append(p.pop()) 18 | while q: 19 | p.append(q.pop()) 20 | 21 | 22 | x = [1,2,3] 23 | proc1(x) 24 | print x 25 | x = [1,2,3] 26 | proc2(x) 27 | print x 28 | x = [1,2,3] 29 | proc3(x) 30 | print x 31 | x = [1,2,3] 32 | proc4(x) 33 | print x 34 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw3.3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | def product_list(l): 4 | if len(l)<1: 5 | return None 6 | r = 1. 7 | for i in l: 8 | r *= i; 9 | return r 10 | 11 | 12 | print product_list([9]) 13 | print product_list([1,2,3,4]) 14 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw3.4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | def greatest(l): 4 | r = None 5 | if len(l)<1.: 6 | return 0 7 | for i in l: 8 | if i>r: 9 | r=i 10 | return float(r) 11 | 12 | 13 | print greatest([9]) 14 | print greatest([-1,-2,-3,-4]) 15 | print greatest([4,23,1]) 16 | print greatest([]) 17 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw3.5.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | #Define a procedure, total_enrollment, 4 | #that takes as an input a list of elements, 5 | #where each element is a list containing 6 | #three elements: a university name, 7 | #the total number of students enrollect, 8 | #and the annual tuition. 9 | 10 | #The procedure should return two numbers, 11 | #not a string, 12 | #giving the total number of students 13 | #enrolled at all of the universities 14 | #in the list, and the total tuition 15 | #(which is the sum of the number 16 | #of students enrolled times the 17 | #tuition for each university). 18 | 19 | udacious_univs = [['Udacity',90000,0]] 20 | 21 | usa_univs = [ ['California Institute of Technology',2175,37704], 22 | ['Harvard',19627,39849], 23 | ['Massachusetts Institute of Technology',10566,40732], 24 | ['Princeton',7802,37000], 25 | ['Rice',5879,35551], 26 | ['Stanford',19535,40569], 27 | ['Yale',11701,40500] ] 28 | 29 | #>>> print total_enrollment(udacious_univs) 30 | #(90000,0) 31 | 32 | #>>> print total_enrollment(usa_univs) 33 | #(77285,3058581079L) 34 | 35 | def total_enrollment(x): 36 | r = [0,0] 37 | for row in x: 38 | r[0] += row[1] 39 | r[1] += row[1]*row[2] 40 | return r 41 | 42 | print total_enrollment(udacious_univs) 43 | print total_enrollment(usa_univs) 44 | 45 | 46 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw3.6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.6 2 | 3 | #The web crawler we built at the 4 | #end of Unit 2 has some serious 5 | #flaws if we were going to use 6 | #it in a real crawler. One 7 | #problem is if we start with 8 | #a good seed page, it might 9 | #run for an extremely long 10 | #time (even forever, since the 11 | #number of URLS on the web is not 12 | #actually finite). The final two 13 | #questions of the homework ask 14 | #you to explore two different ways 15 | #to limit the pages that it can 16 | #crawl. 17 | 18 | 19 | ####### 20 | 21 | 22 | #Modify the crawl_web procedure 23 | #to take a second parameter, 24 | #max_pages, that limits the 25 | #number of pages to crawl. 26 | #Your procedure should 27 | #terminate the crawl after 28 | #max_pages different pages 29 | #have been crawled, or when 30 | #there are no more pages to crawl. 31 | 32 | 33 | 34 | #The following definition of 35 | #get_page provides an interface 36 | #to the website found at 37 | #http://www.udacity.com/cs101x/index.html 38 | 39 | #The function output order does not affect grading. 40 | 41 | #crawl_web("http://www.udacity.com/cs101x/index.html",1) => ['http://www.udacity.com/cs101x/index.html'] 42 | #crawl_web("http://www.udacity.com/cs101x/index.html",3) => ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html', 'http://www.udacity.com/cs101x/walking.html'] 43 | #crawl_web("http://www.udacity.com/cs101x/index.html",500) => ['http://www.udacity.com/cs101x/index.html', 'http://www.udacity.com/cs101x/flying.html', 'http://www.udacity.com/cs101x/walking.html', 'http://www.udacity.com/cs101x/crawling.html', 'http://www.udacity.com/cs101x/kicking.html'] 44 | 45 | def get_page(url): 46 | try: 47 | if url == "http://www.udacity.com/cs101x/index.html": 48 | return '
This is a test page for learning to crawl!It is a good idea to learn to crawl before you try to walk or fly.
' 49 | elif url == "http://www.udacity.com/cs101x/crawling.html": 50 | return ' I have not learned to crawl yet, but I am quite good at kicking. ' 51 | elif url == "http://www.udacity.com/cs101x/walking.html": 52 | return ' I cant get enough crawling! ' 53 | elif url == "http://www.udacity.com/cs101x/flying.html": 54 | return ' The magic words are Squeamish Ossifrage! ' 55 | except: 56 | return "" 57 | return "" 58 | 59 | def get_next_target(page): 60 | start_link = page.find('>> print split_string("This is a test-of the,string separation-code!", " ,!-") 7 | ['This', 'is', 'a', 'test', 'of', 'the', 'string', 'separation', 'code'] 8 | >>> print split_string("After the flood ... all the colors came out.", " .") 9 | ['After', 'the', 'flood', 'all', 'the', 'colors', 'came', 'out'] 10 | """ 11 | # like nltk.tokenize() 12 | result =[] 13 | i0=0 14 | nonsep=False 15 | for i,c in enumerate(source): 16 | if c in splitlist: 17 | if i>i0 and nonsep: 18 | result.append(source[i0:i]) 19 | i0=i+1 20 | nonsep = False 21 | else: 22 | nonsep = True 23 | return result 24 | 25 | def test(): 26 | import doctest 27 | doctest.testmod(verbose=True) 28 | 29 | if __name__ == "__main__": 30 | test() 31 | 32 | -------------------------------------------------------------------------------- /cs101-Introduction-to-Computer-Science/hw4_6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | #The current index includes a url in the list of urls 4 | #for a keyword multiple times if the keyword appears 5 | #on that page more than once. 6 | 7 | #It might be better to only include the same url 8 | #once in the url list for a keyword, even if it appears 9 | #many times. 10 | 11 | #Modify add_to_index so that a given url is only 12 | #included once in the url list for a keyword, 13 | #no matter how many times that keyword appears. 14 | 15 | """ 16 | Examples: 17 | 18 | >>> index = crawl_web("http://www.udacity.com/cs101x/index.html") 19 | >>> print lookup(index,"is") 20 | ['http://www.udacity.com/cs101x/index.html'] 21 | """ 22 | 23 | def add_to_index(index, keyword, url): 24 | for entry in index: 25 | if entry[0] == keyword: 26 | if url not in entry[1]: 27 | entry[1].append(url) 28 | return 29 | # not found, add new keyword to index 30 | index.append([keyword, [url]]) 31 | 32 | 33 | def get_page(url): 34 | try: 35 | if url == "http://www.udacity.com/cs101x/index.html": 36 | return ' This is a test page for learning to crawl!It is a good idea to learn to crawl before you try to walk or fly.
' 37 | elif url == "http://www.udacity.com/cs101x/crawling.html": 38 | return ' I have not learned to crawl yet, but I am quite good at kicking. ' 39 | elif url == "http://www.udacity.com/cs101x/walking.html": 40 | return ' I cant get enough crawling! ' 41 | elif url == "http://www.udacity.com/cs101x/flying.html": 42 | return ' The magic words are Squeamish Ossifrage! ' 43 | except: 44 | return "" 45 | return "" 46 | 47 | def union(a, b): 48 | for e in b: 49 | if e not in a: 50 | a.append(e) 51 | 52 | def get_next_target(page): 53 | start_link = page.find('>> bowling([10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]) 10 | 300 11 | 12 | The rules of bowling are as follows: 13 | 14 | (1) A game consists of 10 frames. In each frame you roll one or two balls, 15 | except for the tenth frame, where you roll one, two, or three. Your total 16 | score is the sum of your scores for the ten frames. 17 | (2) If you knock down fewer than ten pins with your two balls in the frame, 18 | you score the total knocked down. For example, bowling([8, 1, 7, ...]) means 19 | that you knocked down a total of 9 pins in the first frame. You score 9 point 20 | for the frame, and you used up two balls in the frame. The second frame will 21 | start with the 7. 22 | (3) If you knock down all ten pins on your second ball it is called a 'spare' 23 | and you score 10 points plus a bonus: whatever you roll with your next ball. 24 | The next ball will also count in the next frame, so the next ball counts twice 25 | (except in the tenth frame, in which case the bonus ball counts only once). 26 | For example, bowling([8, 2, 7, ...]) means you get a spare in the first frame. 27 | You score 10 + 7 for the frame; the second frame starts with the 7. 28 | (4) If you knock down all ten pins on your first ball it is called a 'strike' 29 | and you score 10 points plus a bonus of your score on the next two balls. 30 | (The next two balls also count in the next frame, except in the tenth frame.) 31 | For example, bowling([10, 7, 3, ...]) means that you get a strike, you score 32 | 10 + 7 + 3 = 20 in the first frame; the second frame starts with the 7. 33 | 34 | """ 35 | 36 | def bowling(balls): 37 | "Compute the total score for a player's game of bowling." 38 | ## bowling([int, ...]) -> int 39 | f=0 40 | scores = [0]*12 # two extra frames in case strikes bolled in all last 3 and frame conter increments 41 | # strike = [False]*11 42 | frame_ball = 0 43 | spares = False 44 | strikes1 = strikes2 = False 45 | print balls 46 | for i,b in enumerate(balls): 47 | if spares: #f>0 and scores[f-1]==10: # spare in previous frame 48 | scores[f-1] += b 49 | if strikes2: 50 | scores[f-1] += b 51 | if strikes1: 52 | if frame_ball == 0: 53 | scores[f-2] += b 54 | else: 55 | scores[f-1] += b 56 | scores[f] += b 57 | # elif f==10: 58 | # scores[f-1] += b 59 | print scores 60 | print i,f,frame_ball,spares,strikes2,strikes1,b,sum(scores[0:10]) 61 | 62 | spares = False 63 | if frame_ball==1 and balls[i-1]+b == 10: 64 | spares = True 65 | strikes1 = strikes2 66 | strikes2 = False 67 | if frame_ball==0 and b == 10 and f<12: 68 | strikes2 = True 69 | if f<12 and (frame_ball==1 or b == 10): 70 | f = f+1 71 | frame_ball = 0 72 | else: 73 | frame_ball += 1 74 | 75 | return sum(scores[0:10]) 76 | 77 | 78 | def test_bowling(): 79 | return [ 80 | 0 == bowling([0] * 20), 81 | 20 == bowling([1] * 20), 82 | 80 == bowling([4] * 20), 83 | 190 == bowling([9,1] * 10 + [9]), 84 | 300 == bowling([10] * 12), 85 | 200 == bowling([10, 5,5] * 5 + [10]), 86 | 11 == bowling([0,0] * 9 + [10, 1,0]), 87 | 12 == bowling([0,0] * 8 + [10, 1,0]), 88 | 34 == bowling([0,0] * 8 + [10, 10,1,2]), 89 | ] 90 | 91 | if __name__ == '__main__': 92 | print test_bowling() 93 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/final-2.py: -------------------------------------------------------------------------------- 1 | """ 2 | UNIT 2: Logic Puzzle 3 | 4 | You will write code to solve the following logic puzzle: 5 | 6 | 1. The person who arrived on Wednesday bought the laptop. 7 | 2. The programmer is not Wilkes. 8 | 3. Of the programmer and the person who bought the droid, 9 | one is Wilkes and the other is Hamming. 10 | 4. The writer is not Minsky. 11 | 5. Neither Knuth nor the person who bought the tablet is the manager. 12 | 6. Knuth arrived the day after Simon. 13 | 7. The person who arrived on Thursday is not the designer. 14 | 8. The person who arrived on Friday didn't buy the tablet. 15 | 9. The designer didn't buy the droid. 16 | 10. Knuth arrived the day after the manager. 17 | 11. Of the person who bought the laptop and Wilkes, 18 | one arrived on Monday and the other is the writer. 19 | 12. Either the person who bought the iphone or the person who bought the tablet 20 | arrived on Tuesday. 21 | 22 | You will write the function logic_puzzle(), which should return a list of the 23 | names of the people in the order in which they arrive. For example, if they 24 | happen to arrive in alphabetical order, Hamming on Monday, Knuth on Tuesday, etc., 25 | then you would return: 26 | 27 | 28 | 29 | (You can assume that the days mentioned are all in the same week.) 30 | """ 31 | 32 | import itertools 33 | 34 | def imafter(d1,d2): 35 | "Day1 is immediately after of Day2 if d1-d2 == 1." 36 | return d1-d2 == 1 37 | 38 | def logic_puzzle(): 39 | "Return a list of the names of the people, in the order they arrive." 40 | 41 | # Inventory of concepts: 42 | names = ['Hamming', 'Knuth', 'Minsky', 'Simon', 'Wilkes'] 43 | N = len(names) # 5 people 44 | people = (Hamming, Knuth, Minsky, Simon, Wilkes) = list( range(1,N+1) ) # this is just an initial assignment 45 | # computers = laptop, droid, tablet, iphone, unspecified_computer = list( range(1,N+1) ) 46 | # jobs = manager, writer, designer, programmer, unspecified_job = list( range(1,N+1) ) 47 | days = Mon, Tues, Wed, Thurs, Fri = list ( range(1,N+1) ) # these are permanent 48 | 49 | orderings = list(itertools.permutations(people)) 50 | order = next( (Hamming, Knuth, Minsky, Simon, Wilkes) 51 | for (Hamming, Knuth, Minsky, Simon, Wilkes) in orderings 52 | #6. Knuth arrived the day after Simon. 53 | if imafter(Knuth,Simon) 54 | for (manager, writer, designer, programmer, job) in orderings 55 | #4. The writer is not Minsky. 56 | if writer is not Minsky 57 | #2. The programmer is not Wilkes. 58 | if programmer is not Wilkes 59 | #10. Knuth arrived the day after the manager. 60 | if imafter(Knuth,manager) # 10 61 | for (laptop, droid, tablet, iphone, other) in orderings 62 | #3. Of the programmer and the person who bought the droid, 63 | # one is Wilkes and the other is Hamming. 64 | #9. The designer didn't buy the droid. 65 | if (programmer,droid) in [(Wilkes,Hamming),(Hamming,Wilkes)] and designer is not droid 66 | #1. The person who arrived on Wednesday bought the laptop. 67 | #12. Either the person who bought the iphone or the person who bought the tablet 68 | # arrived on Tuesday. 69 | #11. Of the person who bought the laptop and Wilkes, 70 | # one arrived on Monday and the other is the writer. 71 | #5. Neither Knuth nor the person who bought the tablet is the manager. 72 | #7. The person who arrived on Thursday is not the designer. 73 | #8. The person who arrived on Friday didn't buy the tablet. 74 | if Wed is laptop and (iphone is Tues or tablet is Tues) and ((laptop,Wilkes) in [(Mon,writer),(writer,Mon)]) and Knuth is not manager and tablet is not manager and designer is not Thurs and Fri is not tablet 75 | ) 76 | # print '(Hamming, Knuth, Minsky, Simon, Wilkes)' 77 | # print order 78 | # print '(laptop, droid, tablet, iphone, other)' 79 | # print order 80 | # print '(manager, writer, designer, programmer, job)' 81 | # print order 82 | return [dict(zip(order, names))[i] for i in range(1,N+1)] 83 | 84 | print logic_puzzle() 85 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw1-1-rev2.py: -------------------------------------------------------------------------------- 1 | # CS 212, hw1-1: 7-card stud 2 | # 3 | # ----------------- 4 | # User Instructions 5 | # 6 | # Write a function best_hand(hand) that takes a seven 7 | # card hand as input and returns the best possible 5 8 | # card hand. The itertools library has some functions 9 | # that may help you solve this problem. 10 | # 11 | # ----------------- 12 | # Grading Notes 13 | # 14 | # Muliple correct answers will be accepted in cases 15 | # where the best hand is ambiguous (for example, if 16 | # you have 4 kings and 3 queens, there are three best 17 | # hands: 4 kings along with any of the three queens). 18 | 19 | import itertools 20 | 21 | def allmax(iterable, key=None): 22 | key = key or (lambda x:x) 23 | L = list(iterable) 24 | # so now l holds the data and iterable is empty! 25 | import itertools 26 | mx = hand_rank(max(L, key=key)) 27 | return list( itertools.ifilter(lambda x:hand_rank(x)==mx, iter(L) ) ) 28 | 29 | 30 | def best_hand(hand): 31 | "From a 7-card hand, return the best 5 card hand." 32 | 33 | # Your code here 34 | hands = [list(tp) for tp in itertools.combinations(hand,5)] 35 | # Must deal with more than one best hand (ties), but may only happen in 10-choose-5 hands 36 | return allmax(hands,key=hand_rank)[0] 37 | 38 | # ------------------ 39 | # Provided Functions 40 | # 41 | # You may want to use some of the functions which 42 | # you have already defined in the unit to write 43 | # your best_hand function. 44 | 45 | def hand_rank(hand): 46 | "Return a value indicating the ranking of a hand." 47 | ranks = card_ranks(hand) 48 | if straight(ranks) and flush(hand): 49 | return (8, max(ranks)) 50 | elif kind(4, ranks): 51 | return (7, kind(4, ranks), kind(1, ranks)) 52 | elif kind(3, ranks) and kind(2, ranks): 53 | return (6, kind(3, ranks), kind(2, ranks)) 54 | elif flush(hand): 55 | return (5, ranks) 56 | elif straight(ranks): 57 | return (4, max(ranks)) 58 | elif kind(3, ranks): 59 | return (3, kind(3, ranks), ranks) 60 | elif two_pair(ranks): 61 | return (2, two_pair(ranks), ranks) 62 | elif kind(2, ranks): 63 | return (1, kind(2, ranks), ranks) 64 | else: 65 | return (0, ranks) 66 | 67 | def card_ranks(hand): 68 | "Return a list of the ranks, sorted with higher first." 69 | ranks = ['--23456789TJQKA'.index(r) for r, s in hand] 70 | ranks.sort(reverse = True) 71 | return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks 72 | 73 | def flush(hand): 74 | "Return True if all the cards have the same suit." 75 | suits = [s for r,s in hand] 76 | return len(set(suits)) == 1 77 | 78 | def straight(ranks): 79 | """Return True if the ordered 80 | ranks form a 5-card straight.""" 81 | return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5 82 | 83 | def kind(n, ranks): 84 | """Return the first rank that this hand has 85 | exactly n-of-a-kind of. Return None if there 86 | is no n-of-a-kind in the hand.""" 87 | for r in ranks: 88 | if ranks.count(r) == n: return r 89 | return None 90 | 91 | def two_pair(ranks): 92 | """If there are two pair here, return the two 93 | ranks of the two pairs, else None.""" 94 | pair = kind(2, ranks) 95 | lowpair = kind(2, list(reversed(ranks))) 96 | if pair and lowpair != pair: 97 | return (pair, lowpair) 98 | else: 99 | return None 100 | 101 | def test_best_hand(): 102 | assert (sorted(best_hand("6C 7C 8C 9C TC 5C JS".split())) 103 | == ['6C', '7C', '8C', '9C', 'TC']) 104 | assert (sorted(best_hand("TD TC TH 7C 7D 8C 8S".split())) 105 | == ['8C', '8S', 'TC', 'TD', 'TH']) 106 | assert (sorted(best_hand("JD TC TH 7C 7D 7S 7H".split())) 107 | == ['7C', '7D', '7H', '7S', 'JD']) 108 | return 'test_best_hand passes' 109 | 110 | print test_best_hand() 111 | 112 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw1-1.py: -------------------------------------------------------------------------------- 1 | # CS 212, hw1-1: 7-card stud 2 | # 3 | # ----------------- 4 | # User Instructions 5 | # 6 | # Write a function best_hand(hand) that takes a seven 7 | # card hand as input and returns the best possible 5 8 | # card hand. The itertools library has some functions 9 | # that may help you solve this problem. 10 | # 11 | # ----------------- 12 | # Grading Notes 13 | # 14 | # Muliple correct answers will be accepted in cases 15 | # where the best hand is ambiguous (for example, if 16 | # you have 4 kings and 3 queens, there are three best 17 | # hands: 4 kings along with any of the three queens). 18 | 19 | import itertools 20 | 21 | def allmax(iterable, key=None): 22 | key = key or (lambda x:x) 23 | L = list(iterable) 24 | # so now l holds the data and iterable is empty! 25 | import itertools 26 | mx = hand_rank(max(L, key=key)) 27 | return list( itertools.ifilter(lambda x:hand_rank(x)==mx, iter(L) ) ) 28 | 29 | 30 | def best_hand(hand): 31 | "From a 7-card hand, return the best 5 card hand." 32 | 33 | # Your code here 34 | hands = [list(tp) for tp in itertools.combinations(hand,5)] 35 | # Must deal with more than one best hand (ties), but may only happen in 10-choose-5 hands 36 | return allmax(hands,key=hand_rank)[0] 37 | 38 | # ------------------ 39 | # Provided Functions 40 | # 41 | # You may want to use some of the functions which 42 | # you have already defined in the unit to write 43 | # your best_hand function. 44 | 45 | def hand_rank(hand): 46 | "Return a value indicating the ranking of a hand." 47 | ranks = card_ranks(hand) 48 | if straight(ranks) and flush(hand): 49 | return (8, max(ranks)) 50 | elif kind(4, ranks): 51 | return (7, kind(4, ranks), kind(1, ranks)) 52 | elif kind(3, ranks) and kind(2, ranks): 53 | return (6, kind(3, ranks), kind(2, ranks)) 54 | elif flush(hand): 55 | return (5, ranks) 56 | elif straight(ranks): 57 | return (4, max(ranks)) 58 | elif kind(3, ranks): 59 | return (3, kind(3, ranks), ranks) 60 | elif two_pair(ranks): 61 | return (2, two_pair(ranks), ranks) 62 | elif kind(2, ranks): 63 | return (1, kind(2, ranks), ranks) 64 | else: 65 | return (0, ranks) 66 | 67 | def card_ranks(hand): 68 | "Return a list of the ranks, sorted with higher first." 69 | ranks = ['--23456789TJQKA'.index(r) for r, s in hand] 70 | ranks.sort(reverse = True) 71 | return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks 72 | 73 | def flush(hand): 74 | "Return True if all the cards have the same suit." 75 | suits = [s for r,s in hand] 76 | return len(set(suits)) == 1 77 | 78 | def straight(ranks): 79 | """Return True if the ordered 80 | ranks form a 5-card straight.""" 81 | return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5 82 | 83 | def kind(n, ranks): 84 | """Return the first rank that this hand has 85 | exactly n-of-a-kind of. Return None if there 86 | is no n-of-a-kind in the hand.""" 87 | for r in ranks: 88 | if ranks.count(r) == n: return r 89 | return None 90 | 91 | def two_pair(ranks): 92 | """If there are two pair here, return the two 93 | ranks of the two pairs, else None.""" 94 | pair = kind(2, ranks) 95 | lowpair = kind(2, list(reversed(ranks))) 96 | if pair and lowpair != pair: 97 | return (pair, lowpair) 98 | else: 99 | return None 100 | 101 | def test_best_hand(): 102 | assert (sorted(best_hand("6C 7C 8C 9C TC 5C JS".split())) 103 | == ['6C', '7C', '8C', '9C', 'TC']) 104 | assert (sorted(best_hand("TD TC TH 7C 7D 8C 8S".split())) 105 | == ['8C', '8S', 'TC', 'TD', 'TH']) 106 | assert (sorted(best_hand("JD TC TH 7C 7D 7S 7H".split())) 107 | == ['7C', '7D', '7H', '7S', 'JD']) 108 | return 'test_best_hand passes' 109 | 110 | print test_best_hand() 111 | 112 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw1-1a-rev2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ----------- 3 | # User Instructions 4 | # 5 | # Write a function, allmax(iterable, key=None), that returns 6 | # a list of all items equal to the max of the iterable, 7 | # according to the function specified by key. 8 | 9 | def poker(hands): 10 | "Return a list of winning hands: poker([hand,...]) => [hand,...]" 11 | return allmax(hands, key=hand_rank) 12 | 13 | def allmax(iterable, key=None): 14 | "Return a list of all items equal to the max of the iterable." 15 | # Your code here. 16 | # from Norvig: 17 | #result, maxval = [], None 18 | key = key or (lambda x:x) 19 | #for x in iterable: 20 | # xval = key(x) 21 | # if not result or xval > maxval: 22 | # result, maxval = [x], xval 23 | # elif xval == maxval: 24 | # result.append(x) 25 | #return result 26 | # if you don't make a new list, the iterable will be consumed to the end! 27 | #print mx 28 | #print hand_rank(mx) 29 | #print iterable 30 | #print [x for x in l] 31 | #print [x==mx for x in l] 32 | #print map(lambda x:(hand_rank(x)==hand_rank(mx)), iter(l)) 33 | #print map(hand_rank, iter(l)) 34 | L = list(iterable) 35 | # so now l holds the data and iterable is empty! 36 | import itertools 37 | mx = hand_rank(max(L, key=key)) 38 | return list( itertools.ifilter(lambda x:hand_rank(x)==mx, iter(L) ) ) 39 | 40 | def hand_rank(hand): 41 | "Return a value indicating the ranking of a hand." 42 | ranks = card_ranks(hand) 43 | if straight(ranks) and flush(hand): 44 | return (8, max(ranks)) 45 | elif kind(4, ranks): 46 | return (7, kind(4, ranks), kind(1, ranks)) 47 | elif kind(3, ranks) and kind(2, ranks): 48 | return (6, kind(3, ranks), kind(2, ranks)) 49 | elif flush(hand): 50 | return (5, ranks) 51 | elif straight(ranks): 52 | return (4, max(ranks)) 53 | elif kind(3, ranks): 54 | return (3, kind(3, ranks), ranks) 55 | elif two_pair(ranks): 56 | return (2, two_pair(ranks), ranks) 57 | elif kind(2, ranks): 58 | return (1, kind(2, ranks), ranks) 59 | else: 60 | return (0, ranks) 61 | 62 | def card_ranks(hand): 63 | "Return a list of the ranks, sorted with higher first." 64 | ranks = ['--23456789TJQKA'.index(r) for r, s in hand] 65 | ranks.sort(reverse = True) 66 | return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks 67 | 68 | def flush(hand): 69 | "Return True if all the cards have the same suit." 70 | suits = [s for r,s in hand] 71 | return len(set(suits)) == 1 72 | 73 | def straight(ranks): 74 | "Return True if the ordered ranks form a 5-card straight." 75 | return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5 76 | 77 | def kind(n, ranks): 78 | """Return the first rank that this hand has exactly n-of-a-kind of. 79 | Return None if there is no n-of-a-kind in the hand.""" 80 | for r in ranks: 81 | if ranks.count(r) == n: return r 82 | return None 83 | 84 | def two_pair(ranks): 85 | "If there are two pair here, return the two ranks of the two pairs, else None." 86 | pair = kind(2, ranks) 87 | lowpair = kind(2, list(reversed(ranks))) 88 | if pair and lowpair != pair: 89 | return (pair, lowpair) 90 | else: 91 | return None 92 | 93 | 94 | mydeck = [r+s for r in '23456789TJQKA' for s in 'SHDC'] 95 | 96 | def deal(numhands, n=5, deck=mydeck): 97 | # Your code here. 98 | return [random.sample(deck,n*numhands)[(i*n):(i+1)*n] for i in range(numhands)] 99 | 100 | def best_hand(hand): 101 | """ 102 | Combinations works as long as the hand_rank function doesn't get confused by card order 103 | Perumtations inefficiently checks all possible 5-card hands to find the best one. 104 | """ 105 | from itertools import combinations 106 | hands = [list(tp) for tp in combinations(hand,5)] 107 | # will this work with the tuple of tuples returned by itertools.combination() ? 108 | return allmax(hands) 109 | 110 | 111 | def test(): 112 | "Test cases for the functions in poker program." 113 | sf1 = "6C 7C 8C 9C TC".split() # Straight Flush 114 | sf2 = "6D 7D 8D 9D TD".split() # Straight Flush 115 | fk = "9D 9H 9S 9C 7D".split() # Four of a Kind 116 | fh = "TD TC TH 7C 7D".split() # Full House 117 | assert poker([sf1, sf2, fk, fh]) == [sf1, sf2] 118 | #print allmax(iter([['6C', '7C', '8C', '9C', 'TC'], ['6D', '7D', '8D', '9D', 'TD'], ['9D', '9H', '9S', '9C', '7D'], ['TD', 'TC', 'TH', '7C', '7D']]),hand_rank) 119 | assert allmax([['6C', '7C', '8C', '9C', 'TC'], ['6D', '7D', '8D', '9D', 'TD'], ['9D', '9H', '9S', '9C', '7D'], ['TD', 'TC', 'TH', '7C', '7D']],hand_rank) == [['6C', '7C', '8C', '9C', 'TC'],['6D', '7D', '8D', '9D', 'TD']] 120 | print best_hand("6C 7C 8C 9C TC 6D 7D".split()) 121 | print best_hand("6C 7C 8C 9C TC 9D TD".split()) 122 | print best_hand("6C 7C 8C 9C TC TD JD".split()) 123 | print best_hand("6C 7C 8C 9C TC TD TS".split()) 124 | print best_hand("6C 7C 9D 9C TC TD TS".split()) 125 | return 'tests pass' 126 | 127 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw1-1a.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ----------- 3 | # User Instructions 4 | # 5 | # Write a function, allmax(iterable, key=None), that returns 6 | # a list of all items equal to the max of the iterable, 7 | # according to the function specified by key. 8 | 9 | def poker(hands): 10 | "Return a list of winning hands: poker([hand,...]) => [hand,...]" 11 | return allmax(hands, key=hand_rank) 12 | 13 | def allmax(iterable, key=None): 14 | "Return a list of all items equal to the max of the iterable." 15 | # Your code here. 16 | # from Norvig: 17 | #result, maxval = [], None 18 | key = key or (lambda x:x) 19 | #for x in iterable: 20 | # xval = key(x) 21 | # if not result or xval > maxval: 22 | # result, maxval = [x], xval 23 | # elif xval == maxval: 24 | # result.append(x) 25 | #return result 26 | # if you don't make a new list, the iterable will be consumed to the end! 27 | #print mx 28 | #print hand_rank(mx) 29 | #print iterable 30 | #print [x for x in l] 31 | #print [x==mx for x in l] 32 | #print map(lambda x:(hand_rank(x)==hand_rank(mx)), iter(l)) 33 | #print map(hand_rank, iter(l)) 34 | L = list(iterable) 35 | # so now l holds the data and iterable is empty! 36 | import itertools 37 | mx = hand_rank(max(L, key=key)) 38 | return list( itertools.ifilter(lambda x:hand_rank(x)==mx, iter(L) ) ) 39 | 40 | def hand_rank(hand): 41 | "Return a value indicating the ranking of a hand." 42 | ranks = card_ranks(hand) 43 | if straight(ranks) and flush(hand): 44 | return (8, max(ranks)) 45 | elif kind(4, ranks): 46 | return (7, kind(4, ranks), kind(1, ranks)) 47 | elif kind(3, ranks) and kind(2, ranks): 48 | return (6, kind(3, ranks), kind(2, ranks)) 49 | elif flush(hand): 50 | return (5, ranks) 51 | elif straight(ranks): 52 | return (4, max(ranks)) 53 | elif kind(3, ranks): 54 | return (3, kind(3, ranks), ranks) 55 | elif two_pair(ranks): 56 | return (2, two_pair(ranks), ranks) 57 | elif kind(2, ranks): 58 | return (1, kind(2, ranks), ranks) 59 | else: 60 | return (0, ranks) 61 | 62 | def card_ranks(hand): 63 | "Return a list of the ranks, sorted with higher first." 64 | ranks = ['--23456789TJQKA'.index(r) for r, s in hand] 65 | ranks.sort(reverse = True) 66 | return [5, 4, 3, 2, 1] if (ranks == [14, 5, 4, 3, 2]) else ranks 67 | 68 | def flush(hand): 69 | "Return True if all the cards have the same suit." 70 | suits = [s for r,s in hand] 71 | return len(set(suits)) == 1 72 | 73 | def straight(ranks): 74 | "Return True if the ordered ranks form a 5-card straight." 75 | return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5 76 | 77 | def kind(n, ranks): 78 | """Return the first rank that this hand has exactly n-of-a-kind of. 79 | Return None if there is no n-of-a-kind in the hand.""" 80 | for r in ranks: 81 | if ranks.count(r) == n: return r 82 | return None 83 | 84 | def two_pair(ranks): 85 | "If there are two pair here, return the two ranks of the two pairs, else None." 86 | pair = kind(2, ranks) 87 | lowpair = kind(2, list(reversed(ranks))) 88 | if pair and lowpair != pair: 89 | return (pair, lowpair) 90 | else: 91 | return None 92 | 93 | 94 | mydeck = [r+s for r in '23456789TJQKA' for s in 'SHDC'] 95 | 96 | def deal(numhands, n=5, deck=mydeck): 97 | # Your code here. 98 | return [random.sample(deck,n*numhands)[(i*n):(i+1)*n] for i in range(numhands)] 99 | 100 | def best_hand(hand): 101 | """ 102 | Combinations works as long as the hand_rank function doesn't get confused by card order 103 | Perumtations inefficiently checks all possible 5-card hands to find the best one. 104 | """ 105 | from itertools import combinations 106 | hands = [list(tp) for tp in combinations(hand,5)] 107 | # will this work with the tuple of tuples returned by itertools.combination() ? 108 | return allmax(hands) 109 | 110 | 111 | def test(): 112 | "Test cases for the functions in poker program." 113 | sf1 = "6C 7C 8C 9C TC".split() # Straight Flush 114 | sf2 = "6D 7D 8D 9D TD".split() # Straight Flush 115 | fk = "9D 9H 9S 9C 7D".split() # Four of a Kind 116 | fh = "TD TC TH 7C 7D".split() # Full House 117 | assert poker([sf1, sf2, fk, fh]) == [sf1, sf2] 118 | #print allmax(iter([['6C', '7C', '8C', '9C', 'TC'], ['6D', '7D', '8D', '9D', 'TD'], ['9D', '9H', '9S', '9C', '7D'], ['TD', 'TC', 'TH', '7C', '7D']]),hand_rank) 119 | assert allmax([['6C', '7C', '8C', '9C', 'TC'], ['6D', '7D', '8D', '9D', 'TD'], ['9D', '9H', '9S', '9C', '7D'], ['TD', 'TC', 'TH', '7C', '7D']],hand_rank) == [['6C', '7C', '8C', '9C', 'TC'],['6D', '7D', '8D', '9D', 'TD']] 120 | print best_hand("6C 7C 8C 9C TC 6D 7D".split()) 121 | print best_hand("6C 7C 8C 9C TC 9D TD".split()) 122 | print best_hand("6C 7C 8C 9C TC TD JD".split()) 123 | print best_hand("6C 7C 8C 9C TC TD TS".split()) 124 | print best_hand("6C 7C 9D 9C TC TD TS".split()) 125 | return 'tests pass' 126 | 127 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw2-1--cryptarithmatic-compiled.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # solves any cryptarithmatic problem using brute force 3 | 4 | # -------------- 5 | # User Instructions 6 | # 7 | # Modify the function compile_formula so that the function 8 | # it returns, f, does not allow numbers where the first digit 9 | # is zero. So if the formula contained YOU, f would return 10 | # False anytime that Y was 0 11 | 12 | import re 13 | import itertools 14 | import string 15 | 16 | def compile_formula(formula, verbose=False): 17 | """Compile formula into a function. Also return letters found, as a str, 18 | in same order as parms of function. The first digit of a multi-digit 19 | number can't be 0. So if YOU is a word in the formula, and the function 20 | is called with Y eqal to 0, the function should return False.""" 21 | 22 | # modify the code in this function. 23 | 24 | letters = ''.join(set(re.findall('[A-Z]', formula))) 25 | firstletters = set(re.findall(r'\b([A-Z])[A-Z]', formula)) 26 | parms = ', '.join(letters) 27 | tokens = map(compile_word, re.split('([A-Z]+)', formula)) 28 | body = ''.join(tokens) 29 | if firstletters: 30 | tests = ' and '.join(L+'!=0' for L in firstletters) 31 | body = tests+' and ('+body+')' 32 | f = 'lambda %s: %s' % (parms, body) 33 | if verbose: print f 34 | return eval(f), letters 35 | 36 | def compile_word(word): 37 | """Compile a word of uppercase letters as numeric digits. 38 | E.g., compile_word('YOU') => '(1*U+10*O+100*Y)' 39 | Non-uppercase words uncahanged: compile_word('+') => '+'""" 40 | if word.isupper(): 41 | terms = [('%s*%s' % (10**i, d)) 42 | for (i, d) in enumerate(word[::-1])] 43 | return '(' + '+'.join(terms) + ')' 44 | else: 45 | return word 46 | 47 | def faster_solve(formula): 48 | """Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it. 49 | Input formula is a string; output is a digit-filled-in string or None. 50 | This version precompiles the formula; only one eval per formula.""" 51 | f, letters = compile_formula(formula) 52 | for digits in itertools.permutations((1,2,3,4,5,6,7,8,9,0), len(letters)): 53 | try: 54 | if f(*digits) is True: 55 | table = string.maketrans(letters, ''.join(map(str, digits))) 56 | return formula.translate(table) 57 | except ArithmeticError: 58 | pass 59 | 60 | examples = """TWO+TWO==FOUR 61 | A**2+B**2==C**2 62 | A**2+BE**2==BY**2 63 | X/X==X 64 | A**N+B**N==C**N and N>1 65 | ATOM**.5 == A + TO + M 66 | GLITTERS is not GOLD 67 | ONE < TWO and FOUR < FIVE 68 | ONE < TWO < THREE 69 | RAMN == R**3 + RM**3 == N**3 + RX**3 70 | sum(range(AA)) == BB 71 | sum(range(POP)) = BOB0 72 | ODD + ODD = EVEN 73 | PLUTO no in set([PLANETS])""".splitlines() 74 | 75 | def test(): 76 | t0 = time.clock() 77 | for e in examples: 78 | print; print 13*' ', e 79 | print '%6.4f sec: %s ' % timedcall(faster_solve, e) 80 | print '%6.4f tot.' % (time.clock()-t0) 81 | 82 | assert faster_solve('A + B == BA') == None # should NOT return '1 + 0 == 01' 83 | assert faster_solve('YOU == ME**2') == ('289 == 17**2' or '576 == 24**2' or '841 == 29**2') 84 | assert faster_solve('X / X == X') == '1 / 1 == 1' 85 | return 'tests pass' 86 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw2-2--apartment-puzzle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # module for solving the apartment "Floor" puzzle and measuring execution time 3 | 4 | import itertools 5 | 6 | def floor_puzzle(): 7 | houses = bottom, _, _, _, top = [1, 2, 3, 4, 5] 8 | orderings = list(itertools.permutations(houses)) # 1 9 | return next((Hopper, Kay, Liskov, Perlis, Ritchie) 10 | for (Hopper, Kay, Liskov, Perlis, Ritchie) in orderings 11 | if ( Hopper is not top 12 | and Kay is not bottom 13 | and Liskov is not top 14 | and Liskov is not bottom 15 | and Perlis > Kay 16 | and abs(Ritchie-Liskov) > 1 17 | and abs(Liskov-Kay) > 1)) 18 | 19 | import time 20 | 21 | def timedcall(fn, *args): 22 | "Call function with args; return the time in seconds and result." 23 | t0 = time.clock() 24 | result = fn(*args) 25 | t1 = time.clock() 26 | return t1-t0, result 27 | 28 | def average(numbers): 29 | "Return the average (arithmetic mean) of a sequence of numbers." 30 | return sum(numbers) / float(len(numbers)) 31 | 32 | def timedcalls(n, fn, *args): 33 | """Call fn(*args) repeatedly: n times if n is an int, or up to 34 | n seconds if n is a float; return the min, avg, and max time""" 35 | tt,times = 0,[] 36 | if isinstance(n,int): 37 | while tt < n: 38 | t,result = timedcall(fn,*args) 39 | times.append(t) 40 | tt += 1 41 | else: 42 | while tt < n: 43 | t, result = timedcall(fn,*args) 44 | tt += t 45 | times.append(t) 46 | return min(times), average(times), max(times) 47 | 48 | print timedcall(floor_puzzle) 49 | print timedcalls(1000,floor_puzzle) 50 | 51 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/hw2-3--subpalindome.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # looks for a palindrome within a string 3 | # _hobs version fails the efficiency check for 1 of the 4 answers/tests checked by Peter 4 | 5 | # -------------- 6 | # User Instructions 7 | # 8 | # Write a function, longest_subpalindrome_slice(text) that takes 9 | # a string as input and returns the i and j indices that 10 | # correspond to the beginning and end indices of the longest 11 | # palindrome in the string. 12 | # 13 | # Grading Notes: 14 | # 15 | # You will only be marked correct if your function runs 16 | # efficiently enough. We will be measuring efficency by counting 17 | # the number of times you access each string. That count must be 18 | # below a certain threshold to be marked correct. 19 | # 20 | # Please do not use regular expressions to solve this quiz! 21 | 22 | def longest_subpalindrome_slice(text): 23 | "Return (i, j) such that text[i:j] is the longest palindrome in text." 24 | if not text: return (0,0) 25 | text=text.lower() 26 | candidate_slices = [ grow(text, i0, i1) for i0 in range(len(text)) 27 | for i1 in (i0, i0+1) ] # even and odd-lengthed pdromes 28 | print candidate_slices 29 | return max(candidate_slices, key=lambda s: s[1]-s[0]) 30 | 31 | def grow(text, i0, i1): 32 | """Grow length of slice indeces from center outward, checking palindrome symetry 33 | 34 | Start with 0 or 1-length strings""" 35 | # HL: what about starting at the first character (i0=0)? Single letter doesn't count as a palindrome? 36 | # No, it's just that i0 isn't the first character in the checked palindrome--i0-1 is 37 | while (i0 >0 and i1 < len(text) and text[i0-1].upper() == text[i1].upper() ): 38 | i0 -= 1; i1 += 1 39 | return (i0, i1) 40 | 41 | def is_pal(text): 42 | if not text: return True 43 | for i in range(len(text)/2+1): 44 | if not text[i]==text[-1-i]: return False 45 | return True 46 | 47 | test_examples="""racecar 48 | Racecar 49 | racecarX 50 | Race carr 51 | something rac e car going 52 | xxxxx 53 | Mad am I ma dam. 54 | """.splitlines() 55 | 56 | test_answers = [(0,7),(0,7),(0,7),(7,9),(8,21),(0,5),(0,15)] 57 | 58 | def test(): 59 | L = longest_subpalindrome_slice 60 | for t,a in zip(test_examples,test_answers): 61 | print t + ': ' + repr(L(t)) 62 | assert L(t) == a 63 | print L('racecar') 64 | assert L('racecar') == (0, 7) 65 | print L('Racecar') 66 | assert L('Racecar') == (0, 7) 67 | 68 | print L('racecarX') 69 | assert L('RacecarX') == (0, 7) 70 | assert L('Race carr') == (7, 9) 71 | assert L('') == (0, 0) 72 | assert L('something rac e car going') == (8,21) 73 | assert L('xxxxx') == (0, 5) 74 | assert L('Mad am I ma dam.') == (0, 15) 75 | return 'tests pass' 76 | 77 | print test() 78 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q1-24--evaluate_poker_hand_rank.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ----------- 3 | # User Instructions 4 | # 5 | # Write a function, allmax(iterable, key=None), that returns 6 | # a list of all items equal to the max of the iterable, 7 | # according to the function specified by key. 8 | 9 | 10 | def poker(hands): 11 | "Return a list of winning hands: poker([hand,...]) => [hand,...]" 12 | return allmax(hands, key=hand_rank) 13 | 14 | 15 | def allmax(iterable, key=None): 16 | "Return a list of all items equal to the max of the iterable." 17 | L = list(iterable) 18 | import itertools 19 | mx = max(key(x) for x in L) 20 | return list(itertools.ifilter(lambda x: key(x) == mx, iter(L))) 21 | 22 | 23 | def hand_rank(hand): 24 | "Return a value indicating the ranking of a hand." 25 | ranks = card_ranks(hand) 26 | if straight(ranks) and flush(hand): # straight flush 27 | return (8, max(ranks)) 28 | elif kind(4, ranks): # four of a kind 29 | return (7, kind(4, ranks), kind(1, ranks)) 30 | elif kind(3, ranks) and kind(2, ranks): 31 | return (6, kind(3, ranks), kind(2, ranks)) 32 | elif flush(hand): 33 | return (5, ranks) 34 | elif straight(ranks): 35 | return (4, max(ranks)) 36 | elif kind(3, ranks): 37 | return (3, kind(3, ranks), ranks) 38 | elif two_pair(ranks): 39 | return (2, two_pair(ranks), ranks) 40 | elif kind(2, ranks): 41 | return (1, kind(2, ranks), ranks) 42 | else: 43 | return (0, ranks) 44 | 45 | 46 | def card_ranks(hand): 47 | "Return a list of the ranks, sorted with higher first." 48 | ranks = ['--23456789TJQKA'.index(r) for r, s in hand] 49 | ranks.sort(reverse=True) 50 | return ranks 51 | 52 | 53 | def flush(hand): 54 | "Return True if all the cards have the same suit." 55 | suits = (s for r, s in hand) 56 | return len(set(suits)) == 1 57 | 58 | 59 | def straight(ranks): 60 | "Return True if the ordered ranks form a 5-card straight." 61 | return (max(ranks)-min(ranks) == 4) and len(set(ranks)) == 5 62 | 63 | 64 | def kind(n, ranks): 65 | """Return the first rank that this hand has exactly n-of-a-kind of. 66 | Return None if there is no n-of-a-kind in the hand.""" 67 | for r in ranks: 68 | if ranks.count(r) == n: 69 | return r 70 | return None 71 | 72 | 73 | def two_pair(ranks): 74 | "If there are two pair here, return the two ranks of the two pairs, else None." 75 | pair = kind(2, ranks) 76 | lowpair = kind(2, list(reversed(ranks))) 77 | if pair and lowpair != pair: 78 | return (pair, lowpair) 79 | else: 80 | return None 81 | 82 | 83 | def test(): 84 | "Test cases for the functions in poker program" 85 | sf = "6C 7C 8C 9C TC".split() # Straight Flush 86 | fk = "9D 9H 9S 9C 7D".split() # Four of a Kind 87 | fh = "TD TC TH 7C 7D".split() # Full House 88 | tp = "5H 5D 9C 9H 6S".split() # two pair 89 | assert flush(sf) 90 | assert flush(fk) is False 91 | assert flush(fh) is False 92 | fkranks = card_ranks(fk) 93 | tpranks = card_ranks(tp) 94 | assert kind(4, fkranks) == 9 95 | assert kind(3, fkranks) == None 96 | assert kind(2, fkranks) == None 97 | assert kind(1, fkranks) == 7 98 | assert card_ranks(sf) == [10, 9, 8, 7, 6] 99 | assert fkranks == [9, 9, 9, 9, 7] 100 | assert card_ranks(fh) == [10, 10, 10, 7, 7] 101 | 102 | assert straight([9, 8, 7, 6, 5]) == True 103 | assert straight([9, 8, 8, 6, 5]) == False 104 | assert hand_rank(sf) == (8, 10) 105 | assert hand_rank(fk) == (7, 9, 7) 106 | assert hand_rank(fh) == (6, 10, 7) 107 | assert poker([sf, fk, fh]) == [sf] 108 | assert poker([fk, fh]) == [fk] 109 | assert poker([fh, fh]) == [fh, fh] 110 | assert poker([sf]) == [sf] 111 | assert poker([sf] + 99*[fh]) == [sf] 112 | assert hand_rank(sf) == (8, 10) 113 | assert hand_rank(fk) == (7, 9, 7) 114 | assert hand_rank(fh) == (6, 10, 7) 115 | 116 | return 'tests pass' 117 | 118 | 119 | #print allmax(iter([['6C', '7C', '8C', '9C', 'TC'], ['6D', '7D', '8D', '9D', 'TD'], ['9D', '9H', '9S', '9C', '7D'], ['TD', 'TC', 'TH', '7C', '7D']]),hand_rank) 120 | #assert allmax([['6C', '7C', '8C', '9C', 'TC'], ['6D', '7D', '8D', '9D', 'TD'], ['9D', '9H', '9S', '9C', '7D'], ['TD', 'TC', 'TH', '7C', '7D']],hand_rank) == [['6C', '7C', '8C', '9C', 'TC'],['6D', '7D', '8D', '9D', 'TD']] 121 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q1-27--deal-deck.py: -------------------------------------------------------------------------------- 1 | # ----------- 2 | # User Instructions 3 | # 4 | # Write a function, deal(numhands, n=5, deck), that 5 | # deals numhands hands with n cards each. 6 | # 7 | 8 | import random # this will be a useful library for shuffling 9 | 10 | # This builds a deck of 52 cards. If you are unfamiliar 11 | # with this notation, check out Andy's supplemental video 12 | # on list comprehensions (you can find the link in the 13 | # Instructor Comments box below). 14 | 15 | mydeck = [r+s for r in '23456789TJQKA' for s in 'SHDC'] 16 | 17 | def deal(numhands, n=10, deck=mydeck): 18 | return [random.sample(deck,n*numhands)[(i*n):(i+1)*n] for i in range(numhands)] 19 | # Your code here. 20 | 21 | print deal(5) 22 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q2-19--zebra-puzzle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # module for solving the zebra puzzle and measuring execution time 3 | 4 | import itertools 5 | 6 | def imright(h1, h2): 7 | "House h1 is immediately right of h2 if h1-h2 == 1." 8 | return h1-h2 == 1 9 | 10 | def nextto(h1, h2): 11 | "Two houses are next to each other if they differ by 1." 12 | return abs(h1-h2) == 1 13 | 14 | def zebra_puzzle(): 15 | "Return a tuple (WATER, ZEBRA indicating their house numbers." 16 | houses = first, _, middle, _, _ = [1, 2, 3, 4, 5] 17 | orderings = list(itertools.permutations(houses)) # 1 18 | return next((WATER, ZEBRA) 19 | for (red, green, ivory, yellow, blue) in orderings 20 | if imright(green, ivory) 21 | for (Englishman, Spaniard, Ukranian, Japanese, Norwegian) in orderings 22 | if Englishman is red 23 | if Norwegian is first 24 | if nextto(Norwegian, blue) 25 | for (coffee, tea, milk, oj, WATER) in orderings 26 | if coffee is green 27 | if Ukranian is tea 28 | if milk is middle 29 | for (OldGold, Kools, Chesterfields, LuckyStrike, Parliaments) in orderings 30 | if Kools is yellow 31 | if LuckyStrike is oj 32 | if Japanese is Parliaments 33 | for (dog, snails, fox, horse, ZEBRA) in orderings 34 | if Spaniard is dog 35 | if OldGold is snails 36 | if nextto(Chesterfields, fox) 37 | if nextto(Kools, horse) 38 | ) 39 | 40 | import time 41 | 42 | def timedcall(fn, *args): 43 | "Call function with args; return the time in seconds and result." 44 | t0 = time.clock() 45 | result = fn(*args) 46 | t1 = time.clock() 47 | return t1-t0, result 48 | 49 | def average(numbers): 50 | "Return the average (arithmetic mean) of a sequence of numbers." 51 | return sum(numbers) / float(len(numbers)) 52 | 53 | def timedcalls(n, fn, *args): 54 | """Call fn(*args) repeatedly: n times if n is an int, or up to 55 | n seconds if n is a float; return the min, avg, and max time""" 56 | tt,times = 0,[] 57 | if isinstance(n,int): 58 | while tt < n: 59 | t,result = timedcall(fn,*args) 60 | times.append(t) 61 | tt += 1 62 | else: 63 | while tt < n: 64 | t, result = timedcall(fn,*args) 65 | tt += t 66 | times.append(t) 67 | return min(times), average(times), max(times) 68 | 69 | 70 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q2-19.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # module for solving the zebra puzzle and measuring execution time 3 | 4 | import itertools 5 | 6 | def imright(h1, h2): 7 | "House h1 is immediately right of h2 if h1-h2 == 1." 8 | return h1-h2 == 1 9 | 10 | def nextto(h1, h2): 11 | "Two houses are next to each other if they differ by 1." 12 | return abs(h1-h2) == 1 13 | 14 | def zebra_puzzle(): 15 | "Return a tuple (WATER, ZEBRA indicating their house numbers." 16 | houses = first, _, middle, _, _ = [1, 2, 3, 4, 5] 17 | orderings = list(itertools.permutations(houses)) # 1 18 | return next((WATER, ZEBRA) 19 | for (red, green, ivory, yellow, blue) in orderings 20 | if imright(green, ivory) 21 | for (Englishman, Spaniard, Ukranian, Japanese, Norwegian) in orderings 22 | if Englishman is red 23 | if Norwegian is first 24 | if nextto(Norwegian, blue) 25 | for (coffee, tea, milk, oj, WATER) in orderings 26 | if coffee is green 27 | if Ukranian is tea 28 | if milk is middle 29 | for (OldGold, Kools, Chesterfields, LuckyStrike, Parliaments) in orderings 30 | if Kools is yellow 31 | if LuckyStrike is oj 32 | if Japanese is Parliaments 33 | for (dog, snails, fox, horse, ZEBRA) in orderings 34 | if Spaniard is dog 35 | if OldGold is snails 36 | if nextto(Chesterfields, fox) 37 | if nextto(Kools, horse) 38 | ) 39 | 40 | import time 41 | 42 | def timedcall(fn, *args): 43 | "Call function with args; return the time in seconds and result." 44 | t0 = time.clock() 45 | result = fn(*args) 46 | t1 = time.clock() 47 | return t1-t0, result 48 | 49 | def average(numbers): 50 | "Return the average (arithmetic mean) of a sequence of numbers." 51 | return sum(numbers) / float(len(numbers)) 52 | 53 | def timedcalls(n, fn, *args): 54 | """Call fn(*args) repeatedly: n times if n is an int, or up to 55 | n seconds if n is a float; return the min, avg, and max time""" 56 | tt,times = 0,[] 57 | if isinstance(n,int): 58 | while tt < n: 59 | t,result = timedcall(fn,*args) 60 | times.append(t) 61 | tt += 1 62 | else: 63 | while tt < n: 64 | t, result = timedcall(fn,*args) 65 | tt += t 66 | times.append(t) 67 | return min(times), average(times), max(times) 68 | 69 | 70 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q2-32--cryptarithmatic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # solves any cryptarithmatic problem using brute force 3 | 4 | from __future__ import division 5 | import string, re, itertools 6 | 7 | def solve(formula): 8 | """Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it. 9 | Input formula is a string; output is a digit-filled-in string or None.""" 10 | for f in fill_in(formula): 11 | if valid(f): 12 | return f 13 | 14 | def fill_in(formula): 15 | "Generate all possible fillings-in of letters in formula with digits." 16 | letters = ''.join(set(re.findall('[A-Z]', formula))) #should be a string 17 | for digits in itertools.permutations('1234567890', len(letters) ): 18 | table = string.maketrans(letters, ''.join(digits)) 19 | yield formula.translate(table) 20 | 21 | def valid(f): 22 | """Formula f is valid if and only if it has no 23 | numbers with leading zero, and evals true.""" 24 | try: 25 | return not re.search(r'\b0[0-9]', f) and eval(f) is True 26 | except ArithmeticError: 27 | return False 28 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q2-34--cryptarithmatic-examples.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # solves any cryptarithmatic problem using brute force 3 | 4 | # -------------- 5 | # User Instructions 6 | # 7 | # Modify the function compile_formula so that the function 8 | # it returns, f, does not allow numbers where the first digit 9 | # is zero. So if the formula contained YOU, f would return 10 | # False anytime that Y was 0 11 | 12 | from __future__ import division 13 | import re, itertools, string, time 14 | 15 | def compile_formula(formula, verbose=False): 16 | """Compile formula into a function. Also return letters found, as a str, 17 | in same order as parms of function. The first digit of a multi-digit 18 | number can't be 0. So if YOU is a word in the formula, and the function 19 | is called with Y eqal to 0, the function should return False.""" 20 | 21 | # modify the code in this function. 22 | 23 | letters = ''.join(set(re.findall('[A-Z]', formula))) 24 | firstletters = set(re.findall(r'\b([A-Z])[A-Z]', formula)) 25 | parms = ', '.join(letters) 26 | tokens = map(compile_word, re.split('([A-Z]+)', formula)) 27 | body = ''.join(tokens) 28 | if firstletters: 29 | tests = ' and '.join(L+'!=0' for L in firstletters) 30 | body = tests+' and ('+body+')' 31 | f = 'lambda %s: %s' % (parms, body) 32 | if verbose: print f 33 | return eval(f), letters 34 | 35 | def compile_word(word): 36 | """Compile a word of uppercase letters as numeric digits. 37 | E.g., compile_word('YOU') => '(1*U+10*O+100*Y)' 38 | Non-uppercase words uncahanged: compile_word('+') => '+'""" 39 | if word.isupper(): 40 | terms = [('%s*%s' % (10**i, d)) 41 | for (i, d) in enumerate(word[::-1])] 42 | return '(' + '+'.join(terms) + ')' 43 | else: 44 | return word 45 | 46 | def faster_solve(formula): 47 | """Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it. 48 | Input formula is a string; output is a digit-filled-in string or None. 49 | This version precompiles the formula; only one eval per formula.""" 50 | f, letters = compile_formula(formula) 51 | for digits in itertools.permutations((1,2,3,4,5,6,7,8,9,0), len(letters)): 52 | try: 53 | if f(*digits) is True: 54 | table = string.maketrans(letters, ''.join(map(str, digits))) 55 | return formula.translate(table) 56 | except ArithmeticError: 57 | pass 58 | 59 | def timedcall(fn, *args): 60 | "Call function with args; return the time in seconds and result." 61 | t0 = time.clock() 62 | result = fn(*args) 63 | t1 = time.clock() 64 | return t1-t0, result 65 | 66 | def average(numbers): 67 | "Return the average (arithmetic mean) of a sequence of numbers." 68 | return sum(numbers) / float(len(numbers)) 69 | 70 | def timedcalls(n, fn, *args): 71 | """Call fn(*args) repeatedly: n times if n is an int, or up to 72 | n seconds if n is a float; return the min, avg, and max time""" 73 | tt,times = 0,[] 74 | if isinstance(n,int): 75 | while tt < n: 76 | t,result = timedcall(fn,*args) 77 | times.append(t) 78 | tt += 1 79 | else: 80 | while tt < n: 81 | t, result = timedcall(fn,*args) 82 | tt += t 83 | times.append(t) 84 | return min(times), average(times), max(times) 85 | 86 | examples = """TWO+TWO==FOUR 87 | A**2+B**2==C**2 88 | A**2+BE**2==BY**2 89 | X/X==X 90 | A**N+B**N==C**N and N>1 91 | A**N+B**N==C**N and N>2 92 | AB**N+C**N==EF**N and N>2 93 | AB**N+CD**N==EF**N and N>2 94 | AB**N+CD**N==EFG**N and N>2 95 | AB**N+CD**N==EFGH**N and N>2 96 | ATOM**.5 == A + TO + M 97 | GLITTERS is not GOLD 98 | ONE < TWO and FOUR < FIVE 99 | ONE < TWO < THREE 100 | RAMN == R**3 + RM**3 == N**3 + RX**3 101 | sum(range(AA)) == BB 102 | sum(range(POP))== BOBO 103 | ODD+ODD==EVEN 104 | PLUTO not in set([PLANETS])""".splitlines() 105 | 106 | # Peter Norvig suggested he'd be interested if we could solve the problem A**3+B**3==C**3 107 | # Seems to me you can use an anaalogy 108 | # for 2-D (**2) problem, you can divide a square into a set of equally-sized squares 109 | # 110 | def test(): 111 | t0 = time.clock() 112 | for e in examples: 113 | print; print 13*' ', e 114 | print '%6.4f sec: %s ' % timedcall(faster_solve, e) 115 | print '%6.4f tot.' % (time.clock()-t0) 116 | 117 | assert faster_solve('A + B == BA') == None # should NOT return '1 + 0 == 01' 118 | assert faster_solve('YOU == ME**2') == ('289 == 17**2' or '576 == 24**2' or '841 == 29**2') 119 | assert faster_solve('X / X == X') == '1 / 1 == 1' 120 | return 'tests pass' 121 | 122 | test() 123 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q2_3_cryptographic_formula.py: -------------------------------------------------------------------------------- 1 | # ------------- 2 | # User Instructions 3 | # 4 | # Complete the fill_in(formula) function by adding your code to 5 | # the two places marked with ?????. 6 | 7 | import string, re, itertools, time 8 | 9 | 10 | def solve(formula): 11 | """Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it. 12 | Input formula is a string; output is a digit-filled-in string or None.""" 13 | for f in fill_in(formula): 14 | #print f 15 | if valid(f): 16 | return f 17 | 18 | 19 | def fill_in(formula): 20 | "Generate all possible fillings-in of letters in formula with digits." 21 | letters = re.sub(r'[^A-Z]', '', formula) 22 | letters = ''.join(set(letters)) 23 | for digits in itertools.permutations('1234567890', len(letters)): 24 | #print ''.join(digits), letters 25 | table = string.maketrans(letters, ''.join(digits)) 26 | yield formula.translate(table) 27 | 28 | 29 | def valid(f): 30 | """Formula f is valid if and only if it has no 31 | numbers with leading zero, and evals true.""" 32 | try: 33 | return not re.search(r'\b0[0-9]', f) and eval(f) is True 34 | except ArithmeticError: 35 | return False 36 | 37 | 38 | examples = """TWO + TWO == FOUR 39 | A**2 + B**2 == C**2 40 | A**2 + BE**2 == BY**2 41 | X / X == X 42 | A**N + B**N == C**N and N > 1 43 | ATOM**0.5 == A + TO + M 44 | GLITTERS is not GOLD 45 | ONE < TWO and FOUR < FIVE 46 | ONE < TWO < THREE 47 | RAMN == R**3 + RM**3 == N**3 + RX**3 48 | sum(range(AA)) == BB 49 | sum(range(POP)) == BOBO 50 | ODD + ODD == EVEN 51 | PLUTO not in set ([PLANETS])""".splitlines() 52 | 53 | def test(): 54 | t0 = time.clock() 55 | for example in examples: 56 | print 57 | print ' '*10, example 58 | print '%6.4f s: ' % timedcall(solve, example) 59 | print '%6.4f s total' % (time.clock() - t0,) 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q3-29--trace.py: -------------------------------------------------------------------------------- 1 | # --------------- 2 | # User Instructions 3 | # 4 | # Modify the function, trace, so that when it is used 5 | # as a decorator it gives a trace as shown in the previous 6 | # video. You can test your function by applying the decorator 7 | # to the provided fibonnaci function. 8 | # 9 | # Note: Running this in the browser's IDE will not display 10 | # the indentations. 11 | 12 | from functools import update_wrapper 13 | 14 | 15 | def decorator(d): 16 | "Make function d a decorator: d wraps a function fn." 17 | def _d(fn): 18 | return update_wrapper(d(fn), fn) 19 | update_wrapper(_d, d) 20 | return _d 21 | 22 | @decorator 23 | def trace(f): 24 | indent = ' ' 25 | def _f(*args): 26 | signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args))) 27 | print '%s--> %s' % (trace.level*indent, signature) 28 | trace.level += 1 29 | try: 30 | result = f(*args) 31 | print '%s<-- %s == %s' % ((trace.level-1)*indent, 32 | signature, result) 33 | finally: 34 | trace.level -= 1 35 | return result 36 | trace.level = 0 37 | return _f 38 | 39 | @trace 40 | def fib(n): 41 | if n == 0 or n == 1: 42 | return 1 43 | else: 44 | return fib(n-1) + fib(n-2) 45 | 46 | fib(6) #running this in the browser's IDE will not display the indentations! 47 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q3-6--matchset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # module for solving the zebra puzzle and measuring execution time 3 | #---------------- 4 | # User Instructions 5 | # 6 | # The function, matchset, takes a pattern and a text as input 7 | # and returns a set of remainders. For example, if matchset 8 | # were called with the pattern star(lit(a)) and the text 9 | # 'aaab', matchset would return a set with elements 10 | # {'aaab', 'aab', 'ab', 'b'}, since a* can consume one, two 11 | # or all three of the a's in the text. 12 | # 13 | # Your job is to complete this function by filling in the 14 | # 'dot' and 'oneof' operators to return the correct set of 15 | # remainders. 16 | # 17 | # dot: matches any character. 18 | # oneof: matches any of the characters in the string it is 19 | # called with. oneof('abc') will match a or b or c. 20 | 21 | def matchset(pattern, text): 22 | "Match pattern at start of text; return a set of remainders of text." 23 | op, x, y = components(pattern) 24 | if 'lit' == op: 25 | return set([text[len(x):]]) if text.startswith(x) else null 26 | elif 'seq' == op: 27 | return set(t2 for t1 in matchset(x, text) for t2 in matchset(y, t1)) 28 | elif 'alt' == op: 29 | return matchset(x, text) | matchset(y, text) 30 | elif 'dot' == op: 31 | return set([text[1:]]) if len(text)>0 else null 32 | elif 'oneof' == op: 33 | return set([text[len(x):]]) if text.startswith(tuple(x)) else null 34 | elif 'eol' == op: 35 | return set(['']) if text == '' else null 36 | elif 'star' == op: 37 | return (set([text]) | 38 | set(t2 for t1 in matchset(x, text) 39 | for t2 in matchset(pattern, t1) if t1 != text)) 40 | else: 41 | raise ValueError('unknown pattern: %s' % pattern) 42 | 43 | null = frozenset() 44 | 45 | def components(pattern): 46 | "Return the op, x, and y arguments; x and y are None if missing." 47 | x = pattern[1] if len(pattern) > 1 else None 48 | y = pattern[2] if len(pattern) > 2 else None 49 | return pattern[0], x, y 50 | 51 | def test(): 52 | assert matchset(('lit', 'abc'), 'abcdef') == set(['def']) 53 | assert matchset(('seq', ('lit', 'hi '), 54 | ('lit', 'there ')), 55 | 'hi there nice to meet you') == set(['nice to meet you']) 56 | assert matchset(('alt', ('lit', 'dog'), 57 | ('lit', 'cat')), 'dog and cat') == set([' and cat']) 58 | assert matchset(('dot',), 'am i missing something?') == set(['m i missing something?']) 59 | assert matchset(('oneof', 'a'), 'aabc123') == set(['abc123']) 60 | assert matchset(('eol',),'') == set(['']) 61 | assert matchset(('eol',),'not end of line') == frozenset([]) 62 | assert matchset(('star', ('lit', 'hey')), 'heyhey!') == set(['!', 'heyhey!', 'hey!']) 63 | 64 | return 'tests pass' 65 | 66 | print test() 67 | 68 | 69 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/quiz/q3-8--match-and-search.py: -------------------------------------------------------------------------------- 1 | #--------------- 2 | # User Instructions 3 | # 4 | # Complete the search and match functions. Match should 5 | # match a pattern only at the start of the text. Search 6 | # should match anywhere in the text. 7 | 8 | def search(pattern, text): 9 | "Match pattern anywhere in text; return longest earliest match or None." 10 | for i in range(len(text)): 11 | m = match(pattern, text[i:]) 12 | if m is not None: 13 | return m 14 | 15 | def match(pattern, text): 16 | "Match pattern against start of text; return longest match found or None." 17 | remainders = matchset(pattern, text) 18 | if remainders: 19 | shortest = min(remainders, key=len) 20 | return text[:len(text)-len(shortest)] 21 | 22 | def components(pattern): 23 | "Return the op, x, and y arguments; x and y are None if missing." 24 | x = pattern[1] if len(pattern) > 1 else None 25 | y = pattern[2] if len(pattern) > 2 else None 26 | return pattern[0], x, y 27 | 28 | def matchset(pattern, text): 29 | "Match pattern at start of text; return a set of remainders of text." 30 | op, x, y = components(pattern) 31 | if 'lit' == op: 32 | return set([text[len(x):]]) if text.startswith(x) else null 33 | elif 'seq' == op: 34 | return set(t2 for t1 in matchset(x, text) for t2 in matchset(y, t1)) 35 | elif 'alt' == op: 36 | return matchset(x, text) | matchset(y, text) 37 | elif 'dot' == op: 38 | return set([text[1:]]) if text else null 39 | elif 'oneof' == op: 40 | return set([text[1:]]) if text.startswith(x) else null 41 | elif 'eol' == op: 42 | return set(['']) if text == '' else null 43 | elif 'star' == op: 44 | return (set([text]) | 45 | set(t2 for t1 in matchset(x, text) 46 | for t2 in matchset(pattern, t1) if t1 != text)) 47 | else: 48 | raise ValueError('unknown pattern: %s' % pattern) 49 | 50 | null = frozenset() 51 | 52 | def lit(string): return ('lit', string) 53 | def seq(x, y): return ('seq', x, y) 54 | def alt(x, y): return ('alt', x, y) 55 | def star(x): return ('star', x) 56 | def plus(x): return seq(x, start(x)) 57 | def opt(x): return alt(lit(''), x) 58 | def oneof(chars): return ('oneof', tuple(chars)) 59 | dot = ('dot',) 60 | eol = ('eol',) 61 | 62 | def test(): 63 | assert match(('star', ('lit', 'a')),'aaabcd') == 'aaa' 64 | assert match(('alt', ('lit', 'b'), ('lit', 'c')), 'ab') == None 65 | assert match(('alt', ('lit', 'b'), ('lit', 'a')), 'ab') == 'a' 66 | assert search(('alt', ('lit', 'b'), ('lit', 'c')), 'ab') == 'b' 67 | return 'tests pass' 68 | 69 | print test() 70 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/cannibals.py: -------------------------------------------------------------------------------- 1 | import doctest 2 | 3 | def mc_problem(start = (3, 3, 1, 0, 0, 0), goal = None): 4 | """Solve the missionaries and cannibals problem. State is 6 ints: (M1, C1, 5 | B1, M2, C2, B2) on the start (1) and other (2) sides. Find a path that goes 6 | from the initial state to the goal state (which, if not specified, is the 7 | state with no people or boats on the start side.) """ 8 | if goal is None: 9 | goal = (0, 0, 0) + start[:3] 10 | if start == goal: 11 | return [start] 12 | explored = set() # set of states we have visited 13 | frontier = [ [start] ] # ordered list of paths we have blazed 14 | while frontier: 15 | path = frontier.pop(0) 16 | s = path[-1] 17 | for (state, action) in csuccessors(s).items(): 18 | if state not in explored: 19 | explored.add(state) 20 | path2 = path + [action, state] 21 | if state == goal: 22 | return path2 23 | else: 24 | frontier.append(path2) 25 | 26 | def csuccessors(state): 27 | # Norvig's solution, with a check to make sure no state has negative numbers. 28 | """Find successors (including those that result in dining) to this 29 | state. But a state where the cannibals can dine has no successors.""" 30 | M1, C1, B1, M2, C2, B2 = state 31 | ## Check for state with no successors 32 | if C1 > M1 > 0 or C2 > M2 > 0: 33 | return {} 34 | items = [] 35 | if B1 > 0: 36 | for delta, a in deltas.items(): 37 | x = sub(state, delta) 38 | if all(val >= 0 for val in x): 39 | items.append((sub(state, delta), a + '->')) 40 | if B2 > 0: 41 | for delta, a in deltas.items(): 42 | x = add(state, delta) 43 | if all(val >= 0 for val in x): 44 | items.append((add(state, delta), '<-' + a)) 45 | return dict(items) 46 | 47 | deltas = { 48 | (2, 0, 1, -2, 0, -1): 'MM', 49 | (0, 2, 1, 0, -2, -1): 'CC', 50 | (1, 1, 1, -1, -1, -1): 'MC', 51 | (1, 0, 1, -1, 0, -1): 'M', 52 | (0, 1, 1, 0, -1, -1): 'C'} 53 | 54 | def add(X, Y): 55 | "add two vectors, X and Y." 56 | return tuple(x+y for x, y in zip(X, Y)) 57 | 58 | def sub(X, Y): 59 | "subtract two vectors, X and Y." 60 | return tuple(x-y for x, y in zip(X, Y)) 61 | 62 | def test(): 63 | """ 64 | >>> mc_problem((1, 2, 1, 0, 0, 0)) 65 | 66 | """ 67 | assert csuccessors((2, 2, 1, 0, 0, 0)) == {(2, 1, 0, 0, 1, 1): 'C->', 68 | (1, 2, 0, 1, 0, 1): 'M->', 69 | (0, 2, 0, 2, 0, 1): 'MM->', 70 | (1, 1, 0, 1, 1, 1): 'MC->', 71 | (2, 0, 0, 0, 2, 1): 'CC->'} 72 | assert csuccessors((1, 1, 0, 4, 3, 1)) == {(1, 2, 1, 4, 2, 0): '<-C', 73 | (2, 1, 1, 3, 3, 0): '<-M', 74 | (3, 1, 1, 2, 3, 0): '<-MM', 75 | (1, 3, 1, 4, 1, 0): '<-CC', 76 | (2, 2, 1, 3, 2, 0): '<-MC'} 77 | assert csuccessors((1, 0, 0, 4, 1, 1)) == {(1, 1, 1, 4, 0, 0): '<-C', 78 | (2, 0, 1, 3, 1, 0): '<-M', 79 | (2, 1, 1, 3, 0, 0): '<-MC', 80 | (3, 0, 1, 2, 1, 0): '<-MM'} 81 | assert csuccessors((1, 4, 1, 2, 2, 0)) == {} 82 | assert mc_problem((1, 0, 1, 0, 0, 0)) == [(1, 0, 1, 0, 0, 0), 'M->', (0, 0, 0, 1, 0, 1)] 83 | assert mc_problem((1, 1, 1, 0, 0, 0)) == [(1, 1, 1, 0, 0, 0), 'MC->', (0, 0, 0, 1, 1, 1)] 84 | assert mc_problem((2, 1, 1, 0, 0, 0)) == [(2, 1, 1, 0, 0, 0), 'MC->', (1, 0, 0, 1, 1, 1), '<-C', (1, 1, 1, 1, 0, 0), 'MC->', (0, 0, 0, 2, 1, 1)] 85 | assert mc_problem((1, 2, 1, 0, 0, 0)) == None 86 | return 'tests pass' 87 | 88 | print(doctest.testmod()) 89 | print test() 90 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/cryptarithmatic.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import string, re 3 | import itertools 4 | import time 5 | 6 | def solve(formula): 7 | """Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it. 8 | Input formula is a string; output is a digit-filled-in string or None.""" 9 | for answer in (f for f in fill_in(formula) if valid(f)): 10 | return answer 11 | 12 | def fill_in(formula): 13 | "Generate all possible fillings-in of letters in formula with digits." 14 | letters = ''.join(set(l for l in formula if l in string.uppercase)) 15 | for digits in itertools.permutations('1234567890', len(letters)): 16 | table = string.maketrans(letters, ''.join(digits)) 17 | yield formula.translate(table) 18 | 19 | def valid(f): 20 | """Formula f is valid if and only if it has no 21 | numbers with leading zero, and evals true.""" 22 | try: 23 | return not re.search(r'\b0[0-9]', f) and eval(f) is True 24 | except ArithmeticError: 25 | return False 26 | 27 | def faster_solve(formula): 28 | """Given a formula like 'ODD + ODD == EVEN', fill in digits to solve it. 29 | Input formula is a string; output is a digit-filled-in string or None. 30 | This version precompiles the formula; only one eval per formula.""" 31 | f, letters = compile_formula(formula) 32 | for digits in itertools.permutations((1,2,3,4,5,6,7,8,9,0), len(letters)): 33 | try: 34 | if f(*digits) is True: 35 | table = string.maketrans(letters, ''.join(map(str, digits))) 36 | return formula.translate(table) 37 | except ArithmeticError: 38 | pass 39 | 40 | def compile_formula(formula, verbose=False): 41 | """Compile formula into a function. Also return letters found, as a str, 42 | in same order as parms of function. For example, 'YOU == ME**2' returns 43 | (lambda Y, M, E, U, O): (U+10*O+100*Y) == (E+10*M)**2), 'YMEUO' """ 44 | letters = ''.join(set(re.findall('[A-Z]', formula))) 45 | parms = ', '.join(letters) 46 | tokens = map(compile_word, re.split('([A-Z]+)', formula)) 47 | body = ''.join(tokens) 48 | f = 'lambda %s: %s' % (parms, body) 49 | if verbose: print f 50 | return eval(f), letters 51 | 52 | def compile_word(word): 53 | """Compile a word of uppercase letters as numeric digits. 54 | E.g., compile_word('YOU') => '(1*U+10*O+100*Y)' 55 | Non-uppercase words unchanged: compile_word('+') => '+'""" 56 | if word.isupper(): 57 | terms = [('%s*%s' % (10**i, d)) 58 | for (i, d) in enumerate(word[::-1])] 59 | return '(' + '+'.join(terms) + ')' 60 | else: 61 | return word 62 | 63 | examples = """TWO + TWO == FOUR 64 | A**2 + B**2 == C**2 65 | A**2 + BE**2 == BY**2 66 | X / X == X 67 | A**N + B**N == C**N and N > 1 68 | ATOM**0.5 == A + TO + M 69 | GLITTERS is not GOLD 70 | ONE < TWO and FOUR < FIVE 71 | ONE < TWO < THREE 72 | RAMN == R**3 + RM**3 == N**3 + RX**3 73 | sum(range(AA)) == BB 74 | sum(range(POP)) == BOBO 75 | ODD + ODD == EVEN 76 | PLUTO not in set([PLANETS])""".splitlines() 77 | 78 | def test(): 79 | t0 = time.clock() 80 | for example in examples: 81 | print; print 13*' ', example 82 | print '%6.4f sec: %s ' % timedcall(faster_solve, example) 83 | print '%6.4f tot.' % (time.clock()-t0) 84 | 85 | def timedcall(fn, *args): 86 | "Call function with args; return the time in seconds and result." 87 | t0 = time.clock() 88 | result = fn(*args) 89 | t1 = time.clock() 90 | return t1-t0, result 91 | 92 | def average(numbers): 93 | "Return the average (arithmetic mean) of a sequence of numbers." 94 | return sum(numbers) / float(len(numbers)) 95 | 96 | def timedcalls(n, fn, *args): 97 | """Call fn(*args) repeatedly: n times if n is an int, or up to 98 | n seconds if n is a float; return the min, avg, and max time""" 99 | if isinstance(n, int): 100 | times = [timedcall(fn, *args)[0] for _ in range(n)] 101 | else: 102 | times = [] 103 | total = 0.0 104 | while total < n: 105 | t = timedcall(fn, *args)[0] 106 | total += t 107 | times.append(t) 108 | return min(times), average(times), max(times) 109 | 110 | test() 111 | 112 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/decorators.py: -------------------------------------------------------------------------------- 1 | import functools 2 | 3 | def decorator(d): 4 | "Make function d a decorator: d wraps a function fn." 5 | def _d(fn): 6 | return functools.update_wrapper(d(fn), fn) 7 | return _d 8 | decorator = decorator(decorator) 9 | 10 | @decorator 11 | def n_ary(f): 12 | """Given binary function f(x, y), return an n_ary function such 13 | that f(x, y, z) = f(x, f(y,z)), etc. Also allow f(x) = x.""" 14 | def n_ary_f(x, *args): 15 | return x if not args else f(x, n_ary_f(*args)) 16 | return n_ary_f 17 | 18 | @decorator 19 | def memo(f): 20 | """Decorator that caches the return value for each call to f(args). 21 | Then when called again with same args, we can just look it up.""" 22 | cache = {} 23 | def _f(*args): 24 | try: 25 | return cache[args] 26 | except KeyError: 27 | result = f(*args) 28 | cache[args] = result 29 | return result 30 | except TypeError: 31 | # some element of args can't be a dict key 32 | return f(*args) 33 | _f.cache = cache 34 | return _f 35 | 36 | @decorator 37 | def countcalls(f): 38 | "Decorator that makes the function count calls to it, in callcounts[f]." 39 | def _f(*args): 40 | callcounts[_f] += 1 41 | return f(*args) 42 | callcounts[_f] = 0 43 | return _f 44 | callcounts = {} 45 | 46 | @decorator 47 | def trace(f): 48 | indent = ' ' 49 | def _f(*args): 50 | signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args))) 51 | print '%s--> %s' % (trace.level*indent, signature) 52 | trace.level += 1 53 | try: 54 | result = f(*args) 55 | print '%s<-- %s == %s' % ((trace.level-1)*indent, 56 | signature, result) 57 | finally: 58 | trace.level -= 1 59 | return result 60 | trace.level = 0 61 | return _f 62 | 63 | def disabled(f): 64 | # Example: Use trace = disabled to turn off trace decorators 65 | return f 66 | 67 | @trace 68 | def fib(n): 69 | if n == 0 or n == 1: 70 | return 1 71 | else: 72 | return fib(n-1) + fib(n-2) 73 | 74 | fib(6) #running this in the browser's IDE will not display the indentations! 75 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/pour.py: -------------------------------------------------------------------------------- 1 | import doctest 2 | 3 | def pour_problem(X, Y, goal, start = (0, 0)): 4 | """X and Y are the capacity of glasses; (x,y) is current fill levels and 5 | represent a state. The goal is a level that can be in either glass. Start at 6 | start state and follow successors until we reach the goal. Keep track of 7 | frontier and previously explored; fail when no frontier.""" 8 | if goal in start: 9 | return [start] 10 | explored = set() # set the states we have visited 11 | frontier = [ [start] ] # ordered list of paths we have blazed 12 | while frontier: 13 | path = frontier.pop(0) 14 | (x, y) = path[-1] # Last state in the first path of the frontier 15 | for (state, action) in successors(x, y, X, Y).items(): 16 | if state not in explored: 17 | explored.add(state) 18 | path2 = path + [action, state] 19 | if goal in state: 20 | return path2 21 | else: 22 | frontier.append(path2) 23 | return Fail 24 | Fail = [] 25 | 26 | def successors(x, y, X, Y): 27 | """Return a dict of {state:action} pairs describing what can be reached from 28 | the (x, y) state and how.""" 29 | assert x <= X and y <= Y ## (x, y) is glass levels; X and Y are glass sizes 30 | return {((0, y+x) if y+x <= Y else (x-(Y-y), y+(Y-y))): 'X->Y', 31 | ((x+y, 0) if x+y <= X else (x+(X-x), y-(X-x))): 'X<-Y', 32 | (X, y): 'fill X', 33 | (x, Y): 'fill Y', 34 | (0, y): 'empty X', 35 | (x, 0): 'empty Y' 36 | } 37 | 38 | class Test: 39 | """ 40 | >>> successors(0, 0, 4, 9) 41 | {(0, 9): 'fill Y', (0, 0): 'empty Y', (4, 0): 'fill X'} 42 | 43 | >>> successors(3, 5, 4, 9) 44 | {(4, 5): 'fill X', (4, 4): 'X<-Y', (3, 0): 'empty Y', (3, 9): 'fill Y', (0, 5): 'empty X', (0, 8): 'X->Y'} 45 | 46 | >>> successors(3, 7, 4, 9) 47 | {(4, 7): 'fill X', (4, 6): 'X<-Y', (3, 0): 'empty Y', (0, 7): 'empty X', (3, 9): 'fill Y', (1, 9): 'X->Y'} 48 | 49 | >>> pour_problem(4, 9, 6) 50 | [(0, 0), 'fill Y', (0, 9), 'X<-Y', (4, 5), 'empty X', (0, 5), 'X<-Y', (4, 1), 'empty X', (0, 1), 'X<-Y', (1, 0), 'fill Y', (1, 9), 'X<-Y', (4, 6)] 51 | 52 | ## What problem, with X, Y, and goal < 10 has the longest solution? 53 | ## Answer: pour_problem(7, 9, 8) with 14 steps. 54 | 55 | >>> def num_actions(triplet): X, Y, goal = triplet; return len(pour_problem(X, Y, goal)) / 2 56 | 57 | >>> def hardness(triplet): X, Y, goal = triplet; return num_actions((X, Y, goal)) - max(X, Y) 58 | >>> max([(X, Y, goal) for X in range(1, 10) for Y in range(1, 10) 59 | ... for goal in range(1, max(X, Y))], key = num_actions) 60 | (7, 9, 8) 61 | 62 | >>> max([(X, Y, goal) for X in range(1, 10) for Y in range(1, 10) 63 | ... for goal in range(1, max(X, Y))], key = hardness) 64 | (7, 9, 8) 65 | 66 | >>> pour_problem(7, 9, 8) 67 | [(0, 0), 'fill Y', (0, 9), 'X<-Y', (7, 2), 'empty X', (0, 2), 'X<-Y', (2, 0), 'fill Y', (2, 9), 'X<-Y', (7, 4), 'empty X', (0, 4), 'X<-Y', (4, 0), 'fill Y', (4, 9), 'X<-Y', (7, 6), 'empty X', (0, 6), 'X<-Y', (6, 0), 'fill Y', (6, 9), 'X<-Y', (7, 8)] 68 | """ 69 | 70 | print(doctest.testmod()) 71 | # TestResults(failed=0, attempted=9) 72 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/regex_compiler.py: -------------------------------------------------------------------------------- 1 | def match(pattern, text): 2 | "Match pattern against start of text; return longest match found or None." 3 | remainders = pattern(text) 4 | if remainders: 5 | shortest = min(remainders, key = len) 6 | return text[:len(text)-len(shortest)] 7 | 8 | def search(pattern, text): 9 | "Match pattern anywhere in text; return longest earliest match or None." 10 | for i in range(len(text) or 1): 11 | m = match(pattern, text[i:]) 12 | if m is not None: return m 13 | 14 | def lit(s): return lambda t: set([t[len(s):]]) if t.startswith(s) else null 15 | def seq(x, y): return lambda t: set().union(*map(y, x(t))) 16 | def alt(x, y): return lambda t: x(t) | y(t) 17 | def oneof(chars): return lambda t: set([t[1:]]) if (t and t[0] in chars) else null 18 | def opt(x): return lambda t: alt(lit(''), x)(t) 19 | 20 | dot = lambda t: set([t[1:]]) if t else null 21 | eol = lambda t: set(['']) if t == '' else null 22 | def star(x): return lambda t: (set([t]) | 23 | set(t2 for t1 in x(t) if t1 != t 24 | for t2 in star(x)(t1))) 25 | def plus(x): return lambda t: seq(x, star(x))(t) 26 | 27 | null = frozenset([]) 28 | 29 | def test(): 30 | g = alt(lit('a'), lit('b')) 31 | assert g('abc') == set(['bc']) 32 | 33 | assert match(star(lit('a')), 'aaaaabbbaa') == 'aaaaa' 34 | assert match(lit('hello'), 'hello how are you?') == 'hello' 35 | assert match(lit('x'), 'hello how are you?') == None 36 | assert match(oneof('xyz'), 'x**2 + y**2 = r**2') == 'x' 37 | assert match(oneof('xyz'), ' x is here!') == None 38 | 39 | assert match(star(lit('a')), 'aaabcd') == 'aaa' 40 | assert match(lit('abc'), 'abc') == 'abc' 41 | assert match(alt(lit('b'), lit('c')), 'ab') == None 42 | assert match(alt(lit('b'), lit('a')), 'ab') == 'a' 43 | assert search(lit(''), '') == '' 44 | assert search(alt(lit('b'), lit('c')), 'ab') == 'b' 45 | assert search(star(alt(lit('a'), lit('b'))), 'ab') == 'ab' 46 | assert search(alt(lit('b'), lit('c')), 'ad') == None 47 | assert lit('abc')('abcdef') == set(['def']) 48 | assert (seq(lit('hi '), lit('there '))('hi there nice to meet you') 49 | == set(['nice to meet you'])) 50 | assert alt(lit('dog'), lit('cat'))('dog and cat') == set([' and cat']) 51 | assert dot('am i missing something?') == set(['m i missing something?']) 52 | assert dot('') == frozenset([]) 53 | assert oneof('a')('aabc123') == set(['abc123']) 54 | assert oneof('abc')('babc123') == set(['abc123']) 55 | assert oneof('abc')('dabc123') == frozenset([]) 56 | assert eol('') == set(['']) 57 | assert eol('not end of line') == frozenset([]) 58 | assert star(lit('hey'))('heyhey!') == set(['!', 'heyhey!', 'hey!']) 59 | assert plus(lit('hey'))('heyhey!') == set(['!', 'hey!']) 60 | assert opt(lit('hey'))('heyhey!') == set(['hey!', 'heyhey!']) 61 | 62 | return 'tests pass' 63 | 64 | print test() 65 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/regex_generator.py: -------------------------------------------------------------------------------- 1 | def lit(s): return lambda Ns: set([s]) if len(s) in Ns else null 2 | def alt(x, y): return lambda Ns: x(Ns) | y(Ns) 3 | def star(x): return lambda Ns: opt(plus(x))(Ns) 4 | def plus(x): return lambda Ns: genseq(x, star(x), Ns, startx = 1) #Tricky 5 | def oneof(chars): return lambda Ns: set(chars) if 1 in Ns else null 6 | def seq(x, y): return lambda Ns: genseq(x, y, Ns) 7 | def opt(x): return alt(epsilon, x) 8 | dot = oneof('?') # You could expand the alphabet to more chars. 9 | epsilon = lit('') # The pattern that matches the empty string. 10 | 11 | null = frozenset([]) 12 | 13 | def genseq(x, y, Ns, startx = 0): 14 | """Set of matches to xy whose total len is in Ns, with x-match's len in Ns and 15 | >= startx""" 16 | # Tricky part: x+ is defined as: x+ = x x* To stop the recursion, the first x 17 | # must generate at least 1 char, and then the recursive x* has that many fewer 18 | # characters. We use startx = 1 to say that x must match at least 1 character 19 | if not Ns: 20 | return null 21 | xmatches = x(set(range(startx, max(Ns)+1))) 22 | Ns_x = set(len(m) for m in xmatches) 23 | Ns_y = set(n-m for n in Ns for m in Ns_x if n-m >= 0) 24 | ymatches = y(Ns_y) 25 | return set(m1+m2 for m1 in xmatches for m2 in ymatches if len(m1+m2) in Ns) 26 | 27 | def test(): 28 | f = lit('hello') 29 | assert f(set([1, 2, 3, 4, 5])) == set(['hello']) 30 | assert f(set([1, 2, 3, 4])) == null 31 | 32 | g = alt(lit('hi'), lit('bye')) 33 | assert g(set([1, 2, 3, 4, 5, 6])) == set(['bye', 'hi']) 34 | assert g(set([1, 3, 5])) == set(['bye']) 35 | 36 | h = oneof('theseletters') 37 | assert h(set([1, 2, 3])) == set(['t', 'h', 'e', 's', 'l', 'r']) 38 | assert h(set([2, 3, 4])) == null 39 | return 'tests pass' 40 | 41 | def test_gen(): 42 | def N(hi): 43 | return set(range(hi+1)) 44 | a, b, c = map(lit, 'abc') 45 | assert star(oneof('ab'))(N(2)) == set(['', 'a', 'aa', 'ab', 'ba', 'bb', 'b']) 46 | assert (seq(star(a), seq(star(b), star(c)))(set([4])) == 47 | set(['aaaa', 'aaab', 'aaac', 'aabb', 'aabc', 'aacc', 'abbb', 48 | 'abbc', 'abcc', 'accc', 'bbbb', 'bbbc', 'bbcc', 'bccc', 'cccc'])) 49 | assert (seq(plus(a), seq(plus(b), plus(c)))(set([5])) == 50 | set(['aaabc', 'aabbc', 'aabcc', 'abbbc', 'abbcc', 'abccc'])) 51 | assert (seq(oneof('bcfhrsm'), lit('at'))(N(3)) == 52 | set(['bat', 'cat', 'fat', 'hat', 'mat', 'rat', 'sat'])) 53 | assert (seq(star(alt(a, b)), opt(c))(set([3])) == 54 | set(['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'baa', 55 | 'bab', 'bac', 'bba', 'bbb', 'bbc'])) 56 | assert lit('hello')(set([5])) == set(['hello']) 57 | assert lit('hello')(set([4])) == set() 58 | assert lit('hello')(set([6])) == set() 59 | return 'test_gen passes' 60 | 61 | print(test()) 62 | print(test_gen()) 63 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/regex_interpreter.py: -------------------------------------------------------------------------------- 1 | def search(pattern, text): 2 | "Match pattern anywhere in text; return longest earliest match or None." 3 | for i in range(len(text) or 1): 4 | m = match(pattern, text[i:]) 5 | if m is not None: return m 6 | 7 | def match(pattern, text): 8 | "Match pattern against start of text; return longest match found or None." 9 | remainders = matchset(pattern, text) 10 | if remainders: 11 | shortest = min(remainders, key = len) 12 | return text[:len(text)-len(shortest)] 13 | 14 | def matchset(pattern, text): 15 | "Match pattern at start of text; return a set of remainders of text." 16 | op, x, y = components(pattern) 17 | if 'lit' == op: 18 | return set([text[len(x):]]) if text.startswith(x) else null 19 | elif 'seq' == op: 20 | return set(t2 for t1 in matchset(x, text) for t2 in matchset(y, t1)) 21 | elif 'alt' == op: 22 | return matchset(x, text) | matchset(y, text) 23 | elif 'dot' == op: 24 | return set([text[1:]]) if text else null 25 | elif 'oneof' == op: 26 | return set([text[1:]]) if text.startswith(tuple(x)) else null 27 | elif 'eol' == op: 28 | return set(['']) if text == '' else null 29 | elif 'star' == op: 30 | return (set([text]) | 31 | set(t2 for t1 in matchset(x, text) 32 | for t2 in matchset(pattern, t1) if t1 != text)) 33 | else: 34 | raise ValueError('unknown pattern: %s' % pattern) 35 | 36 | null = frozenset() 37 | 38 | def components(pattern): 39 | "Return the op, x, and y arguments; x and y are None if missing." 40 | x = pattern[1] if len(pattern) > 1 else None 41 | y = pattern[2] if len(pattern) > 2 else None 42 | return pattern[0], x, y 43 | 44 | def lit(string): return ('lit', string) 45 | def seq(x, y): return ('seq', x, y) 46 | def alt(x, y): return ('alt', x, y) 47 | def star(x): return ('star', x) 48 | def plus(x): return ('seq', x, ('star', x)) 49 | def opt(x): return alt(lit(''), x) #opt(x) means that x is optional 50 | def oneof(chars): return ('oneof', tuple(chars)) 51 | dot = ('dot', ) 52 | eol = ('eol', ) 53 | 54 | def test(): 55 | assert match(('star', ('lit', 'a')), 'aaabcd') == 'aaa' 56 | assert match(('alt', ('lit', 'b'), ('lit', 'c')), 'ab') == None 57 | assert match(('alt', ('lit', 'b'), ('lit', 'a')), 'ab') == 'a' 58 | assert search(('lit', ''), '') == '' 59 | assert search(('alt', ('lit', 'b'), ('lit', 'c')), 'ab') == 'b' 60 | assert matchset(('lit', 'abc'), 'abcdef') == set(['def']) 61 | assert matchset(('seq', ('lit', 'hi '), 62 | ('lit', 'there ')), 63 | 'hi there nice to meet you') == set(['nice to meet you']) 64 | assert matchset(('alt', ('lit', 'dog'), 65 | ('lit', 'cat')), 'dog and cat') == set([' and cat']) 66 | assert (matchset(('dot', ), 'am i missing something?') 67 | == set(['m i missing something?'])) 68 | assert matchset(('dot', ), '') == frozenset([]) 69 | assert matchset(('oneof', 'a'), 'aabc123') == set(['abc123']) 70 | assert matchset(('oneof', 'abc'), 'babc123') == set(['abc123']) 71 | assert matchset(('oneof', 'abc'), 'dabc123') == frozenset([]) 72 | assert matchset(('eol', ), '') == set(['']) 73 | assert matchset(('eol', ), 'not end of line') == frozenset([]) 74 | assert matchset(('star', ('lit', 'hey')), 'heyhey!') == set(['!', 'heyhey!', 'hey!']) 75 | 76 | assert lit('abc') == ('lit', 'abc') 77 | assert seq(('lit', 'a'), 78 | ('lit', 'b')) == ('seq', ('lit', 'a'), ('lit', 'b')) 79 | assert alt(('lit', 'a'), 80 | ('lit', 'b')) == ('alt', ('lit', 'a'), ('lit', 'b')) 81 | assert star(('lit', 'a')) == ('star', ('lit', 'a')) 82 | assert plus(('lit', 'c')) == ('seq', ('lit', 'c'), 83 | ('star', ('lit', 'c'))) 84 | assert opt(('lit', 'x')) == ('alt', ('lit', ''), ('lit', 'x')) 85 | assert oneof('abc') == ('oneof', ('a', 'b', 'c')) 86 | return 'tests pass' 87 | 88 | if __name__ == '__main__': 89 | print test() 90 | -------------------------------------------------------------------------------- /cs212-Design-of-Computer-Programs/wiki-code/zebra.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | import time 3 | 4 | def imright(h1, h2): 5 | "House h1 is immediately right of h2 if h1-h2 == 1." 6 | return h1-h2 == 1 7 | 8 | def nextto(h1, h2): 9 | "Two houses are next to each other if they differ by 1." 10 | return abs(h1-h2) == 1 11 | 12 | def zebra_puzzle(): 13 | "Return a tuple (WATER, ZEBRA indicating their house numbers." 14 | houses = first, _, middle, _, _ = [1, 2, 3, 4, 5] 15 | orderings = list(itertools.permutations(houses)) # 1 16 | return next((WATER, ZEBRA) 17 | for (red, green, ivory, yellow, blue) in c(orderings) 18 | if imright(green, ivory) 19 | for (Englishman, Spaniard, Ukranian, Japanese, Norwegian) in c(orderings) 20 | if Englishman is red 21 | if Norwegian is first 22 | if nextto(Norwegian, blue) 23 | for (coffee, tea, milk, oj, WATER) in c(orderings) 24 | if coffee is green 25 | if Ukranian is tea 26 | if milk is middle 27 | for (OldGold, Kools, Chesterfields, LuckyStrike, Parliaments) in c(orderings) 28 | if Kools is yellow 29 | if LuckyStrike is oj 30 | if Japanese is Parliaments 31 | for (dog, snails, fox, horse, ZEBRA) in c(orderings) 32 | if Spaniard is dog 33 | if OldGold is snails 34 | if nextto(Chesterfields, fox) 35 | if nextto(Kools, horse) 36 | ) 37 | 38 | def c(sequence): 39 | c.starts += 1 40 | for item in sequence: 41 | c.items += 1 42 | yield item 43 | 44 | def instrument_fn(fn, *args): 45 | c.starts, c.items = 0, 0 46 | result = fn(*args) 47 | print('%s got %s with %5d iters over %7d items'%( 48 | fn.__name__, result, c.starts, c.items)) 49 | 50 | -------------------------------------------------------------------------------- /cs253-Web-Application-Engineering/app.yaml: -------------------------------------------------------------------------------- 1 | application: guestbook 2 | version: 1 3 | runtime: python27 4 | api_version: 1 5 | threadsafe: yes 6 | 7 | handlers: 8 | - url: .* 9 | script: guestbook.app 10 | 11 | libraries: 12 | - name: webapp2 13 | version: "2.5.1" 14 | -------------------------------------------------------------------------------- /cs253-Web-Application-Engineering/guestbook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2007 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | import cgi 18 | import datetime 19 | import webapp2 20 | 21 | from google.appengine.ext import db 22 | from google.appengine.api import users 23 | 24 | class Greeting(db.Model): 25 | author = db.UserProperty() 26 | content = db.StringProperty(multiline=True) 27 | date = db.DateTimeProperty(auto_now_add=True) 28 | 29 | 30 | class MainPage(webapp2.RequestHandler): 31 | def get(self): 32 | self.response.out.write('') 33 | 34 | greetings = db.GqlQuery("SELECT * " 35 | "FROM Greeting " 36 | "ORDER BY date DESC LIMIT 10") 37 | 38 | for greeting in greetings: 39 | if greeting.author: 40 | self.response.out.write('%s wrote:' % greeting.author.nickname()) 41 | else: 42 | self.response.out.write('An anonymous person wrote:') 43 | self.response.out.write('%s' % 44 | cgi.escape(greeting.content)) 45 | 46 | 47 | self.response.out.write(""" 48 | 52 | 53 | """) 54 | 55 | 56 | class Guestbook(webapp2.RequestHandler): 57 | def post(self): 58 | greeting = Greeting() 59 | 60 | if users.get_current_user(): 61 | greeting.author = users.get_current_user() 62 | 63 | greeting.content = self.request.get('content') 64 | greeting.put() 65 | self.redirect('/') 66 | 67 | 68 | app = webapp2.WSGIApplication([ 69 | ('/', MainPage), 70 | ('/sign', Guestbook) 71 | ], debug=True) 72 | -------------------------------------------------------------------------------- /cs262-Programming-Languages/cs262--Norvig Answers/CS262 Unit 1-v24 Parsing, Regular Expressions, Finite State Machines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/cs262-Programming-Languages/cs262--Norvig Answers/CS262 Unit 1-v24 Parsing, Regular Expressions, Finite State Machines.pdf -------------------------------------------------------------------------------- /cs262-Programming-Languages/cs262--Norvig Answers/CS262 Unit 3-v4 Grammar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hobson/udacity/1786646d8ae61b7986679c5fa12a914149a7fffa/cs262-Programming-Languages/cs262--Norvig Answers/CS262 Unit 3-v4 Grammar.pdf -------------------------------------------------------------------------------- /cs262-Programming-Languages/cs262--Norvig Answers/final1-bowling.py: -------------------------------------------------------------------------------- 1 | """ 2 | UNIT 1: Bowling: 3 | 4 | You will write the function bowling(balls), which returns an integer indicating 5 | the score of a ten-pin bowling game. balls is a list of integers indicating 6 | how many pins are knocked down with each ball. For example, a perfect game of 7 | bowling would be described with: 8 | 9 | >>> bowling([10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]) 10 | 300 11 | 12 | The rules of bowling are as follows: 13 | 14 | (1) A game consists of 10 frames. In each frame you roll one or two balls, 15 | except for the tenth frame, where you roll one, two, or three. Your total 16 | score is the sum of your scores for the ten frames. 17 | (2) If you knock down fewer than ten pins with your two balls in the frame, 18 | you score the total knocked down. For example, bowling([8, 1, 7, ...]) means 19 | that you knocked down a total of 9 pins in the first frame. You score 9 point 20 | for the frame, and you used up two balls in the frame. The second frame will 21 | start with the 7. 22 | (3) If you knock down all ten pins on your second ball it is called a 'spare' 23 | and you score 10 points plus a bonus: whatever you roll with your next ball. 24 | The next ball will also count in the next frame, so the next ball counts twice 25 | (except in the tenth frame, in which case the bonus ball counts only once). 26 | For example, bowling([8, 2, 7, ...]) means you get a spare in the first frame. 27 | You score 10 + 7 for the frame; the second frame starts with the 7. 28 | (4) If you knock down all ten pins on your first ball it is called a 'strike' 29 | and you score 10 points plus a bonus of your score on the next two balls. 30 | (The next two balls also count in the next frame, except in the tenth frame.) 31 | For example, bowling([10, 7, 3, ...]) means that you get a strike, you score 32 | 10 + 7 + 3 = 20 in the first frame; the second frame starts with the 7. 33 | 34 | """ 35 | 36 | def bowling(balls): 37 | "Compute the total score for a player's game of bowling." 38 | total = 0 39 | for frame in range(10): 40 | score, balls = score_frame(balls) 41 | total += score 42 | return total 43 | 44 | def score_frame(balls): 45 | "Return two values: (score_for_this_frame, remaining_balls)." 46 | n_used, n_scoring = ((1, 3) if balls[0] == 10 # strike 47 | else (2, 3) if balls[0] + balls[1] == 10 # spare 48 | else (2, 2)) # open frame 49 | return (sum(balls[:n_scoring]), balls[n_used:]) 50 | 51 | def test_bowling(): 52 | assert 0 == bowling([0] * 20) 53 | assert 20 == bowling([1] * 20) 54 | assert 80 == bowling([4] * 20) 55 | assert 190 == bowling([9,1] * 10 + [9]) 56 | assert 300 == bowling([10] * 12) 57 | assert 200 == bowling([10, 5,5] * 5 + [10]) 58 | assert 11 == bowling([0,0] * 9 + [10,1,0]) 59 | assert 12 == bowling([0,0] * 8 + [10, 1,0]) 60 | 61 | 62 | 63 | ## In the solution above, score_frame does most of the work, deciding the 64 | ## score for the frame, and what balls remain for subsequent frames. 65 | ## The logic of summing results is obscured by the need to return 2 values. 66 | ## An alternative solution below that makes it more explicit that we are summing 67 | ## the 10 frames scores, by mutating balls rather than returning a 2nd value: 68 | 69 | def bowling(balls): 70 | "Compute the score for one player's game of bowling." 71 | return sum(score_frame1(balls) for frame in range(10)) 72 | 73 | def score_frame1(balls): 74 | "Return (score, balls): the score for this frame and the remaining balls." 75 | n_used, n_scoring = ((1, 3) if balls[0] == 10 # strike 76 | else (2, 3) if balls[0] + balls[1] == 10 # spare 77 | else (2, 2)) # open frame 78 | score = sum(balls[:n_scoring]) 79 | balls[:n_used] = [] 80 | return score 81 | -------------------------------------------------------------------------------- /cs262-Programming-Languages/cs262--Norvig Answers/parsing-code.py: -------------------------------------------------------------------------------- 1 | work_count = 0 # track one notion of "time taken" 2 | 3 | def addtoset(theset,index,elt): 4 | if not (elt in theset[index]): 5 | theset[index] = [elt] + theset[index] 6 | return True 7 | return False 8 | 9 | def parse(tokens,grammar): 10 | global work_count 11 | work_count = 0 12 | tokens = tokens + [ "end_of_input_marker" ] 13 | chart = {} 14 | start_rule = grammar[0] 15 | for i in range(len(tokens)+1): 16 | chart[i] = [ ] 17 | start_state = (start_rule[0], [], start_rule[1], 0) 18 | chart[0] = [ start_state ] 19 | for i in range(len(tokens)): 20 | while True: 21 | changes = False 22 | for state in chart[i]: 23 | # State === x -> a b . c d , j 24 | x = state[0] 25 | ab = state[1] 26 | cd = state[2] 27 | j = state[3] 28 | 29 | # Current State == x -> a b . c d , j 30 | # Option 1: For each grammar rule c -> p q r 31 | # (where the c's match) 32 | # make a next state c -> . p q r , i 33 | # English: We're about to start parsing a "c", but 34 | # "c" may be something like "exp" with its own 35 | # production rules. We'll bring those production rules in. 36 | next_states = [ (rule[0],[],rule[1],i) 37 | for rule in grammar if cd <> [] and cd[0] == rule[0] ] 38 | work_count = work_count + len(grammar) 39 | for next_state in next_states: 40 | changes = addtoset(chart,i,next_state) or changes 41 | 42 | # Current State == x -> a b . c d , j 43 | # Option 2: If tokens[i] == c, 44 | # make a next state x -> a b c . d , j 45 | # in chart[i+1] 46 | # English: We're looking for to parse token c next 47 | # and the current token is exactly c! Aren't we lucky! 48 | # So we can parse over it and move to j+1. 49 | if cd <> [] and tokens[i] == cd[0]: 50 | next_state = (x, ab + [cd[0]], cd[1:], j) 51 | changes = addtoset(chart,i+1,next_state) or changes 52 | 53 | # Current State == x -> a b . c d , j 54 | # Option 3: If cd is [], the state is just x -> a b . , j 55 | # for each p -> q . x r , l in chart[j] 56 | # make a new state p -> q x . r , l 57 | # in chart[i] 58 | # English: We just finished parsing an "x" with this token, 59 | # but that may have been a sub-step (like matching "exp -> 2" 60 | # in "2+3"). We should update the higher-level rules as well. 61 | next_states = [ (jstate[0], jstate[1] + [x], (jstate[2])[1:], 62 | jstate[3] ) 63 | for jstate in chart[j] 64 | if cd == [] and jstate[2] <> [] and (jstate[2])[0] == x ] 65 | work_count = work_count + len(chart[j]) 66 | for next_state in next_states: 67 | changes = addtoset(chart,i,next_state) or changes 68 | 69 | # We're done if nothing changed! 70 | if not changes: 71 | break 72 | 73 | ## Comment this block back in if you'd like to see the chart printed. 74 | # 75 | # for i in range(len(tokens)): 76 | # print "== chart " + str(i) 77 | # for state in chart[i]: 78 | # x = state[0] 79 | # ab = state[1] 80 | # cd = state[2] 81 | # j = state[3] 82 | # print " " + x + " ->", 83 | # for sym in ab: 84 | # print " " + sym, 85 | # print " .", 86 | # for sym in cd: 87 | # print " " + sym, 88 | # print " from " + str(j) 89 | 90 | accepting_state = (start_rule[0], start_rule[1], [], 0) 91 | return accepting_state in chart[len(tokens)-1] 92 | 93 | 94 | 95 | grammar = [ 96 | ("S", ["P" ]) , 97 | ("P", ["(" , "P", ")" ]), 98 | ("P", [ ]) , 99 | ] 100 | tokens = [ "(", "(", ")", ")"] 101 | result=parse(tokens, grammar) 102 | print result 103 | 104 | -------------------------------------------------------------------------------- /cs262-Programming-Languages/final-1.py: -------------------------------------------------------------------------------- 1 | # Underscoring the Magnitude 2 | # 3 | # Focus: Units 1 and 2, Regular Expressions and Lexical Analysis 4 | # 5 | # In this problem you will use regular expressions to specify tokens for a 6 | # part of a new programming language. You must handle seven types of 7 | # tokens: 8 | # 9 | # 10 | # PLUS + 11 | # MINUS - 12 | # TIMES * 13 | # DIVIDE / 14 | # IDENT my_variable Caps_Are_OK 15 | # STRING 'yes' "also this" 16 | # NUMBER 123 123_456_789 17 | # 18 | # The last three merit a more detailed explanation. 19 | # 20 | # An IDENT token is a non-empty sequence of lower- and/or upper-case 21 | # letters and underscores, but the first character cannot be an underscore. 22 | # (Letters are a-z and A-Z only.) The value of an IDENT token is the string 23 | # matched. 24 | # 25 | # A STRING token is zero or more of any character surrounded by 'single 26 | # quotes' or "double quotes". In this language, there are no escape 27 | # sequences, so "this\" is a string containing five characters. The value 28 | # of a STRING token is the string matched with the quotes removed. 29 | # 30 | # A NUMBER is a a non-empty sequence of digits (0-9) and/or underscores, 31 | # except that the first character cannot be an underscore. Many real-world 32 | # languages actually support this, to make large number easier to read. 33 | # All NUMBERs in this language are positive integers; negative signs and/or 34 | # periods are not part of NUMBERs. The value of a NUMBER is the integer 35 | # value of its digits with all of the underscores removed: the value of 36 | # "12_34" is 1234 (the integer). 37 | # 38 | # For this problem we do *not* care about line number information. Only the 39 | # types and values of tokens matter. Whitespace characters are ' \t\v\r' 40 | # (and we have already filled them in for you below). 41 | # 42 | # Complete the lexer below. 43 | 44 | import ply.lex as lex 45 | 46 | tokens = ('PLUS', 'MINUS', 'TIMES', 'DIVIDE', 47 | 'IDENT', 'STRING', 'NUMBER') 48 | 49 | ##### 50 | # 51 | 52 | # Place your token definition rules here. 53 | 54 | # 55 | ##### 56 | 57 | t_PLUS = r'\+' 58 | t_MINUS = r'-' 59 | t_TIMES = r'\*' 60 | t_DIVIDE = r'/' 61 | t_IDENT = r'\w' 62 | t_STRING = r'([\'"]).*\1' # should I refer to the quote character to repeat it at the end? 63 | # ERROR: Invalid regular expression for rule 't_STRING'. cannot refer to open group 64 | #Traceback (most recent call last): 65 | # File "final-1.py", line 70, in