All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars
 perplexus dot info

 Closest to pi (Posted on 2005-09-25)
As you know, the value of pi with some decimals is 3.141592653589...

Write an expression using all digits (0-9) once each, to achieve the closest value to pi. The digits must be in the order 1, 2, 3, 4, ...8, 9, 0. You may also use as many parentheses, +, -, /, and *, as you wish, but only these symbols.

As an example: 123/45 - 6/7 + 8/9 + 0 = 2.765079... gives a difference of approximately 0.376.

You may post the difference or the approximation you achieve in the subject of your comment.

 See The Solution Submitted by pcbouhid Rating: 3.0000 (4 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
 .00000026676419 -- computer solution | Comment 10 of 25 |

A program to find all possibilities gives (1-2/(3-4/(5/6-7*8)))*(9+0) = 3.141592920353983 (the same 355 / 113 Ady found -- double precision used, so the difference is found more accurately).

A later program, designed to allow a leading negative sign, which the first was not, found an alternate: -1 + 2/((345-6)/(78*(9+0))). This is also equivalent to 355/113.

The table below shows the successively better solutions found by the first program.  The first column shows the Reverse Polish Notation form; the second shows algebraic form; and the third shows the approximation.  Note that some of the algebraic forms involve division by a product; parentheses were not placed around the product, and you must interpret as multiplication taking precedence over division, which is not standard. Just insert the needed parentheses for standard order of operations. This is not involved with the most accurate solution.

`123456789,0*                 123456789*0                 012345,67890/                 12345/67890                 .181838267786124612345,6789,0+/               12345/(6789+0)              1.81838267786124612345,678,9,0+*/             12345/678*(9+0)             2.02310717797443512345,67,89,0+*/             12345/67*(89+0)             2.07026664430655712345,67,8,9,0+**/           12345/67*8*(9+0)            2.5590796019900512345,6,789,0+*/             12345/6*(789+0)             2.60773130544993712345,6,78,9,0+**/           12345/6*78*(9+0)            2.93091168091168112345,6,7,89,0+**/           12345/6*7*(89+0)            3.30256821829855512345,6,7,8,90+**/           12345/6*7*(8+90)            2.99927113702623912345,6,7*/,8-,90/           (12345/6*7-8)/90            3.1769841269841271234,567/,8,9,0+--           1234/567-(8-(9+0))          3.176366843033511234,567/,8-,9,0++           1234/567-8+9+0              3.1763668430335091234,56,7,89,0*+*/           1234/56*(7+89*0)            3.1479591836734691234,56,7*,8,90/+/           1234/(56*7+8/90)            3.1472455225572431234,56,7*,8,9,0+--/         1234/(56*7-(8-(9+0)))       3.1399491094147581234,56,7*,8,9,0+/+/         1234/(56*7+8/(9+0))         3.140837104072398123,4-,5,6*,7,8,9,0+//+/     (123-4)/(5*6+7/(8/(9+0)))   3.14191419141914212,34+,5,6,7,8,90/*/+/       (12+34)/(5+6/(7*8/90))      3.14146341463414612,3,4,5,67,8,90*/+///       12/(3/(4/(5+67/8*90)))      3.1415325879465512,3,4,5*+,6//,7,8-,90/-     12/((3+4*5)/6)-(7-8)/90     3.14154589371980612,3,4,5/,6,7+,890/-//       12/(3/(4/5-(6+7)/890))      3.1415730337078661,23,4,56,7-/-,8,9,0+*//     1/((23-4/(56-7))/8*(9+0))   3.1415850400712381,2,3,4,5,6/,7,8*-/-/-,9,0+* (1-2/(3-4/(5/6-7*8)))*(9+0) 3.141592920353983`

The program actually was two programs--the first to find the RPN form and the second to convert RPN to algebraic notation:

To produce RPN:

DEFDBL A-Z
DIM SHARED stack(11)
DIM SHARED upTo, stackLevel
DIM SHARED h\$, best

best = 9999
stack(1) = 1: stackLevel = 1: upTo = 1
h\$ = "1"

nextOne = upTo + 1
SELECT CASE nextOne
CASE 10
nextOne = 0
CASE 1
' this is the end
' evaluate
IF stackLevel = 1 THEN
diff = ABS(stack(1) - 3.141592654#)
IF diff < best THEN
best = diff
PRINT h\$, stack(1)
END IF
EXIT SUB
ELSE
nextOne = 999
END IF
END SELECT

'first try concatenation
IF nextOne < 999 THEN
lc\$ = RIGHT\$(h\$, 1)
ix = INSTR("0123456789", lc\$)
IF ix THEN
h\$ = h\$ + LTRIM\$(STR\$(nextOne))
stack(stackLevel) = 10 * stack(stackLevel) + nextOne
utSave = upTo
upTo = nextOne
upTo = utSave
stack(stackLevel) = stack(stackLevel) 10
h\$ = LEFT\$(h\$, LEN(h\$) - 1)
END IF
END IF

'try comma
IF nextOne < 999 THEN
stackLevel = stackLevel + 1
stack(stackLevel) = nextOne
h\$ = h\$ + "," + LTRIM\$(STR\$(nextOne))
utSave = upTo
upTo = nextOne
upTo = utSave
stackLevel = stackLevel - 1
h\$ = LEFT\$(h\$, LEN(h\$) - 2)
END IF

EXIT SUB

IF stackLevel >= 2 THEN
s1 = stack(stackLevel - 1)
s2 = stack(stackLevel)
stackLevel = stackLevel - 1

stack(stackLevel) = s1 + s2
h\$ = h\$ + "+"
h\$ = LEFT\$(h\$, LEN(h\$) - 1)

stack(stackLevel) = s1
stackLevel = stackLevel + 1
stack(stackLevel) = s2

s1 = stack(stackLevel - 1)
s2 = stack(stackLevel)
stackLevel = stackLevel - 1

stack(stackLevel) = s1 - s2
h\$ = h\$ + "-"
h\$ = LEFT\$(h\$, LEN(h\$) - 1)

stack(stackLevel) = s1
stackLevel = stackLevel + 1
stack(stackLevel) = s2

s1 = stack(stackLevel - 1)
s2 = stack(stackLevel)
stackLevel = stackLevel - 1

stack(stackLevel) = s1 * s2
h\$ = h\$ + "*"
h\$ = LEFT\$(h\$, LEN(h\$) - 1)

stack(stackLevel) = s1
stackLevel = stackLevel + 1
stack(stackLevel) = s2

s1 = stack(stackLevel - 1)
s2 = stack(stackLevel)

IF s2 <> 0 THEN
stackLevel = stackLevel - 1

stack(stackLevel) = s1 / s2
h\$ = h\$ + "/"
h\$ = LEFT\$(h\$, LEN(h\$) - 1)

stack(stackLevel) = s1
stackLevel = stackLevel + 1
stack(stackLevel) = s2
END IF

END IF
RETURN

END SUB

And this one to convert RPN to algebraic:

DECLARE SUB checkParen (s\$, ops\$)
OPEN "close2pi.txt" FOR INPUT AS #1
OPEN "clsepi.TXT" FOR OUTPUT AS #2
DO
LINE INPUT #1, l\$
ix = INSTR(l\$, " ")
nOrig\$ = LTRIM\$(MID\$(l\$, ix))
l\$ = LEFT\$(l\$, ix - 1)
stackLevel = 0
bld\$ = ""
FOR i = 1 TO LEN(l\$)
c\$ = MID\$(l\$, i, 1)
ix = INSTR("0123456789", c\$)
IF ix THEN
bld\$ = bld\$ + c\$
stkRaise = 1
ELSE
IF stkRaise THEN
stackLevel = stackLevel + 1
stack\$(stackLevel) = bld\$
stkRaise = 0
bld\$ = ""
END IF
SELECT CASE c\$
CASE "+"
stackLevel = stackLevel - 1
stack\$(stackLevel) = stack\$(stackLevel) + "+" + stack\$(stackLevel + 1)
CASE "-"
h2\$ = stack\$(stackLevel)
checkParen h2\$, "+-"
stackLevel = stackLevel - 1
h1\$ = stack\$(stackLevel)
stack\$(stackLevel) = h1\$ + "-" + h2\$
CASE "*"
h2\$ = stack\$(stackLevel)
checkParen h2\$, "+-"
stackLevel = stackLevel - 1
h1\$ = stack\$(stackLevel)
checkParen h1\$, "+-/"
stack\$(stackLevel) = h1\$ + "*" + h2\$
CASE "/"
h2\$ = stack\$(stackLevel)
checkParen h2\$, "+-/"
stackLevel = stackLevel - 1
h1\$ = stack\$(stackLevel)
checkParen h1\$, "+-/"
stack\$(stackLevel) = h1\$ + "/" + h2\$
CASE "^"
h2\$ = stack\$(stackLevel)
checkParen h2\$, "+-*/"
stackLevel = stackLevel - 1
h1\$ = stack\$(stackLevel)
checkParen h1\$, "+-*/"
stack\$(stackLevel) = h1\$ + "^" + h2\$
END SELECT
END IF
NEXT
IF stackLevel <> 1 THEN
REM
END IF
PRINT l\$, stack\$(1), nOrig\$: PRINT #2, l\$, stack\$(1)
LOOP UNTIL EOF(1)
CLOSE

SUB checkParen (s\$, ops\$)
pLevel = 0
flag = 0
FOR i = 1 TO LEN(s\$)
SELECT CASE MID\$(s\$, i, 1)
CASE "("
pLevel = pLevel + 1
CASE ")"
pLevel = pLevel - 1
CASE ELSE
IF pLevel = 0 AND INSTR(ops\$, MID\$(s\$, i, 1)) THEN flag = 1: EXIT FOR
END SELECT
NEXT i
IF flag THEN s\$ = "(" + s\$ + ")"
END SUB

Edited on September 26, 2005, 12:26 am
 Posted by Charlie on 2005-09-26 00:14:36

 Search: Search body:
Forums (0)