Learning a little about T-SQL, and thought an interesting exercise would be to generate a Mandelbrot set with it.
Turns out someone already has (and recently, it appears). I'll let someone else post it as an answer, but I'm curious what optimizations can be made.
Alternately, what would you do to make the code more readable?
I'll select the most readable (yet reasonably compact) version as the accepted answer (too bad we don't have rep bounties yet!) unless someone really comes along with a great optimization.
Bonus points to those answers that teach me a little something about T-SQL.
-Adam
From 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
(source: thedailywtf.com)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With