[20250527]24点计算2.txt

来源:这里教程网 时间:2026-03-03 22:02:15 作者:

[20250527]24点计算2.txt --//有一张表 cards,id 是自增字段的数字主键,另外有4个字段 c1,c2,c3,c4 ,每个字段随机从 1~10 之间选择一个整数,要求选手 --//使用一条 SQL 给出 24 点的计算公式. --//单独写出一条sql语句有点难度,我先尝试使用sqlplus+ bash shell的方式实现看看,计算使用dc或者bc。 --//实际上sqlplus一般采用穷举方法计算,蛮力计算结果是否等于24,使用sqlplus,要根据运算符号计算2个数字的计算结果,每次运 --//算都是如此,处理难度集中在哪里,而且题目并没有除法时必须整除,另外运算除法时分母是0该如何处理。我简单一点,直接使用 --//sql语句写出运算的排列组合,然后交给dc或者bc计算,我并没有建立表,先尝试直接带入4个数字计算。 --//运算符号 + - * / ,参与运算3次,这样排列组合就是4*4*4=64种。 --//数字是4个,排列组合就是4*3*2*1=24种。 --//计算方法最简单2个数字运算,再加入1个数字运算,再加入1个数字运算。取一个例子:1 7 8 9,计算如下: 1*7=7 7+8=15 15+9=24 --//写成计算公式如下: 1*7+8+9 --//但是具体公式不能这样写,加减乘除有优先级,必须写成: ((1*7)+8)+9 --//这样计算,我自己称为method 1,实际上测试大部分都可以通过该方法实现。还有一种两两计算,然后计算结果在计算1次。 --//我称为method 2,这样排列组合出现的情况有5种: ## method 1: ((n1 p1 n2 ) p2 n3)  p3 n4 ## method 2: ( n1 p1 n2 ) p3 (n3  p2 n4) ## method 3: ( n1 p2 (n2  p1 n3)) p3 n4 ## method 4:   n1 p3 (n2  p2  (n3 p1 n4)) ## method 5:  n1  p3 ((n2 p1 n3) p2 n4) --//注:n1,n2,n3,n4表示数字,p1,p2,p3表示运算符。 --//使用dc与bc 计算问题,oracle计算必须规避除法分母为0的问题,精度问题我估计问题不大。 --//使用dc与bc 存在如下问题。 1.精度问题: SCOTT@book01p> select 1/ 3* 9 *8 from dual ;    1/3*9*8 ----------         24 --//而使用dc 与bc不行,比如: $ echo "10/ 4* 10 + 4 " |bc 24 --//这明显计算错误,必须带入精度 $ echo "10/ 4* 10 + 4 " |bc -l 29.00000000000000000000 --//带入精度出现另外的问题,计算误差,例子: $ echo "1/ 3* 9 *8 " |bc -l 23.99999999999999999976 --//不过这个问题影响不大,能计算出如此接近的结果,排列组合里面一定存在合适的情况。 --//dc的情况也是类似。 $ echo "20k 1  3 /  9 * 8 * pq " |dc 23.99999999999999999976 2.分母为0的情况: --//执行dc的情况: $ echo "20k 1 0 / pq " |dc dc: divide by zero 0 $ echo "20k 1 0 / pq " |dc 2>/dev/null 0 --//只要将错误重定向到/dev/null就可以了。 $ echo " 1 / 0  " |bc -l Runtime error (func=(main), adr=3): Divide by zero $ echo " 1 / 0  " |bc -l 2>/dev/null --//没有输出。这样bash shell编程要注意使用双引号。 3.还是与精度有关的问题: $ echo "(( 2 * 7) + 1) + 9 " | bc -l 24 $ echo "20k 2 7 * 1 + 9 +  pq" |dc 24 --//即使我指定精度,注bc -l 设定scale=20. 但是如果整形运算,结尾有一些情况也不会输出0.这样在判断上要加入一个或判断。 --//我取了一个巧,再使用1做除法,就可以输出小数点结尾后为0的情况。 $ echo "(( 2 * 7) + 1) + 9 /1" | bc -l 24.00000000000000000000  $ echo "20k 2 7 * 1 + 9 + 1 / pq" |dc 24.00000000000000000000 $ ./24doty.sh 1 3 9 8 1 3 9 8 : method 1:20k 1 8 * 9 * 3 / 1 / pq:(( 1 * 8) * 9) / 3 --//如果加入参数5输入all,输出全部结果。 --//我尝试全部组合共715种,发现一些有趣的解法:比如 1 5 5 5,按照道理算不出24.穷举可以找到2个: $ ./24doty.sh 1 5 5 5 all 1 5 5 5 : method 3:20k 5 1 5 / - 5 * 1 / pq:( 5 - ( 1 / 5)) * 5 1 5 5 5 : method 4:20k 5 5 1 5 / - * 1 / pq: 5 * ( 5 - ( 1 / 5)) $ ./24doty.sh 6 9 9 10 all 6 9 9 10 : method 1:20k 9 6 / 10 * 9 + 1 / pq:(( 9 / 6) * 10) + 9 6 9 9 10 : method 1:20k 9 10 * 6 / 9 + 1 / pq:(( 9 * 10) / 6) + 9 6 9 9 10 : method 1:20k 10 9 * 6 / 9 + 1 / pq:(( 10 * 9) / 6) + 9 6 9 9 10 : method 3:20k 9 6 10 / / 9 + 1 / pq:( 9 / ( 6 / 10)) + 9 6 9 9 10 : method 3:20k 10 9 6 / * 9 + 1 / pq:( 10 * ( 9 / 6)) + 9 6 9 9 10 : method 4:20k 9 9 6 10 / / + 1 / pq: 9 + ( 9 / ( 6 / 10)) 6 9 9 10 : method 4:20k 9 10 9 6 / * + 1 / pq: 9 + ( 10 * ( 9 / 6)) 6 9 9 10 : method 5:20k 9 9 6 / 10 * + 1 / pq: 9 + (( 9 / 6) * 10) 6 9 9 10 : method 5:20k 9 9 10 * 6 / + 1 / pq: 9 + (( 9 * 10) / 6) 6 9 9 10 : method 5:20k 9 10 9 * 6 / + 1 / pq: 9 + (( 10 * 9) / 6) --//找到第1个 (( 9 / 6) * 10) + 9。 $ grep "method [345]" js24.txt | sort -t: -k2 3 5 10 10 : method 3:20k 10 10 5 / - 3 * 1 / pq:( 10 - ( 10 / 5)) * 3 4 5 5 8 : method 3:20k 4 5 5 / - 8 * 1 / pq:( 4 - ( 5 / 5)) * 8 4 8 9 9 : method 3:20k 4 9 9 / - 8 * 1 / pq:( 4 - ( 9 / 9)) * 8 1 5 5 5 : method 3:20k 5 1 5 / - 5 * 1 / pq:( 5 - ( 1 / 5)) * 5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 5 5 10 : method 3:20k 5 2 10 / - 5 * 1 / pq:( 5 - ( 2 / 10)) * 5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 6 6 6 : method 3:20k 5 6 6 / - 6 * 1 / pq:( 5 - ( 6 / 6)) * 6 5 6 7 7 : method 3:20k 5 7 7 / - 6 * 1 / pq:( 5 - ( 7 / 7)) * 6 4 7 10 10 : method 3:20k 7 10 10 / - 4 * 1 / pq:( 7 - ( 10 / 10)) * 4 4 5 5 7 : method 3:20k 7 5 5 / - 4 * 1 / pq:( 7 - ( 5 / 5)) * 4 4 7 7 7 : method 3:20k 7 7 7 / - 4 * 1 / pq:( 7 - ( 7 / 7)) * 4 4 7 9 9 : method 3:20k 7 9 9 / - 4 * 1 / pq:( 7 - ( 9 / 9)) * 4 3 9 10 10 : method 3:20k 9 10 10 / - 3 * 1 / pq:( 9 - ( 10 / 10)) * 3 3 3 3 9 : method 3:20k 9 3 3 / - 3 * 1 / pq:( 9 - ( 3 / 3)) * 3 3 7 7 9 : method 3:20k 9 7 7 / - 3 * 1 / pq:( 9 - ( 7 / 7)) * 3 1 3 4 6 : method 4:20k 6 1 3 4 / - / 1 / pq: 6 / ( 1 - ( 3 / 4)) 1 6 6 8 : method 4:20k 6 1 6 8 / - / 1 / pq: 6 / ( 1 - ( 6 / 8)) 1 4 5 6 : method 5:20k 6 5 4 / 1 - / 1 / pq: 6 / (( 5 / 4) - 1) --//大部分使用method 1,2都可以解决。method 5有1条,method 4有2条,而且解法都非常"特殊"。 --//method 3有14条,解法比较特殊的有2条。 $ grep "fail" js24.txt |wc     153     918    2390 --//无法计算得到24仅仅153种情况。 $ cut -d: -f4 js24dc1.txt |  grep -Po "[+\-*/]+" | paste - - - | sort | uniq -c | sort -nr      55 -       +       *      41 +       +       +      38 *       +       +      38 *       -       *      36 +       *       -      34 -       *       +      32 +       -       *      27 +       *       +      21 +       /       *      19 *       -       +      18 *       +       -      16 -       *       -      16 -       /       *      15 /       +       *      14 -       +       +      13 *       -       -      12 +       +       *      12 *       +       *      11 *       *       +       9 /       *       +       9 -       *       *       9 -       -       *       8 +       *       *       8 *       *       -       8 *       -       /       8 /       *       *       7 *       *       /       5 +       *       /       4 *       *       *       3 *       +       /       3 *       /       +       3 *       /       *       3 *       /       -       2 /       +       +       2 /       -       /       1 /       *       -       1 /       /       -       1 -       *       / --//源代码如下: $ cat 24dot.sh #! /bin/bash all=${5:-0} #echo $all tmpfile=$(mktemp) sqlplus -s -l / as sysdba  <<EOF >| ${tmpfile} set pagesize 0 set head off echo off verify off  feed off COLSEP ':' WITH x1         AS (SELECT 1 id, ' +' c FROM DUAL             UNION ALL             SELECT 8 id, ' -' FROM DUAL             UNION ALL             SELECT 1.2 id, ' *' FROM DUAL             UNION ALL             SELECT 16 id, ' /' FROM DUAL)     ,x2         AS (  SELECT decode(replace(x1.c||x2.c||x3.c,' ','') ,'-+*',-55 ,'+++',-41 ,'*++',-38 ,'*-*',-38 ,'+*-',-36 ,'-*+',-34 ,'+-*',-32 ,'+*+',-27 ,'+/*',-21 ,'*-+',-19 ,'*+-',-18 ,'-*-',-16 ,'-/*',-16 ,'/+*',-15 ,'-++',-14 ,'*--',-13 ,'++*',-12 ,'*+*',-12 ,'**+',-11 ,x1.id + x2.id + x3.id) idop                     ,x1.c p1                     ,x2.c p2                     ,x3.c p3                 FROM x1, x1 x2, x1 x3             ORDER BY 1 )     ,y1         AS (SELECT 1 id, to_char($1,'999') n FROM DUAL             UNION ALL             SELECT 2 id, to_char($2,'999') FROM DUAL             UNION ALL             SELECT 3 id, to_char($3,'999') FROM DUAL             UNION ALL             SELECT 4 id, to_char($4,'999') FROM DUAL)     ,y2         AS (  SELECT DISTINCT x1.n n1                              ,x2.n n2                              ,x3.n n3                              ,x4.n n4                 FROM y1 x1                     ,y1 x2                     ,y1 x3                     ,y1 x4                WHERE     x1.id <> x2.id                      AND x1.id <> x3.id                      AND x1.id <> x4.id                      AND x2.id <> x3.id                      AND x2.id <> x4.id                      AND x3.id <> x4.id             ORDER BY 1 ,2 ,3 ,4) --select txt,dc1,bc2 from ( SELECT 'method 1' txt, '20k '||n1||n2||p1||n3||p2||n4||p3 dc1,'(('||n1||p1||n2||')'||p2||n3||')'||p3||n4 bc2 FROM y2, x2 union all SELECT 'method 2' txt, '20k '||n1||n2||p1||n3||n4||p2||p3 dc1,'('||n1||p1||n2||')'||p3||'('||n3||p2||n4||')' bc2 FROM y2, x2 union all SELECT 'method 3' txt, '20k '||n1||n2||n3||p1||p2||n4||p3 dc1,'('||n1||p2||'('||n2||p1||n3||'))'||p3||n4 bc2 FROM y2, x2 union all SELECT 'method 4' txt, '20k '||n1||n2||n3||n4||p1||p2||p3 dc1, n1||p3||'('||n2||p2||'('||n3||p1||n4||'))' bc2 FROM y2, x2 union all SELECT 'method 5' txt, '20k '||n1||n2||n3||p1||n4||p2||p3 dc1, n1||p3||'(('||n2||p1||n3||')'||p2||n4||')' bc2 FROM y2, x2 --) where TO_NUMBER(XMLQUERY(replace(bc2,'/','div') RETURNING CONTENT))=24 --and rownum=1 ; quit EOF #/bin/cp ${tmpfile} e3.txt sed -i "s/ \{2,\}/ /g" ${tmpfile} #exit ## method 1: ((n1 p1 n2 ) p2 n3)  p3 n4 ## method 2: ( n1 p1 n2 ) p3 (n3  p2 n4) ## method 3: ( n1 p2 (n2  p1 n3)) p3 n4 ## method 4:   n1 p3 (n2  p2  (n3 p1 n4)) ## method 5:  n1  p3 ((n2 p1 n3) p2 n4) result='bad' while read line do     #echo "$line"     filed1=$(echo "$line"| cut -d":" -f1)     filed2=$(echo "$line"| cut -d":" -f2)     filed3=$(echo "$line"| cut -d":" -f3)     res=$(echo "$filed2 1 / pq" | dc 2>/dev/null)     #res=$(echo "scale=20 ; $filed3 /1" | bc  2>/dev/null)     if [ "${res}" = '24.00000000000000000000' ]     then         echo "$1 $2 $3 $4 : $line"         result='ok'         #return 1         if [ ${all} != 'all' ]         then             break         fi     fi done < ${tmpfile} if [ $result != 'ok' ] then    echo "$1 $2 $3 $4 : fail" fi /bin/rm  ${tmpfile}

相关推荐