Home All Groups Group Topic Archive Search About
Author
28 Jul 2006 12:02 AM
Mike Labosh
Some of us over on the MS MCT secret server have been arguing about stome
stuff, and one of the posts made me remember this:

The September, 1986 issue of Byte Magazine had a long article about abstract
mathematical art.  The "1-Dimensional Cellular Automaton" algorithm is
deeply steeped in Chaos theory and Evolution, but just wait till you see the
Query Analyzer output.

Spend some time monkeying with the value of the @rule variable.  the @rule
must be 10 digits long, and each digit must be a 0, 1, 2 or 3.

(some of these lines are going to wrap, but the code pasted below should
print out quite nicely with a Courier New 8-pt font.)

DECLARE @GenA   VARCHAR(80) -- First Generation
DECLARE @GenB   VARCHAR(80) -- Next Generation
DECLARE @I      INT         -- Outer Loop Counter
DECLARE @J      INT         -- Inner Loop Counter
DECLARE @Rule   CHAR(10)    -- Replication Rule
DECLARE @Chars  CHAR(4)     -- ASCII Drawing Characters
DECLARE @Line   VARCHAR(80) -- Line of ASCII Output

SET @GenA = '0'             -- First column of GenA should be zero
SET @I = 1                  -- Set Loop counter to 1
SET @J = 1                  -- Set loop counter to 1
SET @Rule = '0102030201'    -- Initialize the rule
SET @Chars = ' .o+'         -- Numbers in GenA will be mapped through here
(n'th character)

WHILE @I < 80               -- Randomly build numbers into the initial state
in GenA
BEGIN
  SET @I = @I + 1
  SET @GenA = @GenA + CAST(CONVERT(INT, RAND() * 3 + .5) AS CHAR(1))
END

SET @GenA = @GenA + '0'     -- Last column of GenA should be zero
SET @I = 0                  -- Reset loop counter

WHILE @I < 25               -- Loop through this many rows of output
BEGIN
  SET @J = 1                -- Reset loop counter
  SET @Line = ''            -- Reset line of ASCII output

  WHILE @J < 80             -- Loop across GenA, populating Line with ASCII
symbols
   BEGIN
SET @J = @J + 1
    SET @Line = @Line + SUBSTRING(@Chars, CAST(SUBSTRING(@GenA, @J, 1) AS
INT) + 1, 1)
   END

  PRINT @Line               -- Print a line of output
  SET @I = @I + 1           -- Increment the row we're on
  SET @J = 1                -- Reset loop counter
  SET @GenB = '0'           -- First column of GenB should be zero

  WHILE @J < 79             -- Calculate the next generation from GenA to
GenB
   BEGIN
    SET @J = @J + 1
    SET @GenB = @GenB +
     SUBSTRING(@Rule, CAST(SUBSTRING(@GenA, @J - 1, 1) AS INT) +
                      CAST(SUBSTRING(@GenA, @J, 1) AS INT) +
                      CAST(SUBSTRING(@GenA, @J + 1, 1) AS INT) + 1, 1)
   END

  SET @GenA = @GenB + '0'   -- Last column of GenB should be zero
END
--

Peace & happy computing,

Mike Labosh, MCSD MCT
Owner, vbSensei.Com
"y = (-b ± (b^2 - 4 * a * c)^.5) / 2 * a" -- Dr. Houser

Author
28 Jul 2006 1:51 AM
Steve Kass
Here's a clunky update using some XML and set-based queries.  I'm sure
there is a less clunky way to do this, and I apologize about the comments.
My dog ate them.  This bad code sends all the wrong signals about the
manageability and stability of SQL, but I'm posting it hoping someone will
help clean it up into something more respectable.


CREATE FUNCTION World(
  @s varchar(max),
  @rule CHAR(10),
  @r INT
) RETURNS @T TABLE (
    row INT,
    col INT,
    v INT,
    vvv INT,
    PRIMARY KEY(row,col)
)
AS BEGIN
  DECLARE @orig_r INT
  SET @orig_r = @r
  INSERT INTO @T
    SELECT 0, n+i, SUM(v*j), SUBSTRING(@rule,1+SUM(v),1)
    FROM (
      SELECT DISTINCT number, CAST(SUBSTRING(@s,number,1) AS INT)
      FROM master..spt_values
      WHERE number BETWEEN 1 AND LEN(@s)
  ) AS E(n,v) CROSS JOIN (
      SELECT -1 AS i, 0 AS j UNION ALL SELECT 0, 1 UNION ALL SELECT 1, 0
    ) AS T
    GROUP BY n+i
    HAVING COUNT(*) > 1
  WHILE @r > 1 BEGIN
    SET @r = @r - 1
    INSERT INTO @T
      SELECT @orig_r-@r, col+i, SUM(vvv*j), SUBSTRING(@rule,1+SUM(vvv),1)
      FROM @T CROSS JOIN (
        SELECT -1 AS i, 0 AS j UNION ALL SELECT 0, 1 UNION ALL SELECT 1, 0
      ) AS T
      WHERE row = @orig_r-@r-1
      GROUP BY col+i
      HAVING COUNT(*) > 1
  END
  RETURN
END
GO

DECLARE @s varchar(max);
SET @s =
'0101012332012332010302123332202032001110301123332202302023210101203201030203011233200200302';
DECLARE @r int;
SET @r = 80;
WITH E(n) AS (
  SELECT DISTINCT number
  FROM master..spt_values
  WHERE number >= 0
  AND (number <= LEN(@s) OR number <= @r)
), W(row,col,v) AS (
  SELECT row,col,v
  FROM World(@s,'0102031101',@r)
)
  SELECT (
    SELECT REPLACE(REPLACE(CAST(s AS
VARCHAR(MAX)),'/',CHAR(13)+CHAR(10)),'|',SPACE(1))
    FROM (
      SELECT SUBSTRING('|.o+',v+1,1) + CASE WHEN col=len(@s) THEN '/'
ELSE '' END AS [text()]
      FROM (
        SELECT * FROM W WHERE row = n
      ) R
      ORDER BY row,col
      FOR XML PATH('')
    ) AS X(s)
  ) FROM E
  WHERE n < @r
GO

DROP FUNCTION World

-- Steve Kass
-- Drew University
-- www.stevekass.com
-- 02DDC4C4-BE2B-49B1-9F48-C7F756F4F414

Mike Labosh wrote:

Show quote
>Some of us over on the MS MCT secret server have been arguing about stome
>stuff, and one of the posts made me remember this:
>
>The September, 1986 issue of Byte Magazine had a long article about abstract
>mathematical art.  The "1-Dimensional Cellular Automaton" algorithm is
>deeply steeped in Chaos theory and Evolution, but just wait till you see the
>Query Analyzer output.
>
>Spend some time monkeying with the value of the @rule variable.  the @rule
>must be 10 digits long, and each digit must be a 0, 1, 2 or 3.
>
>(some of these lines are going to wrap, but the code pasted below should
>print out quite nicely with a Courier New 8-pt font.)
>
>DECLARE @GenA   VARCHAR(80) -- First Generation
>DECLARE @GenB   VARCHAR(80) -- Next Generation
>DECLARE @I      INT         -- Outer Loop Counter
>DECLARE @J      INT         -- Inner Loop Counter
>DECLARE @Rule   CHAR(10)    -- Replication Rule
>DECLARE @Chars  CHAR(4)     -- ASCII Drawing Characters
>DECLARE @Line   VARCHAR(80) -- Line of ASCII Output
>
>SET @GenA = '0'             -- First column of GenA should be zero
>SET @I = 1                  -- Set Loop counter to 1
>SET @J = 1                  -- Set loop counter to 1
>SET @Rule = '0102030201'    -- Initialize the rule
>SET @Chars = ' .o+'         -- Numbers in GenA will be mapped through here
>(n'th character)
>
>WHILE @I < 80               -- Randomly build numbers into the initial state
>in GenA
> BEGIN
>  SET @I = @I + 1
>  SET @GenA = @GenA + CAST(CONVERT(INT, RAND() * 3 + .5) AS CHAR(1))
> END
>
>SET @GenA = @GenA + '0'     -- Last column of GenA should be zero
>SET @I = 0                  -- Reset loop counter
>
>WHILE @I < 25               -- Loop through this many rows of output
> BEGIN
>  SET @J = 1                -- Reset loop counter
>  SET @Line = ''            -- Reset line of ASCII output
>
>  WHILE @J < 80             -- Loop across GenA, populating Line with ASCII
>symbols
>   BEGIN
> SET @J = @J + 1
>    SET @Line = @Line + SUBSTRING(@Chars, CAST(SUBSTRING(@GenA, @J, 1) AS
>INT) + 1, 1)
>   END
>
>  PRINT @Line               -- Print a line of output
>  SET @I = @I + 1           -- Increment the row we're on
>  SET @J = 1                -- Reset loop counter
>  SET @GenB = '0'           -- First column of GenB should be zero
>
>  WHILE @J < 79             -- Calculate the next generation from GenA to
>GenB
>   BEGIN
>    SET @J = @J + 1
>    SET @GenB = @GenB +
>     SUBSTRING(@Rule, CAST(SUBSTRING(@GenA, @J - 1, 1) AS INT) +
>                      CAST(SUBSTRING(@GenA, @J, 1) AS INT) +
>                      CAST(SUBSTRING(@GenA, @J + 1, 1) AS INT) + 1, 1)
>   END
>
>  SET @GenA = @GenB + '0'   -- Last column of GenB should be zero
> END

>

AddThis Social Bookmark Button