楼主: newkid

[每日一题] 2022 PUZZLEUP

[复制链接]
论坛徽章:
0
211#
发表于 2023-3-4 14:06 | 只看该作者
Among many hidden constraints, Nx>=2 (x in {A, B, .......}) on each side is the most important one (its logic is obvious and can be use to estimate the possible miminum, eg, must have 2 Axx, Axx on each side).

I add this constraint and one more, that is, on each side, Na>=Nx where x<>a.  The purpose is to elimiate invalid OR equivilent combinations during each recusive step for tmp part in the brutal force process.

Although helpful but no way to reach to the practical point (小打小闹没有太大的帮助) for 12 people (I think using a specific pattern is able to solve the problem for 12  people within acceptable timing, my next effort).  Ofcurse procesural approach is more efficient particularly when only one valid combination needing to be returned (similay to sudoku).

Below are some results for N = 7/8

G=6 N=7 (minimum)

GRPS1
--------------------------------------------------------------------------------
GRPS2
--------------------------------------------------------------------------------
GPAIRS1
--------------------------------------------------------------------------------
GPAIRS2
--------------------------------------------------------------------------------
ABC|ABE|ADF|AFG|BDG|CEF
ABD|ABG|ACF|AEF|BCE|DFG
AB|AB|AC|AD|AE|AF|AF|AG|BC|BD|BE|BG|CE|CF|DF|DG|EF|FG
AB|AB|AC|AD|AE|AF|AF|AG|BC|BD|BE|BG|CE|CF|DF|DG|EF|FG


Elapsed: 00:00:11.53

--==================================

G=6 N=8 (minimum)


GRPS1
--------------------------------------------------------------------------------
GRPS2
--------------------------------------------------------------------------------
GPAIRS1
--------------------------------------------------------------------------------
GPAIRS2
--------------------------------------------------------------------------------
ABC|ADE|AFG|BDH|CFH|EGH
ABD|ACF|AEG|BCH|DEH|FGH
AB|AC|AD|AE|AF|AG|BC|BD|BH|CF|CH|DE|DH|EG|EH|FG|FH|GH
AB|AC|AD|AE|AF|AG|BC|BD|BH|CF|CH|DE|DH|EG|EH|FG|FH|GH


Elapsed: 00:10:03.07


--===========================================================
the sql has been revised to some extent.  the two hidden constraints applied in the where clause in tmp recursive part.
--==============================================================

