From 61b8906f7004b749b3d89720831e4a52ad3871c6 Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Tue, 17 Jan 2023 09:44:11 -0800 Subject: [PATCH] Add files via upload --- ipynb/Countdown.ipynb | 1020 ++++++++++++----------------------------- 1 file changed, 297 insertions(+), 723 deletions(-) diff --git a/ipynb/Countdown.ipynb b/ipynb/Countdown.ipynb index fa84c95..9c39852 100644 --- a/ipynb/Countdown.ipynb +++ b/ipynb/Countdown.ipynb @@ -199,8 +199,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 20.1 s, sys: 514 ms, total: 20.6 s\n", - "Wall time: 20.7 s\n" + "CPU times: user 19.1 s, sys: 427 ms, total: 19.5 s\n", + "Wall time: 19.5 s\n" ] }, { @@ -754,7 +754,8 @@ "\n", "@cache\n", "def digit_expressions(digits: Tuple[int], ops: str) -> ExpTable:\n", - " \"Return {value: expr} for expressions made with all the digits, in the given order, maybe with a decimal point.\"\n", + " \"\"\"Return {value: expr} for expressions made with all the digits, in the given order, \n", + " maybe with a decimal point.\"\"\"\n", " D = ''.join(map(str, digits))\n", " table = {}\n", " if len(digits) == 1 or (',' in ops and not D.startswith('0')): \n", @@ -865,10 +866,11 @@ " 2: '√√16', 24: '√16!'}\n", "\n", "assert expressions((3, 2), '+-*,') == {32.0: '32', 5: '(3+2)', 1: '(3-2)', 6: '(3*2)'}\n", - "assert expressions((1,2,3), '+^') == {6:'(1+(2+3))', 1:'(1^(2+3))', 9:'(1+(2^3))', 27:'((1+2)^3)', 4:'((1^2)+3)'}\n", - "assert expressions((1,2,3), '+^', permute=True) == {1: '(1^(2+3))', 2: '(2^(1^3))', 3: '((1^3)+2)',\n", - " 4: '((1^2)+3)', 5: '((2^1)+3)', 6: '(1+(2+3))', 8: '((2^1)^3)', 9: '(1+(2^3))', 10: '(1+(3^2))',\n", - " 16: '((1+3)^2)', 27: '((1+2)^3)'}" + "assert expressions((1, 2, 3), '+^') == {6:'(1+(2+3))', 1:'(1^(2+3))', 9:'(1+(2^3))', \n", + " 27:'((1+2)^3)', 4:'((1^2)+3)'}\n", + "assert expressions((1, 2, 3), '+^', permute=True) == {\n", + " 1: '(1^(2+3))', 2: '(2^(1^3))', 3: '((1^3)+2)', 4: '((1^2)+3)', 5: '((2^1)+3)', \n", + " 6: '(1+(2+3))', 8: '((2^1)^3)', 9: '(1+(2^3))', 10: '(1+(3^2))', 16: '((1+3)^2)', 27: '((1+2)^3)'}" ] }, { @@ -898,13 +900,16 @@ }, "outputs": [], "source": [ - "def show(numbers: tuple, limit=None, ops=OPS, nesting=2, permute=False):\n", + "def show(numbers: tuple, limit=None, ops=OPS, nesting=2, cols=4, permute=False):\n", " \"\"\"Print expressions for integers from 0 up to limit or the first unmakeable integer.\"\"\"\n", " table = expressions(numbers, ops, nesting, permute)\n", " print(f'Can make 0 to {unmakeable(table)-1} with expressions({numbers}, ops=\"{ops}\", permute={permute}).'\n", " f' [{len(table):,} table entries]\\n')\n", - " for i in range(limit or unmakeable(table)): \n", - " print('{:4} = {}'.format(i, unbracket(table[i])))\n", + " N = limit or unmakeable(table)\n", + " R = ceil(N / cols) # number of rows\n", + " for r in range(R):\n", + " print(*[f'{i:4} = {unbracket(table[i]):<19}'\n", + " for i in range(r, min(N, r + cols * R), R)])\n", " \n", "def unmakeable(table) -> int:\n", " \"\"\"The integer i such that table makes every integer from 0 to i - 1, but not i.\"\"\"\n", @@ -941,81 +946,27 @@ "text": [ "Can make 0 to 72 with expressions((4, 4, 4, 4), ops=\"+-*/^_√!.,\", permute=False). [711,642 table entries]\n", "\n", - " 0 = 44-44\n", - " 1 = 44/44\n", - " 2 = 4*(4/(4+4))\n", - " 3 = (4+(4+4))/4\n", - " 4 = 4+(4*(4-4))\n", - " 5 = (4+(4*4))/4\n", - " 6 = 4+((4+4)/4)\n", - " 7 = (44/4)-4\n", - " 8 = 4+(4+(4-4))\n", - " 9 = 4+(4+(4/4))\n", - " 10 = 44/4.4\n", - " 11 = 44/√(4*4)\n", - " 12 = (4+44)/4\n", - " 13 = 4!-(44/4)\n", - " 14 = 4+(4+(4!/4))\n", - " 15 = 4+(44/4)\n", - " 16 = .4*(44-4)\n", - " 17 = (4/4)+(4*4)\n", - " 18 = .4+(4*4.4)\n", - " 19 = 4!-(4+(4/4))\n", - " 20 = 4*(4+(4/4))\n", - " 21 = (4+4.4)/.4\n", - " 22 = √4*(44/4)\n", - " 23 = ((4*4!)-4)/4\n", - " 24 = 4+(4+(4*4))\n", - " 25 = (4+(4*4!))/4\n", - " 26 = 4+(44/√4)\n", - " 27 = 4+(4!-(4/4))\n", - " 28 = 44-(4*4)\n", - " 29 = 4+(4!+(4/4))\n", - " 30 = (4+(4+4))/.4\n", - " 31 = 4!+((4+4!)/4)\n", - " 32 = (4*4)+(4*4)\n", - " 33 = 4!+((4-.4)/.4)\n", - " 34 = 44-(4/.4)\n", - " 35 = 4!+(44/4)\n", - " 36 = 44-(4+4)\n", - " 37 = ((.4+4!)/.4)-4!\n", - " 38 = 44-(4!/4)\n", - " 39 = 44-(√4/.4)\n", - " 40 = 44-√(4*4)\n", - " 41 = (.4+(4*4))/.4\n", - " 42 = √4+(44-4)\n", - " 43 = 44-(4/4)\n", - " 44 = 4+(44-4)\n", - " 45 = 44+(4/4)\n", - " 46 = 4+(44-√4)\n", - " 47 = 4!+(4!-(4/4))\n", - " 48 = 4*(4+(4+4))\n", - " 49 = 44+(√4/.4)\n", - " 50 = 44+(4!/4)\n", - " 51 = (.4+(4!-4))/.4\n", - " 52 = 4+(4+44)\n", - " 53 = 4!+(4!+(√4/.4))\n", - " 54 = 44+(4/.4)\n", - " 55 = 44/(.4+.4)\n", - " 56 = 4*(4+(4/.4))\n", - " 57 = ((.4+4!)/.4)-4\n", - " 58 = ((4^4)-4!)/4\n", - " 59 = (4!/.4)-(4/4)\n", - " 60 = 44+(4*4)\n", - " 61 = (4/4)+(4!/.4)\n", - " 62 = (4*(4*4))-√4\n", - " 63 = ((4^4)-4)/4\n", - " 64 = (4+4)*(4+4)\n", - " 65 = (4+(4^4))/4\n", - " 66 = √4+(4*(4*4))\n", - " 67 = √4+((4!+√4)/.4)\n", - " 68 = 4+(4*(4*4))\n", - " 69 = (4+(4!-.4))/.4\n", - " 70 = (4!+(4^4))/4\n", - " 71 = (4!+4.4)/.4\n", - " 72 = 4+(4!+44)\n", - "CPU times: user 19.7 s, sys: 71 ms, total: 19.7 s\n", - "Wall time: 19.8 s\n" + " 0 = 44-44 19 = 4!-(4+(4/4)) 38 = 44-(4!/4) 57 = ((.4+4!)/.4)-4 \n", + " 1 = 44/44 20 = 4*(4+(4/4)) 39 = 44-(√4/.4) 58 = ((4^4)-4!)/4 \n", + " 2 = 4*(4/(4+4)) 21 = (4+4.4)/.4 40 = 44-√(4*4) 59 = (4!/.4)-(4/4) \n", + " 3 = (4+(4+4))/4 22 = √4*(44/4) 41 = (.4+(4*4))/.4 60 = 44+(4*4) \n", + " 4 = 4+(4*(4-4)) 23 = ((4*4!)-4)/4 42 = √4+(44-4) 61 = (4/4)+(4!/.4) \n", + " 5 = (4+(4*4))/4 24 = 4+(4+(4*4)) 43 = 44-(4/4) 62 = (4*(4*4))-√4 \n", + " 6 = 4+((4+4)/4) 25 = (4+(4*4!))/4 44 = 4+(44-4) 63 = ((4^4)-4)/4 \n", + " 7 = (44/4)-4 26 = 4+(44/√4) 45 = 44+(4/4) 64 = (4+4)*(4+4) \n", + " 8 = 4+(4+(4-4)) 27 = 4+(4!-(4/4)) 46 = 4+(44-√4) 65 = (4+(4^4))/4 \n", + " 9 = 4+(4+(4/4)) 28 = 44-(4*4) 47 = 4!+(4!-(4/4)) 66 = √4+(4*(4*4)) \n", + " 10 = 44/4.4 29 = 4+(4!+(4/4)) 48 = 4*(4+(4+4)) 67 = √4+((4!+√4)/.4) \n", + " 11 = 44/√(4*4) 30 = (4+(4+4))/.4 49 = 44+(√4/.4) 68 = 4+(4*(4*4)) \n", + " 12 = (4+44)/4 31 = 4!+((4+4!)/4) 50 = 44+(4!/4) 69 = (4+(4!-.4))/.4 \n", + " 13 = 4!-(44/4) 32 = (4*4)+(4*4) 51 = (.4+(4!-4))/.4 70 = (4!+(4^4))/4 \n", + " 14 = 4+(4+(4!/4)) 33 = 4!+((4-.4)/.4) 52 = 4+(4+44) 71 = (4!+4.4)/.4 \n", + " 15 = 4+(44/4) 34 = 44-(4/.4) 53 = 4!+(4!+(√4/.4)) 72 = 4+(4!+44) \n", + " 16 = .4*(44-4) 35 = 4!+(44/4) 54 = 44+(4/.4) \n", + " 17 = (4/4)+(4*4) 36 = 44-(4+4) 55 = 44/(.4+.4) \n", + " 18 = .4+(4*4.4) 37 = ((.4+4!)/.4)-4! 56 = 4*(4+(4/.4)) \n", + "CPU times: user 18.5 s, sys: 18.5 ms, total: 18.6 s\n", + "Wall time: 18.6 s\n" ] } ], @@ -1111,37 +1062,14 @@ "text": [ "Can make 0 to 30 with expressions((2, 2, 2, 2), ops=\"+-*/^_√!.,\", permute=False). [109,291 table entries]\n", "\n", - " 0 = 22-22\n", - " 1 = 22/22\n", - " 2 = 2+(2*(2-2))\n", - " 3 = (2+(2+2))/2\n", - " 4 = .2*(22-2)\n", - " 5 = 2+(2+(2/2))\n", - " 6 = (2*(2+2))-2\n", - " 7 = 2+(2/(2*.2))\n", - " 8 = 2+(2+(2+2))\n", - " 9 = (22/2)-2\n", - " 10 = 22/2.2\n", - " 11 = 22/√(2+2)\n", - " 12 = (2+22)/2\n", - " 13 = 2+(22/2)\n", - " 14 = (2^(2+2))-2\n", - " 15 = (2+(2/2))/.2\n", - " 16 = 2*(2*(2+2))\n", - " 17 = 22-(√.2^-2)\n", - " 18 = 22-(2+2)\n", - " 19 = (2+(2-.2))/.2\n", - " 20 = 22-√(2+2)\n", - " 21 = 22-(2/2)\n", - " 22 = 2+(22-2)\n", - " 23 = 22+(2/2)\n", - " 24 = 22+√(2+2)\n", - " 25 = (2-2.2)^-2\n", - " 26 = 2+(2+22)\n", - " 27 = 22+(√.2^-2)\n", - " 28 = 2+(2+(2+2)!)\n", - " 29 = 2+(2+(.2^-2))\n", - " 30 = (2+(2+2))/.2\n" + " 0 = 22-22 8 = 2+(2+(2+2)) 16 = 2*(2*(2+2)) 24 = 22+√(2+2) \n", + " 1 = 22/22 9 = (22/2)-2 17 = 22-(√.2^-2) 25 = (2-2.2)^-2 \n", + " 2 = 2+(2*(2-2)) 10 = 22/2.2 18 = 22-(2+2) 26 = 2+(2+22) \n", + " 3 = (2+(2+2))/2 11 = 22/√(2+2) 19 = (2+(2-.2))/.2 27 = 22+(√.2^-2) \n", + " 4 = .2*(22-2) 12 = (2+22)/2 20 = 22-√(2+2) 28 = 2+(2+(2+2)!) \n", + " 5 = 2+(2+(2/2)) 13 = 2+(22/2) 21 = 22-(2/2) 29 = 2+(2+(.2^-2)) \n", + " 6 = (2*(2+2))-2 14 = (2^(2+2))-2 22 = 2+(22-2) 30 = (2+(2+2))/.2 \n", + " 7 = 2+(2/(2*.2)) 15 = (2+(2/2))/.2 23 = 22+(2/2) \n" ] } ], @@ -1172,68 +1100,22 @@ "text": [ "Can make 0 to 61 with expressions((9, 9, 9, 9), ops=\"+-*/^_√!.,\", permute=False). [774,333 table entries]\n", "\n", - " 0 = 99-99\n", - " 1 = 99/99\n", - " 2 = (99/9)-9\n", - " 3 = (9+(9+9))/9\n", - " 4 = 9-(9/(.9+.9))\n", - " 5 = √9+((9+9)/9)\n", - " 6 = ((9+(9+9))/9)!\n", - " 7 = 9-((9+9)/9)\n", - " 8 = ((9*9)-9)/9\n", - " 9 = 9+(9*(9-9))\n", - " 10 = 99/9.9\n", - " 11 = 9+((9+9)/9)\n", - " 12 = (9+99)/9\n", - " 13 = 9+(√9+(9/9))\n", - " 14 = √9+(99/9)\n", - " 15 = 9+((9+9)/√9)\n", - " 16 = 9+((9/.9)-√9)\n", - " 17 = 9+(9-(9/9))\n", - " 18 = 99-(9*9)\n", - " 19 = 9+(9+(9/9))\n", - " 20 = 9+(99/9)\n", - " 21 = (9+9.9)/.9\n", - " 22 = 9+(√9+(9/.9))\n", - " 23 = √9+((9+9)/.9)\n", - " 24 = (99/√9)-9\n", - " 25 = 9+(√9!+(9/.9))\n", - " 26 = (9*√9)-(9/9)\n", - " 27 = 9+(9+√(9*9))\n", - " 28 = 9+(9+(9/.9))\n", - " 29 = 9+((9+9)/.9)\n", - " 30 = (9+(9+9))/.9\n", - " 31 = (.9+(9*√9))/.9\n", - " 32 = (99-√9)/√9\n", - " 33 = √9*(99/9)\n", - " 34 = (√9+99)/√9\n", - " 35 = (√9!+99)/√9\n", - " 36 = 9+(9+(9+9))\n", - " 37 = (9/.9)+(9*√9)\n", - " 38 = √9!*(√9+(√9/.9))\n", - " 39 = 9+(9*(√9/.9))\n", - " 40 = (9+(9*√9))/.9\n", - " 41 = (.9+(√9!*√9!))/.9\n", - " 42 = 9+(99/√9)\n", - " 43 = √9+(√9!*(√9!/.9))\n", - " 44 = (9*√9!)-(9/.9)\n", - " 45 = 9*(9/(.9+.9))\n", - " 46 = (9/.9)+(√9!*√9!)\n", - " 47 = √9*(9+(√9!/.9))\n", - " 48 = √9!*(9-(9/9))\n", - " 49 = 9+(√9!*(√9!/.9))\n", - " 50 = ((9*√9!)-9)/.9\n", - " 51 = 9*(9-(√9/.9))\n", - " 52 = √9!*(9-(√9/9))\n", - " 53 = (9*√9!)-(9/9)\n", - " 54 = (9*9)-(9*√9)\n", - " 55 = 99/(.9+.9)\n", - " 56 = 9!/(9*(9-√9)!)\n", - " 57 = √9*(9+(9/.9))\n", - " 58 = √9!*(9+(√9!/9))\n", - " 59 = ((9*√9!)-.9)/.9\n", - " 60 = √9*((9+9)/.9)\n", - " 61 = (.9+(9*√9!))/.9\n" + " 0 = 99-99 16 = 9+((9/.9)-√9) 32 = (99-√9)/√9 48 = √9!*(9-(9/9)) \n", + " 1 = 99/99 17 = 9+(9-(9/9)) 33 = √9*(99/9) 49 = 9+(√9!*(√9!/.9)) \n", + " 2 = (99/9)-9 18 = 99-(9*9) 34 = (√9+99)/√9 50 = ((9*√9!)-9)/.9 \n", + " 3 = (9+(9+9))/9 19 = 9+(9+(9/9)) 35 = (√9!+99)/√9 51 = 9*(9-(√9/.9)) \n", + " 4 = 9-(9/(.9+.9)) 20 = 9+(99/9) 36 = 9+(9+(9+9)) 52 = √9!*(9-(√9/9)) \n", + " 5 = √9+((9+9)/9) 21 = (9+9.9)/.9 37 = (9/.9)+(9*√9) 53 = (9*√9!)-(9/9) \n", + " 6 = ((9+(9+9))/9)! 22 = 9+(√9+(9/.9)) 38 = √9!*(√9+(√9/.9)) 54 = (9*9)-(9*√9) \n", + " 7 = 9-((9+9)/9) 23 = √9+((9+9)/.9) 39 = 9+(9*(√9/.9)) 55 = 99/(.9+.9) \n", + " 8 = ((9*9)-9)/9 24 = (99/√9)-9 40 = (9+(9*√9))/.9 56 = 9!/(9*(9-√9)!) \n", + " 9 = 9+(9*(9-9)) 25 = 9+(√9!+(9/.9)) 41 = (.9+(√9!*√9!))/.9 57 = √9*(9+(9/.9)) \n", + " 10 = 99/9.9 26 = (9*√9)-(9/9) 42 = 9+(99/√9) 58 = √9!*(9+(√9!/9)) \n", + " 11 = 9+((9+9)/9) 27 = 9+(9+√(9*9)) 43 = √9+(√9!*(√9!/.9)) 59 = ((9*√9!)-.9)/.9 \n", + " 12 = (9+99)/9 28 = 9+(9+(9/.9)) 44 = (9*√9!)-(9/.9) 60 = √9*((9+9)/.9) \n", + " 13 = 9+(√9+(9/9)) 29 = 9+((9+9)/.9) 45 = 9*(9/(.9+.9)) 61 = (.9+(9*√9!))/.9 \n", + " 14 = √9+(99/9) 30 = (9+(9+9))/.9 46 = (9/.9)+(√9!*√9!) \n", + " 15 = 9+((9+9)/√9) 31 = (.9+(9*√9))/.9 47 = √9*(9+(√9!/.9)) \n" ] } ], @@ -1269,47 +1151,18 @@ "text": [ "Can make 0 to 38 with expressions((5, 5, 5, 5), ops=\"+-*/^_√!.,\", permute=False). [344,933 table entries]\n", "\n", - " 0 = 55-55\n", - " 1 = 55/55\n", - " 2 = 5!/(5+55)\n", - " 3 = (5+(5+5))/5\n", - " 4 = ((5*5)-5)/5\n", - " 5 = 5+(5*(5-5))\n", - " 6 = (55/5)-5\n", - " 7 = 5+((5+5)/5)\n", - " 8 = 5.5+(5*.5)\n", - " 9 = 5+(5-(5/5))\n", - " 10 = 55/5.5\n", - " 11 = 5.5+5.5\n", - " 12 = (5+55)/5\n", - " 13 = (5!-55)/5\n", - " 14 = (5!/5)-(5+5)\n", - " 15 = (5*5)-(5+5)\n", - " 16 = 5+(55/5)\n", - " 17 = 5+(5!/(5+5))\n", - " 18 = ((5!-5)/5)-5\n", - " 19 = (5!-(5*5))/5\n", - " 20 = 5+(5+(5+5))\n", - " 21 = (5+5.5)/.5\n", - " 22 = 55/(5*.5)\n", - " 23 = 55-(.5^-5)\n", - " 24 = (5*5)-(5/5)\n", - " 25 = .5*(55-5)\n", - " 26 = (5/5)+(5*5)\n", - " 27 = (5*5.5)-.5\n", - " 28 = .5+(5*5.5)\n", - " 29 = (5!+(5*5))/5\n", - " 30 = 55-(5*5)\n", - " 31 = 55-(5!/5)\n", - " 32 = (5.5-5)^-5\n", - " 33 = .5*(5!*.55)\n", - " 34 = 5+(5+(5!/5))\n", - " 35 = 5+(5+(5*5))\n", - " 36 = (5!+(.5*5!))/5\n", - " 37 = 5+(.5^-√(5*5))\n", - " 38 = ((5!/5)-5)/.5\n", - "CPU times: user 9.77 s, sys: 35.6 ms, total: 9.8 s\n", - "Wall time: 9.82 s\n" + " 0 = 55-55 10 = 55/5.5 20 = 5+(5+(5+5)) 30 = 55-(5*5) \n", + " 1 = 55/55 11 = 5.5+5.5 21 = (5+5.5)/.5 31 = 55-(5!/5) \n", + " 2 = 5!/(5+55) 12 = (5+55)/5 22 = 55/(5*.5) 32 = (5.5-5)^-5 \n", + " 3 = (5+(5+5))/5 13 = (5!-55)/5 23 = 55-(.5^-5) 33 = .5*(5!*.55) \n", + " 4 = ((5*5)-5)/5 14 = (5!/5)-(5+5) 24 = (5*5)-(5/5) 34 = 5+(5+(5!/5)) \n", + " 5 = 5+(5*(5-5)) 15 = (5*5)-(5+5) 25 = .5*(55-5) 35 = 5+(5+(5*5)) \n", + " 6 = (55/5)-5 16 = 5+(55/5) 26 = (5/5)+(5*5) 36 = (5!+(.5*5!))/5 \n", + " 7 = 5+((5+5)/5) 17 = 5+(5!/(5+5)) 27 = (5*5.5)-.5 37 = 5+(.5^-√(5*5)) \n", + " 8 = 5.5+(5*.5) 18 = ((5!-5)/5)-5 28 = .5+(5*5.5) 38 = ((5!/5)-5)/.5 \n", + " 9 = 5+(5-(5/5)) 19 = (5!-(5*5))/5 29 = (5!+(5*5))/5 \n", + "CPU times: user 9.37 s, sys: 5.85 ms, total: 9.37 s\n", + "Wall time: 9.37 s\n" ] } ], @@ -1341,190 +1194,116 @@ { "cell_type": "code", "execution_count": 26, - "metadata": { - "id": "-A_sbzTAKEBA", - "outputId": "b1e525b2-573c-42a3-f997-5ed224b069b3" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Can make 0 to 30 with expressions((2, 0, 1, 8), ops=\"+-*/^_√!.,\", permute=False). [58,587 table entries]\n", - "\n", - " 0 = 2*(.0*18)\n", - " 1 = 2^(.0*18)\n", - " 2 = 20-18\n", - " 3 = 2.0+(1^8)\n", - " 4 = 20*(1-.8)\n", - " 5 = -(2.0+1)+8\n", - " 6 = -2.0+(1*8)\n", - " 7 = -2.0+(1+8)\n", - " 8 = (2.0-1)*8\n", - " 9 = (2.0-1)+8\n", - " 10 = 2.0+(1*8)\n" - ] - } - ], - "source": [ - "show((2,0,1,8), 11)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "id": "EJ1gOa_JKEBA", - "outputId": "3025010d-78a9-48ed-8e7a-a140b0d19207" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Can make 0 to 36 with expressions((2, 0, 1, 9), ops=\"+-*/^_√!.,\", permute=False). [80,501 table entries]\n", - "\n", - " 0 = 2*(.0*19)\n", - " 1 = 20-19\n", - " 2 = 20/(1+9)\n", - " 3 = 2.0+(1^9)\n", - " 4 = (-.20^-1)+9\n", - " 5 = .20^(-1^9)\n", - " 6 = -(2.0+1)+9\n", - " 7 = -2.0+(1*9)\n", - " 8 = -2.0+(1+9)\n", - " 9 = (2.0-1)*9\n", - " 10 = 20-(1+9)\n" - ] - } - ], - "source": [ - "show((2,0,1,9), 11)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "id": "mZW-JHoSKEBB", - "outputId": "06a4bbb1-4f7f-4616-8ba1-92beb3fdc1ac" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Can make 0 to 27 with expressions((2, 0, 2, 0), ops=\"+-*/^_√!.,\", permute=False). [8,845 table entries]\n", - "\n", - " 0 = 20-20\n", - " 1 = 20/20\n", - " 2 = 2+(.0*20)\n", - " 3 = 2+(.02^.0)\n", - " 4 = 20*.20\n", - " 5 = (2^.0)/.20\n", - " 6 = 2*(.0!+2.0)\n", - " 7 = 2+(.0!/.20)\n", - " 8 = 2^(.0!+2.0)\n", - " 9 = (20/2)-.0!\n", - " 10 = 2/0.20\n" - ] - } - ], - "source": [ - "show((2,0,2,0), 11)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": { - "id": "AW_j87acKEBB", - "outputId": "e0ac8ab6-e64d-4583-9d76-82c02826e8a5" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Can make 0 to 33 with expressions((2, 0, 2, 1), ops=\"+-*/^_√!.,\", permute=False). [40,927 table entries]\n", - "\n", - " 0 = 2*(.0*21)\n", - " 1 = -20+21\n", - " 2 = 2+(.0*21)\n", - " 3 = 2.0+(2-1)\n", - " 4 = 20*(2*.1)\n", - " 5 = 2.0+(2+1)\n", - " 6 = 2.0*(2+1)\n", - " 7 = 2+(0.2^-1)\n", - " 8 = 2.0^(2+1)\n", - " 9 = (20/2)-1\n", - " 10 = 20/(2*1)\n" - ] - } - ], - "source": [ - "show((2,0,2,1), 11)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "id": "JD1UNX1GKEBB", - "outputId": "ed5a7bdd-fedd-43ab-b285-ab1fc5903745" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Can make 0 to 32 with expressions((2, 0, 2, 2), ops=\"+-*/^_√!.,\", permute=False). [45,613 table entries]\n", - "\n", - " 0 = 20*(2-2)\n", - " 1 = 20^(2-2)\n", - " 2 = -20+22\n", - " 3 = 2.0+(2/2)\n", - " 4 = -20+(2+2)!\n", - " 5 = 20/(2+2)\n", - " 6 = 2.0+(2+2)\n", - " 7 = 2+(.0!+(2+2))\n", - " 8 = (20/2)-2\n", - " 9 = (20-2)/2\n", - " 10 = 20-(2/.2)\n" - ] - } - ], - "source": [ - "show((2,0,2,2), 11)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Can make 0 to 40 with expressions((2, 0, 2, 3), ops=\"+-*/^_√!.,\", permute=False). [105,399 table entries]\n", + "10 = (2.0+(1*8))\n", + " 9 = ((2.0-1)+8)\n", + " 8 = ((2.0-1)*8)\n", + " 7 = (-2.0+(1+8))\n", + " 6 = (-2.0+(1*8))\n", + " 5 = (-(2.0+1)+8)\n", + " 4 = (20*(1-.8))\n", + " 3 = (2.0+(1^8))\n", + " 2 = (20-18)\n", + " 1 = (2^(.0*18))\n", + " 0 = (2*(.0*18))\n", "\n", - " 0 = 2*(.0*23)\n", - " 1 = .20*(2+3)\n", - " 2 = 2+(.0*23)\n", - " 3 = -20+23\n", - " 4 = 20/(2+3)\n", - " 5 = .20^(2-3)\n", - " 6 = (20-2)/3\n", - " 7 = (20/2)-3\n", - " 8 = 2.0+(2*3)\n", - " 9 = ((2^.0)+2)*3\n", - " 10 = 2.0*(2+3)\n" + "\n", + "10 = (20-(1+9))\n", + " 9 = ((2.0-1)*9)\n", + " 8 = (-2.0+(1+9))\n", + " 7 = (-2.0+(1*9))\n", + " 6 = (-(2.0+1)+9)\n", + " 5 = (.20^(-1^9))\n", + " 4 = ((-.20^-1)+9)\n", + " 3 = (2.0+(1^9))\n", + " 2 = (20/(1+9))\n", + " 1 = (20-19)\n", + " 0 = (2*(.0*19))\n", + "\n", + "\n", + "10 = (2/0.20)\n", + " 9 = ((20/2)-.0!)\n", + " 8 = (2^(.0!+2.0))\n", + " 7 = (2+(.0!/.20))\n", + " 6 = (2*(.0!+2.0))\n", + " 5 = ((2^.0)/.20)\n", + " 4 = (20*.20)\n", + " 3 = (2+(.02^.0))\n", + " 2 = (2+(.0*20))\n", + " 1 = (20/20)\n", + " 0 = (20-20)\n", + "\n", + "\n", + "10 = (20/(2*1))\n", + " 9 = ((20/2)-1)\n", + " 8 = (2.0^(2+1))\n", + " 7 = (2+(0.2^-1))\n", + " 6 = (2.0*(2+1))\n", + " 5 = (2.0+(2+1))\n", + " 4 = (20*(2*.1))\n", + " 3 = (2.0+(2-1))\n", + " 2 = (2+(.0*21))\n", + " 1 = (-20+21)\n", + " 0 = (2*(.0*21))\n", + "\n", + "\n", + "10 = (20-(2/.2))\n", + " 9 = ((20-2)/2)\n", + " 8 = ((20/2)-2)\n", + " 7 = (2+(.0!+(2+2)))\n", + " 6 = (2.0+(2+2))\n", + " 5 = (20/(2+2))\n", + " 4 = (-20+(2+2)!)\n", + " 3 = (2.0+(2/2))\n", + " 2 = (-20+22)\n", + " 1 = (20^(2-2))\n", + " 0 = (20*(2-2))\n", + "\n", + "\n", + "10 = (2.0*(2+3))\n", + " 9 = (((2^.0)+2)*3)\n", + " 8 = (2.0+(2*3))\n", + " 7 = ((20/2)-3)\n", + " 6 = ((20-2)/3)\n", + " 5 = (.20^(2-3))\n", + " 4 = (20/(2+3))\n", + " 3 = (-20+23)\n", + " 2 = (2+(.0*23))\n", + " 1 = (.20*(2+3))\n", + " 0 = (2*(.0*23))\n", + "\n", + "\n", + "10 = (20*(2/4))\n", + " 9 = ((20-2)/√4)\n", + " 8 = (2.0+(2+4))\n", + " 7 = (2.0+(2/.4))\n", + " 6 = ((20/2)-4)\n", + " 5 = ((2.0/2)+4)\n", + " 4 = (-20+24)\n", + " 3 = ((2.0/-2)+4)\n", + " 2 = (2+(.0*24))\n", + " 1 = (20*(.2/4))\n", + " 0 = (2*(.0*24))\n", + "\n", + "\n" ] } ], "source": [ - "show((2,0,2,3), 11)" + "def countdown(years):\n", + " \"\"\"Print a countdown using the digits of this year, in order.\"\"\"\n", + " for year in years:\n", + " table = expressions(tuple(int(d) for d in str(year)))\n", + " for i in reversed(range(11)):\n", + " print(f'{i:2d} = {table[i]}')\n", + " print('\\n')\n", + " \n", + "countdown(range(2018, 2025))" ] }, { @@ -1535,12 +1314,12 @@ "source": [ "# Can you make 24?\n", "\n", - "In the [538 Riddler for July 10th 2020](https://fivethirtyeight.com/features/can-you-make-24/), Zach Wissner-Gross asks \"Can you make 24?\" from the digits (2, 3, 3, 4), **in any order**, with just the five binary operators. " + "In the [538 Riddler for July 10th 2020](https://fivethirtyeight.com/features/can-you-make-24/), Zach Wissner-Gross asks \"Can you make 24?\" from the digits (2, 3, 3, 4), in any order, with just the five binary operators. " ] }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -1549,7 +1328,7 @@ "'(((3^2)-3)*4)'" ] }, - "execution_count": 32, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -1564,14 +1343,14 @@ "id": "PPs4y4mxKEBB" }, "source": [ - "For extra credit, Zach asks for multiple ways to make 24. \n", + "For extra credit, Zach asks for **multiple ways** to make 24. \n", "\n", - "We haven't dealt with reporting multiple ways to make a number; the `ExpTable` only keeps one. I'll try collecting one expression from each permutation of the numbers. If there are multiple ways with a single permutation we won't keep more than one of those, but this approach should be good enough to answer Zach's question." + "We haven't dealt with reporting multiple ways to make a number; the `ExpTable` only keeps one. I'll try collecting one expression from each permutation of the numbers. If there are multiple ways from a single permutation we won't keep more than one of those, but this approach won't give you every way (in general), but it should be good enough to answer Zach's question." ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 28, "metadata": { "id": "dLZMMnH-KEBB", "outputId": "9e964cef-f10d-49fd-faf6-bc171de07344" @@ -1588,7 +1367,7 @@ " '(4*((3^2)-3))'}" ] }, - "execution_count": 33, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1609,12 +1388,12 @@ "id": "sNnNDjCvKEBB" }, "source": [ - "Readers suggested other interesting tuples of digits:" + "Readers suggested other interesting tuples of numbers:" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 29, "metadata": { "id": "snhb7k8OKEBB", "outputId": "44f3cf49-aa56-4900-f510-3eedb4970307" @@ -1636,7 +1415,7 @@ " '(8*(8-(3+2)))'}" ] }, - "execution_count": 34, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1647,7 +1426,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 30, "metadata": { "id": "gia8RdaUKEBB", "outputId": "46852452-3ebd-4718-ad7a-52d4fc6de9bf" @@ -1665,7 +1444,7 @@ " '(10-(2*(3-10)))'}" ] }, - "execution_count": 35, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1676,7 +1455,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 31, "metadata": { "id": "VhhMQ33sKEBB", "outputId": "66fe6857-f940-409b-aa2a-04fdb00e064e" @@ -1688,7 +1467,7 @@ "{'(8/(3-(8/3)))'}" ] }, - "execution_count": 36, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1699,7 +1478,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 32, "metadata": { "id": "nbcNqMdFKEBB", "outputId": "e3d17354-e297-4ded-9193-5fe615902072" @@ -1722,7 +1501,7 @@ " '(6+(2*(6+3)))'}" ] }, - "execution_count": 37, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1733,7 +1512,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 33, "metadata": { "id": "L8SAsmSrKEBB", "outputId": "33874782-4dcd-460e-dfaf-140fe71bf502" @@ -1745,7 +1524,7 @@ "{'((5^2)-(0^0))'}" ] }, - "execution_count": 38, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -1760,14 +1539,14 @@ "id": "77JudWtrKEBB" }, "source": [ - "This relies on 00 = 1, which Python agrees with, but many mathematicians would say is undefined.\n", + "This relies on 00 = 1, which Python agrees with, but some mathematicians treat as [undefined](https://en.wikipedia.org/wiki/Zero_to_the_power_of_zero).\n", "\n", "Nicolas Schank asked for the following in the Facebook \"omg math\" group:" ] }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 34, "metadata": { "id": "VDlW5eWVKEBB", "outputId": "d2d3e78c-485f-407a-8888-579ba423f1d2" @@ -1779,7 +1558,7 @@ "{'(10-(6/(13-11))!)!'}" ] }, - "execution_count": 39, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1790,7 +1569,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 35, "metadata": { "id": "5GYEEXhnKEBB", "outputId": "bdee3db6-f560-4b4f-ba2a-036b4d8ee1b3" @@ -1802,7 +1581,7 @@ "{'(8/((1^9)+1))!', '(8/(1+(1^9)))!'}" ] }, - "execution_count": 40, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1813,7 +1592,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 36, "metadata": { "id": "pqZLLXXCKEBB", "outputId": "97da7ef1-2033-45d0-f636-1ea7bc14d126" @@ -1825,7 +1604,7 @@ "{'(9!/(7!+(7!+7!)))'}" ] }, - "execution_count": 41, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1844,41 +1623,39 @@ "\n", "Another Facebook \"omg math\" problem:\n", "\n", - " *For each digit, find a way to express 6 using only that digit exactly three times and arithmetic operations. E.g., for the digit 2, `'2+2^2'` = 6.*\n", + " *For each digit, find a way to express 6 using only that digit exactly three times and arithmetic operations. E.g., for the digit 2, `'2+2+2'` = 6.*\n", "\n", "This is easy if \"arithmetic operations\" include square root and factorial:" ] }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 37, "metadata": { "id": "CoKnbYBxKEBB", "outputId": "dd72b838-7b22-4080-9b29-739585881ce7" }, "outputs": [ { - "data": { - "text/plain": [ - "{'(0!+(0!+0!))!': 6,\n", - " '(1+(1+1))!': 6,\n", - " '(2+(2+2))': 6,\n", - " '((3*3)-3)': 6,\n", - " '(4-(4/4))!': 6,\n", - " '(5+(5/5))': 6,\n", - " '(6+(6-6))': 6,\n", - " '(7-(7/7))': 6,\n", - " '√(8+(8/8))!': 6,\n", - " '((9+9)/√9)': 6}" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "6 = (0!+(0!+0!))!\n", + "6 = (1+(1+1))!\n", + "6 = (2+(2+2))\n", + "6 = ((3*3)-3)\n", + "6 = (4-(4/4))!\n", + "6 = (5+(5/5))\n", + "6 = (6+(6-6))\n", + "6 = (7-(7/7))\n", + "6 = √(8+(8/8))!\n", + "6 = ((9+9)/√9)\n" + ] } ], "source": [ - "{expressions((n, n, n), '+-*/^!√').get(6): 6 for n in range(10)}" + "for n in range(10):\n", + " print(f\"6 = {expressions((n, n, n), '+-*/√!').get(6)}\")" ] }, { @@ -1895,7 +1672,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 38, "metadata": { "id": "jbJsFkNZKEBC", "outputId": "fea9ae24-2e75-4a11-8098-162790f91625" @@ -1907,108 +1684,33 @@ "text": [ "Can make 0 to 1644 with expressions((4, 4, 4, 4), ops=\"+-*/^_√!.,⌊⌈\", permute=False). [1,184,901 table entries]\n", "\n", - " 0 = 44-44\n", - " 1 = 44/44\n", - " 2 = 4*(4/(4+4))\n", - " 3 = (4+(4+4))/4\n", - " 4 = ⌊4.444⌋\n", - " 5 = ⌈4.444⌉\n", - " 6 = 4+((4+4)/4)\n", - " 7 = (44/4)-4\n", - " 8 = 4+(4+(4-4))\n", - " 9 = 4+(4+(4/4))\n", - " 10 = 44/4.4\n", - " 11 = 44/√(4*4)\n", - " 12 = (4+44)/4\n", - " 13 = 4!-(44/4)\n", - " 14 = 4+(4+(4!/4))\n", - " 15 = 4+(44/4)\n", - " 16 = .4*(44-4)\n", - " 17 = (4/4)+(4*4)\n", - " 18 = .4+(4*4.4)\n", - " 19 = ⌊(44*.44)⌋\n", - " 20 = 4*(4+(4/4))\n", - " 21 = (4+4.4)/.4\n", - " 22 = √4*(44/4)\n", - " 23 = ((4*4!)-4)/4\n", - " 24 = 4+(4+(4*4))\n", - " 25 = (4+(4*4!))/4\n", - " 26 = 4+(44/√4)\n", - " 27 = 4+(4!-(4/4))\n", - " 28 = 44-(4*4)\n", - " 29 = 4+(4!+(4/4))\n", - " 30 = (4+(4+4))/.4\n", - " 31 = 4!+((4+4!)/4)\n", - " 32 = (4*4)+(4*4)\n", - " 33 = ⌊(4*(4+4.4))⌋\n", - " 34 = 44-(4/.4)\n", - " 35 = 4!+(44/4)\n", - " 36 = 44-(4+4)\n", - " 37 = 44-⌈√44⌉\n", - " 38 = 44-(4!/4)\n", - " 39 = 44-⌈4.4⌉\n", - " 40 = 44-√(4*4)\n", - " 41 = ⌈44.4⌉-4\n", - " 42 = √4+(44-4)\n", - " 43 = 44-(4/4)\n", - " 44 = 4+(44-4)\n", - " 45 = 44+(4/4)\n", - " 46 = 4+(44-√4)\n", - " 47 = 4+(44-⌈.4⌉)\n", - " 48 = 4*(4+(4+4))\n", - " 49 = 4+⌈44.4⌉\n", - " 50 = 44+(4!/4)\n", - " 51 = 44+⌈√44⌉\n", - " 52 = 4+(4+44)\n", - " 53 = 44+⌊(.4*4!)⌋\n", - " 54 = 44+(4/.4)\n", - " 55 = 44/(.4+.4)\n", - " 56 = 4*(4+(4/.4))\n", - " 57 = ((.4+4!)/.4)-4\n", - " 58 = ((4^4)-4!)/4\n", - " 59 = (4!/.4)-(4/4)\n", - " 60 = 44+(4*4)\n", - " 61 = (4/4)+(4!/.4)\n", - " 62 = (4*(4*4))-√4\n", - " 63 = ((4^4)-4)/4\n", - " 64 = (4+4)*(4+4)\n", - " 65 = (4+(4^4))/4\n", - " 66 = √4+(4*(4*4))\n", - " 67 = 4!+(44-⌈.4⌉)\n", - " 68 = 4+(4*(4*4))\n", - " 69 = 4!+⌈44.4⌉\n", - " 70 = (4!+(4^4))/4\n", - " 71 = (4!+4.4)/.4\n", - " 72 = 4+(4!+44)\n", - " 73 = 4+⌊(44/√.4)⌋\n", - " 74 = 4+((4+4!)/.4)\n", - " 75 = (4!+(4!/4))/.4\n", - " 76 = (4*(4!-4))-4\n", - " 77 = ⌈(44*(4^.4))⌉\n", - " 78 = (4*(4!-4))-√4\n", - " 79 = ⌈(4*(4!-4.4))⌉\n", - " 80 = 4*(4+(4*4))\n", - " 81 = (4-(4/4))^4\n", - " 82 = √4+(4*(4!-4))\n", - " 83 = 44+⌊(.4^-4)⌋\n", - " 84 = (√4*44)-4\n", - " 85 = (4!+(4/.4))/.4\n", - " 86 = (44/.4)-4!\n", - " 87 = (√4*44)-⌈.4⌉\n", - " 88 = 44+44\n", - " 89 = ⌈(√4*44.4)⌉\n", - " 90 = (4*4!)-(4!/4)\n", - " 91 = (4*4!)-⌈4.4⌉\n", - " 92 = 4+(√4*44)\n", - " 93 = ⌊((4.4^4)/4)⌋\n", - " 94 = (4*(4!-.4))-.4\n", - " 95 = (4*4!)-(4/4)\n", - " 96 = √4*(4+44)\n", - " 97 = (4/4)+(4*4!)\n", - " 98 = .4+(4*(.4+4!))\n", - " 99 = ⌈(.4*(4^4))⌉-4\n", - "CPU times: user 57.5 s, sys: 181 ms, total: 57.6 s\n", - "Wall time: 57.7 s\n" + " 0 = 44-44 25 = (4+(4*4!))/4 50 = 44+(4!/4) 75 = (4!+(4!/4))/.4 \n", + " 1 = 44/44 26 = 4+(44/√4) 51 = 44+⌈√44⌉ 76 = (4*(4!-4))-4 \n", + " 2 = 4*(4/(4+4)) 27 = 4+(4!-(4/4)) 52 = 4+(4+44) 77 = ⌈(44*(4^.4))⌉ \n", + " 3 = (4+(4+4))/4 28 = 44-(4*4) 53 = 44+⌊(.4*4!)⌋ 78 = (4*(4!-4))-√4 \n", + " 4 = ⌊4.444⌋ 29 = 4+(4!+(4/4)) 54 = 44+(4/.4) 79 = ⌈(4*(4!-4.4))⌉ \n", + " 5 = ⌈4.444⌉ 30 = (4+(4+4))/.4 55 = 44/(.4+.4) 80 = 4*(4+(4*4)) \n", + " 6 = 4+((4+4)/4) 31 = 4!+((4+4!)/4) 56 = 4*(4+(4/.4)) 81 = (4-(4/4))^4 \n", + " 7 = (44/4)-4 32 = (4*4)+(4*4) 57 = ((.4+4!)/.4)-4 82 = √4+(4*(4!-4)) \n", + " 8 = 4+(4+(4-4)) 33 = ⌊(4*(4+4.4))⌋ 58 = ((4^4)-4!)/4 83 = 44+⌊(.4^-4)⌋ \n", + " 9 = 4+(4+(4/4)) 34 = 44-(4/.4) 59 = (4!/.4)-(4/4) 84 = (√4*44)-4 \n", + " 10 = 44/4.4 35 = 4!+(44/4) 60 = 44+(4*4) 85 = (4!+(4/.4))/.4 \n", + " 11 = 44/√(4*4) 36 = 44-(4+4) 61 = (4/4)+(4!/.4) 86 = (44/.4)-4! \n", + " 12 = (4+44)/4 37 = 44-⌈√44⌉ 62 = (4*(4*4))-√4 87 = (√4*44)-⌈.4⌉ \n", + " 13 = 4!-(44/4) 38 = 44-(4!/4) 63 = ((4^4)-4)/4 88 = 44+44 \n", + " 14 = 4+(4+(4!/4)) 39 = 44-⌈4.4⌉ 64 = (4+4)*(4+4) 89 = ⌈(√4*44.4)⌉ \n", + " 15 = 4+(44/4) 40 = 44-√(4*4) 65 = (4+(4^4))/4 90 = (4*4!)-(4!/4) \n", + " 16 = .4*(44-4) 41 = ⌈44.4⌉-4 66 = √4+(4*(4*4)) 91 = (4*4!)-⌈4.4⌉ \n", + " 17 = (4/4)+(4*4) 42 = √4+(44-4) 67 = 4!+(44-⌈.4⌉) 92 = 4+(√4*44) \n", + " 18 = .4+(4*4.4) 43 = 44-(4/4) 68 = 4+(4*(4*4)) 93 = ⌊((4.4^4)/4)⌋ \n", + " 19 = ⌊(44*.44)⌋ 44 = 4+(44-4) 69 = 4!+⌈44.4⌉ 94 = (4*(4!-.4))-.4 \n", + " 20 = 4*(4+(4/4)) 45 = 44+(4/4) 70 = (4!+(4^4))/4 95 = (4*4!)-(4/4) \n", + " 21 = (4+4.4)/.4 46 = 4+(44-√4) 71 = (4!+4.4)/.4 96 = √4*(4+44) \n", + " 22 = √4*(44/4) 47 = 4+(44-⌈.4⌉) 72 = 4+(4!+44) 97 = (4/4)+(4*4!) \n", + " 23 = ((4*4!)-4)/4 48 = 4*(4+(4+4)) 73 = 4+⌊(44/√.4)⌋ 98 = .4+(4*(.4+4!)) \n", + " 24 = 4+(4+(4*4)) 49 = 4+⌈44.4⌉ 74 = 4+((4+4!)/.4) 99 = ⌈(.4*(4^4))⌉-4 \n", + "CPU times: user 55.4 s, sys: 44.6 ms, total: 55.5 s\n", + "Wall time: 55.5 s\n" ] } ], @@ -2032,7 +1734,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 39, "metadata": { "id": "4MHPG5L8KEBC", "outputId": "63bffec7-8b22-4bb2-cd44-6fd03f124ccf" @@ -2044,180 +1746,51 @@ "text": [ "Can make 0 to 171 with expressions((5, 5, 5, 5, 5), ops=\"+-*/^_√!.,\", permute=False). [14,809,921 table entries]\n", "\n", - " 0 = 5*(55-55)\n", - " 1 = 5^(55-55)\n", - " 2 = 55/(5*5.5)\n", - " 3 = .5*((55/5)-5)\n", - " 4 = 5-(55/55)\n", - " 5 = 5+(55-55)\n", - " 6 = 5+(55/55)\n", - " 7 = ((5+55)/5)-5\n", - " 8 = .5*(5+(55/5))\n", - " 9 = 5!-(555/5)\n", - " 10 = 5!-(55+55)\n", - " 11 = 5*(55/(5*5))\n", - " 12 = (5/5)+(55/5)\n", - " 13 = (5+(5+55))/5\n", - " 14 = (5*5)-(55/5)\n", - " 15 = 5+(55/5.5)\n", - " 16 = (55+(5*5))/5\n", - " 17 = 5+((5+55)/5)\n", - " 18 = 5+((5!-55)/5)\n", - " 19 = (5*5)-(5+(5/5))\n", - " 20 = 55/(5*.55)\n", - " 21 = 5+(5+(55/5))\n", - " 22 = (55+55)/5\n", - " 23 = (5+(55/.5))/5\n", - " 24 = (5-(55/55))!\n", - " 25 = 55-(5+(5*5))\n", - " 26 = 5*(5+(5/(5*5)))\n", - " 27 = 5+(55/(5*.5))\n", - " 28 = .5*(55+(5/5))\n", - " 29 = 5+((5*5)-(5/5))\n", - " 30 = 5*((55/5)-5)\n", - " 31 = 5+((5/5)+(5*5))\n", - " 32 = (5+(55/5))/.5\n", - " 33 = .55*(5+55)\n", - " 34 = (5!+(55-5))/5\n", - " 35 = 5+(55-(5*5))\n", - " 36 = (5*5)+(55/5)\n", - " 37 = 5+((5.5-5)^-5)\n", - " 38 = 5+(.5*(5!*.55))\n", - " 39 = ((5*5)-5.5)/.5\n", - " 40 = 55-(5+(5+5))\n", - " 41 = (5!*.55)-(5*5)\n", - " 42 = (5+5.5)/(.5*.5)\n", - " 43 = 55-(5!/(5+5))\n", - " 44 = 55-(55/5)\n", - " 45 = (5*5!)-555\n", - " 46 = 55+((.5-5)/.5)\n", - " 47 = 5+(5+(5+(.5^-5)))\n", - " 48 = 5!/(5*(5.5-5))\n", - " 49 = 55-(5+(5/5))\n", - " 50 = 55.5-5.5\n", - " 51 = 55+((5/5)-5)\n", - " 52 = 55-(.5+(5*.5))\n", - " 53 = 55-((5+5)/5)\n", - " 54 = ((5*55)-5)/5\n", - " 55 = .5*(55+55)\n", - " 56 = (5+(5*55))/5\n", - " 57 = 55+((5+5)/5)\n", - " 58 = (5*.5)+55.5\n", - " 59 = 5+(55-(5/5))\n", - " 60 = 5+(5+(55-5))\n", - " 61 = 5.5+55.5\n", - " 62 = (55-(5!/5))/.5\n", - " 63 = .5+(5*(5*(5*.5)))\n", - " 64 = .5^(5-(55/5))\n", - " 65 = 5+(5!-(5+55))\n", - " 66 = 55+(55/5)\n", - " 67 = 55+(5!/(5+5))\n", - " 68 = 5.5+(.5*(5+5!))\n", - " 69 = 5+(.5^-(5+(5/5)))\n", - " 70 = 5+(5+(5+55))\n", - " 71 = 55+(.5/(.5^5))\n", - " 72 = (5+(5/5))!/(5+5)\n", - " 73 = (5*5)+(5!/(5*.5))\n", - " 74 = 55+((5!/5)-5)\n", - " 75 = 55+((5*5)-5)\n", - " 76 = 5+(5+(5!*.55))\n", - " 77 = 5+(5!*(.5+(.5/5)))\n", - " 78 = 55+((5!-5)/5)\n", - " 79 = (5!+(5*55))/5\n", - " 80 = 5*(5+(55/5))\n", - " 81 = 5+(.5*(5!+(.5^-5)))\n", - " 82 = 55+((.5^-5)-5)\n", - " 83 = (.5*5!)+((5!-5)/5)\n", - " 84 = 5+(55+(5!/5))\n", - " 85 = 5+(55+(5*5))\n", - " 86 = (55/.5)-(5!/5)\n", - " 87 = (555-5!)/5\n", - " 88 = 5*(.55/(.5^5))\n", - " 89 = 5!+((5!/5)-55)\n", - " 90 = (55-(5+5))/.5\n", - " 91 = (5*5)+(5!*.55)\n", - " 92 = 5+(55+(.5^-5))\n", - " 93 = .5+(5!-(5*5.5))\n", - " 94 = 5!-((5/5)+(5*5))\n", - " 95 = (55/.55)-5\n", - " 96 = 5!+((5/5)-(5*5))\n", - " 97 = 5!+((.5^-5)-55)\n", - " 98 = 5!-(55/(5*.5))\n", - " 99 = (55-5.5)/.5\n", - " 100 = (55/.5)-(5+5)\n", - " 101 = (55.5-5)/.5\n", - " 102 = (.5+(5*5))/(.5*.5)\n", - " 103 = 55+(5!/(5*.5))\n", - " 104 = 5!-(5+(55/5))\n", - " 105 = 55+(55-5)\n", - " 106 = (555/5)-5\n", - " 107 = 5!+((55-5!)/5)\n", - " 108 = (55-(5/5))/.5\n", - " 109 = (55/.5)-(5/5)\n", - " 110 = (555-5)/5\n", - " 111 = 555/√(5*5)\n", - " 112 = (5+555)/5\n", - " 113 = 5!-(5+((5+5)/5))\n", - " 114 = 5+(5!-(55/5))\n", - " 115 = 5+(55+55)\n", - " 116 = 5+(555/5)\n", - " 117 = 5!-((5+(5+5))/5)\n", - " 118 = 5!-(5!/(5+55))\n", - " 119 = 5!-(55/55)\n", - " 120 = 5!+(55-55)\n", - " 121 = 5!+(55/55)\n", - " 122 = 5!+(5!/(5+55))\n", - " 123 = 5!+((5+(5+5))/5)\n", - " 124 = (5*(5*5))-(5/5)\n", - " 125 = 5*(.5*(55-5))\n", - " 126 = (5/5)+(5*(5*5))\n", - " 127 = (5!*(5.5/5))-5\n", - " 128 = (5-(5/5))/(.5^5)\n", - " 129 = (5!-55.5)/.5\n", - " 130 = 5!+(55/5.5)\n", - " 131 = (55+(5*5!))/5\n", - " 132 = 5!+((5+55)/5)\n", - " 133 = (5+(5!*5.5))/5\n", - " 134 = (5!/5)+(55/.5)\n", - " 135 = (5!+555)/5\n", - " 136 = 5+(5!+(55/5))\n", - " 137 = (5*(5*5.5))-.5\n", - " 138 = .5+(5*(5*5.5))\n", - " 139 = ((5+(5/5))!/5)-5\n", - " 140 = .5*(5+(5*55))\n", - " 141 = 5!+((5+5.5)/.5)\n", - " 142 = 5!+(55/(5*.5))\n", - " 143 = ((5+(5/5))!-5)/5\n", - " 144 = ((55/5)-5)!/5\n", - " 145 = (5*(5+(5*5)))-5\n", - " 146 = 5!+((5/5)+(5*5))\n", - " 147 = 5!+((5*5.5)-.5)\n", - " 148 = .5+(5!+(5*5.5))\n", - " 149 = (5!/5)+(5*(5*5))\n", - " 150 = 5*(55-(5*5))\n", - " 151 = 5!+(55-(5!/5))\n", - " 152 = 5!+((5.5-5)^-5)\n", - " 153 = 5!+(.5*(5!*.55))\n", - " 154 = 5+(5+(5!+(5!/5)))\n", - " 155 = 5+(5*(5+(5*5)))\n", - " 156 = (5!+(5!*5.5))/5\n", - " 157 = (.5^-5)+(5*(5*5))\n", - " 158 = (55+(5!/5))/.5\n", - " 159 = (5/(.5^5))-(5/5)\n", - " 160 = (55+(5*5))/.5\n", - " 161 = (5/5)+(5/(.5^5))\n", - " 162 = 5+(5+(5!+(.5^-5)))\n", - " 163 = .5+(5*(.5+(.5^-5)))\n", - " 164 = 5!+(.5*(5!-(.5^-5)))\n", - " 165 = 55+(55/.5)\n", - " 166 = 5!+((5!-5)/(5*.5))\n", - " 167 = 5!+(((5!/.5)-5)/5)\n", - " 168 = (5!+(5+(5/5))!)/5\n", - " 169 = 5!+((5*5)+(5!/5))\n", - " 170 = 5!+((5*5)+(5*5))\n", - " 171 = (5.5/(.5^5))-5\n", - "CPU times: user 8min 36s, sys: 2.01 s, total: 8min 38s\n", - "Wall time: 8min 39s\n" + " 0 = 5*(55-55) 43 = 55-(5!/(5+5)) 86 = (55/.5)-(5!/5) 129 = (5!-55.5)/.5 \n", + " 1 = 5^(55-55) 44 = 55-(55/5) 87 = (555-5!)/5 130 = 5!+(55/5.5) \n", + " 2 = 55/(5*5.5) 45 = (5*5!)-555 88 = 5*(.55/(.5^5)) 131 = (55+(5*5!))/5 \n", + " 3 = .5*((55/5)-5) 46 = 55+((.5-5)/.5) 89 = 5!+((5!/5)-55) 132 = 5!+((5+55)/5) \n", + " 4 = 5-(55/55) 47 = 5+(5+(5+(.5^-5))) 90 = (55-(5+5))/.5 133 = (5+(5!*5.5))/5 \n", + " 5 = 5+(55-55) 48 = 5!/(5*(5.5-5)) 91 = (5*5)+(5!*.55) 134 = (5!/5)+(55/.5) \n", + " 6 = 5+(55/55) 49 = 55-(5+(5/5)) 92 = 5+(55+(.5^-5)) 135 = (5!+555)/5 \n", + " 7 = ((5+55)/5)-5 50 = 55.5-5.5 93 = .5+(5!-(5*5.5)) 136 = 5+(5!+(55/5)) \n", + " 8 = .5*(5+(55/5)) 51 = 55+((5/5)-5) 94 = 5!-((5/5)+(5*5)) 137 = (5*(5*5.5))-.5 \n", + " 9 = 5!-(555/5) 52 = 55-(.5+(5*.5)) 95 = (55/.55)-5 138 = .5+(5*(5*5.5)) \n", + " 10 = 5!-(55+55) 53 = 55-((5+5)/5) 96 = 5!+((5/5)-(5*5)) 139 = ((5+(5/5))!/5)-5 \n", + " 11 = 5*(55/(5*5)) 54 = ((5*55)-5)/5 97 = 5!+((.5^-5)-55) 140 = .5*(5+(5*55)) \n", + " 12 = (5/5)+(55/5) 55 = .5*(55+55) 98 = 5!-(55/(5*.5)) 141 = 5!+((5+5.5)/.5) \n", + " 13 = (5+(5+55))/5 56 = (5+(5*55))/5 99 = (55-5.5)/.5 142 = 5!+(55/(5*.5)) \n", + " 14 = (5*5)-(55/5) 57 = 55+((5+5)/5) 100 = (55/.5)-(5+5) 143 = ((5+(5/5))!-5)/5 \n", + " 15 = 5+(55/5.5) 58 = (5*.5)+55.5 101 = (55.5-5)/.5 144 = ((55/5)-5)!/5 \n", + " 16 = (55+(5*5))/5 59 = 5+(55-(5/5)) 102 = (.5+(5*5))/(.5*.5) 145 = (5*(5+(5*5)))-5 \n", + " 17 = 5+((5+55)/5) 60 = 5+(5+(55-5)) 103 = 55+(5!/(5*.5)) 146 = 5!+((5/5)+(5*5)) \n", + " 18 = 5+((5!-55)/5) 61 = 5.5+55.5 104 = 5!-(5+(55/5)) 147 = 5!+((5*5.5)-.5) \n", + " 19 = (5*5)-(5+(5/5)) 62 = (55-(5!/5))/.5 105 = 55+(55-5) 148 = .5+(5!+(5*5.5)) \n", + " 20 = 55/(5*.55) 63 = .5+(5*(5*(5*.5))) 106 = (555/5)-5 149 = (5!/5)+(5*(5*5)) \n", + " 21 = 5+(5+(55/5)) 64 = .5^(5-(55/5)) 107 = 5!+((55-5!)/5) 150 = 5*(55-(5*5)) \n", + " 22 = (55+55)/5 65 = 5+(5!-(5+55)) 108 = (55-(5/5))/.5 151 = 5!+(55-(5!/5)) \n", + " 23 = (5+(55/.5))/5 66 = 55+(55/5) 109 = (55/.5)-(5/5) 152 = 5!+((5.5-5)^-5) \n", + " 24 = (5-(55/55))! 67 = 55+(5!/(5+5)) 110 = (555-5)/5 153 = 5!+(.5*(5!*.55)) \n", + " 25 = 55-(5+(5*5)) 68 = 5.5+(.5*(5+5!)) 111 = 555/√(5*5) 154 = 5+(5+(5!+(5!/5))) \n", + " 26 = 5*(5+(5/(5*5))) 69 = 5+(.5^-(5+(5/5))) 112 = (5+555)/5 155 = 5+(5*(5+(5*5))) \n", + " 27 = 5+(55/(5*.5)) 70 = 5+(5+(5+55)) 113 = 5!-(5+((5+5)/5)) 156 = (5!+(5!*5.5))/5 \n", + " 28 = .5*(55+(5/5)) 71 = 55+(.5/(.5^5)) 114 = 5+(5!-(55/5)) 157 = (.5^-5)+(5*(5*5)) \n", + " 29 = 5+((5*5)-(5/5)) 72 = (5+(5/5))!/(5+5) 115 = 5+(55+55) 158 = (55+(5!/5))/.5 \n", + " 30 = 5*((55/5)-5) 73 = (5*5)+(5!/(5*.5)) 116 = 5+(555/5) 159 = (5/(.5^5))-(5/5) \n", + " 31 = 5+((5/5)+(5*5)) 74 = 55+((5!/5)-5) 117 = 5!-((5+(5+5))/5) 160 = (55+(5*5))/.5 \n", + " 32 = (5+(55/5))/.5 75 = 55+((5*5)-5) 118 = 5!-(5!/(5+55)) 161 = (5/5)+(5/(.5^5)) \n", + " 33 = .55*(5+55) 76 = 5+(5+(5!*.55)) 119 = 5!-(55/55) 162 = 5+(5+(5!+(.5^-5))) \n", + " 34 = (5!+(55-5))/5 77 = 5+(5!*(.5+(.5/5))) 120 = 5!+(55-55) 163 = .5+(5*(.5+(.5^-5)))\n", + " 35 = 5+(55-(5*5)) 78 = 55+((5!-5)/5) 121 = 5!+(55/55) 164 = 5!+(.5*(5!-(.5^-5)))\n", + " 36 = (5*5)+(55/5) 79 = (5!+(5*55))/5 122 = 5!+(5!/(5+55)) 165 = 55+(55/.5) \n", + " 37 = 5+((5.5-5)^-5) 80 = 5*(5+(55/5)) 123 = 5!+((5+(5+5))/5) 166 = 5!+((5!-5)/(5*.5)) \n", + " 38 = 5+(.5*(5!*.55)) 81 = 5+(.5*(5!+(.5^-5))) 124 = (5*(5*5))-(5/5) 167 = 5!+(((5!/.5)-5)/5) \n", + " 39 = ((5*5)-5.5)/.5 82 = 55+((.5^-5)-5) 125 = 5*(.5*(55-5)) 168 = (5!+(5+(5/5))!)/5 \n", + " 40 = 55-(5+(5+5)) 83 = (.5*5!)+((5!-5)/5) 126 = (5/5)+(5*(5*5)) 169 = 5!+((5*5)+(5!/5)) \n", + " 41 = (5!*.55)-(5*5) 84 = 5+(55+(5!/5)) 127 = (5!*(5.5/5))-5 170 = 5!+((5*5)+(5*5)) \n", + " 42 = (5+5.5)/(.5*.5) 85 = 5+(55+(5*5)) 128 = (5-(5/5))/(.5^5) 171 = (5.5/(.5^5))-5 \n", + "CPU times: user 8min 21s, sys: 938 ms, total: 8min 22s\n", + "Wall time: 8min 22s\n" ] } ], @@ -2233,12 +1806,12 @@ "source": [ "# f(n): Unmakeable from (1, ..., *n*)\n", "\n", - "The facebook group \"actually good math problems\" posed the problem of determining the values of `f(n)`, which is defined to be the smallest positive integer that can not be made from, in our terms, `expressions(range(n + 1), '+-*/^,', permute=True)`. Computing up to `f(5)` is fast, but `f(6)` requires humdreds of billions of combinations and 100 minutes to run; it would take some work to make it more efficient." + "The facebook group \"actually good math problems\" posed the problem of determining the values of `f(n)`, which is defined to be the smallest positive integer that can not be made from, in our terms, `expressions(range(n + 1), '+-*/^,', permute=True)`. Computing up to `f(5)` is fast, but `f(6)` requires hundreds of billions of combinations and 100 minutes to run; it would take some work to make it more efficient, or to move on to `f(7)`." ] }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 40, "metadata": {}, "outputs": [], "source": [ @@ -2250,7 +1823,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -2264,8 +1837,8 @@ "f(4) = 175\n", "f(5) = 1099\n", "f(6) = 9562\n", - "CPU times: user 1h 40min 15s, sys: 11.3 s, total: 1h 40min 26s\n", - "Wall time: 1h 42min 44s\n" + "CPU times: user 1h 38min 47s, sys: 4.47 s, total: 1h 38min 52s\n", + "Wall time: 1h 42min 19s\n" ] } ], @@ -2286,17 +1859,18 @@ "One exercise would be adding even more operators, such as:\n", "\n", "- **Nth root**: `3√8` = 2\n", - "- **Percent**: `5%` = 5/100\n", + "- **Percent**: `50%` = 0.5\n", + "- **Absolute value**: `|1-3|` = 2 (redundant if you have unary minus, but add it if you like it)\n", "- **Repeating decimal**: `.4...` = .44444444... = 4/9\n", "- **Booleans**: `1+(2<3)` = 2, because `(2<3)` is True, which is treated as 1.\n", "- **Double factorial**: `9!!` = 9 × 7 × 5 × 3 × 1 = 945; not the same as `(9!)!`\n", "- **Gamma function**: `Γ(n)` = (n − 1)! and works for non-integers\n", "- **Prime counting function**: `π(n)` = number of primes ≲ n; e.g. `π(5)` = 3\n", - "- **Transcendental functions**: `log`, `sin` `cos`, `tan`, `arcsin`, ... maybe \n", + "- **Transcendental functions**: `log`, `sin` `cos`, `tan`, `arcsin`, ... \n", "- **Degree symbol**: `180°` = π\n", "- **Log to base**: `log_10(100)` = 2\n", "- **Matrix notation**: with determinant symbol to get a number.\n", - "- **Combinations and Permutations**: `n P k` and `n C k`\n", + "- **Combinations and Permutations**: `6 C 2` = 15; `6 P 2` = 30\n", "\n", "Another approach would be to look around for related puzzles and solve them. What do you want to do?" ]