|
|
http://oraqa.com/2008/05/30/how- ... tion-puzzle-in-sql/
How to solve the 123456789 Equation Puzzle in SQL
May 30th, 2008 By Frank Zhou
The following is an interesting puzzle posted by Usenet rec-puzzles.org archive:
In how many ways can “.” be replaced with “+”, “-”, or “” (concatenate) in .1.2.3.4.5.6.7.8.9 = 1 to form a correct equation?
——————————————-SQL Solution————————-
SELECT str_eq || ' = ' || output as output, count(*) over ( ) as counter
FROM
(select str_eq, XMLQuery( str_eq RETURNING CONTENT).getnumberval() output
FROM
(
WITH DATA AS
(
SELECT doc.extract('/l/text()').getStringVal() chars
FROM
TABLE(xmlSequence(extract(XMLType('<doc><l>'||
replace('+,-, ',',','</l><l>')||'</l></doc>'),'/doc/l'))) doc
)
SELECT replace(sys_connect_by_path(chars||to_char(LEVEL),'.'), '.') as str_eq
FROM ( SELECT chars from data)
WHERE LEVEL = 9
CONNECT BY LEVEL <= 9
)
)
where output = 1;
OUTPUT COUNTER
-------------------------------------- ----------
+1+2+3+4+5-6-7+8-9 = 1 69
+1+2+3+4-5+6+7-8-9 = 1 69
+1+2+3+45-67+8+9 = 1 69
+1+2+3-4-5-6-7+8+9 = 1 69
+1+2-3+4-5-6+7-8+9 = 1 69
+1+2-3-4+5+6-7-8+9 = 1 69
+1+2-3-4+5-6+7+8-9 = 1 69
+1+2-34+56-7-8-9 = 1 69
+1+23+4-5+67-89 = 1 69
+1+23+45-67+8-9 = 1 69
+1+23-4-5-6-7+8-9 = 1 69
OUTPUT COUNTER
-------------------------------------- ----------
+1+23-45-67+89 = 1 69
+1-2+3+4-5+6-7-8+9 = 1 69
+1-2+3+4-5-6+7+8-9 = 1 69
+1-2+3-4+5+6-7+8-9 = 1 69
+1-2+34-56+7+8+9 = 1 69
+1-2-3+4+5+6+7-8-9 = 1 69
+1-2-3-4+5-6-7+8+9 = 1 69
+1-2-3-4-5+6+7-8+9 = 1 69
+1-2-3-45+67-8-9 = 1 69
+1-23+4+5+6+7-8+9 = 1 69
+1-23+45+67-89 = 1 69
OUTPUT COUNTER
-------------------------------------- ----------
+1-23-4+5-67+89 = 1 69
+1-23-45+67-8+9 = 1 69
+12+34+5-67+8+9 = 1 69
+12-34+5-6+7+8+9 = 1 69
-1+2+3+4+5-6-7-8+9 = 1 69
-1+2+3+4-5+6-7+8-9 = 1 69
-1+2+3-4+5+6+7-8-9 = 1 69
-1+2-3+4-5-6-7+8+9 = 1 69
-1+2-3-4+5-6+7-8+9 = 1 69
-1+2-3-4-5+6+7+8-9 = 1 69
-1+23+4+5-6-7-8-9 = 1 69
OUTPUT COUNTER
-------------------------------------- ----------
-1+23+45-67-8+9 = 1 69
-1+23-4+5+67-89 = 1 69
-1+23-4-5-6-7-8+9 = 1 69
-1-2+3+4-5-6+7-8+9 = 1 69
-1-2+3-4+5+6-7-8+9 = 1 69
-1-2+3-4+5-6+7+8-9 = 1 69
-1-2-3+4+5+6-7+8-9 = 1 69
-1-2-3-4-5+6-7+8+9 = 1 69
-1-23+4+5+6-7+8+9 = 1 69
-12+34-5-6+7-8-9 = 1 69
1+2+3+4+5-6-7+8-9 = 1 69
OUTPUT COUNTER
-------------------------------------- ----------
1+2+3+4-5+6+7-8-9 = 1 69
1+2+3+45-67+8+9 = 1 69
1+2+3-4-5-6-7+8+9 = 1 69
1+2-3+4-5-6+7-8+9 = 1 69
1+2-3-4+5+6-7-8+9 = 1 69
1+2-3-4+5-6+7+8-9 = 1 69
1+2-34+56-7-8-9 = 1 69
1+23+4-5+67-89 = 1 69
1+23+45-67+8-9 = 1 69
1+23-4-5-6-7+8-9 = 1 69
1+23-45-67+89 = 1 69
OUTPUT COUNTER
-------------------------------------- ----------
1-2+3+4-5+6-7-8+9 = 1 69
1-2+3+4-5-6+7+8-9 = 1 69
1-2+3-4+5+6-7+8-9 = 1 69
1-2+34-56+7+8+9 = 1 69
1-2-3+4+5+6+7-8-9 = 1 69
1-2-3-4+5-6-7+8+9 = 1 69
1-2-3-4-5+6+7-8+9 = 1 69
1-2-3-45+67-8-9 = 1 69
1-23+4+5+6+7-8+9 = 1 69
1-23+45+67-89 = 1 69
1-23-4+5-67+89 = 1 69
OUTPUT COUNTER
-------------------------------------- ----------
1-23-45+67-8+9 = 1 69
12+34+5-67+8+9 = 1 69
12-34+5-6+7+8+9 = 1 69
69 rows selected.
这个题目其实就是野花发过的“丢失的符号”: http://www.itpub.net/thread-1301673-1-1.html
11GR2:
WITH n AS (SELECT ROWNUM-1 rn FROM DUAL CONNECT BY ROWNUM<=10)
,o AS (SELECT '+' op FROM DUAL UNION ALL SELECT '-' op FROM DUAL UNION ALL SELECT NULL FROM DUAL)
,t(num,tot,expr,op) AS (
SELECT 0 as num, 0 as tot, '' AS expr, '' AS op FROM DUAL
UNION ALL
SELECT n.rn
,DECODE(o.op,'+',t.tot+n.rn,'-',t.tot-n.rn,DECODE(t.op,'+',t.tot-t.num+t.num*10+n.rn,t.tot+t.num-t.num*10-n.rn))
,t.expr||o.op||n.rn
,o.op
FROM n,t,o
WHERE t.num = n.rn-1 AND (o.op IS NOT NULL OR t.op IS NOT NULL)
)
SELECT expr||'='||tot AS OUTPUT
FROM t
WHERE num=9 AND tot=1;
其他解法:
WITH t AS(
SELECT '+' X FROM DUAL UNION ALL
SELECT '-' X FROM DUAL UNION ALL
SELECT '' X FROM DUAL)
,t2 AS (
SELECT *
FROM (SELECT ROWNUM id,t.x||
1||t1.x||
2||t2.x||
3||t3.x||
4||t4.x||
5||t5.x||
6||t6.x||
7||t7.x||
8||t8.x||
9 y
FROM t,t t1,t t2,t t3,t t4,t t5,t t6,t t7,t t8
WHERE t.x IN ('-','+')
)
WHERE REPLACE(y,123)=y AND
REPLACE(y,234)=y AND
REPLACE(y,345)=y AND
REPLACE(y,456)=y AND
REPLACE(y,567)=y AND
REPLACE(y,678)=y AND
REPLACE(y,789)=y
)
SELECT LTRIM(y,'+')
FROM (SELECT id,y,REGEXP_SUBSTR(y,'[+-]',1,rn) op,REGEXP_SUBSTR(y,'[^+-]+',1,rn) num
FROM t2,(SELECT ROWNUM rn FROM DUAL CONNECT BY ROWNUM<=9)
)
GROUP BY id,y
HAVING SUM(DECODE(op,'+',num,-num))=1
;
WITH t AS(
SELECT n,op
FROM (SELECT '+' op FROM DUAL UNION ALL
SELECT '-' op FROM DUAL UNION ALL
SELECT '' op FROM DUAL)
,(SELECT ROWNUM n FROM DUAL CONNECT BY ROWNUM<=9)
WHERE n>1 OR op IN ('+','-')
)
,t2 AS (
SELECT ROWNUM id, REPLACE(SYS_CONNECT_BY_PATH(op||n,'@'),'@') y
FROM t
WHERE n=9
START WITH n=1
CONNECT BY n= PRIOR n+1 AND (op IS NOT NULL OR PRIOR op IS NOT NULL)
)
SELECT LTRIM(y,'+')
FROM (SELECT id,y,REGEXP_SUBSTR(y,'[+-]',1,rn) op,REGEXP_SUBSTR(y,'[^+-]+',1,rn) num
FROM t2,(SELECT ROWNUM rn FROM DUAL CONNECT BY ROWNUM<=9)
)
GROUP BY id,y
HAVING SUM(DECODE(op,'+',num,-num))=1
;
WITH t AS(
SELECT n,op
FROM (SELECT '+' op FROM DUAL UNION ALL
SELECT '-' op FROM DUAL UNION ALL
SELECT '~' op FROM DUAL)
,(SELECT ROWNUM n FROM DUAL CONNECT BY ROWNUM<=9)
WHERE n>1 OR op IN ('+','-')
)
,t2 AS (
SELECT ROWNUM id, REPLACE(SYS_CONNECT_BY_PATH(op||n,'@'),'@') y
,DECODE(op,'+',n,'-',-n,DECODE(PRIOR op,'+',- (PRIOR n)+ (PRIOR n)*10 +n, (PRIOR n)- (PRIOR n)*10 -n)) val
FROM t
WHERE n=9
START WITH n=1
CONNECT BY n= PRIOR n+1 AND (op <>'~' OR PRIOR op <>'~')
)
SELECT LTRIM(REPLACE(t2.y,'~'),'+')
FROM t2,(SELECT ROWNUM n FROM DUAL CONNECT BY ROWNUM<=9)
GROUP BY t2.y
HAVING SUM(DECODE(SUBSTR(y,(n-1)*2+1,1),'+',n,'-',-n,DECODE(SUBSTR(y,(n-2)*2+1,1),'+',-(n-1)+(n-1)*10+n,(n-1)-(n-1)*10-n )))=1; |
|