From 663dc654626cad5b6d0fa567bbad18429b7524e3 Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Mon, 13 Jul 2020 13:01:39 -0700 Subject: [PATCH] Add files via upload --- ipynb/Countdown.ipynb | 3960 +++++++++++++++++++++++++++-------------- 1 file changed, 2576 insertions(+), 1384 deletions(-) diff --git a/ipynb/Countdown.ipynb b/ipynb/Countdown.ipynb index 16462ed..d9cc6aa 100644 --- a/ipynb/Countdown.ipynb +++ b/ipynb/Countdown.ipynb @@ -12,9 +12,9 @@ "source": [ "
Peter Norvig
Jan 2016
revised 2018, 2020
\n", "\n", - "# Four 4s, Five 5s, Countdowns, and Equilength Number Names\n", + "# Making Numbers: Four 4s, Five 5s, Countdowns, etc.\n", "\n", - "On January 1, 2016 Alex Bellos [posed](http://www.theguardian.com/science/2016/jan/04/can-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) this New Year's puzzle:\n", + "On January 1, 2016 Alex Bellos [posed](http://www.theguardian.com/science/2016/jan/04/can-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) (and subsequently [answered](http://www.theguardian.com/science/2016/jan/04/did-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016)) this New Year's puzzle:\n", "\n", "\n", "> Fill in the blanks so that this equation makes arithmetical sense:\n", @@ -25,7 +25,7 @@ ">\n", "> `(10 + 9) * (8` ... or `10 + (9 * 8)` ...\n", "\n", - "Let's see if we can solve this puzzle, and some of the related ones from Alex's [first](http://www.theguardian.com/science/2016/jan/04/can-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) and [second](http://www.theguardian.com/science/2016/jan/04/did-you-solve-it-complete-the-equation-10-9-8-7-6-5-4-3-2-1-2016) post. First the imports we will eventually need." + "Let's see if we can solve this puzzle, and some related puzzles about making mathematical expressions by combining numbers and operators. First some imports:" ] }, { @@ -34,10 +34,13 @@ "metadata": {}, "outputs": [], "source": [ - "from itertools import product\n", - "from functools import lru_cache\n", + "from collections import Counter, defaultdict, namedtuple\n", "from fractions import Fraction\n", - "from collections import Counter, defaultdict\n", + "from functools import lru_cache\n", + "from itertools import product, permutations\n", + "from math import sqrt, factorial, floor, ceil\n", + "from operator import add, sub, mul, neg, truediv as div\n", + "from typing import List, Tuple, Dict, Union, Sequence, Set, Optional\n", "import re" ] }, @@ -55,7 +58,7 @@ "\n", "We'll start with a simpler version of the puzzle: a countdown with no brackets. \n", "\n", - "There are nine blanks, each of which can be filled by one of four operators, so there are 49 = 262,144 possibilities, few enough that we can enumerate them all, using `itertools.product` to get tuples of operators, and then `str.format` to plug them into blanks, and then `eval` to evaluate the string:" + "There are nine blanks, each of which can be filled by one of four operators, so there are 94 = 262,144 possibilities, few enough that we can enumerate them all, using `itertools.product` to get tuples of operators, and then `str.format` to plug them into blanks, and then `eval` to evaluate the string:" ] }, { @@ -68,30 +71,9 @@ "read_only": false } }, - "outputs": [ - { - "data": { - "text/plain": [ - "[('+', '+', '+', '+', '+', '+', '+', '+', '+'),\n", - " ('+', '-', '/', '-', '-', '+', '/', '+', '-'),\n", - " ('+', '/', '*', '*', '*', '-', '*', '+', '*'),\n", - " ('-', '-', '-', '/', '/', '*', '-', '+', '/'),\n", - " ('-', '/', '-', '-', '+', '/', '+', '-', '+'),\n", - " ('*', '-', '+', '*', '-', '/', '/', '-', '-'),\n", - " ('*', '*', '/', '/', '/', '+', '*', '-', '*'),\n", - " ('/', '+', '/', '-', '+', '-', '-', '-', '/'),\n", - " ('/', '*', '*', '*', '-', '*', '+', '*', '+')]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "allops = list(product(('+', '-', '*', '/'), repeat=9))\n", - "\n", - "allops[::30001] # Sample a few ops tuples (every 30,001 one)" + "allops = list(product('+-*/', repeat=9))" ] }, { @@ -102,7 +84,7 @@ { "data": { "text/plain": [ - "'10+9+8+7+6+5+4+3+2+1'" + "('+', '+', '+', '+', '+', '+', '+', '+', '+')" ] }, "execution_count": 3, @@ -111,7 +93,7 @@ } ], "source": [ - "'10{}9{}8{}7{}6{}5{}4{}3{}2{}1'.format(*allops[0])" + "allops[0]" ] }, { @@ -122,7 +104,7 @@ { "data": { "text/plain": [ - "55" + "('-', '*', '+', '-', '*', '*', '*', '+', '/')" ] }, "execution_count": 4, @@ -130,6 +112,46 @@ "output_type": "execute_result" } ], + "source": [ + "allops[100003]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'10-9*8+7-6*5*4*3+2/1'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'10{}9{}8{}7{}6{}5{}4{}3{}2{}1'.format(*allops[100003])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-413.0" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "eval(_)" ] @@ -138,14 +160,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "(*Warning*: don't use eval on strings that you aren't sure are safe from bad effects.)\n", + "(*Warning*: don't use eval on strings that you aren't sure are safe.)\n", "\n", "We need to catch errors such as dividing by zero, so I'll define a wrapper function, `evaluate`, to do that, and I'll define `simple_countdown` to put the pieces together:" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "button": false, "new_sheet": false, @@ -155,15 +177,18 @@ }, "outputs": [], "source": [ - "def evaluate(exp):\n", - " \"eval(exp), or None if there is an arithmetic error.\"\n", + "Exp = str # The type of expressions, such as \"(10+9)\"\n", + "\n", + "def evaluate(exp: Exp) -> object:\n", + " \"\"\"eval(exp), or None if there is an arithmetic error.\"\"\"\n", " try:\n", " return eval(exp)\n", " except ArithmeticError:\n", " return None\n", "\n", - "def simple_countdown(target, operators=('+', '-', '*', '/')):\n", - " \"All solutions to the countdown puzzle (with no brackets).\"\n", + "@lru_cache(None)\n", + "def simple_countdown(target, operators='+-*/') -> List[Exp]:\n", + " \"\"\"All solutions to the countdown puzzle (with no brackets) for target year.\"\"\"\n", " exps = ('10{}9{}8{}7{}6{}5{}4{}3{}2{}1'.format(*ops)\n", " for ops in product(operators, repeat=9))\n", " return [exp for exp in exps if evaluate(exp) == target]" @@ -171,7 +196,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -180,7 +205,7 @@ "[]" ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -204,7 +229,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": { "button": false, "new_sheet": false, @@ -216,30 +241,30 @@ { "data": { "text/plain": [ - "{1981: '10*9*8+7*6*5*4*3/2+1',\n", - " 1979: '10*9*8+7*6*5*4*3/2-1',\n", + "{1979: '10*9*8+7*6*5*4*3/2-1',\n", " 1980: '10*9*8+7*6*5*4*3/2/1',\n", - " 2019: '10*9*8*7/6/5*4*3+2+1',\n", + " 1981: '10*9*8+7*6*5*4*3/2+1',\n", + " 2013: '10*9*8*7/6/5*4*3-2-1',\n", + " 2014: '10*9*8*7/6/5*4*3-2/1',\n", + " 2015: '10*9*8*7/6/5*4*3-2+1',\n", " 2017: '10*9*8*7/6/5*4*3+2-1',\n", " 2018: '10*9*8*7/6/5*4*3+2/1',\n", - " 2015: '10*9*8*7/6/5*4*3-2+1',\n", - " 2013: '10*9*8*7/6/5*4*3-2-1',\n", - " 2014: '10*9*8*7/6/5*4*3-2/1'}" + " 2019: '10*9*8*7/6/5*4*3+2+1'}" ] }, - "execution_count": 7, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "def simple_countdowns(targets, operators=('+', '-', '*', '/'), \n", - " fmt='10{}9{}8{}7{}6{}5{}4{}3{}2{}1'):\n", - " \"All solutions to the countdown puzzle (with no brackets) in target years.\"\n", + "def simple_countdowns(targets, operators='+-*/',\n", + " fmt='10{}9{}8{}7{}6{}5{}4{}3{}2{}1') -> Dict[int, List[Exp]]:\n", + " \"\"\"All solutions to the countdown puzzle (with no brackets) for target years.\"\"\"\n", " exps = (fmt.format(*ops)\n", - " for ops in product(operators, repeat=fmt.count('{}')))\n", - " return {int(evaluate(exp)): exp \n", - " for exp in exps if evaluate(exp) in targets}\n", + " for ops in product(operators, repeat=9))\n", + " table = {evaluate(exp): exp for exp in exps}\n", + " return {t: table[t] for t in targets if t in table}\n", "\n", "simple_countdowns(range(1900, 2100))" ] @@ -269,9 +294,9 @@ "source": [ "# Four Basic Operators, With Brackets\n", "\n", - "Now we return to the original problem. Can I make use of what I have so far? Well, my second version of `simple_countdown` accepts different format strings, so I could give it all possible bracketed format strings and let it fill in all possible operator combinations. How long would that take? I happen to remember that the number of bracketings of *n* operands is the nth [Catalan number](https://oeis.org/A000108), which I looked up and found to be 4862. A single call to `simple_countdown` took about 2 seconds, so we could do 4862 calls in about 160 minutes. That's not terrible, but (a) it would still take work to generate all the bracketings, and (b) I think I can find another way that is much faster.\n", + "Now we return to the original problem. Can I make use of what I have so far? Well, `simple_countdowns` accepts a `fmt` string as input, so I could give it all possible bracketed format strings and let it fill in all possible operator combinations. How long would that take? I happen to remember that the number of bracketings of *n* operands is the nth [Catalan number](https://oeis.org/A000108), so for *n* = 9 there are 4,862 bracketings. A single call to `simple_countdown` took about 2 seconds, so we could do 4,862 calls in about 160 minutes. That's not terrible, but (a) it would still take work to generate all the bracketings, and (b) I think I can find another way that is much faster.\n", "\n", - "I'll restate the problem as: given the sequence of numbers (10, 9, ... 1), create an expression whose value is 2016. But to get there I'll solve a more general problem: given any sequence of numbers, like `(10, 9, 8)`, what `{value: expression}` pairs can I make with them? I'll define `expressions(numbers)` to return a dict of `{value: expression}` for all expressions (strings) whose numeric value is `value`, and can be made from `numbers`, for example:\n", + "I'll restate the problem as: given the ordered sequence of numbers (10, 9, ... 1), find an expression whose value is 2016. But to get there I'll solve a more general problem: given any sequence of numbers, like `(10, 9, 8)`, what `{value: expression}` pairs can I make with them? I'll define `expressions(numbers)` to return an **expression table**: a dict of `{value: expression}` for all expressions (strings) whose numeric value is `value` that can be made from `numbers`, for example:\n", "\n", " expressions((10,)) ⇒ {10: '10'}\n", " expressions((9, 8)) ⇒ {1: '(9-8)', 1.125: '(9/8)', 17: '(9+8)', 72: '(9*8)'}\n", @@ -285,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": { "button": false, "new_sheet": false, @@ -295,9 +320,7 @@ }, "outputs": [], "source": [ - "c10 = (10, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n", - "\n", - "def splits(sequence):\n", + "def splits(sequence) -> List[Tuple[Sequence, Sequence]]:\n", " \"Split sequence into two non-empty parts, in all ways.\"\n", " return [(sequence[:i], sequence[i:]) \n", " for i in range(1, len(sequence))]" @@ -305,7 +328,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": { "button": false, "new_sheet": false, @@ -328,12 +351,14 @@ " ((10, 9, 8, 7, 6, 5, 4, 3, 2), (1,))]" ] }, - "execution_count": 9, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "c10 = (10, 9, 8, 7, 6, 5, 4, 3, 2, 1) # A countdown from 10 to 1\n", + "\n", "splits(c10)" ] }, @@ -347,32 +372,37 @@ } }, "source": [ - "Now the function `expressions`:" + "Now the function `expressions`. Note that we place the dummy `@` operator in the `exp` string, and then replace it with real operators in four ways. Note also that `for (L, R) in product(..., ...)` is equivalent to the two lines\n", + " \n", + " for L in ...\n", + " for R in ...\n", + " " ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ + "ExpTable = Dict[float, Exp] # A table of {1.125: '(9/8)', ...}\n", + " \n", "@lru_cache(None)\n", - "def expressions(numbers: tuple) -> dict:\n", - " \"Return {value: expr} for all expressions that can be made from numbers.\"\n", + "def expressions(numbers: tuple) -> ExpTable:\n", + " \"\"\"Return a {value: exp} table for all expressions that can be made from `numbers`.\"\"\"\n", " if len(numbers) == 1: \n", " return {numbers[0]: str(numbers[0])}\n", " else: \n", - " result = {}\n", + " table = {}\n", " for (Lnums, Rnums) in splits(numbers):\n", " for (L, R) in product(expressions(Lnums), expressions(Rnums)):\n", - " Lexp = '(' + expressions(Lnums)[L]\n", - " Rexp = expressions(Rnums)[R] + ')'\n", - " result[L * R] = Lexp + '*' + Rexp\n", - " result[L - R] = Lexp + '-' + Rexp\n", - " result[L + R] = Lexp + '+' + Rexp\n", + " exp = '(' + expressions(Lnums)[L] + '@' + expressions(Rnums)[R] + ')'\n", " if R != 0: \n", - " result[L / R] = Lexp + '/' + Rexp\n", - " return result" + " table[L / R] = exp.replace('@', '/')\n", + " table[L * R] = exp.replace('@', '*')\n", + " table[L - R] = exp.replace('@', '-')\n", + " table[L + R] = exp.replace('@', '+')\n", + " return table" ] }, { @@ -387,25 +417,27 @@ "source": [ "For example, at one point in a call to `expressions((10, 9, 8))` we would have:\n", "\n", - " Lnums, Rnums = (10), (9, 8)\n", - " L, R = 10, 1\n", - " Lexp, Rexp = '(10', '(9-8))'\n", + " Lnums, Rnums = (10,), (9, 8)\n", + " L, R = 10, 1\n", + " expressions(Lnums)[L] = '10'\n", + " expressions(Rnums)[R] = '(9-8)'\n", + " exp = '(10@(9-8))'\n", "\n", - "This would lead to us adding the following four entries to `result`:\n", + "This would lead to us adding the following four entries to `table`:\n", "\n", - " result[10] = '(10*(9-8))'\n", - " result[9] = '(10-(9-8))'\n", - " result[11] = '(10+(9-8))'\n", - " result[10] = '(10/(9-8))'\n", + " table[10] = '(10/(9-8))'\n", + " table[10] = '(10*(9-8))'\n", + " table[9] = '(10-(9-8))'\n", + " table[11] = '(10+(9-8))'\n", " \n", - "The decorator `@lru_cache` takes care of storing the intermediate results. Rather than catching errors, we just avoid division by 0.\n", + "The decorator `@lru_cache` takes care of storing the intermediate results so we don't have to recompute them. Rather than catching errors, we just avoid division by 0.\n", "\n", "Let's give it a try:" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -414,7 +446,7 @@ "{10: '10'}" ] }, - "execution_count": 11, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -425,7 +457,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": { "button": false, "new_sheet": false, @@ -437,10 +469,10 @@ { "data": { "text/plain": [ - "{72: '(9*8)', 1: '(9-8)', 17: '(9+8)', 1.125: '(9/8)'}" + "{1.125: '(9/8)', 72: '(9*8)', 1: '(9-8)', 17: '(9+8)'}" ] }, - "execution_count": 12, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -451,7 +483,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": { "button": false, "new_sheet": false, @@ -463,31 +495,31 @@ { "data": { "text/plain": [ - "{720: '((10*9)*8)',\n", - " -62: '(10-(9*8))',\n", - " 82: '((10*9)-8)',\n", - " 0.1388888888888889: '((10/9)/8)',\n", - " 10: '(10/(9-8))',\n", - " 9: '((10-9)+8)',\n", - " 11: '((10+9)-8)',\n", - " 170: '(10*(9+8))',\n", - " -7: '((10-9)-8)',\n", - " 27: '((10+9)+8)',\n", - " 0.5882352941176471: '(10/(9+8))',\n", + "{8.88888888888889: '((10/9)*8)',\n", " 11.25: '((10*9)/8)',\n", " 8.875: '(10-(9/8))',\n", " 11.125: '(10+(9/8))',\n", - " 8.88888888888889: '((10/9)*8)',\n", - " 98: '((10*9)+8)',\n", - " 8: '((10-9)*8)',\n", - " 0.125: '((10-9)/8)',\n", - " 152: '((10+9)*8)',\n", - " 2.375: '((10+9)/8)',\n", + " 0.1388888888888889: '((10/9)/8)',\n", + " 720: '((10*9)*8)',\n", + " -62: '(10-(9*8))',\n", + " 82: '((10*9)-8)',\n", + " 10.0: '(10*(9-8))',\n", + " 9: '((10-9)+8)',\n", + " 11: '((10+9)-8)',\n", + " 0.5882352941176471: '(10/(9+8))',\n", + " 170: '(10*(9+8))',\n", + " -7: '((10-9)-8)',\n", + " 27: '((10+9)+8)',\n", " -6.888888888888889: '((10/9)-8)',\n", - " 9.11111111111111: '((10/9)+8)'}" + " 9.11111111111111: '((10/9)+8)',\n", + " 98: '((10*9)+8)',\n", + " 0.125: '((10-9)/8)',\n", + " 8: '((10-9)*8)',\n", + " 2.375: '((10+9)/8)',\n", + " 152: '((10+9)*8)'}" ] }, - "execution_count": 13, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -513,7 +545,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": { "button": false, "new_sheet": false, @@ -526,8 +558,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 24 s, sys: 617 ms, total: 24.6 s\n", - "Wall time: 24.9 s\n" + "CPU times: user 26.4 s, sys: 628 ms, total: 27.1 s\n", + "Wall time: 28 s\n" ] }, { @@ -536,7 +568,7 @@ "'(((((((((10*9)+8)*7)-6)-5)-4)*3)+2)+1)'" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -560,7 +592,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -568,23 +600,23 @@ "text/plain": [ "{2010: '((((((10+(((9*8)-7)*6))*5)+4)+3)+2)+1)',\n", " 2011: '((((((10+9)*8)+7)*(6+(5*(4/3))))-2)-1)',\n", - " 2012: '((((((10+9)*8)+7)*(6+(5*(4/3))))-2)/1)',\n", + " 2012: '((((((10+9)*8)+7)*(6+(5*(4/3))))-2)*1)',\n", " 2013: '((((((10+9)*8)+7)*(6+(5*(4/3))))-2)+1)',\n", " 2014: '(((((((10+((9*8)*7))-6)-5)*4)+3)-2)+1)',\n", - " 2015: '(((((((((10*9)+8)*7)-6)-5)-4)*3)+2)/1)',\n", + " 2015: '(((((((((10*9)+8)*7)-6)-5)-4)*3)+2)*1)',\n", " 2016: '(((((((((10*9)+8)*7)-6)-5)-4)*3)+2)+1)',\n", " 2017: '(((10*(((9*8)-((7*6)/(5+4)))*3))-2)-1)',\n", - " 2018: '(((10*(((9*8)-((7*6)/(5+4)))*3))-2)/1)',\n", + " 2018: '(((10*(((9*8)-((7*6)/(5+4)))*3))-2)*1)',\n", " 2019: '(((10*(((9*8)-((7*6)/(5+4)))*3))-2)+1)',\n", " 2020: '(((((10+((9+((8+7)*6))*5))*4)+3)-2)-1)',\n", " 2021: '((((((((10-9)+(8*7))*6)-5)*4)*3)/2)-1)',\n", - " 2022: '((((((((10-9)+(8*7))*6)-5)*4)*3)/2)/1)',\n", - " 2023: '(((((((10*9)*(8+7))/6)*(5+4))-3)+2)-1)',\n", - " 2024: '(((((((10*9)*(8+7))/6)*(5+4))-3)+2)/1)',\n", - " 2025: '(((((((10*9)*(8+7))/6)*(5+4))-3)+2)+1)'}" + " 2022: '((((((((10-9)+(8*7))*6)-5)*4)*3)/2)*1)',\n", + " 2023: '(((((10*(((9*8)*(7-6))-5))+4)*3)+2)-1)',\n", + " 2024: '(((((10*(((9*8)*(7-6))-5))+4)*3)+2)*1)',\n", + " 2025: '(((((10*(((9*8)*(7-6))-5))+4)*3)+2)+1)'}" ] }, - "execution_count": 15, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -611,18 +643,18 @@ "\n", "As it stands, my program can't answer that question, because I only keep one expression for each value. \n", "\n", - "Also, I'm not sure what it means to be a distinct solution. For example, are `((10+9)+8)` and `(10+(9+8))` different, or are they same, because they both are equivalent to `(10+9+8)`? Similarly, are `((3-2)-1)` and `(3-(2+1)` different, or the same because they both are equivalent to `(3 + -2 + -1)`? I think the notion of \"distinct solution\" is just inherently ambiguous. My choice is to count each of these as distinct: every expression has exactly ten numbers, nine operators, and nine pairs of brackets, and if an expression differs in any character, it is different. But I won't argue with anyone who prefers a different definition of \"distinct solution.\"\n", + "Also, I'm not sure what it means to be a distinct solution. For example, are `((10+9)+8)` and `(10+(9+8))` different, or are they same, because they both are equivalent to `(10+9+8)`? Similarly, are `((3-2)-1)` and `(3-(2+1))` different, or the same because they both are equivalent to `(3 + -2 + -1)`? I think the notion of \"distinct solution\" is just inherently ambiguous. My choice is to count each of these as distinct: every expression has exactly ten numbers, nine operators, and nine pairs of brackets, and if an expression differs in any character, it is different. But I won't argue with anyone who prefers a different definition of \"distinct solution.\"\n", "\n", "So how can I count expressions? One approach would be to go back to enumerating every equation (all 4862 × 49 = 1.2 bilion of them) and checking which ones equal 2016. That would take about 40 hours with my Python program. A better approach is to mimic `expressions`, but to make a table of counts, rather than expression strings. I want:\n", "\n", - " counts[(10, 9, 8)][27] == 2\n", + " counts((10, 9, 8))[27] == 2\n", " \n", - "because there are 2 ways to make 27 with the numbers `(10, 9, 8)`, namely, `((10+9)+8)` and `(10+(9+8))`. And in general, if there are `Lcount` ways to make `L` using `Lnums` and `Rcount` ways to make `R` using `Rnums` then there are `Lcount * Rcount` ways of making `L * R` using `Lnums` followed by `Rnums`. So we have:\n" + "because there are 2 ways to make 27 with the numbers `(10, 9, 8)`, namely, `((10+9)+8)` and `(10+(9+8))`. And in general, if there are `Lcount` ways to make `L` using `Lnums` and `Rcount` ways to make `R` using `Rnums` then there are `Lcount * Rcount` ways of making `L + R` using `Lnums` followed by `Rnums`. So we have:\n" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": { "button": false, "new_sheet": false, @@ -638,31 +670,30 @@ " if len(numbers) == 1: # Only one way to make an expression out of a single number\n", " return Counter(numbers)\n", " else: \n", - " result = Counter()\n", + " table = Counter()\n", " for (Lnums, Rnums) in splits(numbers):\n", - " for L in counts(Lnums):\n", - " for R in counts(Rnums):\n", - " count = counts(Lnums)[L] * counts(Rnums)[R]\n", - " result[L + R] += count\n", - " result[L - R] += count\n", - " result[L * R] += count\n", - " if R != 0:\n", - " result[L / R] += count\n", - " return result" + " for L, R in product(counts(Lnums), counts(Rnums)):\n", + " count = counts(Lnums)[L] * counts(Rnums)[R]\n", + " if R != 0:\n", + " table[L / R] += count\n", + " table[L + R] += count\n", + " table[L - R] += count\n", + " table[L * R] += count\n", + " return table" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Counter({4: 2, 0: 1, 1.0: 1})" + "Counter({1.0: 1, 4: 2, 0: 1})" ] }, - "execution_count": 17, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -673,7 +704,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "metadata": { "button": false, "new_sheet": false, @@ -688,7 +719,7 @@ "2" ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -712,7 +743,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "metadata": { "button": false, "new_sheet": false, @@ -727,7 +758,7 @@ "30066" ] }, - "execution_count": 19, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -746,100 +777,40 @@ } }, "source": [ - "This says there are 30,066 distinct expressions for 2016. Is that the answer for Alex?\n", + "This says there are 30,066 distinct expressions for 2016. Is that the answer Alex wanted?\n", "\n", - "# What About Round-off Error?\n", + "# The Trouble with Round-off Error\n", "\n", - "Let's find all the values in `counts(c10)` that are very near to `2016`, within ±0.0000000001:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "button": false, - "new_sheet": false, - "run_control": { - "read_only": false - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{2016.0000000000002: 5792,\n", - " 2016.0: 30066,\n", - " 2015.9999999999995: 1930,\n", - " 2015.999999999997: 15,\n", - " 2016.0000000000005: 510,\n", - " 2016.0000000000018: 264,\n", - " 2016.0000000000023: 12,\n", - " 2015.9999999999998: 5868,\n", - " 2015.9999999999993: 14,\n", - " 2016.000000000002: 18,\n", - " 2015.999999999999: 10}" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "{y: counts(c10)[y] \n", - " for y in counts(c10)\n", - " if abs(y - 2016) < 1e-10}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "I suspect that all of these actually should be *exactly* equal to 2016. If they were, then the total count would be:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "44499" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sum(_.values())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "button": false, - "new_sheet": false, - "run_control": { - "read_only": false - } - }, - "source": [ - "To be absolutely sure, I could re-do *all* the calculations using exact rational arithmetic, as provided by the `Fraction` class. From experience I know that would be an order of magnitude slower if used everywhere, so instead I'll just verify the small set of expressions in the output above. The function `exact(exp)` returns a string that will exactly calculate `exp`:" + "I don't think it is the right answer. The trouble is: round-off error.\n", + "\n", + "Let's find all the values in `expressions(c10)` that are very near to `2016`, within ±0.0000000001:" ] }, { "cell_type": "code", "execution_count": 22, - "metadata": {}, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, "outputs": [ { "data": { "text/plain": [ - "'Fraction(1)/(Fraction(2)+Fraction(3))'" + "{2016.0000000000002: '((((10*((9*(8+7))-(6/(5+4))))*3)/2)+1)',\n", + " 2016.0: '(((((((((10*9)+8)*7)-6)-5)-4)*3)+2)+1)',\n", + " 2015.9999999999995: '((((((10*9)*8)*7)*((6/5)-(4-3)))*2)*1)',\n", + " 2015.999999999997: '(((10*9)*8)/(7-(6-(((5/(4+3))/2)-1))))',\n", + " 2016.0000000000005: '(((((10*9)*8)*((((7*6)/5)-4)-3))*2)*1)',\n", + " 2016.0000000000018: '((((((10*9)*8)*7)*(((6/5)-4)+3))*2)*1)',\n", + " 2016.0000000000023: '(10*((9*8)/((7-(6-((5/(4+3))/2)))-1)))',\n", + " 2015.9999999999998: '((10*((9*(((8-(7/6))*5)-(4*3)))+2))+1)',\n", + " 2015.9999999999993: '(10*(((((9*8)*7)*6)/5)*(((4/3)-2)+1)))',\n", + " 2016.000000000002: '(((10*9)*8)/((7-(6-((5/(4+3))/2)))-1))',\n", + " 2015.999999999999: '((((10*9)*(8+7))-6)/(((5-(4/3))-2)-1))'}" ] }, "execution_count": 22, @@ -848,9 +819,22 @@ } ], "source": [ - "def exact(exp): return re.sub(r\"([0-9]+)\", r\"Fraction(\\1)\", exp)\n", - "\n", - "exact('1/(2+3)')" + "{y: expressions(c10)[y]\n", + " for y in expressions(c10)\n", + " if abs(y - 2016) < 1e-10}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "I suspect that all of these actually should be *exactly* equal to 2016. To determine if they are, I could re-do *all* the calculations using exact rational arithmetic, as provided by the `fractions.Fraction` class. From experience I know that would be at least an order of magnitude slower, so instead I'll just verify the small set of expressions in the output above. I'll define `exact(exp)` to return a string that, when passed to `eval`, will exactly calculate `exp` using rational arithmetic:" ] }, { @@ -861,7 +845,7 @@ { "data": { "text/plain": [ - "Fraction(1, 5)" + "'Fraction(1)/(Fraction(5)-Fraction(2))'" ] }, "execution_count": 23, @@ -870,46 +854,47 @@ } ], "source": [ - "eval(_)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here are all the expressions near 2016:" + "def exact(exp) -> Exp: return re.sub(r\"([0-9]+)\", r\"Fraction(\\1)\", exp)\n", + "\n", + "exact('1/(5-2)')" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, + "outputs": [], + "source": [ + "assert eval(exact('1/(5-2)')) == Fraction(1, 3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now I can count up all the expressions in the `counts(c10)` table that are near 2016, but with `exact` computation to check that the expressions evaluate to exactly 2016:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[(Fraction(2016, 1), '((((10*((9*(8+7))-(6/(5+4))))*3)/2)+1)'),\n", - " (Fraction(2016, 1), '(((((((((10*9)+8)*7)-6)-5)-4)*3)+2)+1)'),\n", - " (Fraction(2016, 1), '((((((10*9)*8)*7)*((6/5)-(4-3)))*2)/1)'),\n", - " (Fraction(2016, 1), '(((10*9)*8)/(7-(6-(((5/(4+3))/2)-1))))'),\n", - " (Fraction(2016, 1), '(((((10*9)*8)*((((7*6)/5)-4)-3))*2)/1)'),\n", - " (Fraction(2016, 1), '((((((10*9)*8)*7)*(((6/5)-4)+3))*2)/1)'),\n", - " (Fraction(2016, 1), '(10*((9*8)/((7-(6-((5/(4+3))/2)))-1)))'),\n", - " (Fraction(2016, 1), '((10*((9*(((8-(7/6))*5)-(4*3)))+2))+1)'),\n", - " (Fraction(2016, 1), '(10*(((((9*8)*7)*6)/5)*(((4/3)-2)+1)))'),\n", - " (Fraction(2016, 1), '(((10*9)*8)/((7-(6-((5/(4+3))/2)))-1))'),\n", - " (Fraction(2016, 1), '((((10*9)*(8+7))-6)/(((5-(4/3))-2)-1))')]" + "44499" ] }, - "execution_count": 24, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "[(eval(exact(exp)), exp)\n", - " for y, exp in expressions(c10).items()\n", - " if abs(y - 2016) < 1e-10]" + "sum(counts(c10)[y] \n", + " for y, exp in expressions(c10).items()\n", + " if abs(y - 2016) < 1e-10 and eval(exact(exp)) == 2016)" ] }, { @@ -922,7 +907,7 @@ } }, "source": [ - "They all evaluate to `Fraction(2016, 1)`, which is `2016/1` or just `2016`. This gives me more confidence in the 44,499 count, but I wouldn't accept it as definitive until it was independently verified and passed an extensive test suite. And of course, if you have a different definition of \"distinct solution,\" you will get a different answer; there are multiple possible definitions that are all very reasonable." + "I can claim that the answer is **44,499**, but I would feel more confident if I did *all* the computations with exact arithmetic, and if the result was independently verified by someone else, and passed an extensive test suite. And of course, if you have a different definition of \"distinct solution,\" you will get a different answer; there are multiple possible definitions that are all very reasonable." ] }, { @@ -933,18 +918,18 @@ "\n", "Alex Bellos continues with a related puzzle:\n", " \n", - "> The most famous “fill in the gaps in the equation” puzzle is known as the [four fours](https://en.wikipedia.org/wiki/Four_fours), because every equation is of the form\n", + "> The most famous “fill in the gaps in the equation” puzzle is known as [**four fours**](https://en.wikipedia.org/wiki/Four_fours), because every equation is of the form\n", ">\n", - "> `4 ␣ 4 ␣ 4 ␣ 4 = X.`\n", + "> `4 ␣ 4 ␣ 4 ␣ 4 = x.`\n", ">\n", - ">In the classic form of the puzzle you must find a solution for X = 0 to 9 using just addition, subtraction, multiplication and division (and brackets).\n", + ">In the classic form of the puzzle you must find a solution for x = 0 to 9 using just addition, subtraction, multiplication and division (and brackets).\n", "\n", - "This puzzle goes back to a [1914 publication](https://archive.org/details/mathematicalrecr00ball) by the \"most famous\" mathematician/magician [W. W. Rouse Ball](https://en.wikipedia.org/wiki/W._W._Rouse_Ball). The solution is easy:" + "This puzzle goes back to a [1914 publication](https://archive.org/details/mathematicalrecr00ball) by the mathematician/magician [W. W. Rouse Ball](https://en.wikipedia.org/wiki/W._W._Rouse_Ball). The solution is easy:" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -954,7 +939,7 @@ " 1: '(((4/4)-4)+4)',\n", " 2: '((4/(4+4))*4)',\n", " 3: '(((4+4)+4)/4)',\n", - " 4: '(((4-4)/4)+4)',\n", + " 4: '(((4-4)*4)+4)',\n", " 5: '(((4*4)+4)/4)',\n", " 6: '(((4+4)/4)+4)',\n", " 7: '((4-(4/4))+4)',\n", @@ -962,7 +947,7 @@ " 9: '(((4/4)+4)+4)'}" ] }, - "execution_count": 25, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -988,80 +973,129 @@ " \n", "> If you want to show off, you can introduce **new mathematical operations** such as powers, square roots, concatenation and decimals, ... or use the factorial symbol, `!`.\n", "\n", - "Bellos is suggesting the following operations:\n", + "It seems there are a lot of puzzles that are similar to four 4s, and they all have different rules for which numbers are required and which operators are allowed. To facilitate solving a range of puzzles with different operators, I will redefine `expressions` to take a second argument, `ops`, listing the allowable operations.\n", "\n", - "- **Powers**: `(4 ^ 4)` is 4 to the fourth power, or 256.\n", - "- **Square roots:** `√4` is the square root of 4, or 2.\n", - "- **Concatenation:** `44` is forty-four.\n", - "- **Decimals:** `4.4` is four and four tenths.\n", - "- **Factorials** `4!` is 4 × 3 × 2 × 1, or 24.\n", + "The operations will be specified as a string of one-character codes. The table below gives the allowable codes, binary operators on the left and unary operators on the right, except that the last row gives two \"operations\" on digits, decimal points and concatenation:\n", "\n", - "There are some complications to deal with:\n", + "|Code|Operator|Code|Operator|\n", + "|------|--------|------|--------|\n", + "|`'+'`|addition: 1 + 2 = 3 |`'_'`|unary minus: -2 = -2|\n", + "|`'-'`|subtraction: 3 - 2 = 1 |`'√'`|square root: √9 = 3|\n", + "|`'*'`|multiplication: 2 * 3 = 6|`'!'`|factorial: 4! = 24 |\n", + "|`'/'`|division: 6 / 3 = 2 |`'⌊'`|floor:⌊4.4⌋ = 4|\n", + "|`'^'`|exponentiation: 2 ^ 3 = 8|`'⌈'`|ceiling: ⌈4.4⌉ = 5|\n", + "|`'.'`|decimal point: 1.23 = 1.23|`'$'`|concatenation of digits: 123 = 123|\n", "\n", - "- **Irrationals**: `√2` is an irrational number; so we can't do exact rational arithmetic.\n", - "- **Imaginaries**: `√-1` is an imaginary number; do we want to deal with that?\n", - "- **Overflow**: `(10. ^ (9. ^ 8.))`, as a `float`, gives an `OverflowError`.\n", - "- **Out of memory**: [`(10 ^ (9 ^ (8 * 7)))`](http://www.wolframalpha.com/input/?i=10+%5E+9+%5E+56), as an `int`, gives an `OutOfMemoryError` (even if your memory uses every atom on Earth).\n", - "- **Infinite expressions**: We could add an infinite number of square root and/or factorial signs to any expression: `√√√√√√(4!!!!!!!!)`...\n", - "- **Round-off error**: `(49*(1/49))` evaluates to `0.9999999999999999`, not `1`.\n", - "\n", - "We could try to manage this with *symbolic algebra*, perhaps using [SymPy](http://www.sympy.org/en/index.html), but that seems complicated, so instead I will make some arbitrary decisions:\n", - "\n", - "- Use floating point approximations for everything, rational or irrational.\n", - "- Disallow irrationals.\n", - "- Disallow overflow errors (a type of arithmetic error).\n", - "- Put limits on what is allow for exponentiation.\n", - "- Allow only two nested unary operations to avoid infinite expressions.\n", - "\n", - "I'll define the function `do` to do an arithmetic computation, catch any errors, and try to correct round-off errors. The idea is that since my expressions start with integers, any result that is very close to an integer is probably actually that integer. So I'll correct `(49*(1/49))` to be `1.0`. Of course, an expression like `(1+(10^-99))` is also very close to `1.0`, but it should not be rounded off. Instead, I'll try to avoid such expressions by silently dropping any value whose magnitude is outside the range of 10-10 to 1010 (except of course I will accept an exact 0)." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "from operator import add, sub, mul, truediv as div\n", - "from math import sqrt, factorial\n", - "\n", - "def do(op, *args): \n", - " \"Return op(*args), trying to correct for roundoff error, or `None` on Error or too big/small.\"\n", - " try:\n", - " val = op(*args)\n", - " return (val if val == 0 else\n", - " None if isinstance(val, complex) else\n", - " None if not (1e-10 < abs(val) < 1e10) else\n", - " round(val) if abs(val - round(val)) < 1e-12 else \n", - " val)\n", - " except (ArithmeticError, ValueError):\n", - " return None" + "I will define the data type `Operator` to define an operator, giving its code symbol, its arity (binary or unary), the Python function to call to do the calculation, the format string for unary operations, and for some operations, a `guard` that says when it is applicable (for example, division is applicable when the second argument is not zero, and for square root, factorial, and exponentiation I impose some limits that are not mathematically necessary, but keep the table from being overpopulated with numbers that are unlikely to help lead to solutions). For binary operations, the code symbol is used to construct the expression string, but for uunary ops the `fmt` field gives a format string; this allows us to have prefix and postfix operators. The function `operators` picks out the operators you want from the `OPERATORS` global variable. You can augment this with new operators as you wish." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "4.5 in range(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, "outputs": [], "source": [ - "assert do(div, 12, 4) == 3 and do(div, 12, 0) == None\n", - "assert do(mul, 49, do(div, 1, 49)) == 1\n", - "assert do(pow, 10, -99) == None" + "def true(*args): return True\n", + "\n", + "Operator = namedtuple('Operator', 'symbol, func, fmt, guard', defaults=[None, true])\n", + "\n", + "OPERATORS = {\n", + " 2: {Operator('+', add),\n", + " Operator('-', sub),\n", + " Operator('*', mul),\n", + " Operator('/', div, None, lambda L, R: R != 0),\n", + " Operator('^', pow, None, lambda L, R: -10 <= R <= 10 and (L > 0 or R == int(R)))},\n", + " 1: {Operator('√', sqrt, '√{}', lambda v: 0 < v <= 100 and (120. * v).is_integer()),\n", + " Operator('!', factorial, '{}!', lambda v: v in range(7)),\n", + " Operator('_', neg, '-{}'),\n", + " Operator('⌊', floor, '⌊{}⌋'),\n", + " Operator('⌈', ceil, '⌈{}⌉')}}\n", + "\n", + "OPS = '+-*/^_√!.$' # Default set of operators; omits floor and ceiling.\n", + "\n", + "def operators(arity: int, ops: str) -> List[Operator]:\n", + " \"\"\"All the operators in OPERATORS with given arity whose code symbol is one of `ops`.\"\"\"\n", + " return [op for op in OPERATORS[arity] if op.symbol in ops]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "I'll take this opportunity to refactor `expressions` to have these subfunctions:\n", - "- `digit_expressions(result, numbers)`: returns a dict like {0.44: '.44', 4.4: '4.4', 44.0: '44'}\n", - "- `add_unary_expressions(result)`: add expressions like `√44` and `4!` to `result` and return `result`. \n", - "- `add_binary_expressions(result, numbers)`: add expressions like `4+√44` and `4^4` to `result` and return `result`." + "There are some complications (and how I'll handle them):\n", + "\n", + "- **Irrationals**: `√2` is an irrational number (I'll use floating point approximations for everything).\n", + "- **Imaginaries**: `√-1` is an imaginary number (I won't allow imaginary numbers).\n", + "- **Overflow**: `(10. ^ (9. ^ 8.))`, as a `float`, gives an `OverflowError` (I'll drop overflow results).\n", + "- **Memory**: `(10 ^ (9 ^ (8 ^ 7)))`, as an `int`, gives an `OutOfMemoryError` (I'll limit exponents).\n", + "- **Infinite unary operators**: `√√√√√√...(4!!!!!!!!...)` (I'll only allow two unary operators per expression).\n", + "- **Round-off error**: As we have seen, `(49*(1/49))` evaluates to `0.9999999999999999`, not `1` (I'll try to round off)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I'll define the function `do` to do an arithmetic computation, catch any errors, and try to correct round-off errors. The idea is that since my expressions start with integers, results that are close to an integer probably are that integer. So I'll correct `(49*(1/49))` to be `1.0`. Of course, an expression like `(1+(10^-99))` is also very close to `1.0`, but it should not be rounded off. Instead, I'll try to avoid such expressions by silently dropping any value whose magnitude is outside the range of 10-10 to 1010 (except of course I will accept an exact 0)." ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "def do(operator, *args) -> Optional[float]: \n", + " \"Return op(*args), trying to correct for roundoff error, or `None` if too big/small/erroneous.\"\n", + " if operator.guard(*args):\n", + " try:\n", + " val = operator.func(*args)\n", + " return (val if val == 0 else\n", + " None if isinstance(val, complex) else\n", + " None if not (1e-10 < abs(val) < 1e10) else\n", + " round(val) if abs(val - round(val)) < 1e-12 else \n", + " val)\n", + " except (ArithmeticError, ValueError):\n", + " pass\n", + " return None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Refactoring `expressions`\n", + "\n", + "I'll take this opportunity to refactor `expressions` to use the new `OPERATORS`. I introduce these subfunctions:\n", + "- `digit_expressions(digits, ops)`: returns a table of expressions with just digits (and maybe a decimal place). If `'$'` is in `ops` allow concatenation of digits (e.g. `{44: '44'}`) and if `'.'` is in ops allow decimals (e.g. `{4.4: '4.4'}`. \n", + "- `add_unary_expressions(table, ops)`: add expressions like `√4` and `4!` to `table` and return `table`. \n", + "- `add_binary_expressions(table, numbers, ops)`: add expressions like `4+√4` and `4^4` to `table` and return `table`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, "metadata": { "button": false, "new_sheet": false, @@ -1072,68 +1106,95 @@ "outputs": [], "source": [ "@lru_cache(None)\n", - "def expressions(numbers: tuple) -> dict:\n", - " \"Return {value: expr} for all expressions that can be made from numbers.\"\n", - " return add_unary_expressions(add_binary_expressions(digit_expressions(numbers), numbers))\n", + "def expressions(numbers: Tuple[int], ops=OPS) -> ExpTable:\n", + " \"Return {value: expr} for all expressions that can be made from numbers using ops.\"\n", + " table = digit_expressions(numbers, ops)\n", + " table = add_binary_expressions(table, numbers, ops)\n", + " return add_unary_expressions(table, ops)\n", "\n", - "def digit_expressions(digits: tuple) -> dict:\n", + "def digit_expressions(digits: Tuple[int], ops: str) -> ExpTable:\n", " \"All ways of making numbers from these digits (in order), and a decimal point.\"\n", " D = ''.join(map(str, digits))\n", - " exps = [(D[:i] + '.' + D[i:]).rstrip('.')\n", - " for i in range(len(D) + 1)\n", - " if not (D.startswith('0') and i > 1)]\n", - " return {float(exp): exp for exp in exps}\n", + " table = {}\n", + " if '.' in ops: table.update({float(d): d for d in decimals(D)})\n", + " if '$' in ops or len(D) == 1: table[int(D)] = D\n", + " return table\n", + "\n", + "def decimals(digits: str)-> List[str]:\n", + " \"\"\"All ways to insert a decimal point into digits.\"\"\"\n", + " return [digits[:i] + '.' + digits[i:]\n", + " for i in range(len(digits))\n", + " if i <= 1 or not digits.startswith('0')]\n", " \n", - "def add_binary_expressions(result: dict, numbers: tuple) -> dict:\n", + "def add_binary_expressions(table: ExpTable, numbers: tuple, ops: str) -> ExpTable:\n", " \"Add binary expressions by splitting numbers and combining with an op.\"\n", + " binary_ops = operators(2, ops)\n", " for (Lnums, Rnums) in splits(numbers):\n", - " for (L, R) in product(expressions(Lnums), expressions(Rnums)):\n", - " Lexp = '(' + expressions(Lnums)[L]\n", - " Rexp = expressions(Rnums)[R] + ')'\n", - " assign(result, do(div, L, R), Lexp + '/' + Rexp)\n", - " assign(result, do(mul, L, R), Lexp + '*' + Rexp)\n", - " assign(result, do(add, L, R), Lexp + '+' + Rexp)\n", - " assign(result, do(sub, L, R), Lexp + '-' + Rexp)\n", - " if -10 <= R <= 10 and (L > 0 or int(R) == R):\n", - " assign(result, do(pow, L, R), Lexp + '^' + Rexp)\n", - " return result\n", + " for (L, R) in product(expressions(Lnums, ops), expressions(Rnums, ops)):\n", + " exp = '(' + expressions(Lnums, ops)[L] + '@' + expressions(Rnums, ops)[R] + ')'\n", + " for op in binary_ops:\n", + " assign(table, do(op, L, R), exp.replace('@', op.symbol))\n", + " return table\n", " \n", - "def add_unary_expressions(result: dict, nesting_level=2) -> dict:\n", - " \"Add unary expressions: -v, √v and v! to result\"\n", + "def add_unary_expressions(table: ExpTable, ops: str, nesting_level=2) -> ExpTable:\n", + " \"Add unary expressions (possibly -v, √v and v!) to table\"\n", + " unary_ops = operators(1, ops)\n", " for _ in range(nesting_level):\n", - " for v in tuple(result):\n", - " exp = result[v]\n", - " if -v not in result:\n", - " assign(result, -v, '-' + exp)\n", - " if 0 < v <= 100 and 120 * v == round(120 * v): \n", - " assign(result, sqrt(v), '√' + exp)\n", - " if 3 <= v <= 6 and v == int(v):\n", - " assign(result, factorial(v), exp + '!')\n", - " return result" + " for v in tuple(table):\n", + " for op in unary_ops:\n", + " assign(table, do(op, v), op.fmt.format(table[v]))\n", + " return table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The function `assign` will silently drop expressions whose value is `None`, and if two expressions have the same value, `assign` keeps the one with the lower \"weight\"—a measure of the characters in the expression. This shows simpler expressions in favor of complex ones: for four 4s, the entry for `0` will be `44-44`, not something like `-√((-√4*--4)*(-√4--√4))`." + "The function `assign` adds a `{val: exp}` entry to `table`, but if there is already an entry for `val`, it prefers the entry with the lowest total *weight*: the number of characters plus extra points for particularly complex characters. The idea is to prefer simpler expressions, but the weights are completely arbitrary. If you want to prefer complex expressions, you cvan change the weights to be negative. The weights don't change how many different values can be made, they just change which of two or more expressions are chosen to represent a value." ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ - "def assign(result: dict, value: float, exp: str): \n", - " \"Assign result[value] = exp, unless we already have a lighter exp or value is None.\"\n", - " if (value is not None \n", - " and (value not in result or weight(exp) < weight(result[value]))): \n", - " result[value] = exp\n", + "def assign(table: dict, val: float, exp: str): \n", + " \"Assign table[val] = exp, unless we already have a lighter exp or val is None.\"\n", + " if val is not None and (val not in table or weight(exp) < weight(table[val])): \n", + " table[val] = exp\n", " \n", - "PENALTIES = defaultdict(int, {'√':7, '!':5, '.':1, '^':3, '/':1, '-':1})\n", + "WEIGHTS = Counter({'√':2, '!':2, '.':1, '^':1, '/':0.2, '-':0.1, '⌊': 2, '⌈':2})\n", " \n", - "def weight(exp: str) -> int: return len(exp) + sum(PENALTIES[c] for c in exp)" + "def weight(exp: str) -> int: return len(exp) + sum(WEIGHTS[c] for c in exp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's a lot of new code; let's have some tests:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "assert digit_expressions((1, 2), OPS) == {12: '12', 0.12: '.12', 1.2: '1.2'}\n", + "assert digit_expressions((1, 2), '$') == {12.0: '12'}\n", + "assert digit_expressions((1, 2), '') == {} # If concatenation is not allowed, (1, 2) can't be put together.\n", + "assert digit_expressions((1,), '$') == {1: '1'}\n", + "\n", + "assert decimals('123') == ['.123', '1.23', '12.3']\n", + "assert decimals('007') == ['.007', '0.07']\n", + "\n", + "assert add_unary_expressions({16: '16'}, '_') == {16: '16', -16: '-16'}\n", + "assert add_unary_expressions({16: '16'}, OPS) == {16: '16', -16: '-16', 4: '√16', -4: '-√16', \n", + " 2: '√√16', 24: '√16!'}\n", + "\n", + "assert expressions((3, 2), '+-*$') == {32.0: '32', 5: '(3+2)', 1: '(3-2)', 6: '(3*2)'}" ] }, { @@ -1151,7 +1212,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 33, "metadata": { "button": false, "new_sheet": false, @@ -1161,30 +1222,43 @@ }, "outputs": [], "source": [ - "def show(numbers: tuple, upto=10000, clear=True):\n", + "def show(numbers: tuple, limit=10000, ops=OPS, clear=True):\n", " \"\"\"Print expressions for integers from 0 up to limit or the first unmakeable integer.\"\"\"\n", " if clear: expressions.cache_clear() # To free up memory\n", - " print('{:,} entries for {}\\n'.format(len(expressions(numbers)), numbers))\n", - " for i in range(upto + 1): \n", - " if i not in expressions(numbers):\n", + " table = expressions(numbers, ops)\n", + " print(f'Can make 0 to {unmakeable(table)-1} with expressions({numbers}, \"{ops}\").'\n", + " f' ({len(table):,} table entries)\\n')\n", + " for i in range(unmakeable(table)): \n", + " print('{:4} = {}'.format(i, unbracket(table[i])))\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", + " for i in range(len(table) + 1):\n", + " if i not in table:\n", " return i\n", - " print('{:4} = {}'.format(i, unbracket(expressions(numbers)[i])))\n", " \n", "def unbracket(exp: str) -> str:\n", " \"Strip outer parens from exp, if they are there\"\n", " return (exp[1:-1] if exp.startswith('(') and exp.endswith(')') else exp)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Four 4s with New Mathematical Operations" + ] + }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "705,959 entries for (4, 4, 4, 4)\n", + "Can make 0 to 72 with expressions((4, 4, 4, 4), \"+-*/^_√!.$\"). (705,959 table entries)\n", "\n", " 0 = 44-44\n", " 1 = 44/44\n", @@ -1192,30 +1266,30 @@ " 3 = (4+(4+4))/4\n", " 4 = 4+(4*(4-4))\n", " 5 = (4+(4*4))/4\n", - " 6 = 4+((4+4)/4)\n", + " 6 = √(44-(4+4))\n", " 7 = (44/4)-4\n", - " 8 = 4+(4*(4/4))\n", + " 8 = 4+(4+(4-4))\n", " 9 = 4+(4+(4/4))\n", " 10 = 44/4.4\n", - " 11 = (4/4)+(4/.4)\n", + " 11 = 44/√(4*4)\n", " 12 = (4+44)/4\n", - " 13 = 4!-(44/4)\n", - " 14 = (4+(.4*4))/.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*44)\n", - " 19 = (4+(4-.4))/.4\n", + " 18 = (44/√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", + " 23 = (√4+44)/√4\n", " 24 = 4+(4+(4*4))\n", " 25 = (4+(4*4!))/4\n", - " 26 = (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", + " 29 = 4+(4!+(4/4))\n", " 30 = (4+(4+4))/.4\n", " 31 = 4!+((4+4!)/4)\n", " 32 = (4*4)+(4*4)\n", @@ -1224,8 +1298,8 @@ " 35 = 4!+(44/4)\n", " 36 = 44-(4+4)\n", " 37 = ((.4+4!)/.4)-4!\n", - " 38 = 44-(4!/4)\n", - " 39 = ((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", @@ -1236,7 +1310,7 @@ " 47 = 4!+(4!-(4/4))\n", " 48 = 4*(4+(4+4))\n", " 49 = 44+(√4/.4)\n", - " 50 = (4+(4*4))/.4\n", + " 50 = 4+(√4+44)\n", " 51 = (.4+(4!-4))/.4\n", " 52 = 4+(4+44)\n", " 53 = 4!+(4!+(√4/.4))\n", @@ -1253,25 +1327,15 @@ " 64 = (4+4)*(4+4)\n", " 65 = (4+(4^4))/4\n", " 66 = √4+(4*(4*4))\n", - " 67 = √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", + " 70 = 4!+(√4+44)\n", " 71 = (4!+4.4)/.4\n", " 72 = 4+(4!+44)\n", - "CPU times: user 10.2 s, sys: 96.5 ms, total: 10.3 s\n", - "Wall time: 10.7 s\n" + "CPU times: user 28.7 s, sys: 101 ms, total: 28.8 s\n", + "Wall time: 28.9 s\n" ] - }, - { - "data": { - "text/plain": [ - "73" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ @@ -1293,7 +1357,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 35, "metadata": { "button": false, "new_sheet": false, @@ -1308,13 +1372,13 @@ "'(4!*(4!+(4!/.4)))'" ] }, - "execution_count": 32, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "expressions((4, 4, 4, 4))[2016]" + "expressions((4, 4, 4, 4), OPS)[2016]" ] }, { @@ -1331,21 +1395,21 @@ "\n", "Donald Knuth has [conjectured](https://www.tandfonline.com/doi/abs/10.1080/0025570X.1964.11975546) that with floor, square root and factorial, you can make any positive integer with just **one** 4.\n", "\n", - "Below are some popular variants:\n", + "Below are some popular variant problems:\n", "\n", "# Four 2s" ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "109,747 entries for (2, 2, 2, 2)\n", + "Can make 0 to 30 with expressions((2, 2, 2, 2), \"+-*/^_√!.$\"). (109,747 table entries)\n", "\n", " 0 = 22-22\n", " 1 = 22/22\n", @@ -1353,15 +1417,15 @@ " 3 = (2+(2*2))/2\n", " 4 = .2*(22-2)\n", " 5 = 2+(2+(2/2))\n", - " 6 = 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 = (2/2)+(2/.2)\n", + " 11 = 22/√(2*2)\n", " 12 = (2+22)/2\n", " 13 = 2+(22/2)\n", - " 14 = 2+(2+(2/.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", @@ -1371,24 +1435,14 @@ " 21 = 22-(2/2)\n", " 22 = 2+(22-2)\n", " 23 = 22+(2/2)\n", - " 24 = 2*(2+(2/.2))\n", - " 25 = 2/(.2*(.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" ] - }, - { - "data": { - "text/plain": [ - "31" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ @@ -1404,30 +1458,30 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "539,849 entries for (9, 9, 9, 9)\n", + "Can make 0 to 61 with expressions((9, 9, 9, 9), \"+-*/^_√!.$\"). (539,849 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", + " 4 = (9+(9*√9))/9\n", " 5 = √9+((9+9)/9)\n", - " 6 = ((9+(9+9))/9)!\n", + " 6 = √(9+(9+(9+9)))\n", " 7 = 9-((9+9)/9)\n", - " 8 = ((9*9)-9)/9\n", + " 8 = (99/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+(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", @@ -1443,8 +1497,8 @@ " 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", + " 30 = (99-9)/√9\n", + " 31 = (99-√9!)/√9\n", " 32 = (99-√9)/√9\n", " 33 = √9*(99/9)\n", " 34 = (√9+99)/√9\n", @@ -1458,7 +1512,7 @@ " 42 = 9+(99/√9)\n", " 43 = √9+(√9!*(√9!/.9))\n", " 44 = (9*√9!)-(9/.9)\n", - " 45 = 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", @@ -1467,7 +1521,7 @@ " 51 = 9*(9-(√9/.9))\n", " 52 = √9!*(9-(√9/9))\n", " 53 = (9*√9!)-(9/9)\n", - " 54 = 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", @@ -1476,16 +1530,6 @@ " 60 = √9*((9+9)/.9)\n", " 61 = (.9+(9*√9!))/.9\n" ] - }, - { - "data": { - "text/plain": [ - "62" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ @@ -1501,7 +1545,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 38, "metadata": { "button": false, "new_sheet": false, @@ -1514,13 +1558,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "202,937 entries for (5, 5, 5, 5)\n", + "Can make 0 to 38 with expressions((5, 5, 5, 5), \"+-*/^_√!.$\"). (202,937 table entries)\n", "\n", " 0 = 55-55\n", " 1 = 55/55\n", - " 2 = (5/5)+(5/5)\n", + " 2 = 5!/(5+55)\n", " 3 = (5+(5+5))/5\n", - " 4 = ((5*5)-5)/5\n", + " 4 = √(5+(55/5))\n", " 5 = 5+(5*(5-5))\n", " 6 = (55/5)-5\n", " 7 = 5+((5+5)/5)\n", @@ -1529,17 +1573,17 @@ " 10 = 55/5.5\n", " 11 = 5.5+5.5\n", " 12 = (5+55)/5\n", - " 13 = .5+(.5*(5*5))\n", - " 14 = 5+((5-.5)/.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", + " 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 = .5+(5*(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", @@ -1553,77 +1597,2099 @@ " 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" + " 37 = 5+(.5^-√(5*5))\n", + " 38 = ((5!/5)-5)/.5\n", + "CPU times: user 8.55 s, sys: 17 ms, total: 8.57 s\n", + "Wall time: 8.58 s\n" ] - }, - { - "data": { - "text/plain": [ - "39" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "show((5, 5, 5, 5))" + "%time show((5, 5, 5, 5))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "\n", + "# Countdown to 2018\n", + "\n", + "Now a slightly different kind of puzzle. On December 31 2017, [Michael Littman](http://cs.brown.edu/~mlittman/) posted this:\n", + "\n", + "> 2+0+1×8, 2+0-1+8, (2+0-1)×8, |2-0-1-8|, -2-0+1×8, -(2+0+1-8), √|2+0-18|, 2+0+1^8, 20-18, 2^(0×18), 2×0×1×8... Happy New Year!\n", + "\n", + "Can we replicate that countdown? For 2018 and for following years?" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Can make 0 to 30 with expressions((2, 0, 1, 8), \"+-*/^_√!.$\"). (50,633 table entries)\n", + "\n", + " 0 = 2*(0*18)\n", + " 1 = 2^(0*18)\n", + " 2 = 20-18\n", + " 3 = 2+(01^8)\n", + " 4 = √(-2+018)\n", + " 5 = -(2+01)+8\n", + " 6 = √(2*018)\n", + " 7 = -2+(01+8)\n", + " 8 = (2-01)*8\n", + " 9 = (2-01)+8\n", + " 10 = 2+(01*8)\n", + " 11 = 2+(01+8)\n", + " 12 = 20-(1*8)\n", + " 13 = 20+(1-8)\n", + " 14 = 2*(-01+8)\n", + " 15 = -(2+0!)+18\n", + " 16 = -2+018\n", + " 17 = -(2^0)+18\n", + " 18 = 2*(01+8)\n", + " 19 = (2^0)+18\n", + " 20 = 2+018\n", + " 21 = 20+(1^8)\n", + " 22 = ((2+0!)/.1)-8\n", + " 23 = 20+√(1+8)\n", + " 24 = (2+01)*8\n", + " 25 = 2/(.01*8)\n", + " 26 = 20+√(1+8)!\n", + " 27 = (20-1)+8\n", + " 28 = 20+(1*8)\n", + " 29 = 20+(1+8)\n", + " 30 = (2*(0!+1))!/.8\n" + ] + } + ], + "source": [ + "show((2,0,1,8), 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Can make 0 to 36 with expressions((2, 0, 1, 9), \"+-*/^_√!.$\"). (72,371 table entries)\n", + "\n", + " 0 = 2*(0*19)\n", + " 1 = 20-19\n", + " 2 = 2+(0*19)\n", + " 3 = 2+(01^9)\n", + " 4 = (2-01)+√9\n", + " 5 = 2+(01*√9)\n", + " 6 = -(2+01)+9\n", + " 7 = -2+(01*9)\n", + " 8 = -2+(01+9)\n", + " 9 = (2-01)*9\n", + " 10 = 20-(1+9)\n", + " 11 = 2+(01*9)\n", + " 12 = 2+(01+9)\n", + " 13 = 2+(0!+(1+9))\n", + " 14 = (.2^-01)+9\n", + " 15 = (2+01)!+9\n", + " 16 = 2*(-01+9)\n", + " 17 = -2+019\n", + " 18 = 2*(01*9)\n", + " 19 = (2*0)+19\n", + " 20 = 2*(01+9)\n", + " 21 = 2+019\n", + " 22 = 2+(0!+19)\n", + " 23 = 20+(1*√9)\n", + " 24 = 20+(1+√9)\n", + " 25 = 20/(-.1+.9)\n", + " 26 = 2+(01+√9)!\n", + " 27 = (2+01)*9\n", + " 28 = (20-1)+9\n", + " 29 = 20+(1*9)\n", + " 30 = 20+(1+9)\n", + " 31 = (.2^-(0!+1))+√9!\n", + " 32 = √2^(01+9)\n", + " 33 = (2*(0!+1))!+9\n", + " 34 = (.2^-(0!+1))+9\n", + " 35 = (√2^(0!/.1))+√9\n", + " 36 = 2*(-0!+19)\n" + ] + } + ], + "source": [ + "show((2,0,1,9), 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Can make 0 to 27 with expressions((2, 0, 2, 0), \"+-*/^_√!.$\"). (8,195 table entries)\n", + "\n", + " 0 = 202*0\n", + " 1 = 20/20\n", + " 2 = 2+(0*20)\n", + " 3 = 2+(02^0)\n", + " 4 = .2*020\n", + " 5 = 2+(02+0!)\n", + " 6 = 2*(02+0!)\n", + " 7 = 2+(0!/.20)\n", + " 8 = 2^(02+0!)\n", + " 9 = (20/2)-0!\n", + " 10 = 2/0.20\n", + " 11 = (20/2)+0!\n", + " 12 = 2*(02+0!)!\n", + " 13 = (2*(0!+2)!)+0!\n", + " 14 = 20-(2+0!)!\n", + " 15 = (2+0!)/.20\n", + " 16 = 20*(-.2+0!)\n", + " 17 = 20-(2+0!)\n", + " 18 = -2+020\n", + " 19 = 20-(2^0)\n", + " 20 = 20+(2*0)\n", + " 21 = 20+(2^0)\n", + " 22 = 2+020\n", + " 23 = 2+(0!+20)\n", + " 24 = (.2*020)!\n", + " 25 = .20^-2.0\n", + " 26 = 20+(2+0!)!\n", + " 27 = (2+0!)^(2+0!)\n" + ] + } + ], + "source": [ + "show((2,0,2,0), 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Can make 0 to 33 with expressions((2, 0, 2, 1), \"+-*/^_√!.$\"). (38,867 table entries)\n", + "\n", + " 0 = 2*(0*21)\n", + " 1 = -20+21\n", + " 2 = 2+(0*21)\n", + " 3 = 2+(02-1)\n", + " 4 = 2*(02*1)\n", + " 5 = 2+(02+1)\n", + " 6 = 2*(02+1)\n", + " 7 = 2+(0.2^-1)\n", + " 8 = 2^(02+1)\n", + " 9 = (20/2)-1\n", + " 10 = 20/(2*1)\n", + " 11 = (20/2)+1\n", + " 12 = 2*(02+1)!\n", + " 13 = (2*(0!+2)!)+1\n", + " 14 = 20-(2+1)!\n", + " 15 = 20-(.2^-1)\n", + " 16 = 20*(-.2+1)\n", + " 17 = 20-(2+1)\n", + " 18 = 20-(2*1)\n", + " 19 = -2+021\n", + " 20 = 20*(2-1)\n", + " 21 = (2*0)+21\n", + " 22 = 20+(2*1)\n", + " 23 = 2+021\n", + " 24 = 20*(.2+1)\n", + " 25 = (2*02)!+1\n", + " 26 = 20+(2+1)!\n", + " 27 = (2+0!)!+21\n", + " 28 = -2+((0!+2)/.1)\n", + " 29 = ((2+0!)!/.2)-1\n", + " 30 = ((2^0)+2)/.1\n", + " 31 = (2^(0!/.2))-1\n", + " 32 = 2^(0.2^-1)\n", + " 33 = (2^(0!/.2))+1\n" + ] + } + ], + "source": [ + "show((2,0,2,1), 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Can make 0 to 32 with expressions((2, 0, 2, 2), \"+-*/^_√!.$\"). (43,815 table entries)\n", + "\n", + " 0 = 2*(0*22)\n", + " 1 = 2-(02/2)\n", + " 2 = -20+22\n", + " 3 = 2+(02/2)\n", + " 4 = 2*((0*2)+2)\n", + " 5 = 20/(2*2)\n", + " 6 = 2+(02*2)\n", + " 7 = 2+(0!+(2*2))\n", + " 8 = 2*(02*2)\n", + " 9 = (20-2)/2\n", + " 10 = 20-(2/.2)\n", + " 11 = (20+2)/2\n", + " 12 = (20/2)+2\n", + " 13 = 2+(0!+(2/.2))\n", + " 14 = 2*((0!/.2)+2)\n", + " 15 = ((2^0)+2)/.2\n", + " 16 = 20-(2*2)\n", + " 17 = 2+((0!+2)/.2)\n", + " 18 = 20-√(2*2)\n", + " 19 = 20-(2/2)\n", + " 20 = -2+022\n", + " 21 = 20+(2/2)\n", + " 22 = (2*0)+22\n", + " 23 = (2^0)+22\n", + " 24 = 2+022\n", + " 25 = 2+(0!+22)\n", + " 26 = 2+(02*2)!\n", + " 27 = 2+(0.2^-2)\n", + " 28 = (2+0!)!+22\n", + " 29 = (.2^-0!)+(2*2)!\n", + " 30 = 20+(2/.2)\n", + " 31 = (2+0!)!+(.2^-2)\n", + " 32 = √2^(02/.2)\n" + ] + } + ], + "source": [ + "show((2,0,2,2), 10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Five 5s " + "# Making 6 from 3 Digits\n", + "\n", + "Nicolas Schank posted the following in the Facebook \"omg math\" group.\n", + "\n", + "> For each digit from 0 to 9, find at least one way to express 6 using only that digit exactly three times and arithmetic operations. For instance, using the digit 2, `'2+2^2'` = 6.\n", + "\n", + "It turns out this is easy (if we assume \"arithmetic operations\" include square root and factorial):" ] }, { "cell_type": "code", - "execution_count": 36, - "metadata": { - "scrolled": false - }, + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['(0!+(0!+0!))!',\n", + " '(1+(1+1))!',\n", + " '(2+(2*2))',\n", + " '((3*3)-3)',\n", + " '(4+(4-√4))',\n", + " '(5+(5/5))',\n", + " '(6+(6-6))',\n", + " '(7-(7/7))',\n", + " '(8-√√(8+8))',\n", + " '((9+9)/√9)']" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[expressions((n, n, n), '+-*/^!√').get(6) for n in range(10)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The 24 Problem\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. For extra credit, Zach asks for multiple ways to make 24.\n", + "\n", + "We haven't dealt with reporting multiple ways, and we haven't allowed different orders for the digits. I'll deal with both by trying all permutations of the digits, and collecting one expression from each permutation (if there is one). If there are multiple ways with a single permutation we won't get more than one of those, but this approach should be good enough to answer the question." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'(((3^2)-3)*4)',\n", + " '(((4-2)^3)*3)',\n", + " '(3*((4-2)^3))',\n", + " '(3*(4^(3/2)))',\n", + " '(3/((2/4)^3))',\n", + " '(4*((3^2)-3))'}" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def can_make(total: int, numbers: tuple, ops=OPS) -> Set[Exp]:\n", + " \"\"\"Can we make the total from the numbers (in any order)? Return a set of ways to do it.\"\"\"\n", + " return {expressions(nums, ops).get(total)\n", + " for nums in set(permutations(numbers))} - {None}\n", + "\n", + "can_make(24, (2, 3, 3, 4), '+-*/^')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Even More Fours: The Power of Floor and Ceiling\n", + "\n", + "With the standard set of `OPS`, we got all the integers up to 72 with four 4s. If we add the floor and ceiling operators, we get a big jump: suddenly, all the results of a division or a square root that didn't form an integer and hence didn't contribute to the output of `show`, can now be coerced into integers. Instead of stopping at 72, we get all the way up to 1644:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "7,624,387 entries for (5, 5, 5, 5, 5)\n", + "Can make 0 to 1644 with expressions((4, 4, 4, 4), \"+-*/^_√!.$⌊⌈\"). (1,147,507 table entries)\n", + "\n", + " 0 = 44-44\n", + " 1 = 44/44\n", + " 2 = √⌊4.444⌋\n", + " 3 = 4-⌈.444⌉\n", + " 4 = ⌊4.444⌋\n", + " 5 = ⌈4.444⌉\n", + " 6 = √(44-(4+4))\n", + " 7 = (44/4)-4\n", + " 8 = 4+⌊4.44⌋\n", + " 9 = 4+⌈4.44⌉\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.44)⌋\n", + " 18 = ⌈(4*4.44)⌉\n", + " 19 = ⌊(.44*44)⌋\n", + " 20 = 4*⌈4.44⌉\n", + " 21 = (4+4.4)/.4\n", + " 22 = √4*(44/4)\n", + " 23 = 4!-⌈.444⌉\n", + " 24 = 4+(4+(4*4))\n", + " 25 = ⌊(.444^-4)⌋\n", + " 26 = 4+(44/√4)\n", + " 27 = ⌈(4*√44.4)⌉\n", + " 28 = 44-(4*4)\n", + " 29 = 4!+⌈4.44⌉\n", + " 30 = (4+(4+4))/.4\n", + " 31 = 4+⌈(4*√44)⌉\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 = ⌊44.44⌋\n", + " 45 = ⌈44.44⌉\n", + " 46 = 4+(44-√4)\n", + " 47 = √4+⌈44.4⌉\n", + " 48 = 4*(4+(4+4))\n", + " 49 = 4+⌈44.4⌉\n", + " 50 = 4+(√4+44)\n", + " 51 = 44+⌈√44⌉\n", + " 52 = 4+(4+44)\n", + " 53 = ⌊((4+4)*√44)⌋\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.44)⌋\n", + " 59 = ⌈(.4^-4.44)⌉\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+44)\n", + " 71 = ⌈(.4*(4*44))⌉\n", + " 72 = 4+(4!+44)\n", + " 73 = 4+⌊(44/√.4)⌋\n", + " 74 = 4+((4+4!)/.4)\n", + " 75 = ⌊((4+44)/√.4)⌋\n", + " 76 = ⌈4.4⌉!-44\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-.44))⌋\n", + " 86 = (44/.4)-4!\n", + " 87 = (√4*44)-⌈.4⌉\n", + " 88 = 44+44\n", + " 89 = ⌈(√4*44.4)⌉\n", + " 90 = √4+(√4*44)\n", + " 91 = ⌈(444/√4!)⌉\n", + " 92 = 4+(√4*44)\n", + " 93 = ⌈(44*√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!+.44))⌉\n", + " 99 = ⌊(4^√(44/4))⌋\n", + " 100 = 44/.44\n", + " 101 = ⌈4.4⌉+(4*4!)\n", + " 102 = (.4*(4^4))-.4\n", + " 103 = (4*4!)+⌈√44⌉\n", + " 104 = 44+(4!/.4)\n", + " 105 = (44-√4)/.4\n", + " 106 = (44/.4)-4\n", + " 107 = ⌈(4!*4.44)⌉\n", + " 108 = (44/.4)-√4\n", + " 109 = (44-.4)/.4\n", + " 110 = ⌊44.4⌋/.4\n", + " 111 = 444/4\n", + " 112 = √4+(44/.4)\n", + " 113 = ⌈(.44*(4^4))⌉\n", + " 114 = 4+(44/.4)\n", + " 115 = (√4+44)/.4\n", + " 116 = 4+(4*(4+4!))\n", + " 117 = ⌈(44*√⌈√44⌉)⌉\n", + " 118 = ⌈4.44⌉!-√4\n", + " 119 = ⌈4.4⌉!-(4/4)\n", + " 120 = (4+44)/.4\n", + " 121 = (44/4)^√4\n", + " 122 = √4+⌈4.44⌉!\n", + " 123 = ⌊(4.4*(4+4!))⌋\n", + " 124 = 4+⌈4.44⌉!\n", + " 125 = ⌈(44*√(4+4))⌉\n", + " 126 = ((4^4)-4)/√4\n", + " 127 = ((4^4)-√4)/√4\n", + " 128 = 4*(4*(4+4))\n", + " 129 = (√4+(4^4))/√4\n", + " 130 = (4+(4^4))/√4\n", + " 131 = ⌈(4!*(4!/4.4))⌉\n", + " 132 = 44*⌈√4.4⌉\n", + " 133 = ⌈((4!-4)*√44)⌉\n", + " 134 = 4!+(44/.4)\n", + " 135 = ⌊(4!/.44)⌋/.4\n", + " 136 = √4*(4!+44)\n", + " 137 = ⌈(√4.4^√44)⌉\n", + " 138 = ⌈(.44^-(4+√4))⌉\n", + " 139 = ⌊(4^(4-.44))⌋\n", + " 140 = 44+(4*4!)\n", + " 141 = ⌈(4*((.4^-4)-4))⌉\n", + " 142 = (4!*(4+√4))-√4\n", + " 143 = ((4!*4!)-4)/4\n", + " 144 = (4+(4+4))^√4\n", + " 145 = (4+(4!*4!))/4\n", + " 146 = (4!/(.4*.4))-4\n", + " 147 = ⌊(44^(√4^.4))⌋\n", + " 148 = 4+(4!*(4+√4))\n", + " 149 = ⌊(.4*(4.4^4))⌋\n", + " 150 = .4*⌈(4.4^4)⌉\n", + " 151 = 4+⌊(4^(4-.4))⌋\n", + " 152 = (4*44)-4!\n", + " 153 = ⌈(4/(.4^4))⌉-4\n", + " 154 = 4+(4!/(.4*.4))\n", + " 155 = ⌊(4!*√44)⌋-4\n", + " 156 = ⌊(44*(4!^.4))⌋\n", + " 157 = ⌈(44*(4!^.4))⌉\n", + " 158 = ⌊(44*(4-.4))⌋\n", + " 159 = ⌈(44*(4-.4))⌉\n", + " 160 = 4*(44-4)\n", + " 161 = ⌈((4-.44)^4)⌉\n", + " 162 = ⌈((.4+4!)*√44)⌉\n", + " 163 = 4+⌊(4!*√44)⌋\n", + " 164 = 44+⌈4.4⌉!\n", + " 165 = 4+⌊(√.4*(4^4))⌋\n", + " 166 = ⌊(4!*√(4+44))⌋\n", + " 167 = ⌈(4!*√(4+44))⌉\n", + " 168 = 4*(44-√4)\n", + " 169 = ⌈(4!*(.4+√44))⌉\n", + " 170 = (4!+44)/.4\n", + " 171 = ⌊(4.4/(.4^4))⌋\n", + " 172 = (4*44)-4\n", + " 173 = ⌊(4*(44-√.4))⌋\n", + " 174 = (4*44)-√4\n", + " 175 = (4*44)-⌈.4⌉\n", + " 176 = 4*⌊44.4⌋\n", + " 177 = ⌊(.4*444)⌋\n", + " 178 = √4+(4*44)\n", + " 179 = ⌈(.4*(4^4.4))⌉\n", + " 180 = 4+(4*44)\n", + " 181 = (4+(4+√4)!)/4\n", + " 182 = ⌈(4*(√√4+44))⌉\n", + " 183 = ⌈(4!*(4+(4-.4)))⌉\n", + " 184 = 4*(√4+44)\n", + " 185 = ⌊((4+4!)*√44)⌋\n", + " 186 = ⌈((4+4!)*√44)⌉\n", + " 187 = ⌊(4.4^4)⌋/√4\n", + " 188 = (4!*(4+4))-4\n", + " 189 = ⌊(44/(√.4-.4))⌋\n", + " 190 = (4!*(4+4))-√4\n", + " 191 = (4!*(4+4))-⌈.4⌉\n", + " 192 = 4*(4+44)\n", + " 193 = ⌊(4.4*44)⌋\n", + " 194 = ⌈(4.4*44)⌉\n", + " 195 = ⌊(4*(√4!+44))⌋\n", + " 196 = 4+(4!*(4+4))\n", + " 197 = ⌈(44*√(4!-4))⌉\n", + " 198 = ⌈(44*(√4!-.4))⌉\n", + " 199 = ⌊(44^(.4+⌈.4⌉))⌋\n", + " 200 = 4!+(4*44)\n", + " 201 = ⌊(4!*(4+4.4))⌋\n", + " 202 = ⌈(4!*(4+4.4))⌉\n", + " 203 = ⌊(44*(4+√.4))⌋\n", + " 204 = ⌈(44*(4+√.4))⌉\n", + " 205 = ⌈((.4+.4)*(4^4))⌉\n", + " 206 = ⌊(44^√√4)⌋-4\n", + " 207 = ⌊(4.4^(4-.4))⌋\n", + " 208 = 4*(4+(4!+4!))\n", + " 209 = ⌊((4-√.4)^4.4)⌋\n", + " 210 = ⌊(√44^√(4+4))⌋\n", + " 211 = ⌊(√4!*44)⌋-4\n", + " 212 = (4^4)-44\n", + " 213 = ⌊(44.4^√√4)⌋\n", + " 214 = ⌈(44.4^√√4)⌉\n", + " 215 = 4+⌈(44^√√4)⌉\n", + " 216 = 4!*(4+⌈4.4⌉)\n", + " 217 = ⌊(√4!*44.4)⌋\n", + " 218 = ⌈(√4!*44.4)⌉\n", + " 219 = ⌈(4*(4!/.44))⌉\n", + " 220 = 44*⌈4.4⌉\n", + " 221 = ⌈(4!*(4^(.4*4)))⌉\n", + " 222 = 444/√4\n", + " 223 = ⌈(4^4.4)⌉/√4\n", + " 224 = (4+4)*(4+4!)\n", + " 225 = ⌊(4/(.4^4.4))⌋\n", + " 226 = ⌈(4/(.4^4.4))⌉\n", + " 227 = 4+⌈((4^√4!)/4)⌉\n", + " 228 = (4^4)-(4+4!)\n", + " 229 = ⌈(4^(4-(√4/4!)))⌉\n", + " 230 = ((4*4!)-4)/.4\n", + " 231 = ⌊(.44^-√44)⌋\n", + " 232 = ⌈(.44^-√44)⌉\n", + " 233 = ⌈(44*√(4+4!))⌉\n", + " 234 = √4+((4^4)-4!)\n", + " 235 = ⌊(√4!*(4+44))⌋\n", + " 236 = 4+((4^4)-4!)\n", + " 237 = ⌊(√.4*(4.4^4))⌋\n", + " 238 = ⌊(44*(4+√√4))⌋\n", + " 239 = ⌈(44*(4+√√4))⌉\n", + " 240 = (4^4)-(4*4)\n", + " 241 = (.4+(4*4!))/.4\n", + " 242 = √4+(4*(4!/.4))\n", + " 243 = ⌈√4.4⌉^⌈4.4⌉\n", + " 244 = 4+(4*(4!/.4))\n", + " 245 = (√4+(4*4!))/.4\n", + " 246 = (4^4)-(4/.4)\n", + " 247 = ⌊(4^(4-(.4^4)))⌋\n", + " 248 = (4^4)-(4+4)\n", + " 249 = (4^4)-⌈√44⌉\n", + " 250 = (4^4)-(4+√4)\n", + " 251 = (4^4)-⌈4.4⌉\n", + " 252 = (4^4)-⌊4.4⌋\n", + " 253 = ⌈.4⌉+((4^4)-4)\n", + " 254 = √4+((4^4)-4)\n", + " 255 = (4^4)-(4/4)\n", + " 256 = 4*(4*(4*4))\n", + " 257 = (4/4)+(4^4)\n", + " 258 = 4+((4^4)-√4)\n", + " 259 = (4^4)+⌈√4.4⌉\n", + " 260 = 4+(4^⌊4.4⌋)\n", + " 261 = (4^4)+⌈4.4⌉\n", + " 262 = 4+(√4+(4^4))\n", + " 263 = (4^4)+⌈√44⌉\n", + " 264 = 44*(4+√4)\n", + " 265 = ⌊(4^(4+(.4^4)))⌋\n", + " 266 = (4/.4)+(4^4)\n", + " 267 = ⌈(.4^-(4+√4.4))⌉\n", + " 268 = ⌊(4!^(4*.44))⌋\n", + " 269 = ⌈(4!^(4*.44))⌉\n", + " 270 = ⌊((4*(.4-√√4))^4)⌋\n", + " 271 = ⌊(4*(4!*√(4+4)))⌋\n", + " 272 = 4*(4!+44)\n", + " 273 = ⌊(4^(4!^.44))⌋\n", + " 274 = ⌈(4^(4!^.44))⌉\n", + " 275 = 44/(.4*.4)\n", + " 276 = 4!+((4^4)-4)\n", + " 277 = ⌈(√4!/(.4^4.4))⌉\n", + " 278 = ⌊(4*(44/√.4))⌋\n", + " 279 = ⌈(4*(44/√.4))⌉\n", + " 280 = ⌊(√.4*444)⌋\n", + " 281 = ⌈(√.4*444)⌉\n", + " 282 = 4!+(√4+(4^4))\n", + " 283 = ⌈((4+(.4/4))^4)⌉\n", + " 284 = 4+(4!+(4^4))\n", + " 285 = ⌈((4^4)/(√4!-4))⌉\n", + " 286 = ((4!*4!)-4)/√4\n", + " 287 = ⌈(√4!^(4-.44))⌉\n", + " 288 = 4!*(4+(4+4))\n", + " 289 = ⌊(.4*44)⌋^√4\n", + " 290 = (⌈4.4⌉!-4)/.4\n", + " 291 = ⌊(44*√44)⌋\n", + " 292 = ⌈(44*√44)⌉\n", + " 293 = ⌊(4^(√4+√4.4))⌋\n", + " 294 = ⌊(4^(4+(.4/4)))⌋\n", + " 295 = ⌈(4^(4+(.4/4)))⌉\n", + " 296 = (⌈4.4⌉!/.4)-4\n", + " 297 = ⌊(.4*(4!+(4+√4)!))⌋\n", + " 298 = ⌊((4+(√.4/4))^4)⌋\n", + " 299 = ⌊((4+(.4*.4))^4)⌋\n", + " 300 = 44+(4^4)\n", + " 301 = ⌊((4+(4/4!))^4)⌋\n", + " 302 = ⌈((4+(4/4!))^4)⌉\n", + " 303 = ⌈(.4^(.4-√44))⌉\n", + " 304 = 4!+(4!+(4^4))\n", + " 305 = ⌈(44*√(4!+4!))⌉\n", + " 306 = ⌊(4^(4*(.4+√.4)))⌋\n", + " 307 = ⌈(4^(4*(.4+√.4)))⌉\n", + " 308 = 44*⌈√44⌉\n", + " 309 = ⌊((.4*44)^√4)⌋\n", + " 310 = ⌈((.4*44)^√4)⌉\n", + " 311 = ⌊((4+(.4/√4))^4)⌋\n", + " 312 = ⌊((4+4)/(.4^4))⌋\n", + " 313 = ⌊(444/√√4)⌋\n", + " 314 = ⌈(444/√√4)⌉\n", + " 315 = ⌊((4^4.4)/√√4)⌋\n", + " 316 = (4^4)+(4!/.4)\n", + " 317 = ⌈(.44*(4+√4)!)⌉\n", + " 318 = √4*⌊(4!*√44)⌋\n", + " 319 = ⌊(4^(4+(.4*.4)))⌋\n", + " 320 = 4*(4*(4!-4))\n", + " 321 = ⌈(4*(4^√(4/.4)))⌉\n", + " 322 = ⌊(4^(4+(4/4!)))⌋\n", + " 323 = ⌈(4^(4+(4/4!)))⌉\n", + " 324 = ((4+√4)^4)/4\n", + " 325 = ⌈(.4^(4/-√.4))⌉-4\n", + " 326 = ⌊((4+(⌈.4⌉/4))^4)⌋\n", + " 327 = ⌈((4+(⌈.4⌉/4))^4)⌉\n", + " 328 = ⌊(.4^-√(44-4))⌋\n", + " 329 = ⌈(.4^-√(44-4))⌉\n", + " 330 = ⌊((4+4!)^(4^.4))⌋\n", + " 331 = ⌈((4+4!)^(4^.4))⌉\n", + " 332 = ⌊((.4+√4)^√44)⌋\n", + " 333 = ⌊(√4!*(4!+44))⌋\n", + " 334 = ⌈(√4!*(4!+44))⌉\n", + " 335 = ⌊(4^√(.4*44))⌋\n", + " 336 = 4!*(4+(4/.4))\n", + " 337 = ⌊(√4^(4+4.4))⌋\n", + " 338 = ⌈(√4^(4+4.4))⌉\n", + " 339 = ⌊(4!^(44/4!))⌋\n", + " 340 = ⌈(4!^(44/4!))⌉\n", + " 341 = ⌈(44*√(4!/.4))⌉\n", + " 342 = ⌊(4*(4!*(4!^.4)))⌋\n", + " 343 = ⌈√44⌉^⌈√4.4⌉\n", + " 344 = 4*⌊(4!*(4-.4))⌋\n", + " 345 = ⌊(4*(4!*(4-.4)))⌋\n", + " 346 = ⌊(4!^(4^.44))⌋\n", + " 347 = ⌈(4!^(4^.44))⌉\n", + " 348 = 4*⌈(4!*(4-.4))⌉\n", + " 349 = ⌊((√4-(4/√.4))^4)⌋\n", + " 350 = ⌊(4.4^4)⌋-4!\n", + " 351 = ⌈(4.4^4)⌉-4!\n", + " 352 = 44*(4+4)\n", + " 353 = ⌈(.4^(.4*(4*-4)))⌉\n", + " 354 = ⌊((4.4^√4!)/4)⌋\n", + " 355 = ⌈(4.4^√4!)⌉/4\n", + " 356 = ((4+√4)!/√4)-4\n", + " 357 = ⌈(√√4*((4^4)-4))⌉\n", + " 358 = ⌊((4+4)^√(4+4))⌋\n", + " 359 = ⌈((4+4)^√(4+4))⌉\n", + " 360 = (4*(4*4!))-4!\n", + " 361 = (⌈4.4⌉-4!)^√4\n", + " 362 = (4+(4+√4)!)/√4\n", + " 363 = ⌈((4^4)*√(4-√4))⌉\n", + " 364 = 4+((4+√4)!/√4)\n", + " 365 = ⌈(4*((4*4!)-√4!))⌉\n", + " 366 = 4+⌊(√√4*(4^4))⌋\n", + " 367 = ⌊((4^(4-.4))/.4)⌋\n", + " 368 = 4*((4*4!)-4)\n", + " 369 = ⌊((4.4^4)-√4!)⌋\n", + " 370 = ⌊(4.4^4)⌋-4\n", + " 371 = ⌈(4.4^4)⌉-4\n", + " 372 = ⌊(4.4^4)⌋-√4\n", + " 373 = ⌈(4.4^4)⌉-√4\n", + " 374 = ⌊((4.4^4)-.4)⌋\n", + " 375 = ⌊(.4+(4.4^4))⌋\n", + " 376 = ⌈(.4+(4.4^4))⌉\n", + " 377 = √4+⌈(4.4^4)⌉\n", + " 378 = 4+⌊(4.4^4)⌋\n", + " 379 = 4+⌈(4.4^4)⌉\n", + " 380 = (4*(4*4!))-4\n", + " 381 = ⌊((.4^-(4+4))/4)⌋\n", + " 382 = (4*(4*4!))-√4\n", + " 383 = (4*(4*4!))-⌈.4⌉\n", + " 384 = 4*(4*⌊4.4⌋!)\n", + " 385 = ⌈.4⌉+(4*(4*4!))\n", + " 386 = √4+(4*(4*4!))\n", + " 387 = ⌈(4*(√.4+(4*4!)))⌉\n", + " 388 = ⌊(4.44^4)⌋\n", + " 389 = ⌈(4.44^4)⌉\n", + " 390 = ⌊(4*(4*(.4+4!)))⌋\n", + " 391 = ⌊(44*(4+√4!))⌋\n", + " 392 = 4*(√4+(4*4!))\n", + " 393 = ⌊(4!*(.4+(4*4)))⌋\n", + " 394 = ⌈(4!*(.4+(4*4)))⌉\n", + " 395 = ⌊((√4!-.44)^4)⌋\n", + " 396 = 44*⌊(.4*4!)⌋\n", + " 397 = ⌊(4*(√4^√44))⌋\n", + " 398 = 4!+⌊(4.4^4)⌋\n", + " 399 = 4!+⌈(4.4^4)⌉\n", + " 400 = 4*(4+(4*4!))\n", + " 401 = ⌈((4^4)/√.4)⌉-4\n", + " 402 = √4+((4-4!)^√4)\n", + " 403 = ⌊((4!^(.4*4))/.4)⌋\n", + " 404 = 4+((4-4!)^√4)\n", + " 405 = ⌊(.4^-((.4*4)^4))⌋\n", + " 406 = ⌈(.4^-((.4*4)^4))⌉\n", + " 407 = ⌈(4*(4*(4!+√√4)))⌉\n", + " 408 = 4!+(4*(4*4!))\n", + " 409 = ⌊(.4*(4*(4^4)))⌋\n", + " 410 = ⌈(.4*(4*(4^4)))⌉\n", + " 411 = ⌈((4+(√4/4))^4)⌉\n", + " 412 = 4*⌈(.4*(4^4))⌉\n", + " 413 = ⌈(.4^-√44)⌉-4!\n", + " 414 = 4+⌈((.4-√4!)^4)⌉\n", + " 415 = ⌊(44/(√.4^√4!))⌋\n", + " 416 = 4*(4*(4!+√4))\n", + " 417 = ⌈(4!*(4!-√44))⌉\n", + " 418 = ⌈(4^((4^.4)/.4))⌉\n", + " 419 = ⌊(((.4-4)^4)/.4)⌋\n", + " 420 = 444-4!\n", + " 421 = ⌊(4^4.4)⌋-4!\n", + " 422 = ⌊(.4*(4!*44))⌋\n", + " 423 = ⌈(.4*(4!*44))⌉\n", + " 424 = 4*⌈(4!*4.4)⌉\n", + " 425 = ⌈(.4^-√(44-.4))⌉\n", + " 426 = ⌊(44^(.4*4))⌋\n", + " 427 = ⌈(44^(.4*4))⌉\n", + " 428 = 4*⌈(4^(4-√.4))⌉\n", + " 429 = ⌈(4!^(4/√4.4))⌉\n", + " 430 = √4*⌊(√4!*44)⌋\n", + " 431 = ⌊(44*√(4*4!))⌋\n", + " 432 = 4!*(√4+(4*4))\n", + " 433 = ⌈(.4^-√44)⌉-4\n", + " 434 = ⌊(.4^-√44)⌋-√4\n", + " 435 = ⌊((.4^-√44)-.4)⌋\n", + " 436 = ⌊(.4+(.4^-√44))⌋\n", + " 437 = ⌊((4+(4^-.4))^4)⌋\n", + " 438 = ⌈((4+(4^-.4))^4)⌉\n", + " 439 = ⌊(444-√4!)⌋\n", + " 440 = 444-4\n", + " 441 = ⌊(4^4.4)⌋-4\n", + " 442 = 444-√4\n", + " 443 = 444-⌈.4⌉\n", + " 444 = ⌊444.4⌋\n", + " 445 = ⌈444.4⌉\n", + " 446 = √4+444\n", + " 447 = ⌈(.4+(4^4.4))⌉\n", + " 448 = 4+444\n", + " 449 = 4+⌊(4^4.4)⌋\n", + " 450 = 4+⌈(4^4.4)⌉\n", + " 451 = ⌈(√4!+(4^4.4))⌉\n", + " 452 = 4*(⌊(4!*√4!)⌋-4)\n", + " 453 = ⌈((4^4)/(.4*√√4))⌉\n", + " 454 = ⌊((4^(4+√√4))/4)⌋\n", + " 455 = ⌈((4^(4+√√4))/4)⌉\n", + " 456 = 4!*(4!-⌈4.4⌉)\n", + " 457 = ⌈((4+√.4)^4)⌉-4\n", + " 458 = ⌊((4+√.4)^4)⌋-√4\n", + " 459 = ⌈((4+√.4)^4)⌉-√4\n", + " 460 = ⌊((√4-√44)^4)⌋\n", + " 461 = ⌈((√4-√44)^4)⌉\n", + " 462 = ⌊(4^√(4!-4.4))⌋\n", + " 463 = ⌈(4^√(4!-4.4))⌉\n", + " 464 = 4*(⌈4.4⌉!-4)\n", + " 465 = 4+⌈((4+√.4)^4)⌉\n", + " 466 = ⌊(4*(4!*√4!))⌋-4\n", + " 467 = ⌊(.4^-√⌈44.4⌉)⌋\n", + " 468 = 4!+444\n", + " 469 = 4!+⌊(4^4.4)⌋\n", + " 470 = 4!+⌈(4^4.4)⌉\n", + " 471 = ⌊(4^4.44)⌋\n", + " 472 = ⌈(4^4.44)⌉\n", + " 473 = ⌊(√4^(4+√4!))⌋-4\n", + " 474 = 4+⌊(4*(4!*√4!))⌋\n", + " 475 = 4+⌈(4*(4!*√4!))⌉\n", + " 476 = (4*⌈4.4⌉!)-4\n", + " 477 = ⌊(4^(4/(√4!-4)))⌋\n", + " 478 = (4*⌈4.4⌉!)-√4\n", + " 479 = (4*⌈4.4⌉!)-⌈.4⌉\n", + " 480 = 4*⌈4.44⌉!\n", + " 481 = ⌈.4⌉+(4*⌈4.4⌉!)\n", + " 482 = √4+(4*⌈4.4⌉!)\n", + " 483 = ⌊(4^(√4!-.44))⌋\n", + " 484 = (44^√4)/4\n", + " 485 = ⌊((4+(.4^.4))^4)⌋\n", + " 486 = ⌈((4+(.4^.4))^4)⌉\n", + " 487 = ⌈(4*(4+(4!*√4!)))⌉\n", + " 488 = (√4*(4^4))-4!\n", + " 489 = ⌈(4^√(4!-4))⌉-4\n", + " 490 = ⌊((4+√(√4/4))^4)⌋\n", + " 491 = ⌈((4+√(√4/4))^4)⌉\n", + " 492 = ⌊(4^√(4+(4*4)))⌋\n", + " 493 = ⌈(4^√(4+(4*4)))⌉\n", + " 494 = √4+⌊(4^√(4!-4))⌋\n", + " 495 = √4+⌈(4^√(4!-4))⌉\n", + " 496 = 4*(4+⌈4.4⌉!)\n", + " 497 = 4+⌈(4^√(4!-4))⌉\n", + " 498 = ⌊((√.4/4)^(√.4-4))⌋\n", + " 499 = ⌊(.4^-√(√4+44))⌋\n", + " 500 = ⌈(.4^-√(√4+44))⌉\n", + " 501 = ⌊(.4*(√4!*(4^4)))⌋\n", + " 502 = ⌊((4-.44)^√4!)⌋\n", + " 503 = ⌈((4-.44)^√4!)⌉\n", + " 504 = √4*((4^4)-4)\n", + " 505 = ⌊(√4^(44/√4!))⌋\n", + " 506 = ⌊(4!*(√4^4.4))⌋\n", + " 507 = ⌈(4!*(√4^4.4))⌉\n", + " 508 = (√4*(4^4))-4\n", + " 509 = ⌈(4!*(4!-√(4+4)))⌉\n", + " 510 = (√4*(4^4))-√4\n", + " 511 = (√4*(4^4))-⌈.4⌉\n", + " 512 = (4^4)+(4^4)\n", + " 513 = ⌈.4⌉+(√4*(4^4))\n", + " 514 = √4+(√4*(4^4))\n", + " 515 = ⌈(4*((4-√.4)^4))⌉\n", + " 516 = 4+(√4*(4^4))\n", + " 517 = ⌊(4!*(√4!*4.4))⌋\n", + " 518 = ⌊(.4*((4+√4)^4))⌋\n", + " 519 = ⌈(.4*((4+√4)^4))⌉\n", + " 520 = √4*(4+(4^4))\n", + " 521 = ⌊(.4^-(4+√(4+4)))⌋\n", + " 522 = ⌈(.4^-(4+√(4+4)))⌉\n", + " 523 = ⌊(4^√(.4+(4!-4)))⌋\n", + " 524 = (4!*(4!-√4))-4\n", + " 525 = ⌊(44^√√4)⌋/.4\n", + " 526 = ⌈(4!*(4!-√4.4))⌉\n", + " 527 = ⌊((44^√√4)/.4)⌋\n", + " 528 = 4!*(44/√4)\n", + " 529 = (4!-(4/4))^√4\n", + " 530 = ⌊((.4+4.4)^4)⌋\n", + " 531 = ⌈((.4+4.4)^4)⌉\n", + " 532 = (4!*4!)-44\n", + " 533 = ⌊(4^(√4+(4*√.4)))⌋\n", + " 534 = ⌈(4^(√4+(4*√.4)))⌉\n", + " 535 = ⌊((4!-4)^√4.4)⌋\n", + " 536 = 4!+(√4*(4^4))\n", + " 537 = ⌈((4^4)*√4.4)⌉\n", + " 538 = ⌊(44*(√4!/.4))⌋\n", + " 539 = ⌈(44*(√4!/.4))⌉\n", + " 540 = ⌈(√4!*44)⌉/.4\n", + " 541 = ⌈(4^(√(.4+4!)-.4))⌉\n", + " 542 = ⌊(4!*(4!-.4))⌋-4!\n", + " 543 = ⌊(4^(44^.4))⌋\n", + " 544 = ⌈(4^(44^.4))⌉\n", + " 545 = ⌊(4^(√4/.44))⌋\n", + " 546 = ⌈(4^(√4/.44))⌉\n", + " 547 = 4+⌈(4!*(4!-√√4))⌉\n", + " 548 = (4!*4!)-(4+4!)\n", + " 549 = ⌈(4*(√4!*(4+4!)))⌉\n", + " 550 = (4!*4!)-(4!+√4)\n", + " 551 = (4!*4!)-(⌈.4⌉+4!)\n", + " 552 = 4!*(4!-(4/4))\n", + " 553 = ⌈((.4-4!)^√4)⌉-4\n", + " 554 = √4+((4!*4!)-4!)\n", + " 555 = ⌊((4!-.44)^√4)⌋\n", + " 556 = 4+((4!*4!)-4!)\n", + " 557 = ⌈(4^(4+(.4^√.4)))⌉\n", + " 558 = ⌈(.4+((.4-4!)^√4))⌉\n", + " 559 = ⌊(4!*(4!-(.4^.4)))⌋\n", + " 560 = (4+4!)*(4!-4)\n", + " 561 = ⌈(4*(4^(4!^.4)))⌉\n", + " 562 = ⌊((√4*44)^√√4)⌋\n", + " 563 = ⌈((√4*44)^√√4)⌉\n", + " 564 = 4!*(4!-(√4/4))\n", + " 565 = ⌊(4!*(4!-.44))⌋\n", + " 566 = (4!*4!)-(4/.4)\n", + " 567 = ⌊(4^(4+(4^-.4)))⌋\n", + " 568 = (4!*4!)-(4+4)\n", + " 569 = (4!*4!)-⌈√44⌉\n", + " 570 = (4!*4!)-(4+√4)\n", + " 571 = ⌊(.4^-√(4+44))⌋\n", + " 572 = (4!^(4-√4))-4\n", + " 573 = ⌈((4^4)*√⌈4.4⌉)⌉\n", + " 574 = √4+((4!*4!)-4)\n", + " 575 = (4!*4!)-(4/4)\n", + " 576 = 4!^((4+4)/4)\n", + " 577 = (4/4)+(4!*4!)\n", + " 578 = 4+((4!*4!)-√4)\n", + " 579 = ⌈√4.4⌉+(4!*4!)\n", + " 580 = ((4^4)-4!)/.4\n", + " 581 = ⌊((4^4)/.44)⌋\n", + " 582 = ⌈((4^4)/.44)⌉\n", + " 583 = (4!*4!)+⌈√44⌉\n", + " 584 = 4+(4+(4!*4!))\n", + " 585 = ⌊(√44^(4-√.4))⌋\n", + " 586 = (4/.4)+(4!*4!)\n", + " 587 = ⌈(4!*(4!+.44))⌉\n", + " 588 = 4*⌊(4^(4-.4))⌋\n", + " 589 = ⌈(4*(4^(4-.4)))⌉\n", + " 590 = ⌊(.4^(4*-(4^.4)))⌋\n", + " 591 = ⌈(.4^(4*-(4^.4)))⌉\n", + " 592 = (4*4)+(4!*4!)\n", + " 593 = ⌈((4.4^4)/√.4)⌉\n", + " 594 = ⌊((4+√4)^(4!^.4))⌋\n", + " 595 = ⌊((.4+4!)^(4-√4))⌋\n", + " 596 = 4!+((4!*4!)-4)\n", + " 597 = ⌊((4!+.44)^√4)⌋\n", + " 598 = ⌈((4!+.44)^√4)⌉\n", + " 599 = 4+⌊((.4+4!)^√4)⌋\n", + " 600 = 4!/(.44-.4)\n", + " 601 = (⌈4.4⌉^4)-4!\n", + " 602 = 4!+(√4+(4!*4!))\n", + " 603 = ⌊((4!+(4^-.4))^√4)⌋\n", + " 604 = 4+(4!+(4!*4!))\n", + " 605 = ⌈((4-.4)^⌈4.4⌉)⌉\n", + " 606 = ⌊(.4^-⌈√44⌉)⌋-4\n", + " 607 = ⌈(.4^-⌈√44⌉)⌉-4\n", + " 608 = 4*(4*⌈(4!/√.4)⌉)\n", + " 609 = ⌊((.4^-⌈√44⌉)-.4)⌋\n", + " 610 = ⌊(.4/(.4^(4+4)))⌋\n", + " 611 = ⌈(.4/(.4^(4+4)))⌉\n", + " 612 = ⌈(4^(4+√.4))⌉-4\n", + " 613 = ⌊((√.4-.4)^-4.4)⌋\n", + " 614 = ⌊((.4+√4)*(4^4))⌋\n", + " 615 = ⌊(4^(√44-√4))⌋\n", + " 616 = ((4^4)/.4)-4!\n", + " 617 = √4+⌊(4^(4+√.4))⌋\n", + " 618 = √4+⌈(4^(4+√.4))⌉\n", + " 619 = 4+⌊(4^(4+√.4))⌋\n", + " 620 = 44+(4!*4!)\n", + " 621 = (⌈4.4⌉^4)-4\n", + " 622 = (4!*(4!+√4))-√4\n", + " 623 = (⌈4.4⌉^4)-√4\n", + " 624 = 4!*⌊(4*√44)⌋\n", + " 625 = ⌈4.44⌉^4\n", + " 626 = ⌈.4⌉+(⌈4.4⌉^4)\n", + " 627 = ⌊(√√4*444)⌋\n", + " 628 = ⌈(√√4*444)⌉\n", + " 629 = 4+(⌈4.4⌉^4)\n", + " 630 = ((4^4)-4)/.4\n", + " 631 = ⌈(√√4*(4^4.4))⌉\n", + " 632 = ⌊((4+√4)^(4-.4))⌋\n", + " 633 = ⌈((4+√4)^(4-.4))⌉\n", + " 634 = ⌊(4^√4!)⌋-(4^4)\n", + " 635 = ((4^4)-√4)/.4\n", + " 636 = ((4^4)/.4)-4\n", + " 637 = ⌈(4*(4!*√44))⌉\n", + " 638 = ((4^4)/.4)-√4\n", + " 639 = ((4^4)-.4)/.4\n", + " 640 = (4^⌊4.4⌋)/.4\n", + " 641 = (.4+(4^4))/.4\n", + " 642 = √4+((4^4)/.4)\n", + " 643 = ⌊(4!*(4!+√(4+4)))⌋\n", + " 644 = 4+((4^4)/.4)\n", + " 645 = (√4+(4^4))/.4\n", + " 646 = ⌊(4*(4!^(.4*4)))⌋\n", + " 647 = ⌊(4*(√.4*(4^4)))⌋\n", + " 648 = 4!*⌈(4*√44)⌉\n", + " 649 = 4!+(⌈4.4⌉^4)\n", + " 650 = (4+(4^4))/.4\n", + " 651 = ⌊(.4^(√(4+4)/-.4))⌋\n", + " 652 = ((4!+√4)^√4)-4!\n", + " 653 = ⌈((√4!+(4^4))/.4)⌉\n", + " 654 = ⌊((4!-√4)^√4.4)⌋\n", + " 655 = ⌊((4*√(.4*4))^4)⌋\n", + " 656 = ⌈((4*√(.4*4))^4)⌉\n", + " 657 = ⌈(4!*(4+(4!-√.4)))⌉\n", + " 658 = ⌊((√4!+(4/4!))^4)⌋\n", + " 659 = ⌈((√4!+(4/4!))^4)⌉\n", + " 660 = 44*⌊(√.4*4!)⌋\n", + " 661 = ⌊((4^4)*(4-√√4))⌋\n", + " 662 = ⌈((4^4)*(4-√√4))⌉\n", + " 663 = ⌈(4!*(4+(4!-.4)))⌉\n", + " 664 = 4!+((4^4)/.4)\n", + " 665 = ⌈((⌈4.4⌉^√4!)/4)⌉\n", + " 666 = ⌊(4^√(44/√4))⌋\n", + " 667 = ⌈(4^√(44/√4))⌉\n", + " 668 = (4!*(4+4!))-4\n", + " 669 = ⌊(4^(4+(.4^.4)))⌋\n", + " 670 = (4!*(4+4!))-√4\n", + " 671 = ⌊(4*((.4-4)^4))⌋\n", + " 672 = 4*(4!*⌈√44⌉)\n", + " 673 = ⌊((4/.4)^√(4+4))⌋\n", + " 674 = √4+(4!*(4+4!))\n", + " 675 = ⌊(√4!^(4+(.4/4)))⌋\n", + " 676 = (4+√4)!-44\n", + " 677 = ⌊(4.4^4.4)⌋\n", + " 678 = ⌈(4.4^4.4)⌉\n", + " 679 = ⌊(4^((4!+4!)^.4))⌋\n", + " 680 = 4+((4!+√4)^√4)\n", + " 681 = ⌊(4!*(4!+4.4))⌋\n", + " 682 = ⌈(4!*(4!+4.4))⌉\n", + " 683 = ⌈(4^(4+√(√4/4)))⌉\n", + " 684 = ⌈((.4+4!)*(4+4!))⌉\n", + " 685 = ⌊(.4^(4!/(√.4-4)))⌋\n", + " 686 = ⌊(4^(√4^√⌈4.4⌉))⌋\n", + " 687 = ⌈(4^(√4^√⌈4.4⌉))⌉\n", + " 688 = ⌈(√.4*(√4!^4.4))⌉\n", + " 689 = ⌊((.4^-√44)/√.4)⌋\n", + " 690 = ⌈((.4^-√44)/√.4)⌉\n", + " 691 = ⌊((4!-√√4)^√4.4)⌋\n", + " 692 = (4+√4)!-(4+4!)\n", + " 693 = ⌈((4-(.4/√4))^√4!)⌉\n", + " 694 = (4+√4)!-(4!+√4)\n", + " 695 = (4+√4)!-(⌈.4⌉+4!)\n", + " 696 = ((4/.4)-4)!-4!\n", + " 697 = ⌈((.4*(4^4))^√√4)⌉\n", + " 698 = √4+((4+√4)!-4!)\n", + " 699 = ⌊((4!/.4)^(.4*4))⌋\n", + " 700 = (4!+(4^4))/.4\n", + " 701 = ⌊(⌈√44⌉^(4-√.4))⌋\n", + " 702 = ⌊(444/√.4)⌋\n", + " 703 = ⌈(444/√.4)⌉\n", + " 704 = 4*(4*44)\n", + " 705 = ⌈((4^4.4)/√.4)⌉\n", + " 706 = ⌈(⌈(4^4.4)⌉/√.4)⌉\n", + " 707 = ⌊(4^√(4!-(.4*4)))⌋\n", + " 708 = (4+√4)!-(4!/√4)\n", + " 709 = ⌊((4.4^√4!)/√4)⌋\n", + " 710 = (4+√4)!-(4/.4)\n", + " 711 = ⌊(.44^-(4+4))⌋\n", + " 712 = ⌈(.44^-(4+4))⌉\n", + " 713 = (4+√4)!-⌈√44⌉\n", + " 714 = (4+√4)!-(4+√4)\n", + " 715 = (4+√4)!-⌈4.4⌉\n", + " 716 = ((4/.4)-4)!-4\n", + " 717 = ⌊((4+4)^√(4/.4))⌋\n", + " 718 = ((4/.4)-4)!-√4\n", + " 719 = (4+√4)!-(4/4)\n", + " 720 = √(44-(4+4))!\n", + " 721 = (4/4)+(4+√4)!\n", + " 722 = √4+((4/.4)-4)!\n", + " 723 = ⌈√4.4⌉+(4+√4)!\n", + " 724 = 4+((4/.4)-4)!\n", + " 725 = ⌈((4^4)*√(4+4))⌉\n", + " 726 = ⌊(44^(4^.4))⌋\n", + " 727 = ⌈(44^(4^.4))⌉\n", + " 728 = 4+(4+(4+√4)!)\n", + " 729 = ⌈(4*√44)⌉^√4\n", + " 730 = (4/.4)+(4+√4)!\n", + " 731 = ⌊((4+(√.4^-.4))^4)⌋\n", + " 732 = ⌊(4^(4+(√4^-.4)))⌋\n", + " 733 = ⌊((.4*.4)^(.4-4))⌋\n", + " 734 = ⌈((.4*.4)^(.4-4))⌉\n", + " 735 = ⌊(4!*(4!+√44))⌋\n", + " 736 = (4*4)+(4+√4)!\n", + " 737 = ⌈(4^(√√4*(4-√.4)))⌉\n", + " 738 = ⌈((4!+√(4/.4))^√4)⌉\n", + " 739 = (4+√4)!+⌊(4*√4!)⌋\n", + " 740 = 4!+((4+√4)!-4)\n", + " 741 = ⌊((√√4-√44)^4)⌋\n", + " 742 = ⌈((√√4-√44)^4)⌉\n", + " 743 = ⌈((4^4)*(√4!-√4))⌉\n", + " 744 = 4!+((4/.4)-4)!\n", + " 745 = ⌊((4+(√4!/4))^4)⌋\n", + " 746 = ⌊(4!*(44/√√4))⌋\n", + " 747 = ⌈(4!*(44/√√4))⌉\n", + " 748 = √4*⌊(4.4^4)⌋\n", + " 749 = ⌊(√4*(4.4^4))⌋\n", + " 750 = √4*⌈(4.4^4)⌉\n", + " 751 = ⌈(√4!^(4+(4/4!)))⌉\n", + " 752 = ⌊(√4^(.4*4!))⌋-4!\n", + " 753 = ⌈(√4^(.4*4!))⌉-4!\n", + " 754 = ⌊(4.4^√(4!-4))⌋\n", + " 755 = ⌈(4.4^√(4!-4))⌉\n", + " 756 = ⌊((√4.4/.4)^4)⌋\n", + " 757 = ⌈((√4.4/.4)^4)⌉\n", + " 758 = ⌊((4!-.4)^√4.4)⌋\n", + " 759 = ⌈((4!-.4)^√4.4)⌉\n", + " 760 = ((4+4!)^√4)-4!\n", + " 761 = ⌊(4!^√4.4)⌋-4!\n", + " 762 = ⌊((.4^-(4+4))/√4)⌋\n", + " 763 = ⌈(.4^-(4+4))⌉/√4\n", + " 764 = 44+(4+√4)!\n", + " 765 = ⌊((4/√.4)^(4-.4))⌋\n", + " 766 = ⌈((4/√.4)^(4-.4))⌉\n", + " 767 = ⌈(4^√(4+4!))⌉/√4\n", + " 768 = 4*(4!*(4+4))\n", + " 769 = ⌈((4+√(.4*4))^4)⌉\n", + " 770 = ⌊((44/.4)^√√4)⌋\n", + " 771 = ⌈((44/.4)^√√4)⌉\n", + " 772 = ⌈(4^√(4!-(4/4)))⌉\n", + " 773 = ⌈(√4^(.4*4!))⌉-4\n", + " 774 = ⌊(.4*(44^√4))⌋\n", + " 775 = ⌈(.4*(44^√4))⌉\n", + " 776 = ⌊(4^(.4+4.4))⌋\n", + " 777 = ⌈(4^(.4+4.4))⌉\n", + " 778 = ⌊(.4^-(√.4+√44))⌋\n", + " 779 = ⌊(4!*(√4!*√44))⌋\n", + " 780 = ((4+4!)^√4)-4\n", + " 781 = ⌊(4!^√4.4)⌋-4\n", + " 782 = ((4+4!)^√4)-√4\n", + " 783 = ⌈((4*4)^(4^√.4))⌉\n", + " 784 = (4+4!)*(4+4!)\n", + " 785 = ⌊(.4+(4!^√4.4))⌋\n", + " 786 = √4+((4+4!)^√4)\n", + " 787 = √4+⌊(4!^√4.4)⌋\n", + " 788 = 4+((4+4!)^√4)\n", + " 789 = 4+⌊(4!^√4.4)⌋\n", + " 790 = 4+⌈(4!^√4.4)⌉\n", + " 791 = ⌊(4!^(√4+(.4/4)))⌋\n", + " 792 = 4+⌊((.4+√4!)^4)⌋\n", + " 793 = ⌊(4^(4+(4/√4!)))⌋\n", + " 794 = ⌈(4^(4+(4/√4!)))⌉\n", + " 795 = ⌊(√44*⌈4.4⌉!)⌋\n", + " 796 = ⌈(√44*⌈4.4⌉!)⌉\n", + " 797 = ⌈(4!*((.4+√4)^4))⌉\n", + " 798 = ⌊(4!^(4-√(4-.4)))⌋\n", + " 799 = ⌈(4!^(4-√(4-.4)))⌉\n", + " 800 = ((4/√.4)^4)/√4\n", + " 801 = ⌈((4+(√4^.4))^4)⌉\n", + " 802 = ⌊((4-(√4/4!))^√4!)⌋\n", + " 803 = ⌊(√44^(√√4/.4))⌋\n", + " 804 = ⌈(√44^(√√4/.4))⌉\n", + " 805 = ⌈((4+√4)!/√(.4+.4))⌉\n", + " 806 = ⌊((4!+4.4)^√4)⌋\n", + " 807 = ⌈((4!+4.4)^√4)⌉\n", + " 808 = 4!+((4+4!)^√4)\n", + " 809 = ⌊((4^4)*√(4/.4))⌋\n", + " 810 = ⌈((4^4)*√(4/.4))⌉\n", + " 811 = ⌊(4^(4+(√.4^.4)))⌋\n", + " 812 = ⌊((√4!+.44)^4)⌋\n", + " 813 = ⌈((√4!+.44)^4)⌉\n", + " 814 = ⌈((.4+4!)^√4.4)⌉\n", + " 815 = ⌈(4!*((4!/√.4)-4))⌉\n", + " 816 = 4!*(4!+(4/.4))\n", + " 817 = ⌊(4^√(4!-.4))⌋-4!\n", + " 818 = 4+⌊(4!*(4!*√√4))⌋\n", + " 819 = ⌊(√.4*((4+√4)^4))⌋\n", + " 820 = ⌈(√.4*((4+√4)^4))⌉\n", + " 821 = ⌊(.4*(4!^(.4+√4)))⌋\n", + " 822 = ⌊(√4!*((.4-4)^4))⌋\n", + " 823 = ⌈(√4!*((.4-4)^4))⌉\n", + " 824 = ⌊((4-(4^-√4))^√4!)⌋\n", + " 825 = ⌈((4-(4^-√4))^√4!)⌉\n", + " 826 = ⌈√44⌉*⌈(4!*√4!)⌉\n", + " 827 = ⌊((√4+√4!)*⌈4.4⌉!)⌋\n", + " 828 = ⌊(4!*(√√4*(.4+4!)))⌋\n", + " 829 = ⌊(4^√(4!-(√4/4)))⌋\n", + " 830 = ⌊((4+(√4-√.4))^4)⌋\n", + " 831 = ⌈((4+(√4-√.4))^4)⌉\n", + " 832 = (4^4)+(4!*4!)\n", + " 833 = ⌊(√4!^(4+(√.4-.4)))⌋\n", + " 834 = ⌊((.4*√4!)^(4/.4))⌋\n", + " 835 = ⌊((4+√√4)^4)⌋-4!\n", + " 836 = 44*⌊(4*√4!)⌋\n", + " 837 = ⌈(((4+4)^4)/√4!)⌉\n", + " 838 = ⌈(4^√(4!-.4))⌉-4\n", + " 839 = ⌊((√√4-(.4*4))^-4)⌋\n", + " 840 = 4*⌊(44^√√4)⌋\n", + " 841 = (4!+⌈4.4⌉)^√4\n", + " 842 = ⌈(4!*((.4^-4)-4))⌉\n", + " 843 = ⌊(4*(44^√√4))⌋\n", + " 844 = 4*⌈(44^√√4)⌉\n", + " 845 = 4+⌊(4^√(4!-.4))⌋\n", + " 846 = ⌊(4^√4!)⌋-44\n", + " 847 = ⌈(4^√4!)⌉-44\n", + " 848 = ⌊(√√4*(4!+(4!*4!)))⌋\n", + " 849 = ⌊((√4!+(√4/4))^4)⌋\n", + " 850 = ⌊((4+√.4)^4.4)⌋\n", + " 851 = ⌈((4+√.4)^4.4)⌉\n", + " 852 = 4*⌊(4!*(4+√4!))⌋\n", + " 853 = ⌈((4^√√4)*⌈4.4⌉!)⌉\n", + " 854 = ⌊(.4^(√.4-(4+4)))⌋\n", + " 855 = ⌊((4+√√4)^4)⌋-4\n", + " 856 = ⌈((4+√√4)^4)⌉-4\n", + " 857 = ⌊(4^(.4+√(4!-4)))⌋\n", + " 858 = ⌊(44^(.4^-√.4))⌋\n", + " 859 = ⌊((4+√(4-√4))^4)⌋\n", + " 860 = 4*⌊(√4!*44)⌋\n", + " 861 = √4+⌊((4+√√4)^4)⌋\n", + " 862 = ⌊(4*(√4!*44))⌋\n", + " 863 = ⌈(4*(√4!*44))⌉\n", + " 864 = 4*⌈(√4!*44)⌉\n", + " 865 = ⌈(4!*(4^(4-√√4)))⌉\n", + " 866 = 4!+⌈(4^√(4!-.4))⌉\n", + " 867 = ⌊(√4^(.4*(.4+4!)))⌋\n", + " 868 = ⌈(√4^(.4*(.4+4!)))⌉\n", + " 869 = ⌊((.4^-(4+√4!))/4)⌋\n", + " 870 = ⌊(√4^((.4^-4)/4))⌋\n", + " 871 = ⌈(√4^((.4^-4)/4))⌉\n", + " 872 = ⌊(√4/(.4^√44))⌋\n", + " 873 = ⌈(√4/(.4^√44))⌉\n", + " 874 = ⌊(4!^(√44^.4))⌋\n", + " 875 = ⌈(4!^(√44^.4))⌉\n", + " 876 = 4+⌈(⌈4.4⌉!^√√4)⌉\n", + " 877 = ⌊((4+(.4^-.4))^4)⌋\n", + " 878 = ⌈((4+(.4^-.4))^4)⌉\n", + " 879 = ⌈((4-.4)^√(4+4!))⌉\n", + " 880 = 44*(4!-4)\n", + " 881 = ⌊(4^(√(4+4!)-.4))⌋\n", + " 882 = ⌊(4^√4!)⌋-(4+4)\n", + " 883 = ⌈(4^√4!)⌉-(4+4)\n", + " 884 = ⌈((4^√4!)-√44)⌉\n", + " 885 = ⌊((4!/4.4)^4)⌋\n", + " 886 = ⌈((4!/4.4)^4)⌉\n", + " 887 = ⌈(.4+(4^√4!))⌉-4\n", + " 888 = √4*444\n", + " 889 = ⌊((4^√4!)-.44)⌋\n", + " 890 = √4*⌊(4^4.4)⌋\n", + " 891 = ⌊(√4*(4^4.4))⌋\n", + " 892 = √4*⌈(4^4.4)⌉\n", + " 893 = ⌈((4^√4!)+√4.4)⌉\n", + " 894 = ⌊(4.4+(4^√4!))⌋\n", + " 895 = ⌈(4.4+(4^√4!))⌉\n", + " 896 = ⌊((4^√4!)+√44)⌋\n", + " 897 = ⌈((4^√4!)+√44)⌉\n", + " 898 = 4+(4+⌊(4^√4!)⌋)\n", + " 899 = 4+(4+⌈(4^√4!)⌉)\n", + " 900 = ((4!/.4)^√4)/4\n", + " 901 = ⌊(4!^(.4+(4^.4)))⌋\n", + " 902 = ⌈(4!^(.4+(4^.4)))⌉\n", + " 903 = ⌈(4^√(4!+(.4/4)))⌉\n", + " 904 = ⌊(((4!*4!)-4)/√.4)⌋\n", + " 905 = ⌊(√√4*(4^4))⌋/.4\n", + " 906 = (4*4)+⌊(4^√4!)⌋\n", + " 907 = (4*4)+⌈(4^√4!)⌉\n", + " 908 = ⌊(√44^(4-.4))⌋\n", + " 909 = ⌈(√44^(4-.4))⌉\n", + " 910 = 4!+(⌊(4^√4!)⌋-4)\n", + " 911 = 4!+(⌈(4^√4!)⌉-4)\n", + " 912 = ⌊((4^4)*(4!^.4))⌋\n", + " 913 = ⌈((4^4)*(4!^.4))⌉\n", + " 914 = ⌈(4!/(.4^4))⌉-4!\n", + " 915 = ⌊(((4!-√4)/4)^4)⌋\n", + " 916 = ⌈(((4!-√4)/4)^4)⌉\n", + " 917 = ⌈(((4+√4)^4)/√√4)⌉\n", + " 918 = 4+(4!+⌊(4^√4!)⌋)\n", + " 919 = 4+(4!+⌈(4^√4!)⌉)\n", + " 920 = 4*⌊(.4*(4!*4!))⌋\n", + " 921 = ⌊((4-.4)*(4^4))⌋\n", + " 922 = ⌈((4-.4)*(4^4))⌉\n", + " 923 = ⌈(4^(√4!+(.4^4)))⌉\n", + " 924 = 4*⌈(.4*(4!*4!))⌉\n", + " 925 = ⌈(4*((⌈.4⌉-√4!)^4))⌉\n", + " 926 = ⌊((4!^(4-√√4))/4)⌋\n", + " 927 = ⌊(4!*((.4^-4)-.4))⌋\n", + " 928 = 4*((4^4)-4!)\n", + " 929 = ⌊(4^(.4^-(4^.4)))⌋\n", + " 930 = ⌈(4^(.4^-(4^.4)))⌉\n", + " 931 = ⌈(.4^-4)⌉+⌈(4^√4!)⌉\n", + " 932 = (4!*⌊(.4^-4)⌋)-4\n", + " 933 = ⌊(4!/(.4^4))⌋-4\n", + " 934 = 44+⌊(4^√4!)⌋\n", + " 935 = ⌊(4.4^4)⌋/.4\n", + " 936 = 4!*⌊(44-√4!)⌋\n", + " 937 = ⌊((4.4^4)/.4)⌋\n", + " 938 = ⌈((4.4^4)/.4)⌉\n", + " 939 = ⌈(4!*(44-√4!))⌉\n", + " 940 = 4+(4!*⌊(.4^-4)⌋)\n", + " 941 = 4+⌊(4!/(.4^4))⌋\n", + " 942 = 4+⌈(4!/(.4^4))⌉\n", + " 943 = ⌈(.4+(4^√(.4+4!)))⌉\n", + " 944 = 4*⌈(4!*√(4*4!))⌉\n", + " 945 = 4+⌊(4^√(.4+4!))⌋\n", + " 946 = 4+⌈(4^√(.4+4!))⌉\n", + " 947 = ⌊(4!*(.4+(.4^-4)))⌋\n", + " 948 = ⌊((4+√(.4+√4))^4)⌋\n", + " 949 = ⌈((4+√(.4+√4))^4)⌉\n", + " 950 = ⌊(4!*(√√4*(4+4!)))⌋\n", + " 951 = ⌈(4!*(√√4*(4+4!)))⌉\n", + " 952 = (4+4!)*⌈(4!*√√4)⌉\n", + " 953 = ⌊((.4+4!)/(.4^4))⌋\n", + " 954 = ⌈((.4+4!)/(.4^4))⌉\n", + " 955 = ⌊(4^√(4!+(√4/4)))⌋\n", + " 956 = ⌊(4.4^(4+√.4))⌋\n", + " 957 = ⌈(4.4^(4+√.4))⌉\n", + " 958 = ⌊(44^(.4+√√4))⌋\n", + " 959 = ⌈(44^(.4+√√4))⌉\n", + " 960 = 4!*(44-4)\n", + " 961 = (4!+⌈√44⌉)^√4\n", + " 962 = 4!+⌈(4!/(.4^4))⌉\n", + " 963 = ⌈((√.4+4!)/(.4^4))⌉\n", + " 964 = 4+(4!*⌈(.4^-4)⌉)\n", + " 965 = ⌊(√.4/(.4^(4+4)))⌋\n", + " 966 = ⌈(√.4/(.4^(4+4)))⌉\n", + " 967 = ⌊(.4^-(.4+(4^√√4)))⌋\n", + " 968 = 44*(4!-√4)\n", + " 969 = ⌈((4!*(.4-√.4))^4)⌉\n", + " 970 = ⌊((4+(√.4/.4))^4)⌋\n", + " 971 = ⌈((4+(√.4/.4))^4)⌉\n", + " 972 = ⌈(.4^-(√.4^-4.4))⌉\n", + " 973 = ⌊((√√4-⌈√44⌉)^4)⌋\n", + " 974 = ⌈((√√4-⌈√44⌉)^4)⌉\n", + " 975 = ⌊(4!^(.4*(4+√√4)))⌋\n", + " 976 = (4^4)+(4+√4)!\n", + " 977 = ⌈(4/(.4^(4+√4)))⌉\n", + " 978 = ⌊(4!^(√4+(4/4!)))⌋\n", + " 979 = ⌈(4!^(√4+(4/4!)))⌉\n", + " 980 = 4*⌈(.4^-(4+√4))⌉\n", + " 981 = ⌈(((4+√√4)^√4!)/4)⌉\n", + " 982 = ⌊((4+(.4/√4!))^√4!)⌋\n", + " 983 = ⌊((4+(.4*4))^4)⌋\n", + " 984 = ⌈((4+(.4*4))^4)⌉\n", + " 985 = ⌊(4!*(√4+(.4^-4)))⌋\n", + " 986 = (4*4!)+⌊(4^√4!)⌋\n", + " 987 = (4*4!)+⌈(4^√4!)⌉\n", + " 988 = ⌊((⌈4.4⌉^4)/√.4)⌋\n", + " 989 = ⌊(√(4+4)^√44)⌋\n", + " 990 = ⌈(√(4+4)^√44)⌉\n", + " 991 = ⌈(√(4!-⌈.4⌉)^4.4)⌉\n", + " 992 = ⌊((4!+√√4)/(.4^4))⌋\n", + " 993 = ⌊(44*(4!-√√4))⌋\n", + " 994 = ⌈(44*(4!-√√4))⌉\n", + " 995 = ⌊(4^√(4!+(.4+.4)))⌋\n", + " 996 = ⌈(4^√(4!+(.4+.4)))⌉\n", + " 997 = ⌈(4^((.4+4!)/√4!))⌉\n", + " 998 = ⌊(√4^(√√4^√44))⌋\n", + " 999 = ⌈(√4^(√√4^√44))⌉\n", + "1000 = (4*(4^4))-4!\n", + "1001 = ⌊((√4+√4.4)^√4!)⌋\n", + "1002 = ⌊(4!*(4!*(4^.4)))⌋\n", + "1003 = ⌈(4!*(4!*(4^.4)))⌉\n", + "1004 = 4*⌊((4^4)-√4!)⌋\n", + "1005 = ⌈(4*((4^4)-√4!))⌉\n", + "1006 = ⌊((√.4+⌈4.4⌉)^4)⌋\n", + "1007 = ⌊((⌈.4⌉-√44)^4)⌋\n", + "1008 = 4*((4^4)-4)\n", + "1009 = ⌈(√4!^((4^.4)/.4))⌉\n", + "1010 = ⌊((4^4)/√.4)⌋/.4\n", + "1011 = ⌊(4*(4!^(4^.4)))⌋\n", + "1012 = 44*(4!-⌈.4⌉)\n", + "1013 = ⌊(4!^(⌈√44⌉^.4))⌋\n", + "1014 = (4!+√4)*⌊(.4^-4)⌋\n", + "1015 = ⌊((4!+√4)/(.4^4))⌋\n", + "1016 = 4*((4^4)-√4)\n", + "1017 = ⌈(((4!-√√4)/4)^4)⌉\n", + "1018 = ⌊(4*((4^4)-√√4))⌋\n", + "1019 = ⌈(4*((4^4)-√√4))⌉\n", + "1020 = (4*(4^4))-4\n", + "1021 = ⌊(4*((4^4)-√.4))⌋\n", + "1022 = (4*(4^4))-√4\n", + "1023 = (4*(4^4))-⌈.4⌉\n", + "1024 = 4^⌈4.44⌉\n", + "1025 = ⌈.4⌉+(4*(4^4))\n", + "1026 = √4+(4*(4^4))\n", + "1027 = ⌈(4*(√.4+(4^4)))⌉\n", + "1028 = 4+(4*(4^4))\n", + "1029 = ⌈(44*(4!-√.4))⌉\n", + "1030 = ⌈(4*(√√4+(4^4)))⌉\n", + "1031 = ⌈(⌈√44⌉^(4!^.4))⌉\n", + "1032 = (4!*44)-4!\n", + "1033 = ⌊(4!*(4+(.4^-4)))⌋\n", + "1034 = ⌈(4!*(4+(.4^-4)))⌉\n", + "1035 = ⌈(4!*(4!+(4!-√4!)))⌉\n", + "1036 = (4+4!)*⌊(4!/√.4)⌋\n", + "1037 = ⌊(4!^(4^√.4))⌋/√4\n", + "1038 = ⌊(44*(4!-.4))⌋\n", + "1039 = ⌈(44*(4!-.4))⌉\n", + "1040 = 4*(4+(4^4))\n", + "1041 = ⌈(4!*(44-√.4))⌉\n", + "1042 = ⌊((.4*.44)^-4)⌋\n", + "1043 = ⌈((.4*.44)^-4)⌉\n", + "1044 = 4*⌈(√4!+(4^4))⌉\n", + "1045 = ⌈(4^(4+(√√4-.4)))⌉\n", + "1046 = ⌊(4!*(44-.4))⌋\n", + "1047 = ⌈(4!*(44-.4))⌉\n", + "1048 = 4!+(4*(4^4))\n", + "1049 = ⌈(√(4!-.4)^4.4)⌉\n", + "1050 = ⌈(((4-.4)/√.4)^4)⌉\n", + "1051 = ⌊((4!*44)-√4!)⌋\n", + "1052 = (4!*44)-4\n", + "1053 = ⌊(√4!*⌊(√4!*44)⌋)⌋\n", + "1054 = (4!*44)-√4\n", + "1055 = (4!*44)-⌈.4⌉\n", + "1056 = 4!*⌊44.4⌋\n", + "1057 = ⌈.4⌉+(4!*44)\n", + "1058 = √4+(4!*44)\n", + "1059 = ⌊(4^((4*√√4)-√.4))⌋\n", + "1060 = 4+(4!*44)\n", + "1061 = ⌈(√4!+(4!*44))⌉\n", + "1062 = ⌊(4!*((4+4!)/√.4))⌋\n", + "1063 = ⌊(√4!^4.4)⌋-4!\n", + "1064 = ⌈(√4!^4.4)⌉-4!\n", + "1065 = ⌊(4!*44.4)⌋\n", + "1066 = ⌈(4!*44.4)⌉\n", + "1067 = ⌊(((4+4!)/√4!)^4)⌋\n", + "1068 = ⌈(((4+4!)/√4!)^4)⌉\n", + "1069 = ⌈(4!/(√4*(.4^√4!)))⌉\n", + "1070 = ⌈(4^(√.4+√4!))⌉/√4\n", + "1071 = ⌊(4^(√.4+4.4))⌋\n", + "1072 = ⌈(4^(√.4+4.4))⌉\n", + "1073 = ⌊(44*(.4+4!))⌋\n", + "1074 = ⌈(44*(.4+4!))⌉\n", + "1075 = ⌈((4!^(√.4+√4))/4)⌉\n", + "1076 = ⌊((4+(√.4/4))^√4!)⌋\n", + "1077 = ⌈((4+(√.4/4))^√4!)⌉\n", + "1078 = ⌊((.4^-(4+4))/√√4)⌋\n", + "1079 = ⌊((4+√(4-⌈.4⌉))^4)⌋\n", + "1080 = 4!*⌈44.4⌉\n", + "1081 = ⌊((4+√4)^(√4!-⌈.4⌉))⌋\n", + "1082 = ⌊((.4-(4^-.4))^-4)⌋\n", + "1083 = ⌊(44*(√.4+4!))⌋\n", + "1084 = ⌈(44*(√.4+4!))⌉\n", + "1085 = ⌊((4+4!)^√4.4)⌋\n", + "1086 = ⌊((4+(4^.4))^4)⌋\n", + "1087 = ⌈((4+(4^.4))^4)⌉\n", + "1088 = ⌈(4!^(4.4/√4))⌉\n", + "1089 = ⌊(4!*(√√4+44))⌋\n", + "1090 = ⌈(4!*(√√4+44))⌉\n", + "1091 = 4+⌊(√4!^4.4)⌋\n", + "1092 = 4+⌈(√4!^4.4)⌉\n", + "1093 = ⌊((4+4!)/(.4^4))⌋\n", + "1094 = ⌈((4+4!)/(.4^4))⌉\n", + "1095 = ⌊(⌈(.4^-4)⌉^√(4-.4))⌋\n", + "1096 = ⌈(⌈(.4^-4)⌉^√(4-.4))⌉\n", + "1097 = ⌊(.4^(.4*(√4!-4!)))⌋\n", + "1098 = ⌈(.4^(.4*(√4!-4!)))⌉\n", + "1099 = ⌊((4+4)^(4-√.4))⌋\n", + "1100 = 44*(⌈.4⌉+4!)\n", + "1101 = ⌈((.4+√4)^(4+4))⌉\n", + "1102 = ⌊(⌈√44⌉^(4-.4))⌋\n", + "1103 = ⌈(⌈√44⌉^(4-.4))⌉\n", + "1104 = 4!*(√4+44)\n", + "1105 = ⌈(4!^(4/(.4+√√4)))⌉\n", + "1106 = ⌊(((4+4)^√4!)/4!)⌋\n", + "1107 = ⌈(((4+4)^√4!)/4!)⌉\n", + "1108 = ⌊(4^(√4!+(√.4/4)))⌋\n", + "1109 = ⌊((4/(.4^.4))^4)⌋\n", + "1110 = 444/.4\n", + "1111 = 4!+⌊(√4!^4.4)⌋\n", + "1112 = ⌊(4^(4*√(.4*4)))⌋\n", + "1113 = ⌈(4^(4*√(.4*4)))⌉\n", + "1114 = ⌊((4^4.4)/.4)⌋\n", + "1115 = ⌈(4^4.4)⌉/.4\n", + "1116 = ⌈((4^4)*√⌊(4*√4!)⌋)⌉\n", + "1117 = ⌈((√4^√.4)*(4+√4)!)⌉\n", + "1118 = ⌊(44*(4!+√√4))⌋\n", + "1119 = ⌈(44*(4!+√√4))⌉\n", + "1120 = 4*(4!+(4^4))\n", + "1121 = ⌈((4+(.4^-√.4))^4)⌉\n", + "1122 = ⌈(4^(√4!+(4/4!)))⌉\n", + "1123 = ⌈((4!+4!)^(.4+√√4))⌉\n", + "1124 = ⌊(√(.4*44)^√4!)⌋\n", + "1125 = ⌈(√(.4*44)^√4!)⌉\n", + "1126 = ⌊(4.4*(4^4))⌋\n", + "1127 = ⌈(4.4*(4^4))⌉\n", + "1128 = ⌈(√(.4+4!)^4.4)⌉\n", + "1129 = ⌈((4!/√4)^√(4+4))⌉\n", + "1130 = ⌊((4-√(4*4!))^4)⌋\n", + "1131 = ⌈((4-√(4*4!))^4)⌉\n", + "1132 = √4*⌊(4!*(4!-.4))⌋\n", + "1133 = ⌈(4!*(√4*(4!-.4)))⌉\n", + "1134 = √4*⌈(4!*(4!-.4))⌉\n", + "1135 = ⌈((4+√4)!/√.4)⌉-4\n", + "1136 = ⌊(√4!*((4^4)-4!))⌋\n", + "1137 = ⌈(√4!*((4^4)-4!))⌉\n", + "1138 = ⌊(((4/.4)-4)!/√.4)⌋\n", + "1139 = ⌈(((4/.4)-4)!/√.4)⌉\n", + "1140 = 4!*(⌊(4*√4!)⌋/.4)\n", + "1141 = ⌈(4!^(4-(.4^-√.4)))⌉\n", + "1142 = ⌊((√√4+4.4)^4)⌋\n", + "1143 = ⌈((√√4+4.4)^4)⌉\n", + "1144 = 44*(4!+√4)\n", + "1145 = ⌈((4^4)*√(4!-4))⌉\n", + "1146 = (4^4)+⌊(4^√4!)⌋\n", + "1147 = (4^4)+⌈(4^√4!)⌉\n", + "1148 = (4!*(4!+4!))-4\n", + "1149 = ⌈(4!^(4^(4^-.4)))⌉\n", + "1150 = (4!*(4!+4!))-√4\n", + "1151 = ⌊(((4+√.4)^4)/.4)⌋\n", + "1152 = 4!*(4+44)\n", + "1153 = ⌈.4⌉+(4!*(4!+4!))\n", + "1154 = √4+(4!*(4!+4!))\n", + "1155 = ⌈(4*(√4!^(4!^.4)))⌉\n", + "1156 = 4+(4!*(4!+4!))\n", + "1157 = ⌈(√4!+(4!*(4!+4!)))⌉\n", + "1158 = ⌊(√4!^4.44)⌋\n", + "1159 = ⌈(√4!^4.44)⌉\n", + "1160 = √4*(4+(4!*4!))\n", + "1161 = ⌊(4^(√√4*(4-.4)))⌋\n", + "1162 = ⌈(4^(√√4*(4-.4)))⌉\n", + "1163 = 4!+⌈((4+√4)!/√.4)⌉\n", + "1164 = ⌊(((√.4-4!)/4)^4)⌋\n", + "1165 = ⌈(((√.4-4!)/4)^4)⌉\n", + "1166 = ⌈((√4^√4!)/(.4^4))⌉\n", + "1167 = ⌊(4^(√(4/.4)^√√4))⌋\n", + "1168 = 4*⌈(4!^(.4^-√.4))⌉\n", + "1169 = ⌈(⌈(4!+√4!)⌉^√4.4)⌉\n", + "1170 = ⌊(4^√(4!+√4))⌋-4\n", + "1171 = ⌈(4^√(4!+√4))⌉-4\n", + "1172 = ⌈((.4-(.4^-√4))^4)⌉\n", + "1173 = ⌊(4!*(√4!+44))⌋\n", + "1174 = ⌈(4!*(√4!+44))⌉\n", + "1175 = ⌈(4^√⌊(4*√44)⌋)⌉\n", + "1176 = 4!*⌈(√4!+44)⌉\n", + "1177 = ⌊(4^((4/.4)-√4!))⌋\n", + "1178 = ⌈(4^((4/.4)-√4!))⌉\n", + "1179 = 4+⌈(4^√(4!+√4))⌉\n", + "1180 = 4*(⌈(4!*√4!)⌉/.4)\n", + "1181 = ⌊(4^((4^√√4)-√4))⌋\n", + "1182 = ⌈(4^((4^√√4)-√4))⌉\n", + "1183 = ⌊(4^(√.4+√(4!-4)))⌋\n", + "1184 = ⌈(4^(√.4+√(4!-4)))⌉\n", + "1185 = ⌊((4^4)*(4+√.4))⌋\n", + "1186 = ⌈((4^4)*(4+√.4))⌉\n", + "1187 = ⌊(√(√4+(4*4))^√4!)⌋\n", + "1188 = ⌈(√(√4+(4*4))^√4!)⌉\n", + "1189 = ⌊(⌈4.4⌉^4.4)⌋\n", + "1190 = ⌈(⌈4.4⌉^4.4)⌉\n", + "1191 = ⌈(√4*((.4+4!)^√4))⌉\n", + "1192 = √4*⌈((.4+4!)^√4)⌉\n", + "1193 = ⌊((√4^(4+√4!))/.4)⌋\n", + "1194 = ⌊(√4!^(√4!-.44))⌋\n", + "1195 = ⌈(√4!^(√4!-.44))⌉\n", + "1196 = ⌊(√4!/(.4^(4+√4)))⌋\n", + "1197 = ⌈(√4!/(.4^(4+√4)))⌉\n", + "1198 = ⌊((4!/(.4^.4))^√4)⌋\n", + "1199 = ⌈((4!/(.4^.4))^√4)⌉\n", + "1200 = 4*(⌈4.4⌉!/.4)\n", + "1201 = ⌈((⌈√44⌉^4)/√4)⌉\n", + "1202 = ⌊((4+(√4!^.4))^4)⌋\n", + "1203 = ⌈((4+(√4!^.4))^4)⌉\n", + "1204 = ⌈(4^(4/(√√4-√.4)))⌉\n", + "1205 = ⌊(4!^(√.4+(.4*4)))⌋\n", + "1206 = ⌈(4!^(√.4+(.4*4)))⌉\n", + "1207 = ⌈((⌈.4⌉+√4!)^4)⌉-4\n", + "1208 = ⌊(4!*(4!*√4.4))⌋\n", + "1209 = ⌊((4+√(4-.4))^4)⌋\n", + "1210 = ⌈((4+√(4-.4))^4)⌉\n", + "1211 = ⌊(((.4-4!)/4)^4)⌋\n", + "1212 = ⌈(((.4-4!)/4)^4)⌉\n", + "1213 = 4+⌊(.4^-√(4!/.4))⌋\n", + "1214 = ⌊((4+√.4)^(4+√.4))⌋\n", + "1215 = ⌊(4!^√⌈4.4⌉)⌋-4\n", + "1216 = ⌈(4!^√⌈4.4⌉)⌉-4\n", + "1217 = ⌊(4!^√⌈4.4⌉)⌋-√4\n", + "1218 = ⌊(4.4^√(4!-⌈.4⌉))⌋\n", + "1219 = ⌊(4!^√⌈4.44⌉)⌋\n", + "1220 = ⌈(4!^√⌈4.44⌉)⌉\n", + "1221 = ⌈(4*(√4!^(4-.4)))⌉\n", + "1222 = √4*⌈(.4^-⌈√44⌉)⌉\n", + "1223 = 4+⌊(4!^√⌈4.4⌉)⌋\n", + "1224 = ⌊(√.4*(44^√4))⌋\n", + "1225 = ⌈(√.4*(44^√4))⌉\n", + "1226 = ⌊(√4.4^(.4*4!))⌋\n", + "1227 = ⌈(√4.4^(.4*4!))⌉\n", + "1228 = ⌈(4/(.4^(.4^-√4)))⌉\n", + "1229 = ⌊((4-(.4^-4))^√4)⌋\n", + "1230 = ⌈((4-(.4^-4))^√4)⌉\n", + "1231 = ⌈(√4*(4^(4+√.4)))⌉\n", + "1232 = 44*(4+4!)\n", + "1233 = ⌈((.4-(4/√.4))^4)⌉\n", + "1234 = ⌊(√4!*((4^4)-4))⌋\n", + "1235 = ⌈(√4!*((4^4)-4))⌉\n", + "1236 = ⌊(4!*(√⌈4.4⌉^√4!))⌋\n", + "1237 = ⌊(4!^(4*(.4^√.4)))⌋\n", + "1238 = ⌈(4!^(4*(.4^√.4)))⌉\n", + "1239 = ⌊(((4+4!)^√4)/√.4)⌋\n", + "1240 = ⌊(.4*(4!^(4*√.4)))⌋\n", + "1241 = ⌈(.4*(4!^(4*√.4)))⌉\n", + "1242 = ⌊((4!^√4.4)/√.4)⌋\n", + "1243 = ⌊((4^4)*√(4!-.4))⌋\n", + "1244 = ⌈((4^4)*√(4!-.4))⌉\n", + "1245 = ⌈(√4!*((4^4)-√4))⌉\n", + "1246 = ⌊(((.4+√4!)^4)/√.4)⌋\n", + "1247 = ⌊((4!/.4)^(4^.4))⌋\n", + "1248 = 4!*(4+(4!+4!))\n", + "1249 = ⌊(4^((4!/.4)^.4))⌋\n", + "1250 = √4*(⌈4.4⌉^4)\n", + "1251 = ⌈(√4!*(4^4))⌉-4\n", + "1252 = ⌊(√4!*((4^4)-.4))⌋\n", + "1253 = ⌊((4^.4)*(4+√4)!)⌋\n", + "1254 = ⌊(.4+(√4!*(4^4)))⌋\n", + "1255 = ⌈(.4+(√4!*(4^4)))⌉\n", + "1256 = ⌊(√4!*(.4+(4^4)))⌋\n", + "1257 = ⌈(√4!*(.4+(4^4)))⌉\n", + "1258 = 4+⌊(√4!*(4^4))⌋\n", + "1259 = 4+⌈(√4!*(4^4))⌉\n", + "1260 = ⌈(√4!*(⌈.4⌉+(4^4)))⌉\n", + "1261 = ⌊((4+(.4*√4!))^4)⌋\n", + "1262 = ⌈((4+(.4*√4!))^4)⌉\n", + "1263 = ⌊(√4!*(√4+(4^4)))⌋\n", + "1264 = ⌊((4^4)*√(.4+4!))⌋\n", + "1265 = ⌈((4^4)*√(.4+4!))⌉\n", + "1266 = ⌊((4/(.4^4))^√√4)⌋\n", + "1267 = ⌊((4*(4+√4!))^√4)⌋\n", + "1268 = ⌊(44^(√4!^.4))⌋\n", + "1269 = ⌈(44^(√4!^.4))⌉\n", + "1270 = ⌈((.4+(.4-√.4))^-4)⌉\n", + "1271 = ⌊(44*(4!+√4!))⌋\n", + "1272 = ((4+√4)^4)-4!\n", + "1273 = ⌊(√4!*(4+(4^4)))⌋\n", + "1274 = ⌈(√4!*(4+(4^4)))⌉\n", + "1275 = ⌈(√4!^(4+(√4/4)))⌉\n", + "1276 = 44*⌈(4!+√4!)⌉\n", + "1277 = ⌊((.4*4!)^√(4/.4))⌋\n", + "1278 = 4!+⌊(√4!*(4^4))⌋\n", + "1279 = 4!+⌈(√4!*(4^4))⌉\n", + "1280 = (4^4)*⌈4.4⌉\n", + "1281 = ⌈(((4+√4!)^4)/√4!)⌉\n", + "1282 = ⌊(4^(√4+√(4/.4)))⌋\n", + "1283 = ⌈(4^(√4+√(4/.4)))⌉\n", + "1284 = ⌊((4^√4!)/(.4^.4))⌋\n", + "1285 = ⌈((4^√4!)/(.4^.4))⌉\n", + "1286 = ⌈(4^(4/√(⌈.4⌉-.4)))⌉\n", + "1287 = ⌊(4^(.44^-√4))⌋\n", + "1288 = ⌈(4^(.44^-√4))⌉\n", + "1289 = ⌈(√⌈4.4⌉^(4+√4!))⌉\n", + "1290 = ⌊(((4!^4)/4)^√.4)⌋\n", + "1291 = ⌊(((4+√4)^4)-√4!)⌋\n", + "1292 = ((4+√4)^4)-4\n", + "1293 = ⌈((4+√(.4/4))^√4!)⌉\n", + "1294 = ((4+√4)^4)-√4\n", + "1295 = ((4+√4)^4)-⌈.4⌉\n", + "1296 = ((4/.4)-4)^4\n", + "1297 = ⌈.4⌉+((4+√4)^4)\n", + "1298 = √4+((4+√4)^4)\n", + "1299 = ⌈((4*4)^(4-√√4))⌉\n", + "1300 = 4+((4+√4)^4)\n", + "1301 = ⌈(√4!+((4+√4)^4))⌉\n", + "1302 = ⌊(((4^√.4)/.4)^4)⌋\n", + "1303 = ⌈(((4^√.4)/.4)^4)⌉\n", + "1304 = ⌈(√(4+4)^(√4+√4!))⌉\n", + "1305 = ⌊((4^4)*√(4!+√4))⌋\n", + "1306 = ⌈((4^4)*√(4!+√4))⌉\n", + "1307 = ⌈((.4+√√4)*(4+√4)!)⌉\n", + "1308 = 4*⌊((4!/.4)^√√4)⌋\n", + "1309 = ⌊(4!*(4!/.44))⌋\n", + "1310 = ⌈(4!*(4!/.44))⌉\n", + "1311 = ⌊(4!^(4-(4^.4)))⌋\n", + "1312 = ⌊(44^√(4-.4))⌋\n", + "1313 = ⌈(44^√(4-.4))⌉\n", + "1314 = ⌊(4/(.4^(4/√.4)))⌋\n", + "1315 = ⌈(4/(.4^(4/√.4)))⌉\n", + "1316 = ⌈(4^(4!/(4+√.4)))⌉\n", + "1317 = ⌊(4^(√4!+(.4/√√4)))⌋\n", + "1318 = ⌈(4^(√4!+(.4/√√4)))⌉\n", + "1319 = ⌊(√√4/(.4^(4!^√.4)))⌋\n", + "1320 = 4!+((4+√4)^4)\n", + "1321 = ⌈(4^(4+√(.4+⌈.4⌉)))⌉\n", + "1322 = ⌊(4!*((4!/.4)-√4!))⌋\n", + "1323 = ⌈(4!*((4!/.4)-√4!))⌉\n", + "1324 = 4*⌊((√.4-√4!)^4)⌋\n", + "1325 = ⌊((4!-4)^(.4+√4))⌋\n", + "1326 = ⌈((4!-4)^(.4+√4))⌉\n", + "1327 = ⌊(4!^(.4*(4*√√4)))⌋\n", + "1328 = ⌊(((4-.4)^√4!)/.4)⌋\n", + "1329 = ⌈(((4-.4)^√4!)/.4)⌉\n", + "1330 = ⌈((4-.4)^√4!)⌉/.4\n", + "1331 = ⌊((√.4*(4^4))^√√4)⌋\n", + "1332 = ⌈((√.4*(4^4))^√√4)⌉\n", + "1333 = ⌊(√4*(4^√(4!-√4)))⌋\n", + "1334 = √4*⌈(4^√(4!-√4))⌉\n", + "1335 = ⌊(4!*(4^(√4!-√4)))⌋\n", + "1336 = ⌊(4.4^√(4!-.4))⌋\n", + "1337 = ⌈(4.4^√(4!-.4))⌉\n", + "1338 = ⌊((4!-4)^(4^√.4))⌋\n", + "1339 = ⌊(4!/(.44^√4!))⌋\n", + "1340 = ⌈(4!/(.44^√4!))⌉\n", + "1341 = ⌊(√4/(.4^(4^√√4)))⌋\n", + "1342 = ⌈(√4/(.4^(4^√√4)))⌉\n", + "1343 = ⌊(4^√⌈(4*√44)⌉)⌋\n", + "1344 = 4!*((4!/.4)-4)\n", + "1345 = ⌊((.4+(4*√√4))^4)⌋\n", + "1346 = ⌈((.4+(4*√√4))^4)⌉\n", + "1347 = ⌈(((4^.4)/.4)^√4!)⌉\n", + "1348 = ⌈((4+(√√4/4))^√4!)⌉\n", + "1349 = ⌊(4!^(4-√(4-⌈.4⌉)))⌋\n", + "1350 = ⌈(4!^(4-√(4-⌈.4⌉)))⌉\n", + "1351 = ⌊(4^(.4*⌈(√4!/.4)⌉))⌋\n", + "1352 = ⌊(4!/(.4^4.4))⌋\n", + "1353 = ⌈(4!/(.4^4.4))⌉\n", + "1354 = ⌊((4^4)*√(4+4!))⌋\n", + "1355 = ⌈((4^4)*√(4+4!))⌉\n", + "1356 = ⌊((.4+√4!)*(4^4))⌋\n", + "1357 = ⌈((.4+√4!)*(4^4))⌉\n", + "1358 = ⌈(4^(√.4^(.4-4)))⌉\n", + "1359 = ⌈((.4*(√.4*4!))^4)⌉\n", + "1360 = ⌈(.4^-√⌊(√√4*44)⌋)⌉\n", + "1361 = 4+⌈(√⌊(4*√4!)⌋^√4!)⌉\n", + "1362 = ⌊((4*4!)^(√.4/.4))⌋\n", + "1363 = ⌈((4*4!)^(√.4/.4))⌉\n", + "1364 = ⌊((⌊(4!/√.4)⌋^√4)-√4!)⌋\n", + "1365 = ⌊(√4!^(44^.4))⌋\n", + "1366 = ⌈(√4!^(44^.4))⌉\n", + "1367 = ⌈(√(4-.4)*(4+√4)!)⌉\n", + "1368 = 4!*⌈(.4^-4.4)⌉\n", + "1369 = ⌈((44^√4)/√√4)⌉\n", + "1370 = ⌈(4/((.4-√.4)^4))⌉\n", + "1371 = ⌈(4!^(⌈.4⌉/.44))⌉\n", + "1372 = 4*⌈((.4-√.4)^-4)⌉\n", + "1373 = ⌊((√4-(.4^-4))^√4)⌋\n", + "1374 = ⌈((√4-(.4^-4))^√4)⌉\n", + "1375 = ⌊(((4^√4!)/4!)^√4)⌋\n", + "1376 = ⌈(((4^√4!)/4!)^√4)⌉\n", + "1377 = ⌈((4+√4)!/(√.4^√√4))⌉\n", + "1378 = ⌊((4^4)*√⌈(4!+√4!)⌉)⌋\n", + "1379 = ⌊(4^(√4!+√(.4/4)))⌋\n", + "1380 = ((4!*4!)-4!)/.4\n", + "1381 = ⌈((√4!^√4!)/(4^.4))⌉\n", + "1382 = ⌊((4+√4.4)^4)⌋\n", + "1383 = ⌈((4+√4.4)^4)⌉\n", + "1384 = ⌊(((.4+4!)/4)^4)⌋\n", + "1385 = ⌈(((.4+4!)/4)^4)⌉\n", + "1386 = ⌊((4^4)*(4+√√4))⌋\n", + "1387 = ⌈((4^4)*(4+√√4))⌉\n", + "1388 = ⌈(4^(√44-√√4))⌉\n", + "1389 = ⌈(4!^(√.4*(4-.4)))⌉\n", + "1390 = ⌊(.4/(.4^(4+√4!)))⌋\n", + "1391 = ⌈(.4/(.4^(4+√4!)))⌉\n", + "1392 = 4!*((4!/.4)-√4)\n", + "1393 = ⌈(((.4-4!)^√4)/.4)⌉\n", + "1394 = ⌈((√.4+√⌈(√4^√4!)⌉)^4)⌉\n", + "1395 = ⌊(4.4^√4!)⌋-4!\n", + "1396 = ⌈(4.4^√4!)⌉-4!\n", + "1397 = ⌊(4!^(.4^(4-√4!)))⌋\n", + "1398 = ⌊(4^(4+(√4!/4)))⌋\n", + "1399 = ⌈(4^(4+(√4!/4)))⌉\n", + "1400 = ⌈(.4^(√(4/.4)/-.4))⌉\n", + "1401 = ⌊(((4^√4!)-4)/√.4)⌋\n", + "1402 = ⌊((4-.4)^(4*√√4))⌋\n", + "1403 = ⌈((4-.4)^(4*√√4))⌉\n", + "1404 = ⌈((4^√4!)/√.4)⌉-4\n", + "1405 = ⌈(4!^(√4+(4!^-.4)))⌉\n", + "1406 = ⌊((√(4+√4)/.4)^4)⌋\n", + "1407 = ⌈((√(4+√4)/.4)^4)⌉\n", + "1408 = ⌈(.4+((4^√4!)/√.4))⌉\n", + "1409 = ⌈((.4+(4^√4!))/√.4)⌉\n", + "1410 = ⌊(4!*(4!*√(4+√4)))⌋\n", + "1411 = ⌈(4!*(4!*√(4+√4)))⌉\n", + "1412 = 4+⌈((4^√4!)/√.4)⌉\n", + "1413 = ⌊((4+(4^√4!))/√.4)⌋\n", + "1414 = ⌈((4+(4^√4!))/√.4)⌉\n", + "1415 = ⌊(4.4^√4!)⌋-4\n", + "1416 = ⌈(4.4^√4!)⌉-4\n", + "1417 = ⌊(4.4^√4!)⌋-√4\n", + "1418 = ⌈(4.4^√4!)⌉-√4\n", + "1419 = ⌊((4.4^√4!)-.4)⌋\n", + "1420 = ⌊(.4+(4.4^√4!))⌋\n", + "1421 = ⌈(.4+(4.4^√4!))⌉\n", + "1422 = √4+⌈(4.4^√4!)⌉\n", + "1423 = 4+⌊(4.4^√4!)⌋\n", + "1424 = 4+⌈(4.4^√4!)⌉\n", + "1425 = ⌈(.4*(4*(4^√4!)))⌉\n", + "1426 = ⌈(.4*(4*⌈(4^√4!)⌉))⌉\n", + "1427 = ⌊(((4!*4!)-√4!)/.4)⌋\n", + "1428 = 4*⌈(.4*(4^√4!))⌉\n", + "1429 = ⌈((.4^-√(4!+4!))/.4)⌉\n", + "1430 = ((4!*4!)-4)/.4\n", + "1431 = ⌈(4!*((4!/.4)-.4))⌉\n", + "1432 = √4*((4+√4)!-4)\n", + "1433 = ⌈(4*(4*(4!^√√4)))⌉\n", + "1434 = ⌊(√4!^(4+(4^-.4)))⌋\n", + "1435 = ((4!*4!)-√4)/.4\n", + "1436 = (4!*(4!/.4))-4\n", + "1437 = ⌈(4^(√4.4/.4))⌉\n", + "1438 = (4!*(4!/.4))-√4\n", + "1439 = ((4!*4!)-.4)/.4\n", + "1440 = √4*((4/.4)-4)!\n", + "1441 = (.4+(4!*4!))/.4\n", + "1442 = √4+(4!*(4!/.4))\n", + "1443 = 4!+⌊(4.4^√4!)⌋\n", + "1444 = 4+(4!*(4!/.4))\n", + "1445 = (√4+(4!*4!))/.4\n", + "1446 = ⌈((4+(4^-√.4))^√4!)⌉\n", + "1447 = ⌈(√(4!-4)^√(4!-.4))⌉\n", + "1448 = √4*(4+(4+√4)!)\n", + "1449 = ⌈(4*(√√4*(4^4)))⌉\n", + "1450 = (4+(4!*4!))/.4\n", + "1451 = ⌊(⌊(4!^(.4+√4))⌋/√√4)⌋\n", + "1452 = 44*⌊(4!*√√4)⌋\n", + "1453 = ⌊((4/.4)^√(4/.4))⌋\n", + "1454 = ⌈((4/.4)^√(4/.4))⌉\n", + "1455 = ⌊(4^√(4+(4!-.4)))⌋\n", + "1456 = ⌈(4^√(4+(4!-.4)))⌉\n", + "1457 = ⌊(4*(√.4*(4!*4!)))⌋\n", + "1458 = ⌊((4-√.4)^(4+√4))⌋\n", + "1459 = ⌈((4-√.4)^(4+√4))⌉\n", + "1460 = 4*⌈(√.4*(4!*4!))⌉\n", + "1461 = ⌊(⌈√4.4⌉^√44)⌋\n", + "1462 = ⌈(⌈√4.4⌉^√44)⌉\n", + "1463 = ⌊(√(4!-4.4)^√4!)⌋\n", + "1464 = 4!*((.4+4!)/.4)\n", + "1465 = ⌈(4!*(.4+4!))⌉/.4\n", + "1466 = (4!*4!)+⌊(4^√4!)⌋\n", + "1467 = (4!*4!)+⌈(4^√4!)⌉\n", + "1468 = 4!+(⌈(4!/√.4)⌉^√4)\n", + "1469 = ⌊((√4!/.4)*⌈4.4⌉!)⌋\n", + "1470 = ⌈(√4!*⌈4.4⌉!)⌉/.4\n", + "1471 = ⌈((.4+(4!/√.4))^√4)⌉\n", + "1472 = ⌊((4!/(4+√√4))^√4!)⌋\n", + "1473 = ⌊((√.4-.4)^-⌈4.4⌉)⌋\n", + "1474 = ⌊((.4*(4*4!))^√4)⌋\n", + "1475 = ⌈((.4*(4*4!))^√4)⌉\n", + "1476 = ⌊((√.4-(.4^-4))^√4)⌋\n", + "1477 = ⌊(4!*((√.4+4!)/.4))⌋\n", + "1478 = ⌊(4^(4+√(.4*4)))⌋\n", + "1479 = ⌈(4^(4+√(.4*4)))⌉\n", + "1480 = 4*⌊(4^(√4!-√.4))⌋\n", + "1481 = ⌊(4*(4^(√4!-√.4)))⌋\n", + "1482 = ⌊(4!^((4+4)^.4))⌋\n", + "1483 = ⌈(4!^((4+4)^.4))⌉\n", + "1484 = ⌊(4.44^√4!)⌋\n", + "1485 = ⌈(4.44^√4!)⌉\n", + "1486 = ⌊(4!*(4!+(4!/√.4)))⌋\n", + "1487 = ⌈(4!*(4!+(4!/√.4)))⌉\n", + "1488 = 4!*⌊(√√4*44)⌋\n", + "1489 = ⌊(.44^-(4+√4!))⌋\n", + "1490 = ⌈(.44^-(4+√4!))⌉\n", + "1491 = ⌈(4!^(√4^(√.4^-.4)))⌉\n", + "1492 = ⌊(4^(.4^-(.4+√√4)))⌋\n", + "1493 = ⌊(4!*(√√4*44))⌋\n", + "1494 = ⌈(4!*(√√4*44))⌉\n", + "1495 = ⌈((.4-(.4^-4))^√4)⌉\n", + "1496 = 4*⌊(4.4^4)⌋\n", + "1497 = (⌊(.4^-4)⌋^√4)-4!\n", + "1498 = ⌊((4*44)^√√4)⌋\n", + "1499 = ⌊(4*(4.4^4))⌋\n", + "1500 = 4*⌈(4.4^4)⌉\n", + "1501 = ⌊(.4^-(4+4))⌋-4!\n", + "1502 = ⌈(.4^-(4+4))⌉-4!\n", + "1503 = ⌈((√4!^√4!)/(.4*4))⌉\n", + "1504 = ⌈(4^((4!^√.4)/√√4))⌉\n", + "1505 = ⌊(4^(4*(√4^.4)))⌋\n", + "1506 = ⌈(4^(4*(√4^.4)))⌉\n", + "1507 = ⌊((.4+√⌈(4!*√√4)⌉)^4)⌋\n", + "1508 = ⌊(4.4^√(.4+4!))⌋\n", + "1509 = ⌊((.4-√44)^4)⌋\n", + "1510 = ⌈((.4-√44)^4)⌉\n", + "1511 = ⌈(√4.4*(4+√4)!)⌉\n", + "1512 = 4!*⌈(√√4*44)⌉\n", + "1513 = ⌈((4+√⌈4.4⌉)^4)⌉\n", + "1514 = ⌈(4!*(4!+(.4^-4)))⌉\n", + "1515 = ⌊((√4!-.44)^√4!)⌋\n", + "1516 = ⌈((√4!-.44)^√4!)⌉\n", + "1517 = (⌊(.4^-4)⌋^√4)-4\n", + "1518 = ⌊(√.4*(⌈√44⌉^4))⌋\n", + "1519 = ⌈(√.4*(⌈√44⌉^4))⌉\n", + "1520 = ⌊((.4^-(4+4))-√4!)⌋\n", + "1521 = ⌊(.4^-(4+4))⌋-4\n", + "1522 = ⌈(.4^-(4+4))⌉-4\n", + "1523 = ⌊(.4^-(4+4))⌋-√4\n", + "1524 = ⌈(.4^-(4+4))⌉-√4\n", + "1525 = ⌊(.4^(4*(√4-4)))⌋\n", + "1526 = ⌊(√(4+4!)^4.4)⌋\n", + "1527 = ⌈(√(4+4!)^4.4)⌉\n", + "1528 = √4+⌈(.4^-(4+4))⌉\n", + "1529 = 4+⌊(.4^-(4+4))⌋\n", + "1530 = 4+⌈(.4^-(4+4))⌉\n", + "1531 = ⌊(4^√(4+4!))⌋-√4\n", + "1532 = ⌈(4^√(4+4!))⌉-√4\n", + "1533 = ⌊(4^√(4*⌈√44⌉))⌋\n", + "1534 = ⌈(4^√(4*⌈√44⌉))⌉\n", + "1535 = ⌈(.4+(4^√(4+4!)))⌉\n", + "1536 = 4*(4*(4*4!))\n", + "1537 = 4+⌊(4^√(4+4!))⌋\n", + "1538 = 4+⌈(4^√(4+4!))⌉\n", + "1539 = ⌈(√√4*(√4!^4.4))⌉\n", + "1540 = ⌈(4^(4+√.4))⌉/.4\n", + "1541 = 4+⌊(√(4!-4)^√4!)⌋\n", + "1542 = 4+⌈(√(4!-4)^√4!)⌉\n", + "1543 = ⌈((√.4-(√4+√4!))^4)⌉\n", + "1544 = √4*⌈(4^√(4!-⌈.4⌉))⌉\n", + "1545 = ⌊(4^(.4+√4!))⌋-4\n", + "1546 = ⌈(4^(.4+√4!))⌉-4\n", + "1547 = ⌊(4^(.4+√4!))⌋-√4\n", + "1548 = ⌈(4^(.4+√4!))⌉-√4\n", + "1549 = 4!+⌊(.4^-(4+4))⌋\n", + "1550 = 4!+⌈(.4^-(4+4))⌉\n", + "1551 = ⌈(.4+(4^(.4+√4!)))⌉\n", + "1552 = √4+⌈(4^(.4+√4!))⌉\n", + "1553 = 4+⌊(4^(.4+√4!))⌋\n", + "1554 = 4+⌈(4^(.4+√4!))⌉\n", + "1555 = ⌈(√4!+(4^(.4+√4!)))⌉\n", + "1556 = ⌈(4!*((4!-√4!)^√√4))⌉\n", + "1557 = 4!+⌊(4^√(4+4!))⌋\n", + "1558 = 4!+⌈(4^√(4+4!))⌉\n", + "1559 = ⌊((4+4)^(√√4/.4))⌋\n", + "1560 = 4!*((4!+√4)/.4)\n", + "1561 = 4!+⌊(√(4!-4)^√4!)⌋\n", + "1562 = ⌊((⌈4.4⌉^4)/.4)⌋\n", + "1563 = ⌈((⌈4.4⌉^4)/.4)⌉\n", + "1564 = ⌊((√.4+(4*√√4))^4)⌋\n", + "1565 = ⌈((√.4+(4*√√4))^4)⌉\n", + "1566 = ⌊((⌈.4⌉+√(4+4!))^4)⌋\n", + "1567 = ⌊(((4+√4!)^4)/4)⌋\n", + "1568 = √4*((4+4!)^√4)\n", + "1569 = ⌊(√4!^(4+√.4))⌋-4\n", + "1570 = √4*⌊(4!^√4.4)⌋\n", + "1571 = ⌊(√4*(4!^√4.4))⌋\n", + "1572 = √4*⌈(4!^√4.4)⌉\n", + "1573 = 4!+⌊(4^(.4+√4!))⌋\n", + "1574 = 4!+⌈(4^(.4+√4!))⌉\n", + "1575 = ⌊(√4!^(√44-√4))⌋\n", + "1576 = ((4/√.4)^4)-4!\n", + "1577 = 4+⌊(√4!^(4+√.4))⌋\n", + "1578 = 4+⌈(√4!^(4+√.4))⌉\n", + "1579 = ⌊((√4!-.4)^√4!)⌋-4\n", + "1580 = ⌊((4^(√4!+√√4))/4)⌋\n", + "1581 = ⌈((4^(√4!+√√4))/4)⌉\n", + "1582 = ⌈((√4!-.4)^√4!)⌉-√4\n", + "1583 = ⌊((√4+√√4)^(4+√4))⌋\n", + "1584 = 4!*⌊(4!^(√4^.4))⌋\n", + "1585 = ⌊((4+(√4/4))^√4!)⌋\n", + "1586 = ⌈((4+(√4/4))^√4!)⌉\n", + "1587 = ⌊(√(.4/4!)^(.4-4))⌋\n", + "1588 = ⌈(√(.4/4!)^(.4-4))⌉\n", + "1589 = ⌊(((4*4!)^√√4)/.4)⌋\n", + "1590 = ⌈((4*4!)^√√4)⌉/.4\n", + "1591 = ⌈(4!*(4!^(√4^.4)))⌉\n", + "1592 = 4+⌊((√4!+√√4)^4)⌋\n", + "1593 = ⌊(.4^-(√√4+√44))⌋\n", + "1594 = ⌊(4^(4+(√4^.4)))⌋\n", + "1595 = ⌈(4^(4+(√4^.4)))⌉\n", + "1596 = ((4/√.4)^4)-4\n", + "1597 = 4!+⌊(√4!^(4+√.4))⌋\n", + "1598 = ((4/√.4)^4)-√4\n", + "1599 = ((4/√.4)^4)-⌈.4⌉\n", + "1600 = (4-44)^√4\n", + "1601 = ⌈.4⌉+((4/√.4)^4)\n", + "1602 = √4+((4/√.4)^4)\n", + "1603 = ⌈(4^(√.4+√(4!-√4)))⌉\n", + "1604 = 4+((4/√.4)^4)\n", + "1605 = ⌊((4^(4/√.4))/4)⌋\n", + "1606 = ⌈(4^(4/√.4))⌉/4\n", + "1607 = ⌊((√√4-√(4!/.4))^4)⌋\n", + "1608 = 4!*⌊(4!*√(4+4))⌋\n", + "1609 = ⌊(√.4*(4^(4*√√4)))⌋\n", + "1610 = ⌈(√.4*(4^(4*√√4)))⌉\n", + "1611 = ⌊(√(4+4)^(4^√√4))⌋\n", + "1612 = ⌈(√(4+4)^(4^√√4))⌉\n", + "1613 = ⌊(.4^-(√4!+√(4/.4)))⌋\n", + "1614 = ⌊(4*(4!^(√4!^.4)))⌋\n", + "1615 = ⌊(4!^((4/√.4)-4))⌋\n", + "1616 = ⌊(4^√(4!+4.4))⌋\n", + "1617 = ⌈(4^√(4!+4.4))⌉\n", + "1618 = ⌈(.44^⌈(.4*-4!)⌉)⌉\n", + "1619 = ⌊(4*((4^4)/√.4))⌋\n", + "1620 = 4*⌈((4^4)/√.4)⌉\n", + "1621 = ⌊(√.4*(√4!^√(.4+4!)))⌋\n", + "1622 = ⌊((4+√4)^√4!)⌋/4\n", + "1623 = ⌈(((4+√4)^√4!)/4)⌉\n", + "1624 = 4!+((4/√.4)^4)\n", + "1625 = ⌊((4!*√√4)^√4.4)⌋\n", + "1626 = ⌈((4!*√√4)^√4.4)⌉\n", + "1627 = ⌈(√4!*⌈((√.4-√4!)^4)⌉)⌉\n", + "1628 = 44*⌊(4!/√.4)⌋\n", + "1629 = ⌊(4!*(4!*√(4+4)))⌋\n", + "1630 = ⌈(4!*(4!*√(4+4)))⌉\n", + "1631 = ⌊(4^(4+(√.4^-√.4)))⌋\n", + "1632 = 4!*(4!+44)\n", + "1633 = ⌈((.4+⌈(.4^-4)⌉)^√4)⌉\n", + "1634 = ⌊(√(.4+4!)^(4+√.4))⌋\n", + "1635 = ⌊((4!^√(4+4))/√4!)⌋\n", + "1636 = ⌊((4+√4)!/.44)⌋\n", + "1637 = ⌈((4+√4)!/.44)⌉\n", + "1638 = ⌊(.4*((4+4)^4))⌋\n", + "1639 = ⌈(.4*((4+4)^4))⌉\n", + "1640 = 4*⌈((.4-√4!)^4)⌉\n", + "1641 = ⌈((⌊(.4*4!)⌋^4)/4)⌉\n", + "1642 = ⌈(√4!^(√(4+4!)-√.4))⌉\n", + "1643 = ⌊((√.4-⌈√44⌉)^4)⌋\n", + "1644 = ⌈((√.4-⌈√44⌉)^4)⌉\n", + "CPU times: user 1min 22s, sys: 192 ms, total: 1min 22s\n", + "Wall time: 1min 23s\n" + ] + } + ], + "source": [ + "%time show((4, 4, 4, 4), ops=OPS + \"⌊⌈\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Even More Fives: Five 5s\n", + "\n", + "In the [xkcd forum](http://forums.xkcd.com/viewtopic.php?f=14&t=116813&start=280) they took up the problem of **five 5s** and got all the integers up to 298, using the \"double factorial\" and π functions. We can get up to 171, using just the default operators, but it does take about seven minutes, whereas all the other puzzles (with four or three digits) took less than a minute. I suspect you could go much further using floor and ceiling, but that computation would take even longer, so for now let's stick with our default set of operations:" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Can make 0 to 171 with expressions((5, 5, 5, 5, 5), \"+-*/^_√!.$\"). (7,624,387 table entries)\n", "\n", " 0 = 5*(55-55)\n", " 1 = 5^(55-55)\n", " 2 = 55/(.5*55)\n", " 3 = .5*((55/5)-5)\n", " 4 = 5-(55/55)\n", - " 5 = 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 = (55-(5+5))/5\n", - " 10 = (55/5)-(5/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 = 5+(5.5+5.5)\n", + " 16 = (55+(5*5))/5\n", " 17 = 5+((5+55)/5)\n", - " 18 = 5.5+(.5*(5*5))\n", - " 19 = (5*5)-(.5+5.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)/(.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*(.5+55.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", + " 31 = 5+((5/5)+(5*5))\n", " 32 = (5+(55/5))/.5\n", " 33 = .55*(5+55)\n", " 34 = (5!+(55-5))/5\n", @@ -1637,13 +3703,13 @@ " 42 = (5+5.5)/(.5*.5)\n", " 43 = 55-(5!/(5+5))\n", " 44 = 55-(55/5)\n", - " 45 = (5*5)+((5*5)-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", + " 47 = 5+(5+(5+(.5^-5)))\n", + " 48 = 5!/(5*(5.5-5))\n", + " 49 = 55-(5+(5/5))\n", " 50 = 55.5-5.5\n", - " 51 = .5+(55.5-5)\n", + " 51 = 55+((5/5)-5)\n", " 52 = 55-(.5+(.5*5))\n", " 53 = 55-((5+5)/5)\n", " 54 = ((5*55)-5)/5\n", @@ -1654,17 +3720,17 @@ " 59 = 5+(55-(5/5))\n", " 60 = 5+(5+(55-5))\n", " 61 = 5.5+55.5\n", - " 62 = (.5*(5*(5*5)))-.5\n", + " 62 = (55-(5!/5))/.5\n", " 63 = .5+(.5*(5*(5*5)))\n", - " 64 = 55+((5-.5)/.5)\n", - " 65 = .5*(5+(5*(5*5)))\n", + " 64 = .5^(5-(55/5))\n", + " 65 = 5+(55+√(5*5))\n", " 66 = 55+(55/5)\n", " 67 = 55+(5!/(5+5))\n", " 68 = 5.5+(.5*(5+5!))\n", - " 69 = 5+(.5^(-.5-5.5))\n", + " 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", + " 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", @@ -1681,7 +3747,7 @@ " 86 = (55/.5)-(5!/5)\n", " 87 = (555-5!)/5\n", " 88 = 5*(.55/(.5^5))\n", - " 89 = (5*5)+((.5^-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", @@ -1692,50 +3758,50 @@ " 97 = 5!+((.5^-5)-55)\n", " 98 = 5!-(55/(.5*5))\n", " 99 = (55-5.5)/.5\n", - " 100 = 5*(5+(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 = ((55-.5)/.5)-5\n", + " 104 = 5!-(5+(55/5))\n", " 105 = 55+(55-5)\n", " 106 = (555/5)-5\n", - " 107 = 5!-(.5+(.5*(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 = (5/5)+(55/.5)\n", + " 111 = 555/√(5*5)\n", " 112 = (5+555)/5\n", - " 113 = .5+(5*(5*(5-.5)))\n", - " 114 = 5+((55-.5)/.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+5))/5\n", + " 118 = 5!-(5!/(5+55))\n", " 119 = 5!-(55/55)\n", - " 120 = 5+(5+(55/.5))\n", - " 121 = (5+55.5)/.5\n", - " 122 = (5*((5*5)-.5))-.5\n", - " 123 = .5+(5*((5*5)-.5))\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", + " 127 = (5!*(5.5/5))-5\n", + " 128 = (5-(5/5))/(.5^5)\n", " 129 = (5!-55.5)/.5\n", - " 130 = (5+(5+55))/.5\n", - " 131 = 5!+(5.5+5.5)\n", - " 132 = 5!*(.55+.55)\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*((5*55)-5)\n", + " 135 = (5!+555)/5\n", " 136 = 5+(5!+(55/5))\n", " 137 = (.5*(5*55))-.5\n", " 138 = .5+(.5*(5*55))\n", - " 139 = ((.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", + " 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", @@ -1754,279 +3820,23 @@ " 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", + " 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", + " 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 2min 24s, sys: 1.17 s, total: 2min 25s\n", - "Wall time: 2min 29s\n" - ] - }, - { - "data": { - "text/plain": [ - "172" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time show((5, 5, 5, 5, 5), clear=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "button": false, - "new_sheet": false, - "run_control": { - "read_only": false - } - }, - "source": [ - "\n", - "# Countdown to 2018\n", - "\n", - "On January 1 2018, [Michael Littman](http://cs.brown.edu/~mlittman/) posted this:\n", - "\n", - "> 2+0+1×8, 2+0-1+8, (2+0-1)×8, |2-0-1-8|, -2-0+1×8, -(2+0+1-8), sqrt(|2+0-18|), 2+0+1^8, 20-18, 2^(0×18), 2×0×1×8... Happy New Year!\n", - "\n", - "Can we replicate that countdown? For 2018 and for following years?" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10,303 entries for (2, 0, 1, 8)\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" + "CPU times: user 6min 41s, sys: 1.24 s, total: 6min 42s\n", + "Wall time: 6min 44s\n" ] } ], "source": [ - "show((2,0,1,8), 10)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "14,957 entries for (2, 0, 1, 9)\n", - "\n", - " 0 = 2*(0*19)\n", - " 1 = 20-19\n", - " 2 = 2+(0*19)\n", - " 3 = 2+(0.1+.9)\n", - " 4 = (2*0)+(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), 10)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "373 entries for (2, 0, 2, 0)\n", - "\n", - " 0 = 202*0\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+(.02^0))!\n" - ] - }, - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show((2,0,2,0), 10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Uh-oh! I knew 2020 was a bad year! The two zeroes don't give us much to work with, and we can't make all the integers in the countdown. But I can turn a 0 into a 1 with `cos(0)`; maybe that will be enough? Let's try it. I'll modify `add_unary_expressions` to assign values for `sin` and `cos`:" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [], - "source": [ - "from math import sin, cos, pi\n", - "\n", - "def add_unary_expressions(result: dict, nesting_level=2) -> dict:\n", - " \"Add unary expressions: -v, √v and v! to result dict.\"\n", - " for _ in range(nesting_level):\n", - " for v in tuple(result):\n", - " exp = result[v]\n", - " if -v not in result:\n", - " assign(result, -v, '-' + exp)\n", - " if 0 < v <= 100 and 120 * v == round(120 * v): \n", - " assign(result, sqrt(v), '√' + exp)\n", - " if 3 <= v <= 6 and v == int(v):\n", - " assign(result, factorial(v), exp + '!')\n", - " if abs(v) in (0, 30, 45, 60, 90, 180, 270, 360):\n", - " assign(result, sin(v * pi / 180), 'sin(' + exp + ')')\n", - " assign(result, cos(v * pi / 180), 'cos(' + exp + ')')\n", - " return result\n", - "\n", - "PENALTIES.update(s=1, i=1, n=1, c=1, o=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "8,203 entries for (2, 0, 2, 0)\n", - "\n", - " 0 = 202*0\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*(cos(0)+2.0)\n", - " 7 = 2+(cos(0)/.20)\n", - " 8 = 2^(cos(0)+2.0)\n", - " 9 = (20/2)-cos(0)\n", - " 10 = 2/0.20\n" - ] - } - ], - "source": [ - "show((2, 0, 2, 0), 10, clear=True) # Clear the cache so we get new results for (2, 0) etc." - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "38,975 entries for (2, 0, 2, 1)\n", - "\n", - " 0 = 2*(0*21)\n", - " 1 = -20+21\n", - " 2 = 2+(0*21)\n", - " 3 = 2+((0*2)+1)\n", - " 4 = 2.0*(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), 10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Making 6 from 3 Digits\n", - "\n", - "Nicolas Schank postedd the following in the Facebook \"omg math\" group.\n", - "\n", - "> For each digit from 1 to 9, find at least one way to express 6 using only that digit exactly three times and arithmetic operations. For instance, using the digit 2, 2+2^2=6.\n", - "\n", - "It turns out what I already have handles this well:" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{1: '(1+(1+1))!',\n", - " 2: '(2+(2*2))',\n", - " 3: '((3*3)-3)',\n", - " 4: '((4/.4)-4)',\n", - " 5: '(.5+5.5)',\n", - " 6: '(6*(6/6))',\n", - " 7: '(7-(7/7))',\n", - " 8: '√(8+(8/8))!',\n", - " 9: '((9+9)/√9)'}" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "{n: expressions((n, n, n))[6] for n in range(1, 10)}" + "%time show((5, 5, 5, 5, 5))" ] }, { @@ -2037,635 +3847,17 @@ "\n", "One exercise would be adding even more operators, such as:\n", "\n", - "- **Floor and Ceiling**: `⌊5.5⌋` = 5, `⌈5.5⌉` = 6\n", "- **Nth root**: `3√8` = 2\n", "- **Percent**: `5%` = 5/100\n", "- **Repeating decimal**: `.4...` = .44444444... = 4/9\n", "- **Double factorial**: `9!!` = 9 × 7 × 5 × 3 × 1 = 945; not the same as `(9!)!`\n", - "- **Gamma function**: `Γ(n)` = (n − 1)!\n", - "- **Prime counting function**: `π(n)` = number of primes ≲ n; `π(5)` = 3\n", - "- **Transcendental functions**: besides `sin` and `cos`, there's `log`, `tan`, `arcsin`, ...\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 degree symbol: 90°\n", + "- **Matrix notation**: with determinant symbol to get a number.\n", + "- **Combinations and Permutations**: `n P k` and `n C k`\n", "\n", - "In the [xkcd forum](http://forums.xkcd.com/viewtopic.php?f=14&t=116813&start=280) they got up to 298 for five fives, using the double factorial and π functions. What would you like to do?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "______\n", - "\n", - "# Equilength Number Names\n", - "\n", - "The internet [claims](https://www.reddit.com/r/Showerthoughts/comments/3h8wpx/four_is_the_only_number_that_has_the_same_amount/) that \"*Four is the only number that has the same amount of letters as its value.*\" But \"Four\" is not a number; it is a *name* for a number. We'll call it an **equilength number name**.\n", - "\n", - "Other languages have different equilength number names. In German there's \"vrei\", in Spanish and Portuguese \"cinco\", and in Pinyin Chinese \"èr\" and \"sān\". French does not have an equilength number name.\n", - "\n", - "There are also *number expressions* such as \"two plus nine\" that are equilength (in letters, not in string length). Let's search for them. I want to define a function similar to `expressions` to generate new expressions and their values. But instead of being required to use a specific set of numbers in creating the expression, I am free to use any numbers in the language. So I will define `equilength_expressions(language, c)` as follows:\n", - "\n", - "- The input `language` is a pair of components:\n", - " - The `operators`, a dict with entries in the form `{add: ['plus', 'and']}`.\n", - " - The `integers`, a dict of the form `{(0, 4): 'zero', (1, 3): 'one', ...}`.\n", - "- The input `c` tells how many times to `combine` expressions, using the operators of the language. There are an infinite number of possible expressions, so with `c=0` we just get integers like `'one'`; with `c=1` we get a combinations of two integers, like `'(one plus two)`; with `c=2` we get combinations of any previously-defined expression, like `((one plus two) times (four minus three))`. I wouldn't recommend going beyond 2 unless you're willing to wait a long time.\n", - "- Like `expressions`, `equilength_expressions` returns a dict such as `{4: 'four'}`.\n", - "- However, internally, `equilength_expressions` keeps a `table` with keys that are\n", - "`(numeric_value, number_of_letters)` pairs, and values that are string expressions, for example `{(3, 10): \"one plus two\", (11, 11): '(two plus nine)'}`. The dict only keeps one entry for each such key; it would be unneccessary to report that both `'two plus nine'` and `'nine plus two'` are equilength expressions. \n", - "- We call `combine` to make larger expressions; it generates all combinations that don't divide by zero. If we allowed operations like `\"factorial\"` and `\"to the power of\"` then we would have to be more careful. \n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [], - "source": [ - "def make_key(value, exp): return (value, sum(ch.isalpha() for ch in exp))\n", - "def make_item(value, exp): return (make_key(value, exp), exp)\n", - "\n", - "def names(text): return [word.replace('-', ' ') for word in text.split()]\n", - "\n", - "def language(operators, integers):\n", - " \"\"\"A language is a pair such as: ({add: ['add'],...}, {(0, 4): 'zero',...}).\"\"\"\n", - " return ({op: names(operators[op]) for op in operators},\n", - " {make_key(i, w): w for i, w in enumerate(names(integers))})" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [], - "source": [ - "def equilength_expressions(language, c=1):\n", - " \"\"\"Combine expressions in the language with each other (using operators) c times.\n", - " Then report all {n: expression} entries where expression has n letters.\"\"\"\n", - " operators, table = language\n", - " for _ in range(c):\n", - " table = {**table, **combine(operators, table)}\n", - " return {n: table[n, v] \n", - " for n, v in sorted(table) \n", - " if n == v}\n", - " \n", - "def combine(operators, table):\n", - " \"\"\"Return table like {(3, 10): \"(one plus two)\"} by combining table entries with operators.\"\"\"\n", - " return dict(make_item(do(OP, L, R), f'({Lexp} {OPexp} {Rexp})')\n", - " for (R, _), Rexp in table.items()\n", - " for OP in operators\n", - " if not (OP == div and R == 0)\n", - " for (L, _), Lexp in table.items()\n", - " for OPexp in operators[OP])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now the names for operators and the first few integers in English, Spanish, Pinyin Chinese and German:" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [], - "source": [ - "english = language({add: 'plus and added-to', sub: 'minus less take-away', \n", - " mul: 'times multiplied-by', div: 'divided-by over',\n", - " lambda x, y: y-x: 'subtracted-from'},\n", - " '''zero one two three four five six seven eight nine ten eleven twelve thirteen \n", - " fourteen fifteen sixteen seventeen eighteen nineteen twenty''')\n", - "\n", - "spanish = language({add: 'más', sub: 'menos', mul: 'por', div: 'dividido-entre dividido-por'},\n", - " '''cero uno dos tres cuatro cinco seis siete ocho nueve diez once doce trece catorce \n", - " quince dieciséis diecisiete dieciocho diecinueve veinte veintiuno veintidós veintitrés \n", - " veinticuatro veinticinco veintiséis veintisiete veintiocho veintinueve treinta''')\n", - "\n", - "chinese = language({add: 'jiā', sub: 'jiǎn', mul: 'chéng', div: 'chú chú-yǐ'},\n", - " 'ling yī èr sān sì wŭ liù qī bā jiŭ shí shí-yī shí-èr shí-sān shí-sì shí-wǔ shí-liù shí-qī')\n", - "\n", - "german = language({add: 'und plus', sub: 'weniger minus', mul: 'mal multipliziert', div: 'durch'},\n", - " '''null eins zwei drei vier fünf sechs sieben acht neun zehn elf zwölf dreizehn \n", - " vierzehn funfzehn sechszehn siebzehn achtzehn neunzehn zwanzig einundzwanzig zweiundzwanzig \n", - " dreiundzwanzig vierundzwanzig fünfundzwanzig sechsundzwanzig siebenundzwanzig achtundzwanzig''')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Multilingual Equilength Expressions\n", - "\n", - "We are ready to find equilength numbers and expressions:" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{4: 'four'}" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "equilength_expressions(english, 0)" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{4: 'four',\n", - " 10: '(zero and ten)',\n", - " 11: '(two plus nine)',\n", - " 12: '(one and eleven)',\n", - " 13: '(one plus twelve)',\n", - " 14: '(one and thirteen)',\n", - " 15: '(one times fifteen)',\n", - " 16: '(three and thirteen)',\n", - " 17: '(one times seventeen)',\n", - " 18: '(seven added to eleven)',\n", - " 19: '(zero added to nineteen)',\n", - " 20: '(seven added to thirteen)'}" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "equilength_expressions(english, 1)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{5: 'cinco',\n", - " 10: '(uno por diez)',\n", - " 11: '(cero más once)',\n", - " 12: '(tres más nueve)',\n", - " 14: '(cero más catorce)',\n", - " 15: '(quince menos cero)',\n", - " 16: '(cero más dieciséis)',\n", - " 17: '(cero más diecisiete)',\n", - " 18: '(veintiuno menos tres)',\n", - " 19: '(diecinueve menos cero)',\n", - " 20: '(veinte dividido por uno)',\n", - " 21: '(veinticuatro menos tres)',\n", - " 25: '(veinticinco dividido por uno)',\n", - " 26: '(veintiséis dividido entre uno)',\n", - " 27: '(veintisiete dividido entre uno)'}" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "equilength_expressions(spanish, 1)" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{2: 'èr',\n", - " 3: 'sān',\n", - " 7: '(èr jiā wŭ)',\n", - " 8: '(èr jiā liù)',\n", - " 9: '(sān jiā liù)',\n", - " 10: '(yī chéng shí)',\n", - " 11: '(shí wǔ jiǎn sì)',\n", - " 12: '(yī chéng shí èr)',\n", - " 13: '(yī chéng shí sān)'}" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "equilength_expressions(chinese, 1)" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{4: 'vier',\n", - " 11: '(null plus elf)',\n", - " 12: '(eins mal zwölf)',\n", - " 13: '(eins plus zwölf)',\n", - " 15: '(eins mal funfzehn)',\n", - " 16: '(eins mal sechszehn)',\n", - " 17: '(eins plus sechszehn)',\n", - " 18: '(zwanzig weniger zwei)',\n", - " 19: '(neunzehn weniger null)',\n", - " 21: '(null plus einundzwanzig)',\n", - " 22: '(null plus zweiundzwanzig)',\n", - " 23: '(achtundzwanzig minus fünf)',\n", - " 24: '(sechsundzwanzig minus zwei)',\n", - " 25: '(achtundzwanzig weniger drei)',\n", - " 26: '(sechsundzwanzig weniger null)',\n", - " 27: '(siebenundzwanzig weniger null)'}" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "equilength_expressions(german, 1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Longer Multilingual Equilength Expressions¶\n", - "\n", - "Now for expressions with 2 combination steps. These take a few minutes each, so I will `%time` them:" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3min 46s, sys: 1.34 s, total: 3min 48s\n", - "Wall time: 3min 52s\n" - ] - }, - { - "data": { - "text/plain": [ - "{4: 'four',\n", - " 10: '(zero and ten)',\n", - " 11: '(two plus nine)',\n", - " 12: '(one and eleven)',\n", - " 13: '(one plus twelve)',\n", - " 14: '(one and thirteen)',\n", - " 15: '(one times fifteen)',\n", - " 16: '(zero and (six and ten))',\n", - " 17: '(one plus (six plus ten))',\n", - " 18: '(ten minus (two less ten))',\n", - " 19: '(ten minus (one minus ten))',\n", - " 20: '(six over (six over twenty))',\n", - " 21: '(two minus (one less twenty))',\n", - " 22: '(eight less (six less twenty))',\n", - " 23: '(seven less (four less twenty))',\n", - " 24: '(ten take away (six less twenty))',\n", - " 25: '(six take away (one minus twenty))',\n", - " 26: '((two and ten) less (six less twenty))',\n", - " 27: '((one and ten) less (four less twenty))',\n", - " 28: '((one plus six) over (five over twenty))',\n", - " 29: '((five plus ten) minus (six less twenty))',\n", - " 30: '(ten and (zero subtracted from twenty))',\n", - " 31: '((one and sixteen) minus (six less twenty))',\n", - " 32: '(two times (four subtracted from twenty))',\n", - " 33: '((zero and nineteen) minus (six less twenty))',\n", - " 34: '((seventeen over two) over (five over twenty))',\n", - " 35: '(nineteen and (four subtracted from twenty))',\n", - " 36: '((ten and ten) and (four subtracted from twenty))',\n", - " 37: '(seventeen plus (zero subtracted from twenty))',\n", - " 38: '((eight and ten) and (zero subtracted from twenty))',\n", - " 39: '((nine plus ten) plus (zero subtracted from twenty))',\n", - " 40: '((ten over four) times (four subtracted from twenty))',\n", - " 41: '((five and twenty) plus (four subtracted from twenty))',\n", - " 42: '((ten plus sixteen) plus (four subtracted from twenty))',\n", - " 43: '((eight and nineteen) and (four subtracted from twenty))',\n", - " 44: '((five times twelve) minus (four subtracted from twenty))',\n", - " 45: '((ten added to nineteen) and (four subtracted from twenty))',\n", - " 46: '((eleven plus nineteen) plus (four subtracted from twenty))',\n", - " 47: '((thirteen plus eighteen) and (four subtracted from twenty))',\n", - " 48: '((twenty less seventeen) times (four subtracted from twenty))',\n", - " 49: '((five times thirteen) take away (four subtracted from twenty))',\n", - " 50: '((six multiplied by eleven) minus (four subtracted from twenty))',\n", - " 51: '((seventeen added to eighteen) and (four subtracted from twenty))',\n", - " 52: '((thirteen over four) multiplied by (four subtracted from twenty))',\n", - " 53: '((seventeen added to twenty) added to (four subtracted from twenty))',\n", - " 54: '((two multiplied by nineteen) added to (four subtracted from twenty))',\n", - " 55: '((eleven divided by four) multiplied by (zero subtracted from twenty))',\n", - " 56: '((four multiplied by eighteen) take away (four subtracted from twenty))',\n", - " 57: '((five multiplied by twelve) multiplied by (nineteen divided by twenty))',\n", - " 58: '((twelve added to seventeen) times (seventeen subtracted from nineteen))',\n", - " 59: '((three multiplied by nineteen) and (seventeen subtracted from nineteen))',\n", - " 60: '((fourteen subtracted from seventeen) times (zero subtracted from twenty))',\n", - " 61: '((five multiplied by thirteen) take away (fifteen subtracted from nineteen))',\n", - " 62: '((eleven added to twenty) multiplied by (seventeen subtracted from nineteen))',\n", - " 63: '((five multiplied by thirteen) take away (seventeen subtracted from nineteen))',\n", - " 64: '((eight multiplied by sixteen) divided by (seventeen subtracted from nineteen))',\n", - " 65: '((thirteen multiplied by twenty) divided by (fourteen subtracted from eighteen))',\n", - " 66: '((fourteen added to nineteen) multiplied by (seventeen subtracted from nineteen))',\n", - " 67: '((nine multiplied by nineteen) subtracted from (fourteen multiplied by seventeen))',\n", - " 68: '((seventeen added to seventeen) multiplied by (seventeen subtracted from nineteen))',\n", - " 69: '((seventeen subtracted from eighteen) subtracted from (five multiplied by fourteen))',\n", - " 70: '((three subtracted from seventeen) multiplied by (fourteen subtracted from nineteen))',\n", - " 71: '((fourteen multiplied by eighteen) subtracted from (seventeen multiplied by nineteen))',\n", - " 72: '((seventeen multiplied by seventeen) subtracted from (nineteen multiplied by nineteen))'}" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time equilength_expressions(english, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4min 50s, sys: 3.14 s, total: 4min 53s\n", - "Wall time: 5min 5s\n" - ] - }, - { - "data": { - "text/plain": [ - "{5: 'cinco',\n", - " 10: '(uno por diez)',\n", - " 11: '(cero más once)',\n", - " 12: '(tres más nueve)',\n", - " 14: '(cero más catorce)',\n", - " 15: '(quince menos cero)',\n", - " 16: '(uno por (dos por ocho))',\n", - " 17: '(uno por (seis más once))',\n", - " 18: '(uno por (siete más once))',\n", - " 19: '(cero más (seis más trece))',\n", - " 20: '(diez por (doce menos diez))',\n", - " 21: '(diez menos (uno menos doce))',\n", - " 22: '(diez menos (uno menos trece))',\n", - " 23: '(diez menos (dos menos quince))',\n", - " 24: '(dos menos (ocho menos treinta))',\n", - " 25: '(seis menos (once menos treinta))',\n", - " 26: '(siete menos (once menos treinta))',\n", - " 27: '(cero menos (uno menos veintiocho))',\n", - " 28: '(dos menos (tres menos veintinueve))',\n", - " 29: '((uno por uno) menos (dos menos treinta))',\n", - " 30: '((seis por ocho) más (doce menos treinta))',\n", - " 31: '((uno más doce) menos (doce menos treinta))',\n", - " 32: '((uno más trece) menos (doce menos treinta))',\n", - " 33: '(veinte menos (diecisiete menos treinta))',\n", - " 34: '(treinta menos (veintiséis menos treinta))',\n", - " 35: '((tres más catorce) menos (doce menos treinta))',\n", - " 36: '((dos menos seis) por (veintiuno menos treinta))',\n", - " 37: '((tres por trece) más (veintiocho menos treinta))',\n", - " 38: '((tres por doce) menos (veintiocho menos treinta))',\n", - " 39: '((seis por quince) por (trece dividido por treinta))',\n", - " 40: '(doce dividido por (nueve dividido entre treinta))',\n", - " 41: '((quince más treinta) más (veintiséis menos treinta))',\n", - " 42: '((cinco por doce) por (veintiuno dividido por treinta))',\n", - " 43: '((seis más veintiocho) menos (veintiuno menos treinta))',\n", - " 44: '((cinco por doce) por (veintidós dividido entre treinta))',\n", - " 45: '(veintiuno dividido por (catorce dividido por treinta))',\n", - " 46: '((cuatro por quince) por (veintitrés dividido por treinta))',\n", - " 47: '((veinte más veinticinco) menos (veintiocho menos treinta))',\n", - " 48: '((dos por treinta) por (veinticuatro dividido entre treinta))',\n", - " 49: '((veintiuno más veintiséis) menos (veintiocho menos treinta))',\n", - " 50: '((dos por quince) dividido por (dieciocho dividido por treinta))',\n", - " 51: '((veinticuatro más veintinueve) más (veintiocho menos treinta))',\n", - " 52: '((veinticuatro más veintiséis) menos (veintiocho menos treinta))',\n", - " 53: '((veinticuatro más veintisiete) menos (veintiocho menos treinta))',\n", - " 54: '((veintiuno menos doce) dividido entre (cinco dividido por treinta))',\n", - " 55: '((diez más veintitrés) dividido por (dieciocho dividido por treinta))',\n", - " 56: '((veintidós más veintinueve) menos (veinticuatro menos veintinueve))',\n", - " 57: '((diecinueve dividido por diez) dividido por (uno dividido por treinta))',\n", - " 58: '((seis por nueve) dividido entre (veintisiete dividido por veintinueve))',\n", - " 59: '((veintinueve dividido entre veintinueve) por (veintinueve más treinta))',\n", - " 60: '((veintiocho más treinta) dividido por (veintinueve dividido por treinta))',\n", - " 62: '((cuatro más veintisiete) dividido entre (doce dividido entre veinticuatro))',\n", - " 63: '((veintiuno dividido entre dos) dividido entre (cinco dividido entre treinta))',\n", - " 64: '((veintiuno más veintisiete) dividido por (veintiuno dividido por veintiocho))',\n", - " 65: '((treinta más treinta) dividido entre (veinticuatro dividido entre veintiséis))',\n", - " 66: '((diecisiete más veintisiete) dividido por (dieciocho dividido por veintisiete))',\n", - " 68: '((veintidós más veintinueve) dividido entre (veintiuno dividido entre veintiocho))',\n", - " 69: '((veintiuno más veinticinco) dividido entre (dieciocho dividido entre veintisiete))',\n", - " 70: '((veintisiete más veintinueve) dividido entre (veinticuatro dividido entre treinta))',\n", - " 72: '((veintiocho más veintinueve) dividido entre (diecinueve dividido entre veinticuatro))'}" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time equilength_expressions(spanish, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 20.2 s, sys: 286 ms, total: 20.5 s\n", - "Wall time: 21.1 s\n" - ] - }, - { - "data": { - "text/plain": [ - "{2: 'èr',\n", - " 3: 'sān',\n", - " 7: '(èr jiā wŭ)',\n", - " 8: '(èr jiā liù)',\n", - " 9: '(sān jiā liù)',\n", - " 10: '(yī chéng shí)',\n", - " 11: '(shí wǔ jiǎn sì)',\n", - " 12: '(yī jiā (sì jiā qī))',\n", - " 13: '(yī jiā (èr jiā shí))',\n", - " 14: '(qī jiǎn (yī jiǎn bā))',\n", - " 15: '(bā chú (bā chú shí wǔ))',\n", - " 16: '(qī chú (qī chú shí liù))',\n", - " 17: '(shí chú (shí chú shí qī))',\n", - " 18: '(sān jiǎn (èr jiǎn shí qī))',\n", - " 19: '(èr jiǎn (ling jiǎn shí qī))',\n", - " 20: '(sān jiǎn (ling jiǎn shí qī))',\n", - " 21: '(shí sì jiǎn (shí jiǎn shí qī))',\n", - " 22: '((èr jiā wŭ) jiǎn (èr jiǎn shí qī))',\n", - " 23: '(shí qī jiǎn (shí yī jiǎn shí qī))',\n", - " 24: '((qī jiā shí) jiǎn (shí jiǎn shí qī))',\n", - " 25: '((jiŭ jiā jiŭ) jiǎn (shí jiǎn shí qī))',\n", - " 26: '((sì chéng bā) jiā (shí yī jiǎn shí qī))',\n", - " 27: '((sān jiā shí qī) jiǎn (shí jiǎn shí qī))',\n", - " 28: '((bā jiā shí wǔ) jiǎn (shí èr jiǎn shí qī))',\n", - " 29: '((bā jiā shí liù) jiǎn (shí èr jiǎn shí qī))',\n", - " 30: '((èr chéng shí qī) chéng (shí wǔ chú shí qī))',\n", - " 31: '((shí yī jiā shí wǔ) jiǎn (shí èr jiǎn shí qī))',\n", - " 32: '((shí qī jiā shí qī) chéng (shí liù chú shí qī))',\n", - " 33: '((sān chéng shí qī) chéng (shí yī chú yǐ shí qī))',\n", - " 34: '((shí liù jiā shí liù) chú (shí liù chú yǐ shí qī))',\n", - " 35: '((shí liù jiā shí liù) jiǎn (shí sān jiǎn shí liù))',\n", - " 36: '((shí èr chéng shí liù) jiǎn (shí èr chéng shí sān))'}" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time equilength_expressions(chinese, 2)" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 5min 7s, sys: 4.02 s, total: 5min 11s\n", - "Wall time: 5min 20s\n" - ] - }, - { - "data": { - "text/plain": [ - "{4: 'vier',\n", - " 11: '(null plus elf)',\n", - " 12: '(eins mal zwölf)',\n", - " 13: '(eins plus zwölf)',\n", - " 15: '(eins mal funfzehn)',\n", - " 16: '(eins mal sechszehn)',\n", - " 17: '(eins und (fünf und elf))',\n", - " 18: '(eins und (sechs und elf))',\n", - " 19: '(eins mal (neun plus zehn))',\n", - " 20: '(elf minus (zwei minus elf))',\n", - " 21: '(zehn minus (null minus elf))',\n", - " 22: '(sechs durch (drei durch elf))',\n", - " 23: '((elf durch elf) und (elf und elf))',\n", - " 24: '(sechs durch (drei durch zwölf))',\n", - " 25: '(zehn durch (acht durch zwanzig))',\n", - " 26: '(elf weniger (fünf minus zwanzig))',\n", - " 27: '(zehn weniger (drei minus zwanzig))',\n", - " 28: '(zwölf weniger (vier minus zwanzig))',\n", - " 29: '(vierzehn minus (fünf minus zwanzig))',\n", - " 30: '(elf minus (zwei minus einundzwanzig))',\n", - " 31: '(elf minus (acht minus achtundzwanzig))',\n", - " 32: '(fünf minus (eins minus achtundzwanzig))',\n", - " 33: '(sechs minus (eins minus achtundzwanzig))',\n", - " 34: '(acht weniger (zwei minus achtundzwanzig))',\n", - " 35: '(elf minus (drei weniger siebenundzwanzig))',\n", - " 36: '(acht weniger (null weniger achtundzwanzig))',\n", - " 37: '((acht mal acht) und (eins minus achtundzwanzig))',\n", - " 38: '((eins und elf) minus (zwei minus achtundzwanzig))',\n", - " 39: '((zwei plus elf) minus (zwei minus achtundzwanzig))',\n", - " 40: '(neunzehn minus (sieben weniger achtundzwanzig))',\n", - " 41: '(zwanzig weniger (sieben weniger achtundzwanzig))',\n", - " 42: '((zehn und elf) durch (vierzehn durch achtundzwanzig))',\n", - " 43: '((drei mal zehn) minus (funfzehn minus achtundzwanzig))',\n", - " 44: '((zehn und zwölf) durch (vierzehn durch achtundzwanzig))',\n", - " 45: '((fünf mal vierzehn) mal (achtzehn durch achtundzwanzig))',\n", - " 46: '((drei und zwanzig) durch (vierzehn durch achtundzwanzig))',\n", - " 47: '((sechs mal neun) und (einundzwanzig minus achtundzwanzig))',\n", - " 48: '((vier mal neun) durch (einundzwanzig durch achtundzwanzig))',\n", - " 49: '((neun plus neunzehn) durch (sechszehn durch achtundzwanzig))',\n", - " 50: '((sieben plus achtzehn) durch (vierzehn durch achtundzwanzig))',\n", - " 51: '((drei mal achtundzwanzig) mal (siebzehn durch achtundzwanzig))',\n", - " 52: '((vier mal vierzehn) mal (sechsundzwanzig durch achtundzwanzig))',\n", - " 53: '((sechs mal neun) plus (siebenundzwanzig weniger achtundzwanzig))',\n", - " 54: '((sieben multipliziert zwölf) mal (achtzehn durch achtundzwanzig))',\n", - " 55: '((vier mal vierzehn) und (siebenundzwanzig weniger achtundzwanzig))',\n", - " 56: '((zwölf plus sechsundzwanzig) durch (neunzehn durch achtundzwanzig))',\n", - " 57: '((sieben mal acht) weniger (siebenundzwanzig weniger achtundzwanzig))',\n", - " 58: '((acht multipliziert acht) plus (zweiundzwanzig minus achtundzwanzig))',\n", - " 59: '((sieben multipliziert neun) und (vierundzwanzig minus achtundzwanzig))',\n", - " 60: '((zwanzig multipliziert achtundzwanzig) mal (drei durch achtundzwanzig))',\n", - " 61: '((fünf multipliziert dreizehn) und (vierundzwanzig minus achtundzwanzig))',\n", - " 62: '((vier multipliziert siebzehn) plus (zweiundzwanzig minus achtundzwanzig))',\n", - " 63: '((drei multipliziert achtzehn) durch (vierundzwanzig durch achtundzwanzig))',\n", - " 64: '((drei mal einundzwanzig) weniger (siebenundzwanzig weniger achtundzwanzig))',\n", - " 65: '((zehn multipliziert dreizehn) multipliziert (vierzehn durch achtundzwanzig))',\n", - " 66: '((vier multipliziert einundzwanzig) mal (zweiundzwanzig durch achtundzwanzig))',\n", - " 67: '((siebenundzwanzig und siebenundzwanzig) minus (funfzehn minus achtundzwanzig))',\n", - " 68: '((dreiundzwanzig und achtundzwanzig) durch (einundzwanzig durch achtundzwanzig))',\n", - " 69: '((vier multipliziert siebzehn) weniger (siebenundzwanzig weniger achtundzwanzig))',\n", - " 70: '((elf weniger einundzwanzig) multipliziert (einundzwanzig weniger achtundzwanzig))',\n", - " 71: '((drei multipliziert vierundzwanzig) und (siebenundzwanzig weniger achtundzwanzig))',\n", - " 72: '((sechs multipliziert vierzehn) multipliziert (vierundzwanzig durch achtundzwanzig))',\n", - " 73: '((drei multipliziert vierundzwanzig) minus (siebenundzwanzig weniger achtundzwanzig))',\n", - " 74: '((drei multipliziert fünfundzwanzig) minus (siebenundzwanzig weniger sechsundzwanzig))',\n", - " 75: '((dreiundzwanzig minus achtundzwanzig) multipliziert (dreizehn weniger achtundzwanzig))',\n", - " 76: '((drei multipliziert fünfundzwanzig) weniger (sechsundzwanzig weniger siebenundzwanzig))',\n", - " 77: '((sechszehn weniger siebenundzwanzig) multipliziert (einundzwanzig minus achtundzwanzig))',\n", - " 78: '((drei multipliziert achtundzwanzig) multipliziert (sechsundzwanzig durch achtundzwanzig))',\n", - " 79: '((fünfundzwanzig mal achtundzwanzig) minus (dreiundzwanzig multipliziert siebenundzwanzig))',\n", - " 80: '((sechsundzwanzig mal achtundzwanzig) minus (vierundzwanzig multipliziert siebenundzwanzig))',\n", - " 81: '((drei multipliziert sechsundzwanzig) multipliziert (siebenundzwanzig durch sechsundzwanzig))',\n", - " 82: '((achtundzwanzig mal achtundzwanzig) weniger (sechsundzwanzig multipliziert siebenundzwanzig))',\n", - " 83: '((einundzwanzig multipliziert fünfundzwanzig) weniger (siebzehn multipliziert sechsundzwanzig))',\n", - " 84: '((einundzwanzig multipliziert fünfundzwanzig) minus (einundzwanzig multipliziert einundzwanzig))',\n", - " 86: '((zweiundzwanzig multipliziert sechsundzwanzig) weniger (achtzehn multipliziert siebenundzwanzig))',\n", - " 87: '((zweiundzwanzig multipliziert achtundzwanzig) minus (dreiundzwanzig multipliziert dreiundzwanzig))',\n", - " 88: '((zweiundzwanzig multipliziert sechsundzwanzig) minus (zweiundzwanzig multipliziert zweiundzwanzig))',\n", - " 89: '((zweiundzwanzig multipliziert sechsundzwanzig) weniger (einundzwanzig multipliziert dreiundzwanzig))',\n", - " 90: '((zweiundzwanzig multipliziert siebenundzwanzig) weniger (einundzwanzig multipliziert vierundzwanzig))'}" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time equilength_expressions(german, 2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# What's Next?\n", - "\n", - "As with the other problems, there are many ways we could extend this: adding more languages, more integers, more operators, etc. It is up to you what to explore next." + "Another approach would be to look around for related puzzles and solve them. What do you want to do?" ] } ], @@ -2689,5 +3881,5 @@ } }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 4 }