ITPUB论坛-中国最专业的IT技术社区

 
 注册
热搜:
查看: 30521|回复: 53

[精华] 我也玩个游戏,我申请加精,求批准

[复制链接]
认证徽章
论坛徽章:
168
SQL数据库编程大师
日期:2016-01-13 10:30:43SQL极客
日期:2013-12-09 14:13:35SQL大赛参与纪念
日期:2013-12-06 14:03:45最佳人气徽章
日期:2015-03-19 09:44:03现任管理团队成员
日期:2015-08-26 02:10:00秀才
日期:2015-07-28 09:12:12举人
日期:2015-07-13 15:30:15进士
日期:2015-07-28 09:12:58探花
日期:2015-07-28 09:12:58榜眼
日期:2015-08-18 09:48:03
跳转到指定楼层
1#
发表于 2016-4-10 22:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Naldonado 于 2016-4-11 11:26 编辑

打开excel就可以玩的三只牛蛙的换位游戏,我真是闲的蛋疼,想用SQL破解,不过写的匆忙,已经不追求好看了。

我的代码如下,大家可以继续玩。
  1. WITH TMP00 AS(SELECT -1 SEED FROM DUAL UNION SELECT -2 FROM DUAL UNION SELECT 1 FROM DUAL UNION SELECT 2 FROM DUAL),
  2. TMP01 AS(
  3. SELECT 'F,F,F,_,G,G,G' STATUS FROM DUAL
  4. ),
  5. TMP02 AS(
  6. SELECT REPLACE(STATUS,',') STATUS,REGEXP_SUBSTR(T.STATUS,'[^,]+',1,LEVEL) SON,LEVEL ID,4 INS
  7.    FROM TMP01 T
  8.    CONNECT BY LEVEL<=REGEXP_COUNT(T.STATUS,',')+1
  9.    AND PRIOR T.STATUS=T.STATUS AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
  10. ),
  11. TMP03(SON,ID,LEV,INS,STATUS,PATH) AS(
  12. SELECT T2.SON,T2.ID,1 LEV,INS,STATUS,CAST(STATUS AS VARCHAR2(4000)) PATH  FROM TMP02 T2
  13. UNION ALL
  14. SELECT CASE WHEN T0.SEED=-1 AND T3.SON='F' AND T3.ID=T3.INS-1 THEN '_'
  15.             WHEN T0.SEED=-2 AND T3.SON='F' AND T3.ID=T3.INS-2 THEN '_'
  16.             WHEN T0.SEED=1 AND T3.SON='G' AND T3.ID=T3.INS+1 THEN '_'
  17.             WHEN T0.SEED=2 AND T3.SON='G' AND T3.ID=T3.INS+2 THEN '_'
  18.             WHEN T3.SON='_' AND T0.SEED>0 AND T3.INS+T0.SEED<=7 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G' THEN 'G'
  19.             WHEN T3.SON='_' AND T0.SEED<0 AND T3.INS+T0.SEED>=1 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F' THEN 'F'
  20.             ELSE T3.SON
  21.          END SON,
  22. T3.ID,T3.LEV+1,T3.INS+T0.SEED,
  23.    listagg(CASE WHEN T0.SEED=-1 AND T3.SON='F' AND T3.ID=T3.INS-1 THEN '_'
  24.             WHEN T0.SEED=-2 AND T3.SON='F' AND T3.ID=T3.INS-2 THEN '_'
  25.             WHEN T0.SEED=1 AND T3.SON='G' AND T3.ID=T3.INS+1 THEN '_'
  26.             WHEN T0.SEED=2 AND T3.SON='G' AND T3.ID=T3.INS+2 THEN '_'
  27.             WHEN T3.SON='_' AND T0.SEED>0 AND T3.INS+T0.SEED<=7 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G' THEN 'G'
  28.             WHEN T3.SON='_' AND T0.SEED<0 AND T3.INS+T0.SEED>=1 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F' THEN 'F'
  29.             ELSE T3.SON
  30.          END ) WITHIN GROUP(ORDER BY T3.ID)  over(partition by T3.LEV+1,T3.INS+T0.SEED,T0.SEED,t3.path),
  31.     T3.PATH||'-->'||listagg(CASE WHEN T0.SEED=-1 AND T3.SON='F' AND T3.ID=T3.INS-1 THEN '_'
  32.             WHEN T0.SEED=-2 AND T3.SON='F' AND T3.ID=T3.INS-2 THEN '_'
  33.             WHEN T0.SEED=1 AND T3.SON='G' AND T3.ID=T3.INS+1 THEN '_'
  34.             WHEN T0.SEED=2 AND T3.SON='G' AND T3.ID=T3.INS+2 THEN '_'
  35.             WHEN T3.SON='_' AND T0.SEED>0 AND T3.INS+T0.SEED<=7 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G' THEN 'G'
  36.             WHEN T3.SON='_' AND T0.SEED<0 AND T3.INS+T0.SEED>=1 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F' THEN 'F'
  37.             ELSE T3.SON
  38.          END ) WITHIN GROUP(ORDER BY T3.ID)  over(partition by T3.LEV+1,T3.INS+T0.SEED,T0.SEED,t3.path)
  39.   FROM TMP03 T3, TMP00 T0
  40.   WHERE T3.INS+T0.SEED>=1 AND T3.INS+T0.SEED<=7 AND ((T0.SEED>0 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G')
  41.    or (T0.SEED<0 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F'))
  42. )
  43. SELECT DISTINCT LEV-1 步数,path 走位 FROM TMP03 where status='GGG_FFF'
复制代码

QQ图片20160410225512.png (155.79 KB, 下载次数: 1044)

QQ图片20160410225512.png

3只青蛙换位.xls

316 KB, 下载次数: 375

认证徽章
论坛徽章:
168
SQL数据库编程大师
日期:2016-01-13 10:30:43SQL极客
日期:2013-12-09 14:13:35SQL大赛参与纪念
日期:2013-12-06 14:03:45最佳人气徽章
日期:2015-03-19 09:44:03现任管理团队成员
日期:2015-08-26 02:10:00秀才
日期:2015-07-28 09:12:12举人
日期:2015-07-13 15:30:15进士
日期:2015-07-28 09:12:58探花
日期:2015-07-28 09:12:58榜眼
日期:2015-08-18 09:48:03
2#
发表于 2016-4-10 22:57 | 只看该作者
本帖最后由 Naldonado 于 2016-4-11 11:26 编辑

我设左边的三只牛蛙为GGG,右边的三只为FFF

使用道具 举报

回复
论坛徽章:
480
榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09
3#
发表于 2016-4-11 07:38 | 只看该作者
好吧,希望你精益求精,再多搞几种解法。

去年有个题目和这个类似:
/forum.php?m ... 70&pid=23095286

使用道具 举报

回复
论坛徽章:
394
阿斯顿马丁
日期:2014-01-03 13:53:522014年世界杯参赛球队:喀麦隆
日期:2014-07-11 12:10:53马上有对象
日期:2014-04-09 16:19:542014年世界杯参赛球队: 洪都拉斯
日期:2014-06-25 08:25:55itpub13周年纪念徽章
日期:2014-09-28 10:55:55itpub13周年纪念徽章
日期:2014-10-01 15:27:22itpub13周年纪念徽章
日期:2014-10-09 12:04:18马上有钱
日期:2014-10-14 21:37:37马上有钱
日期:2015-01-22 00:39:13喜羊羊
日期:2015-02-20 22:26:07
4#
发表于 2016-4-11 08:15 | 只看该作者
lz用code在手机上看不到代码,重新贴一份
WITH TMP00 AS(SELECT -1 SEED FROM DUAL UNION SELECT -2 FROM DUAL UNION SELECT 1 FROM DUAL UNION SELECT 2 FROM DUAL),
TMP01 AS(
SELECT 'F,F,F,_,G,G,G' STATUS FROM DUAL
),
TMP02 AS(
SELECT REPLACE(STATUS,',') STATUS,REGEXP_SUBSTR(T.STATUS,'[^,]+',1,LEVEL) SON,LEVEL ID,4 INS
   FROM TMP01 T
   CONNECT BY LEVEL<=REGEXP_COUNT(T.STATUS,',')+1
   AND PRIOR T.STATUS=T.STATUS AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
),
TMP03(SON,ID,LEV,INS,STATUS,PATH) AS(
SELECT T2.SON,T2.ID,1 LEV,INS,STATUS,CAST(STATUS AS VARCHAR2(4000)) PATH  FROM TMP02 T2
UNION ALL
SELECT CASE WHEN T0.SEED=-1 AND T3.SON='F' AND T3.ID=T3.INS-1 THEN '_'
            WHEN T0.SEED=-2 AND T3.SON='F' AND T3.ID=T3.INS-2 THEN '_'
            WHEN T0.SEED=1 AND T3.SON='G' AND T3.ID=T3.INS+1 THEN '_'
            WHEN T0.SEED=2 AND T3.SON='G' AND T3.ID=T3.INS+2 THEN '_'
            WHEN T3.SON='_' AND T0.SEED>0 AND T3.INS+T0.SEED<=7 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G' THEN 'G'
            WHEN T3.SON='_' AND T0.SEED<0 AND T3.INS+T0.SEED>=1 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F' THEN 'F'
            ELSE T3.SON
         END SON,
T3.ID,T3.LEV+1,T3.INS+T0.SEED,
   listagg(CASE WHEN T0.SEED=-1 AND T3.SON='F' AND T3.ID=T3.INS-1 THEN '_'
            WHEN T0.SEED=-2 AND T3.SON='F' AND T3.ID=T3.INS-2 THEN '_'
            WHEN T0.SEED=1 AND T3.SON='G' AND T3.ID=T3.INS+1 THEN '_'
            WHEN T0.SEED=2 AND T3.SON='G' AND T3.ID=T3.INS+2 THEN '_'
            WHEN T3.SON='_' AND T0.SEED>0 AND T3.INS+T0.SEED<=7 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G' THEN 'G'
            WHEN T3.SON='_' AND T0.SEED<0 AND T3.INS+T0.SEED>=1 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F' THEN 'F'
            ELSE T3.SON
         END ) WITHIN GROUP(ORDER BY T3.ID)  over(partition by T3.LEV+1,T3.INS+T0.SEED,T0.SEED,t3.path),
    T3.PATH||'-->'||listagg(CASE WHEN T0.SEED=-1 AND T3.SON='F' AND T3.ID=T3.INS-1 THEN '_'
            WHEN T0.SEED=-2 AND T3.SON='F' AND T3.ID=T3.INS-2 THEN '_'
            WHEN T0.SEED=1 AND T3.SON='G' AND T3.ID=T3.INS+1 THEN '_'
            WHEN T0.SEED=2 AND T3.SON='G' AND T3.ID=T3.INS+2 THEN '_'
            WHEN T3.SON='_' AND T0.SEED>0 AND T3.INS+T0.SEED<=7 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G' THEN 'G'
            WHEN T3.SON='_' AND T0.SEED<0 AND T3.INS+T0.SEED>=1 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F' THEN 'F'
            ELSE T3.SON
         END ) WITHIN GROUP(ORDER BY T3.ID)  over(partition by T3.LEV+1,T3.INS+T0.SEED,T0.SEED,t3.path)
  FROM TMP03 T3, TMP00 T0
  WHERE T3.INS+T0.SEED>=1 AND T3.INS+T0.SEED<=7 AND ((T0.SEED>0 AND SUBSTR(T3.STATUS,T3.INS+T0.SEED,1)='G')
   or (T0.SEED<0 AND SUBSTR(T3.STATUS,INS+T0.SEED,1)='F'))
)
SELECT DISTINCT LEV-1 步数,path 走位 FROM TMP03 where status='GGG_FFF'

使用道具 举报

回复
认证徽章
论坛徽章:
168
SQL数据库编程大师
日期:2016-01-13 10:30:43SQL极客
日期:2013-12-09 14:13:35SQL大赛参与纪念
日期:2013-12-06 14:03:45最佳人气徽章
日期:2015-03-19 09:44:03现任管理团队成员
日期:2015-08-26 02:10:00秀才
日期:2015-07-28 09:12:12举人
日期:2015-07-13 15:30:15进士
日期:2015-07-28 09:12:58探花
日期:2015-07-28 09:12:58榜眼
日期:2015-08-18 09:48:03
5#
发表于 2016-4-11 08:17 | 只看该作者
〇〇 发表于 2016-4-11 08:15
lz用code在手机上看不到代码,重新贴一份
WITH TMP00 AS(SELECT -1 SEED FROM DUAL UNION SELECT -2 FROM  ...

对哦,为毛手机党看不到代码?这是啥原因呢?


不过这种sql,能用手机读出来,也是神人一个!

使用道具 举报

回复
论坛徽章:
78
生肖徽章2007版:牛
日期:2012-08-02 22:43:00紫蛋头
日期:2012-12-08 09:43:38鲜花蛋
日期:2012-11-17 12:02:07鲜花蛋
日期:2013-02-05 21:53:34复活蛋
日期:2012-11-17 12:02:07SQL极客
日期:2013-12-09 14:13:35SQL数据库编程大师
日期:2013-12-06 13:59:43SQL大赛参与纪念
日期:2013-12-06 14:10:50ITPUB季度 技术新星
日期:2012-11-27 10:16:10最佳人气徽章
日期:2013-03-19 17:24:25
6#
发表于 2016-4-11 09:31 | 只看该作者
40行?哥只看了一眼你的代码,觉得20行够了。但是别让哥写。

使用道具 举报

回复
认证徽章
论坛徽章:
168
SQL数据库编程大师
日期:2016-01-13 10:30:43SQL极客
日期:2013-12-09 14:13:35SQL大赛参与纪念
日期:2013-12-06 14:03:45最佳人气徽章
日期:2015-03-19 09:44:03现任管理团队成员
日期:2015-08-26 02:10:00秀才
日期:2015-07-28 09:12:12举人
日期:2015-07-13 15:30:15进士
日期:2015-07-28 09:12:58探花
日期:2015-07-28 09:12:58榜眼
日期:2015-08-18 09:48:03
7#
发表于 2016-4-11 09:38 | 只看该作者
udfrog 发表于 2016-04-11 09:3140行?哥只看了一眼你的代码,觉得20行够了。但是别让哥写。
对啊,很多可以简化,我这是1.0,昨天写出来就不想搞了。

再说我不卖个破腚给你,你能过来瞅一眼?&#128516;

使用道具 举报

回复
论坛徽章:
740
红钻
日期:2014-12-16 17:51:41布鲁克林篮网
日期:2016-09-23 08:17:18达拉斯小牛
日期:2016-09-23 08:18:15季节之章:冬
日期:2015-07-31 17:16:14ITPUB季度 技术新星
日期:2014-07-17 14:37:00华盛顿奇才
日期:2016-09-23 08:18:15季节之章:夏
日期:2015-07-31 17:16:29绿钻
日期:2015-08-15 13:20:11最佳人气徽章
日期:2015-03-19 09:44:03洛杉矶湖人
日期:2016-09-23 08:18:15
8#
发表于 2016-4-11 09:48 | 只看该作者
小伙有研究精神,顶一把。。。

使用道具 举报

回复
论坛徽章:
480
榜眼
日期:2015-09-09 10:34:21秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12秀才
日期:2015-11-23 10:03:12状元
日期:2015-11-23 10:04:09举人
日期:2015-11-23 10:04:09
9#
发表于 2016-4-11 09:59 | 只看该作者
写了个CONNECT BY的,但是得加上 LEVEL的限制,要不会出来无数个答案:

WITH f(frogs) AS (
SELECT frogs FROM (SELECT '0' frogs FROM DUAL UNION ALL SELECT '1' FROM DUAL UNION ALL SELECT '2' FROM DUAL)
UNION ALL
SELECT f.frogs||c.frogs
  FROM f,(SELECT '0' frogs FROM DUAL UNION ALL SELECT '1' FROM DUAL UNION ALL SELECT '2' FROM DUAL) c
WHERE LENGTH(f.frogs)<7
       AND (c.frogs='0' AND INSTR(f.frogs,'0')=0
            OR c.frogs<>'0' AND REGEXP_COUNT(f.frogs,c.frogs)<3
           )
)
,f2 AS (
SELECT frogs FROM f WHERE length(frogs)=7
)
,t AS (
SELECT f2.frogs,f3.frogs frogs2
  FROM f2,f2 f3
WHERE  INSTR(f3.frogs,'0')<>INSTR(f2.frogs,'0') AND TRIM('0' FROM TO_CHAR(GREATEST(f3.frogs,f2.frogs)-LEAST(f3.frogs,f2.frogs))) IN ('9','18','99','198')
UNION ALL
SELECT NULL,'1110222' FROM DUAL
)
SELECT SYS_CONNECT_BY_PATH(frogs2,',')
  FROM t
WHERE frogs2='2220111'
START WITH frogs IS NULL
CONNECT BY NOCYCLE PRIOR frogs2=frogs AND frogs<>'2220111' AND LEVEL<=16;


SYS_CONNECT_BY_PATH(FROGS2,',')
-----------------------------------------------------------------------------------------------------------------------------------
,1110222,1101222,1121022,1121202,1120212,1021212,0121212,2101212,2121012,2121210,2121201,2120211,2021211,2201211,2221011,2220111
,1110222,1112022,1102122,1012122,1210122,1212102,1212120,1212021,1202121,0212121,2012121,2210121,2212101,2212011,2202111,2220111

如果改用递归和COUNT() OVER()应该可以在找到第一个答案就停止。

1人打赏

使用道具 举报

回复
论坛徽章:
29
秀才
日期:2015-11-23 09:48:22秀才
日期:2015-11-11 09:58:34秀才
日期:2015-11-12 17:43:40秀才
日期:2015-09-21 11:16:42秀才
日期:2015-12-14 14:51:16秀才
日期:2015-12-14 14:56:09秀才
日期:2015-10-26 09:24:12秀才
日期:2015-12-14 14:47:54秀才
日期:2015-11-11 10:22:49巨蟹座
日期:2015-09-08 08:55:26
10#
发表于 2016-4-11 10:43 | 只看该作者
好吧,我承认我只有看热闹的份,门道就让你们几个大神雕琢吧

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 |
  | | |
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表