楼主: newkid

[精华] ITPUB第2届“盛拓传媒杯”SQL数据库编程大赛第二期参考思路

[复制链接]
论坛徽章:
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
51#
发表于 2025-3-26 14:10 | 只看该作者
在oracle 19c中,34楼和42楼都报错了
SQL> @wdl5.txt
SELECT guess.mine AS solution_id
       *
ERROR at line 10:
ORA-01722: invalid number


SQL> @wdl6.txt
             WHEN c>1                      THEN cell_id-1                ---- 左边邻居的id
                                                                                     *
ERROR at line 12:
ORA-01722: invalid 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
52#
 楼主| 发表于 2025-3-28 08:08 来自手机 | 只看该作者
当年有多热闹,现在就有多凄凉

使用道具 举报

回复
论坛徽章:
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
53#
发表于 2025-3-29 20:25 | 只看该作者
让deepseek把43楼SQL改成的python,一次成功

  1. import itertools
  2. from typing import List, Dict, Any

  3. def sql_to_python(width: int, height: int, grid_str: str):
  4.     # CTE 1: cells
  5.     cells = [
  6.         {
  7.             'cell_id': i,
  8.             'r': (i - 1) // width + 1,
  9.             'c': (i - 1) % width + 1,
  10.             'cnt': grid_str[i-1] if i <= len(grid_str) else ' '
  11.         }
  12.         for i in range(1, width * height + 1)
  13.     ]
  14.    
  15.     # CTE 2: cells2
  16.     cells2 = []
  17.     for cell in cells:
  18.         cnt = cell['cnt']
  19.         r = cell['r']
  20.         c = cell['c']
  21.         cell_id = cell['cell_id']
  22.         
  23.         # 处理cnt值
  24.         if cnt == ' ':
  25.             cnt_val = 0
  26.         elif cnt == '*':
  27.             cnt_val = None
  28.         else:
  29.             cnt_val = int(cnt) if cnt.strip() else None
  30.         
  31.         # 计算n_id
  32.         if r > 1 and c > 1:
  33.             n_id = cell_id - width - 1
  34.         elif r > 1:
  35.             n_id = cell_id - width
  36.         elif c > 1:
  37.             n_id = cell_id - 1
  38.         else:
  39.             n_id = None
  40.         
  41.         cells2.append({
  42.             'cell_id': cell_id,
  43.             'r': r,
  44.             'c': c,
  45.             'cnt': cnt_val,
  46.             'n_id': n_id,
  47.             'n_r': r - 1 if r > 1 else r,
  48.             'n_c': c - 1 if c > 1 else c
  49.         })
  50.    
  51.     # CTE 3: empty_cells
  52.     empty_cells = []
  53.     # 先筛选出空单元格(cnt=0)
  54.     empty_candidates = [cell for cell in cells2 if cell['cnt'] == 0]
  55.    
  56.     # 按SQL中的ORDER BY排序
  57.     empty_candidates.sort(key=lambda x: (
  58.         9999 if x['cell_id'] > 2 * width else x['c'],
  59.         9999 if x['cell_id'] > 2 * width else x['r'],
  60.         x['cell_id']
  61.     ))
  62.    
  63.     for idx, cell in enumerate(empty_candidates, 1):
  64.         r = cell['r']
  65.         c = cell['c']
  66.         cell_id = cell['cell_id']
  67.         n_id = cell['n_id']
  68.         n_r = cell['n_r']
  69.         n_c = cell['n_c']
  70.         
  71.         # 计算邻居ID
  72.         n1 = n_id - width - 1 if (n_r > 1 and n_c > 1) else 999999
  73.         n2 = n_id - width if n_r > 1 else 999999
  74.         n3 = n_id - width + 1 if (n_r > 1 and n_c < width) else 999999
  75.         n4 = n_id - 1 if n_c > 1 else 999999
  76.         n6 = n_id + width - 1 if (n_r < height and n_c > 1) else 999999
  77.         
  78.         # 计算n_cnt
  79.         if n_id is None or n_id < 1 or n_id > width * height:
  80.             n_cnt = 0
  81.         else:
  82.             neighbor_char = grid_str[n_id-1]
  83.             if neighbor_char == '*' or not neighbor_char.strip():
  84.                 n_cnt = 0
  85.             else:
  86.                 n_cnt = int(neighbor_char)
  87.         
  88.         # 计算en1, en2, en4
  89.         en1 = cell_id - width - 1 if (r > 1 and c > 1 and grid_str[cell_id - width - 2] == ' ') else 0
  90.         en2 = cell_id - width if (r > 1 and grid_str[cell_id - width - 1] == ' ') else 0
  91.         en4 = cell_id - 1 if (c > 1 and grid_str[cell_id - 2] == ' ') else 0
  92.         
  93.         empty_cells.append({
  94.             **cell,
  95.             'empty_id': idx,
  96.             'n1': n1,
  97.             'n2': n2,
  98.             'n3': n3,
  99.             'n4': n4,
  100.             'n6': n6,
  101.             'n_cnt': n_cnt,
  102.             'en1': en1,
  103.             'en2': en2,
  104.             'en4': en4
  105.         })
  106.    
  107.     # CTE 4: guess
  108.     guess = [{'mine': 0}, {'mine': 1}]
  109.    
  110.     return {
  111.         'cells': cells,
  112.         'cells2': cells2,
  113.         'empty_cells': empty_cells,
  114.         'guess': guess
  115.     }

  116. def solve_minesweeper(width: int, height: int, grid_str: str, total_mines: int):
  117.     # 使用之前定义的函数生成基础数据
  118.     data = sql_to_python(width, height, grid_str)
  119.     empty_cells = data['empty_cells']
  120.     guess = data['guess']
  121.    
  122.     # 递归基 case
  123.     recursive_t = [{
  124.         'm_cnt': 0,
  125.         'empty_id': 1,
  126.         'res': grid_str
  127.     }]
  128.    
  129.     max_empty_id = max([ec['empty_id'] for ec in empty_cells]) if empty_cells else 0
  130.    
  131.     # 使用循环模拟递归(避免Python递归深度限制)
  132.     while True:
  133.         new_rows = []
  134.         for t in recursive_t:
  135.             current_empty_id = t['empty_id']
  136.             if current_empty_id > max_empty_id:
  137.                 continue
  138.             
  139.             # 找到当前empty_id对应的empty_cell
  140.             current_ec = next((ec for ec in empty_cells if ec['empty_id'] == current_empty_id), None)
  141.             if not current_ec:
  142.                 continue
  143.             
  144.             # 与guess做笛卡尔积
  145.             for g in guess:
  146.                 mine = g['mine']
  147.                
  148.                 # 检查WHERE条件
  149.                 if not (t['m_cnt'] + mine <= total_mines):
  150.                     continue
  151.                
  152.                 # 第一个条件:e.cell_id = 1
  153.                 if current_ec['cell_id'] == 1:
  154.                     pass  # 满足条件
  155.                 else:
  156.                     # 复杂条件检查
  157.                     n_cnt = current_ec['n_cnt']
  158.                     res = t['res']
  159.                     
  160.                     # 计算CASE WHEN e.n_cnt = 0...部分
  161.                     if n_cnt == 0:
  162.                         case_val = 1 if (current_ec['n_id'] <= len(res) and res[current_ec['n_id'] - 1] == '*') else 0
  163.                     else:
  164.                         # 计算各个邻居的雷数
  165.                         mine_count = 0
  166.                         for n in ['n1', 'n2', 'n3', 'n4', 'n6']:
  167.                             n_pos = current_ec[n]
  168.                             if n_pos <= len(res) and res[n_pos - 1] == '*':
  169.                                 mine_count += 1
  170.                         
  171.                         case_val = 1 if mine_count < n_cnt else 0
  172.                     
  173.                     # 检查主条件
  174.                     if case_val != mine:
  175.                         continue
  176.                     
  177.                     # 检查en1, en2, en4条件
  178.                     valid = True
  179.                     for en in ['en1', 'en2', 'en4']:
  180.                         en_pos = current_ec[en]
  181.                         if en_pos > 0:
  182.                             if en_pos > len(res):
  183.                                 valid = False
  184.                                 break
  185.                             en_val = 1 if res[en_pos - 1] == '*' else 0
  186.                             if en_val != mine:
  187.                                 valid = False
  188.                                 break
  189.                     if not valid:
  190.                         continue
  191.                
  192.                 # 构建新行
  193.                 new_res = (
  194.                     t['res'][:current_ec['cell_id'] - 1] +
  195.                     ('*' if mine == 1 else ' ') +
  196.                     t['res'][current_ec['cell_id']:]
  197.                 )
  198.                
  199.                 new_rows.append({
  200.                     'm_cnt': t['m_cnt'] + mine,
  201.                     'empty_id': current_empty_id + 1,
  202.                     'res': new_res
  203.                 })
  204.         
  205.         if not new_rows:
  206.             break
  207.         
  208.         # 添加新行到递归表(替换原有内容以模拟递归)
  209.         recursive_t = new_rows
  210.    
  211.     # 筛选最终结果
  212.     solutions = [t['res'] for t in recursive_t if t['m_cnt'] == total_mines]
  213.     return solutions

  214. # 使用示例
  215. if __name__ == "__main__":
  216.     width, height,total_mines,grid_str =9,9,27,' 2**2  2* 3**3  3* 3**3  3* 3**3  3* 3**3  3* 3**3  3* 3**3  3* 3**3  3* 2**2  2*'.replace('*', ' ')

  217.     solutions = solve_minesweeper(width, height, grid_str, total_mines)
  218.     print(f"找到 {len(solutions)} 个解:")
  219.     for i, sol in enumerate(solutions, 1):
  220.         print(f"解 {i}: {sol}")
复制代码

使用道具 举报

回复
论坛徽章:
10000
绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2015-12-16 18:42:35绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-09-10 13:05:08
54#
发表于 2025-3-31 10:28 | 只看该作者
newkid 发表于 2025-3-28 08:08
当年有多热闹,现在就有多凄凉

主要是现在国内oracle用得越来越少了

使用道具 举报

回复
论坛徽章:
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
55#
 楼主| 发表于 2025-4-17 22:58 | 只看该作者
〇〇 发表于 2025-3-26 14:10
在oracle 19c中,34楼和42楼都报错了SQL> @wdl5.txtSELECT guess.mine AS solution_id       *ERROR at lin ...

今天有点空,到19C下面跑了34楼和42楼,完全没问题,是你脚本哪里写错了吧。

使用道具 举报

回复

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

本版积分规则 发表回复

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