12
返回列表 发新帖
楼主: newkid

这个题目可以尝试用SQL来做

[复制链接]
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
11#
 楼主| 发表于 2023-5-12 21:22 | 只看该作者
〇〇 发表于 2023-5-12 13:31
oracle bit_and能处理2^31以上的数?duckdb不行 D select bit_and(1

Oracle bitand 能算number型,最多到一百多个二进制位。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
12#
 楼主| 发表于 2023-5-12 21:29 | 只看该作者

坐标说明:
左下角:(0,0)
右上角: (12,2)

A点:(3,1)
F点:(12,2)

线段表示法:线的编号:小坐标:大坐标
垂直线编号: X0, X1, X2, ... X12
水平线编号:Y0,Y1,Y2
例子:
X3:1:2 表示(3,1)到(3,2)
路径是由上述线段拼起来的,用逗号隔开,相邻的要垂直。

with d as ( ------ 构造所有点
select x,y
from (select level-1 x from dual connect by level<=13)
     ,(select level-1 y from dual connect by level<=3)
)
,T(last_x,last_y,last_direction,path,len) as (
select 3,1,'*',cast('' as varchar2(400)),0 from dual
union all
select d.x,d.y
      ,case when t.last_x=d.x then 'x' else 'y' end
      ,t.path||','||j.line||':'||j.c1||':'||j.c2
      ,t.len+power(2,abs(t.last_x-d.x+t.last_y-d.y))
  from t join d
          on ((t.last_x=d.x and t.last_y<>d.y and t.last_direction<>'x')  ---- 下个箭头方向要垂直
              or
              (t.last_y=d.y and t.last_x<>d.x and t.last_direction<>'y')
              )
       CROSS JOIN LATERAL  --------- 这个LATERAL的目的是为了简化表达式,后面直接引用列名 line:c1:c2 拼到路径里面
              (SELECT case when t.last_x=d.x then 'x'||d.x else 'y'||d.y end as line
                     ,case when t.last_x=d.x then least(t.last_y,d.y) else least(t.last_x,d.x) end as c1
                     ,case when t.last_x=d.x then greatest(t.last_y,d.y) else greatest(t.last_x,d.x) end as c2
                 FROM dual
               ) j
       LEFT OUTER JOIN LATERAL --------- 这个LATERAL的目的是为了打散路径,以检查新加入的路径是否和旧路径有重叠
                (select regexp_substr(s,'[^:]+',1,1) as line
                      ,regexp_substr(s,'[^:]+',1,2) as c1
                      ,regexp_substr(s,'[^:]+',1,3) as c2
                  from (
                        SELECT regexp_substr(t.path,'[^,]+',1,level) s
                          FROM dual
                         connect by level<=regexp_count(t.path,',')+1
                       )
                ) p
             on  j.line=p.line ---- 外连接条件:同一条线且坐标有交叉
                 and  (p.c1>j.c1 and p.c1<j.c2 or p.c2>j.c1 and p.c2<j.c2
                       or j.c1>p.c1 and j.c1<p.c2 or j.c2>p.c1 and j.c2<p.c2
                      )   ----- 四种交叠情形
where  (last_x<>12 or last_y<>2)
        and bitand(t.len,power(2,abs(t.last_x-d.x+t.last_y-d.y)))=0 ---- 要求所有长度都不一样
        and p.line is null ---- 外连接为空,则不存在交叠
)
select count(*) from t where last_x=12 and last_y=2;

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
13#
发表于 2023-5-13 07:15 来自手机 | 只看该作者
我不会正则表达式,也不会LATERAL

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
14#
发表于 2023-5-13 10:57 来自手机 | 只看该作者
原来要把第一个参数强制转换
D select bit_and(1::hugeint<<126);
┌────────────────────────────────────────┐
│  bit_and((CAST(1 AS HUGEINT) << 126))  │
│                 int128                 │
├────────────────────────────────────────┤
│ 85070591730234615865843651857942052864 │
└────────────────────────────────────────┘

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
15#
发表于 2023-5-15 08:42 | 只看该作者
强制转换的版本,在postgresql和duckdb都可以
with recursive points(n,x,y)
as (select row_number()over(order by x,y),x,y
from generate_series(1,13)t(x),
generate_series(1,3)t2(y)
),
lines(m,psn,pen,len,dir,passmap)as
(select row_number()over(),ps.n,pe.n,abs(ps.x-pe.x)+abs(ps.y-pe.y),case when ps.x-pe.x=0 then 0 else 1 end,
case when ps.x=pe.x then (select sum(1::bigint<<t.n::int) from points t
where t.n between least(ps.n,pe.n) and greatest(ps.n,pe.n)and t.n <>pe.n and (t.n-ps.n)%13=0)
when ps.y=pe.y then (select sum(1::bigint<<t.n::int) from points t
where t.n between least(ps.n,pe.n) and greatest(ps.n,pe.n)and t.n <>pe.n)
end
from points ps,points pe
where (ps.x=pe.x and ps.y<>pe.y) or (ps.x<>pe.x and ps.y=pe.y)),
paths(lv,ldir,pen,pathmap,lenmap,path) as
(
select 1,lines.dir,pen,(1::bigint<<psn::int),(1<<len),psn::varchar from lines where psn=(select n from points where x=4 and y=2)
union all
select lv+1,lines.dir,lines.pen,pathmap+(1::bigint<<lines.psn::int),
lenmap+(1<<lines.len),
path||','|| lines.psn::varchar
from paths,lines
where lines.psn=paths.pen
and lines.dir<>paths.ldir
and (pathmap&1::bigint<<lines.psn::int)=0
and (lenmap&(1<<lines.len))=0
and paths.pen<>(select n from points where x=13 and y=1)
)
select * from paths where paths.pen=(select n from points where x=13 and y=1)
;

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
16#
 楼主| 发表于 2023-5-15 09:16 | 只看该作者
〇〇 发表于 2023-5-13 07:15
我不会正则表达式,也不会LATERAL

LATEREL很好理解,它原理和标量子查询一样,都是针对主查询的结果的每一行执行一次子查询。标量子查询有限制最多只能返回一行一列,LATERAL则无此限制,可以返回多行多列。语法上标量子查询要写在SELECT的列表中,LATERAL是写在JOIN的地方。
规则表达式我就只熟悉常用的几个,其他的要用时就上网搜索一下。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
17#
发表于 2023-5-16 10:28 | 只看该作者
newkid 发表于 2023-5-15 09:16
LATEREL很好理解,它原理和标量子查询一样,都是针对主查询的结果的每一行执行一次子查询。标量子查询有限 ...

谢谢。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
18#
发表于 2023-5-16 10:44 | 只看该作者
laterel 类似下面的?
D with t as(select * from range(1,5)t(i)),t1 as(select 1 a, 3 b union all select 2 a,4 b)select t1.*,(select t.* from t where t.i between a and b)from
t1;
┌───────┬───────┬─────────────────────────────────────────────────┐
│   a   │   b   │ (SELECT t.* FROM t WHERE (t.i BETWEEN a AND b)) │
│ int32 │ int32 │                      int64                      │
├───────┼───────┼─────────────────────────────────────────────────┤
│     2 │     4 │                                               4 │
│     1 │     3 │                                               3 │
└───────┴───────┴─────────────────────────────────────────────────┘
D with t as(select * from range(1,5)t(i)),t1 as(select 1 a, 3 b union all select 2 a,4 b)select t1.* , t.* from t join t1 on t.i between a and b;
┌───────┬───────┬───────┐
│   a   │   b   │   i   │
│ int32 │ int32 │ int64 │
├───────┼───────┼───────┤
│     1 │     3 │     1 │
│     1 │     3 │     2 │
│     1 │     3 │     3 │
│     2 │     4 │     2 │
│     2 │     4 │     3 │
│     2 │     4 │     4 │
└───────┴───────┴───────┘

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
19#
发表于 2023-5-16 16:00 | 只看该作者

使用道具 举报

回复

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

本版积分规则 发表回复

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