with t0 as (select 4 G, 6 N from dual
), tA as (select least((3*G-2*N)+2, G) na_max from t0
--), t1 as (select floor(3*G/N)*(1+N)*N/2+decode(mod(3*G, N), 0, 0, (1+mod(3*G, N))*mod(3*G, N)/2) gvcut from t0
), t as (select rownum cid, chr(rownum+64) c, sum(power(2,rownum)+power(2,rownum+N)) over (order by rownum) cvrunsum from t0 connect by rownum<=N
), tt as (select sum(cid) cv, sum(power(2, cid)) cv1 from t
), tt0 as (select cv1*(1+power(2, N)) cbit2N from tt, t0
), pair as (select a.c c1, b.c c2, row_number() over (order by a.c, b.c) pid from t a, t b where a.c<b.c
), ttt as (select sum(power(2,pid)) pv1 from pair
), grp as (select c1, c2, t.c c3, row_number() over (order by c1, c2, c) gid from pair, t where c2<t.c
), grp_pair as (
--
select g.c1, g.c2, g.c3, t1.cid cid1, t2.cid cid2, t3.cid cid3, g.gid, p1.pid pid1, p2.pid pid2, p3.pid pid3,
power(2,t1.cid)+power(2,t2.cid)+power(2,t3.cid) gcv
, t1.cid-1 pre_cid1, nvl(tr.cvrunsum,0) cvrunsum
from grp g, pair p1, pair p2, pair p3, t t1, t t2, t t3, t tr
where p1.c1=g.c1 and p1.c2=g.c2 and p2.c1=g.c1 and p2.c2=g.c3 and p3.c1=g.c2 and p3.c2=g.c3
and t1.c=g.c1 and t2.c=g.c2 and t3.c=g.c3
AND tr.cid(+)=t1.cid-1
--
), tmp (rn, na, cur_gid, cv, grps, gpairs, gids, gval, cv1, pv1, pv_sum, cbit2N) as (
select 1, 1, gid, cid1+cid2+cid3, c1||c2||c3, c1||c2||'|'||c1||c3||'|'||c2||c3, to_char(gid), power(2,gid),
cv1-bitand(cv1, power(2,cid1)+power(2,cid2)+power(2,cid3)),
pv1-bitand(pv1, power(2,pid1)+power(2,pid2)+power(2,pid3)),
power(2,pid1)+power(2,pid2)+power(2,pid3) pv_sum,
cbit2N - bitand(cbit2N, gcv)
from grp_pair, tt, ttt, tt0
where c1||c2||c3 in ('ABC', 'ABD')
union all
select a.rn+1, decode(cid1, 1, na+1, na), b.gid, cv+cid1+cid2+cid3,
grps||'|'||c1||c2||c3, gpairs||'|'||c1||c2||'|'||c1||c3||'|'||c2||c3,
gids||'|'||b.gid, gval+power(2,b.gid),
cv1-bitand(cv1, power(2,cid1)+power(2,cid2)+power(2,cid3)),
pv1-bitand(pv1, power(2,pid1)+power(2,pid2)+power(2,pid3)),
power(2,pid1)+power(2,pid2)+power(2,pid3)+pv_sum,
--
cbit2N - bitand(cbit2N, gcv) - bitand(cbit2N, (gcv-bitand(cbit2N, gcv))*power(2,N))
--
from tmp a, grp_pair b, t0, ta c   --, t1
where a.cur_gid<b.gid and a.rn<G   --and (cv < t1.gvcut)
--
AND bitand(a.cbit2N, b.cvrunsum)=0
AND
(
(cid1 = 1 and a.na < c.na_max) OR (cid1 > 1 and instr(grps, c1, 1, a.na)=0 and instr(grps, c2, 1, a.na)=0 and instr(grps, c3, 1, a.na)=0)
)
--
), results as (
select a.grps grps1, b.grps grps2, a.gpairs gpairs1, b.gpairs gpairs2
from tmp a, tmp b, t0
where a.pv_sum=b.pv_sum and bitand(a.gval, b.gval)=0
and a.rn=G and a.cv1=0 and a.cbit2N=0
and b.rn=G and b.cv1=0 and b.cbit2N=0
), tmp2 as (
select b.i, substr(gpairs1, 1+3*(i-1), 2) pair1, substr(gpairs2, 1+3*(i-1), 2) pair2, a.*
from results a, (select rownum i from t0 connect by rownum<=G*3) b
), results2 as (
select grps1, grps2,
listagg(pair1, '|') within group (order by pair1) gpairs1,
listagg(pair2, '|') within group (order by pair2) gpairs2
from tmp2 group by grps1, grps2
)
--select grps1, grps2, gpairs1, gpairs2 from results
select grps1, grps2, gpairs1, gpairs2 from results2 where gpairs1=gpairs2 and rownum=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
212#
 楼主| 发表于 2023-3-7 05:23 | 只看该作者
如果还想继续玩暴力穷举算法,看看能否找出方法来消除一些拓扑等价的答案,否则已经是到头了。
我有点不明白你写法中G=6起什么作用?是六人一组吗?

使用道具 举报

回复
论坛徽章:
0
213#
发表于 2023-3-16 09:49 | 只看该作者
本帖最后由 jihuyao 于 2023-3-16 09:55 编辑
newkid 发表于 2023-3-7 05:23
如果还想继续玩暴力穷举算法,看看能否找出方法来消除一些拓扑等价的答案,否则已经是到头了。我有点不明白 ...

2G is the total groups for given people N.  G is the group for each side.  Indeed, brutal force can not go far partitcularly for this problem.  

With the hiddwn constraint, Nx>=2 and plus previous approaches, it is easy to tell the the minimum for some of the problems.  For example, N=6 needs at least 12 (2A to 2F) to fill 4 groups (3*4=12) on each side, and N=12 needs at least 24 (2A to 2L) to fill 8 groups (3*8=24).  G=4 and N=6 has been easily obtained (so proved), and G=8 and N=12 has also easily obtained (so proved).

But now focus on N=9, which needs at least 18 (2A to 2I) to fill 6 groups (3*6=18) on each side (one can run G=6 and N=9).  Is it possible?  NO!  Why?  Pure logical analysis can be used for small G and N.  in some specific cases, it is also useful.

For G=6 and N=9 (2A to 2I).  There must be exact 2 groups starting with A in each sides, say AX1X2, AX3X4 on side 1 and AX1X3, AX2X4 on side 2 (easy to prove using X1/X2/X3 find no valid combinations).  And there must be X1X2 and X3X4 in side 2 and also X1X3 and X2X4 in side 1.  To make all valid groups, there must be X5 added to all above pairs, that is, X1X2X5 and X3X4X5 in side 2 and also X1X3X5 and X2X4X5 in side 1 (skip logic process here, simply constrainted by Nxixj(side 1)=Nxixj(side2)).  This constructs the fundation for G=4 and N=6.  But for G=6 and N=9, since 2A and 2X1|2X2|2X3|2X4|2X5 have been already used to fill 4 groups.  It leaves, say,  only 2G2H2I to fill the remaining 2 groups, which we know is impossible!  So it provs G=6 and N=9 is impossible.  Here coming the minimum for N=9 which is 2*7=14 because it has been easily obtained in previous approach.  Similar case for large N is also true (so it saves the brutal force process in case no easy way to prove a minimum for large N).

