【问题标题】:How to generate a Mandelbrot with T-SQL?如何使用 T-SQL 生成 Mandelbrot?
【发布时间】:2010-09-23 19:30:14
【问题描述】:

了解一点 T-SQL,并认为一个有趣的练习是用它生成一个 Mandelbrot 集。

原来有人已经拥有(最近,它出现了)。我会让其他人将其发布为答案,但我很好奇可以进行哪些优化。

或者,您会如何使代码更具可读性?

我会选择最易读(但相当紧凑)的版本作为接受的答案(可惜我们还没有代表赏金!)除非有人真的提出了很好的优化。

奖励点指向那些教会我一些关于 T-SQL 的答案。

-亚当

【问题讨论】:

    标签: tsql code-golf fractals


    【解决方案1】:

    来自thedailywtf.com

    -- AUTHOR: GRAEME JOB
    -- CREATED: 12-OCT-2008
    -- BECAUSE: SINGLE SQL COMMAND < 50 LINES. JUST BECAUSE.
    WITH 
          XGEN(X, IX) AS (              -- X DIM GENERATOR
                SELECT CAST(-2.2 AS FLOAT) AS X, 0 AS IX UNION ALL
                SELECT CAST(X + 0.031 AS FLOAT) AS X, IX + 1 AS IX
                FROM XGEN
                WHERE IX < 100
          ),
          YGEN(Y, IY) AS (              -- Y DIM GENERATOR
                SELECT CAST(-1.5 AS FLOAT) AS Y, 0 AS IY UNION ALL
                SELECT CAST(Y + 0.031 AS FLOAT) AS Y, IY + 1 AS IY
                FROM YGEN
                WHERE IY < 100
          ),
          Z(IX, IY, CX, CY, X, Y, I) AS (           -- Z POINT ITERATOR
                SELECT IX, IY, X, Y, X, Y, 0
                FROM XGEN, YGEN   
                UNION ALL
                SELECT IX, IY, CX, CY, X * X - Y * Y + CX AS X, Y * X * 2 + CY, I + 1
                FROM Z
                WHERE X * X + Y * Y < 16
                AND I < 100
          )
    SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
          REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
          REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
          (X0+X1+X2+X3+X4+X5+X6+X7+X8+X9+X10+X11+X12+X13+X14+X15+X16+X17+X18+X19+
          X20+X21+X22+X23+X24+X25+X26+X27+X28+X29+X30+X31+X32+X33+X34+X35+X36+X37+X38+X39+
          X40+X41+X42+X43+X44+X45+X46+X47+X48+X49+X50+X51+X52+X53+X54+X55+X56+X57+X58+X59+
          X60+X61+X62+X63+X64+X65+X66+X67+X68+X69+X70+X71+X72+X73+X74+X75+X76+X77+X78+X79+
          X80+X81+X82+X83+X84+X85+X86+X87+X88+X89+X90+X91+X92+X93+X94+X95+X96+X97+X98+X99),
          'A',' '),   'B','.'),   'C',','),   'D',','),   'E',','),   'F','-'),   'G','-'),
          'H','-'),   'I','-'),   'J','-'),   'K','+'),   'L','+'),   'M','+'),   'N','+'),
          'O','%'),   'P','%'),   'Q','%'),   'R','%'),   'S','@'),   'T','@'),   'U','@'),
          'V','@'),   'W','#'),   'X','#'),   'Y','#'),   'Z',' ')
    FROM (
          SELECT 'X' + CAST(IX AS VARCHAR) AS IX,
          IY,   SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ', ISNULL(NULLIF(I, 0), 1), 1) AS I
          FROM Z) ZT
    PIVOT (
          MAX(I) FOR IX IN (
          X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13,X14,X15,X16,X17,X18,X19,
          X20,X21,X22,X23,X24,X25,X26,X27,X28,X29,X30,X31,X32,X33,X34,X35,X36,X37,X38,X39,
          X40,X41,X42,X43,X44,X45,X46,X47,X48,X49,X50,X51,X52,X53,X54,X55,X56,X57,X58,X59,
          X60,X61,X62,X63,X64,X65,X66,X67,X68,X69,X70,X71,X72,X73,X74,X75,X76,X77,X78,X79,
          X80,X81,X82,X83,X84,X85,X86,X87,X88,X89,X90,X91,X92,X93,X94,X95,X96,X97,X98,X99)
    ) AS PZT
    


    (来源:thedailywtf.com

    【讨论】:

    • 抱歉,我的意思是包含它的样子。
    • 让我想起了 1987-1992 年的时间,当时有人用 PostScript 编写了一个 Mandelbrot 生成器,而一些白痴一直将它发送给我们公司,只有一个 LaserWriter。
    • @paul - 搞笑!我工作场所的激光打印机故障仅限于更改 HP 打印机上的状态消息。
    【解决方案2】:
    Create PROCEDURE dbo.mandlebrot
    @left float,
    @right float,
    @Top float,
    @Bottom float,
    @Res float,
    @MaxIterations Integer = 500
    As
    Set NoCount On
    
    Declare @Grid Table (
        X float Not Null, 
        Y float Not Null,
        InSet Bit
       Primary Key (X, Y))
    
    Declare @Xo float, @Yo float, @Abs float
    Declare @PtX Float, @PtY Float
    Declare @Iteration Integer Set @Iteration = 0
    Select @Xo = @Left, @Yo = @Bottom
    
    While @Yo <= @Top Begin
        While @Xo <= @Right Begin
            Select @PtX = @Xo, @PtY = @Yo
            While @Iteration < @MaxIterations 
                And (Square(@PtX) + Square(@PtY)) < 4.0 Begin
                Select @PtX = Square(@PtX) - Square(@PtY) + @Xo,
                       @PtY = 2* @PtX * @PtY + @Yo
                Select @Iteration, @PtX, @PtY
                Set @Iteration = @Iteration + 1
            End
            Insert @Grid(X, Y, InSet) 
            Values(@Xo, @Yo, Case 
                When @Iteration < @MaxIterations
                        Then 1 Else 0 End)
            Set @Xo = @Xo + @res
            Set @Iteration = 0
        End
        Select @Xo = @Left, 
               @Yo = @Yo + @Res
    End
    
    Select * From @Grid
    

    【讨论】:

      【解决方案3】:

      希望这也能教授一些关于 T-SQL 的知识,它以基于集合的方法完成所有操作,这是 TSQL 的强项(即没有 while 循环)或变量:

      SET NOCOUNT ON;
      
      --populate
      ;WITH Numbers ([row]) AS
      (
         SELECT TOP 100 CAST(ROW_NUMBER() OVER (ORDER BY NEWID()) AS FLOAT) [row]
         FROM sys.columns
      )
      SELECT A.row AS x, 
         B.row AS y, 
         0 AS iter, 
         A.row AS iterx, 
         B.row AS itery, 
         '.' AS symbol
      INTO #GRID
      FROM Numbers A, Numbers B
      WHERE B.[row] <= 24
      GO
      
      -- scale
      UPDATE #GRID
      SET x = x * 3.0 / 100.0 - 2,
         y = y * 2.0 / 24.0 - 1,
         iterx = x * 3.0 / 100.0 - 2,
         itery = y * 2.0 / 24.0 - 1
      GO
      
      --iterate
      UPDATE #GRID
      SET iterx = iterx*iterx - itery*itery + x,
          itery = 2*iterx*itery + y,
          iter = iter+1
      WHERE iterx*iterx+itery*itery <= 2*2
      GO 257
      
      UPDATE #GRID SET symbol = CHAR(64+(iter%26)) WHERE NOT iter = 257
      GO
      
      --print
      WITH concatenated (y, c) AS 
      (
         SELECT G2.y,
             (SELECT SUBSTRING(G.symbol, 1, 1) AS [data()] FROM #GRID G WHERE G.y = G2.y FOR XML PATH('')) c
         FROM (SELECT DISTINCT y FROM #GRID) AS G2
      )
      SELECT REPLACE(c, ' ', '') FROM concatenated ORDER BY y
      GO
      
      
      DROP TABLE #GRID
      

      【讨论】:

      • 哈哈,不错的技巧“没有循环或变量”,除了“GO 257”,它本质上是一个循环。不过还是很酷。
      【解决方案4】:
      with points (x1,y1,x2,y2,depth) as
      (
          select convert(float,-2.40), convert(float,-2.40), convert(float,2.40), convert(float,2.40), 8
          union all select x1,y1,(x1+x2)/2,(y1+y2)/2,depth-1 from points where depth>0
          union all select (x1+x2)/2,y1,x2,(y1+y2)/2,depth-1 from points where depth>0
          union all select x1,(y1+y2)/2,(x1+x2)/2,y2,depth-1 from points where depth>0
          union all select (x1+x2)/2,(y1+y2)/2,x2,y2,depth-1 from points where depth>0
      ),
      mandelbrot(x1,y1,x2,y2,x,y,depth) as
      (
          select x1,y1,x2,y2,convert(float,0),convert(float,0),20 from points where depth=0
          union all
          select x1,y1,x2,y2, x*x-y*y+x1, 2*x*y+y1,depth-1 from mandelbrot where depth > 0 and (x*x+y*y<4)
      )
      select geometry::STGeomFromText('POLYGON((' +
        convert(varchar,x1) + ' ' + convert(varchar,y1) + ',' +
        convert(varchar,x1) + ' ' + convert(varchar,y2) + ',' +
        convert(varchar,x2) + ' ' + convert(varchar,y2) + ',' +
        convert(varchar,x2) + ' ' + convert(varchar,y1) + ',' +
        convert(varchar,x1) + ' ' + convert(varchar,y1) + '))',0)
        from mandelbrot where depth = 0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多