代码之家  ›  专栏  ›  技术社区  ›  Dave Swersky

数据库宝石迷阵-这个解决方案是如何工作的?

  •  0
  • Dave Swersky  · 技术社区  · 17 年前

    我对珠宝游戏带来的编程挑战感兴趣。这似乎是一个简单的游戏,但从程序上讲,它看起来更复杂。

    在我寻找如何评估董事会的提示时,我遇到了 this QUIZ 在简单的谈话中由好人装腔作势。他们已经公布了获胜的答案,但如果我真的能摸索出解决方案是如何工作的,我会被涂上焦油和羽毛。我可以看到,它与矩阵和将单元格值与其行和列分组有关,但这是目前为止我所了解的。有人能帮我把它再细分一点吗?

    已发布的解决方案(测验的详细信息在上面的链接中):

    --====== Table matches needs to be loaded only once
    CREATE TABLE matches(offsetRow1 INT, offsetCol1 INT, offsetRow2 INT, ofsetCol2 INT, directions VARCHAR(20))
    -- for horizontal 
    INSERT INTO matches VALUES(-1, -1, -1, -2, 'up')
    INSERT INTO matches VALUES(-1, -1, -1, 1, 'up')
    INSERT INTO matches VALUES(-1, 1, -1, 2, 'up')        
    INSERT INTO matches VALUES( 1, -1, 1, -2, 'down')           
    INSERT INTO matches VALUES( 1, -1, 1, 1, 'down')
    INSERT INTO matches VALUES( 1, 1, 1, 2, 'down')       
    INSERT INTO matches VALUES( 0, -2, 0, -3, 'left')     
    INSERT INTO matches VALUES( 0, 2, 0, 3, 'right')            
    -- for verical
    INSERT INTO matches VALUES(-2, -1, -1, -1, 'left')
    INSERT INTO matches VALUES(-1, -1, 1, -1, 'left')
    INSERT INTO matches VALUES( 1, -1, 2, -1, 'left')
    INSERT INTO matches VALUES(-2, 1, -1, 1, 'right')
    INSERT INTO matches VALUES(-1, 1, 1, 1, 'right')
    INSERT INTO matches VALUES( 1, 1, 2, 1, 'right')
    INSERT INTO matches VALUES(-2, 0, -3, 0, 'up')
    INSERT INTO matches VALUES( 2, 0, 3, 0, 'down')
    
    --==================================================
    ;WITH CTE
          AS
      (
      SELECT
            [Row] = CAST( [#] AS INT ),
            [Col] = CAST( [Col] AS INT ),
            [Value]
        FROM bejeweled
            UNPIVOT ([Value] FOR [Col] IN ([1],[2],[3],[4],[5],[6],[7],[8],[9])) unpvt
      )
    SELECT DISTINCT T.Row, T.Col, T.Value, directions
      FROM CTE T
          JOIN CTE T1
          ON T.Value = T1.Value
          JOIN CTE T2
          ON T.Value = T2.Value
          JOIN matches
          ON (T1.Row - T.Row) = offsetRow1
        AND (T1.Col - T.Col) = offsetCol1
        AND (T2.Row - T.Row) = offsetRow2
        AND (T2.Col - T.Col) = ofsetCol2
      ORDER BY T.Row, T.Col
    
    1 回复  |  直到 17 年前
        1
  •  3
  •   Matt Poush    17 年前

    unpivot函数将原始数据转换为线性列表,而不是矩阵。例如,由于原始列中的1,1的值为8,新表的第一行是1,1,8。同样,由于原始表第一行的第二列是5,所以新表的第二行是1,2,5。

    “with cte”有效地创建了一个名为cte的内存表,因此这个新的3列81行表称为cte。

    逻辑发生在内部连接上:CTE中的每个单元格都连接到值匹配的CTE中的每个单元格,并在值匹配的地方再次与自身连接。这意味着原始表中的每个单元格都知道其他可能的三项匹配。也就是说,返回包含值“1”(例如)的3个单元格列表的每一个排列。

    让我们看看值2。有一个在(6,2),另一个在(5,3),另一个在(7,3),所以内部连接的一个可能值是t。row是6,t。col是2,t1。row是5,t1。col是3,t2。row是7,t2。col是3。通过观察我们知道,用(6,3)交换(6,2)将把三个放在一起。但是join语句怎么知道呢?

    好吧,一个有效的移动是把t放在T1和T2之间的移动。确定3个组合是否满足要求的最简单方法是检查偏移并将其与工作的相对位置列表进行比较。T1在T的上方和右侧(-1,1),T2在T的下方和右侧(1,1)。我们检查并查看(-1,1,1,1)是否是有效的匹配项。是的,因此它通过了联接条件,并因此而保留。