Similar or more comlicated logical analysis might be used to prove G=5 and N=7 is impossible (brutal force proves G=6 and N=7/8 are valid and therefore is true minimum, clearly for N=8, G=5 is invalid because 3*5=15<16=2*8).

In short, 3*G>=2N is essential condition but not sufficient.  In addition of pure logical analysis, other easy approaches are available for many specific cases.

Without a sinle perfect approach I will give two more ways in following posts just for fun (or maybe helpeful for someone wanting further exploration).     

使用道具 举报

回复
论坛徽章:
0
214#
发表于 2023-3-19 10:38 | 只看该作者
jihuyao 发表于 2023-3-16 09:49
2G is the total groups for given people N.  G is the group for each side.  Indeed, brutal force can  ...

The following is like lottery ticket.  If only buying one, one still has chance to win.  If buying more, one has better chance to win.  Indeed, luck is better than effort sometimes.  
Besides adjusting rownum(s), the following can also be variable, pattern (calculated from a simple formula) and pairs (all pairs can not used twice).   Both are currently fixred in the sql used below.

Have fun!



====================================================================================

SQL> /
Enter value for g: 8
Enter value for n: 12
Enter value for rowcut1: 1
Enter value for rowcut2: 1
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 8 G, 12 N, 1 RowCut1, 1 RowCut2 from dual

GRPS1
--------------------------------------------------------------------------------
GRPS2
--------------------------------------------------------------------------------
|ABC|ADE|BDF|CEF|GHI|GJK|HJL|IKL
|ABD|ACE|BCF|DEF|GHJ|GIK|HIL|JKL


Elapsed: 00:00:00.04
SQL>
SQL> /
Enter value for g: 6
Enter value for n: 7
Enter value for rowcut1: 1
Enter value for rowcut2: 1
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 6 G, 7 N, 1 RowCut1, 1 RowCut2 from dual

no rows selected

Elapsed: 00:00:00.04
SQL> /
Enter value for g: 6
Enter value for n: 7
Enter value for rowcut1: 10
Enter value for rowcut2: 10
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 6 G, 7 N, 10 RowCut1, 10 RowCut2 from dual

GRPS1
--------------------------------------------------------------------------------
GRPS2
--------------------------------------------------------------------------------
|ABG|ACE|ADF|BCF|BDE|CDG
|ABE|ACF|ADG|BCG|BDF|CDE


Elapsed: 00:00:00.06
SQL>
SQL> /
Enter value for g: 6
Enter value for n: 8
Enter value for rowcut1: 10
Enter value for rowcut2: 10
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 6 G, 8 N, 10 RowCut1, 10 RowCut2 from dual

no rows selected

Elapsed: 00:00:00.04
SQL> /
Enter value for g: 6
Enter value for n: 8
Enter value for rowcut1: 500
Enter value for rowcut2: 500
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 6 G, 8 N, 500 RowCut1, 500 RowCut2 from dual

no rows selected

Elapsed: 00:00:00.20
SQL> /
Enter value for g: 6
Enter value for n: 8
Enter value for rowcut1: 5000
Enter value for rowcut2: 5000
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 6 G, 8 N, 5000 RowCut1, 5000 RowCut2 from dual

GRPS1
--------------------------------------------------------------------------------
GRPS2
--------------------------------------------------------------------------------
|ACH|ADG|AEF|BCF|BDH|BEG
|ACF|ADH|AEG|BCH|BDG|BEF


Elapsed: 00:00:01.76


SQL> /
Enter value for g: 4
Enter value for n: 6
Enter value for rowcut1: 1
Enter value for rowcut2: 1
old   1: with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
new   1: with t0 as (select 4 G, 6 N, 1 RowCut1, 1 RowCut2 from dual

GRPS1
--------------------------------------------------------------------------------
GRPS2
--------------------------------------------------------------------------------
|ABC|ADE|BDF|CEF
|ABD|ACE|BCF|DEF


Elapsed: 00:00:00.05



==================================================================

with t0 as (select &G G, &N N, &RowCut1 RowCut1, &RowCut2 RowCut2 from dual
), t as (select floor(3*G/N) nx, 3*G-floor(3*G/N)*N m from t0
), t1 as (select rownum cid, chr(rownum+64) c, case when rownum<=m then 1+nx else nx end nx from t0, t connect by rownum<=N
), t2 as (select listagg(c) within group (order by c) cs from t1
), t3 as (select a.c||b.c pair, a.c c1, b.c c2 from t1 a, t1 b where a.c<b.c
), t4 as (select listagg(pair, '|') within group (order by pair) pairs from t3
), t5 as (
select a.c c1, b.c c2, c.c c3, a.nx nx1, b.nx nx2, c.nx nx3,
a.c||b.c p1, a.c||c.c p2, b.c||c.c p3, a.c||b.c||c.c grp
from t1 a, t1 b, t1 c where a.c<b.c and b.c<c.c
), t6 as (select listagg(grp, '|') within group (order by grp) grps from t5
), t7 as (
select a.pair p1, b.pair p2, a.c2||b.c2 p3, a.c1 c1, a.c2 c2, b.c2 c3
from t3 a, t3 b where a.c1=b.c1 and a.c2<b.c2 order by p1, p2
), tmp (rn, cs, pairs, pairs1, grps1, cur_grp) as (
select 0, cs, pairs, ' ', ' ', ' ' from t2, t4
union all
select a.rn+1, replace(replace(replace(a.cs, b.c1), b.c2), b.c3), replace(replace(replace(pairs, p1), p2), p3),
a.pairs1||'|'||p1||'|'||p2||'|'||p3, a.grps1||'|'||b.grp, b.grp
from tmp a, t5 b, t0
where a.rn<G and a.cur_grp<b.grp
and instr(a.grps1, b.c1, 1, b.nx1)=0 and instr(a.grps1, b.c2, 1, b.nx2)=0 and instr(a.grps1, b.c3, 1, b.nx3)=0
and instr(a.pairs, p1)>0 and instr(a.pairs, p2)>0 and instr(a.pairs, p3)>0
and rownum<= t0.RowCut1
), tmp2 (rn, cs, pairs1, grps1, grps2, cur_grp) as (
select 0, t2.cs, a.pairs1, a.grps1, ' ', ' ' from tmp a, t0, t2 where a.rn=t0.G and a.cs is null
union all
select a.rn+1, replace(replace(replace(a.cs, b.c1), b.c2), b.c3), replace(replace(replace(pairs1, p1), p2), p3),
a.grps1, a.grps2||'|'||b.grp, b.grp
from tmp2 a, t5 b, t0
where a.rn<G and a.cur_grp<b.grp and instr(a.grps1, b.grp)=0
and instr(a.grps2, b.c1, 1, b.nx1)=0 and instr(a.grps2, b.c2, 1, b.nx2)=0 and instr(a.grps2, b.c3, 1, b.nx3)=0
and instr(a.pairs1, p1)>0 and instr(a.pairs1, p2)>0 and instr(a.pairs1, p3)>0
and rownum<= t0.RowCut2
)
select a.grps1, a.grps2 from tmp2 a, t0 where a.rn=t0.G and a.cs is null and rownum<=1
/





使用道具 举报

回复
论坛徽章:
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
215#
发表于 2025-2-17 15:37 | 只看该作者
deepseek做的第3题

  1. def count_valid_numbers():
  2.     # 定义数字及其最大出现次数
  3.     digits = [1, 2, 3, 4]
  4.     max_counts = {1: 1, 2: 2, 3: 3, 4: 4}
  5.    
  6.     # 用于存储所有符合条件的组合
  7.     valid_numbers = set()
  8.    
  9.     # 递归函数
  10.     def backtrack(current, counts):
  11.         # 如果当前组合不为空,则将其加入结果集
  12.         if current:
  13.             valid_numbers.add(current)
  14.         
  15.         # 尝试添加下一个数字
  16.         for d in digits:
  17.             # 检查当前数字的出现次数是否超过限制
  18.             if counts.get(d, 0) < max_counts[d]:
  19.                 # 更新当前数字的出现次数
  20.                 new_counts = counts.copy()
  21.                 new_counts[d] = new_counts.get(d, 0) + 1
  22.                 # 递归生成更长的组合
  23.                 backtrack(current + str(d), new_counts)
  24.    
  25.     # 从空字符串开始递归
  26.     backtrack("", {})
  27.    
  28.     # 返回符合条件的组合数量
  29.     return len(valid_numbers)

  30. # 调用函数并输出结果
  31. result = count_valid_numbers()
  32. print(f"符合条件的正整数共有:{result} 个")
复制代码

使用道具 举报

回复

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

本版积分规则 发表回复

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