[Shootout-list] fixed Clean mandelbrot

Diederik van Arkel dvanarkel@mac.com
Fri, 25 Mar 2005 10:12:58 +0100


--Apple-Mail-15-290792190
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed

A fixed Clean version of the mandelbrot benchmark (never
clean up your code in your mailer...)

regards,

Diederik van Arkel


--Apple-Mail-15-290792190
Content-Transfer-Encoding: 7bit
Content-Type: application/text;
	x-mac-type=54455854;
	x-unix-mode=0644;
	x-mac-creator=3350524D;
	name="mandelbrot.icl"
Content-Disposition: attachment;
	filename=mandelbrot.icl

// The Great Computer Language Shootout
// http://shootout.alioth.debian.org/
//
// contributed by Diederik van Arkel

module mandelbrot

import StdEnv, LanguageShootout

Start world
	# (console, world)	= stdio world
	# width				= argi
	# console			= console <<< "P4\n" <<< width <<< " " <<< width <<< "\n"
	# chunks			= fractal (points width width)
	# pbm				= map makePBM chunks
	# console			= seq (map fwrites pbm) console
	# (ok,world)		= fclose console world
	= world

mandel_iter :: Int
mandel_iter   = 50

points :: Int Int -> [{!Complex Real}]
points width height
	= [{(2.0*x/w - 1.5, 2.0*y/h - 1.0) \\ x <- [0.0..w-1.0]} \\ y <- [0.0..h-1.0]]
where
	w	= toReal width
	h	= toReal height
	
fractal :: [{!Complex Real}] -> [{#Int}]
fractal []
	= []
fractal [p:ps]
	= [{fractal` (0.0 , 0.0) mandel_iter c \\ c <-: p} : fractal ps]

fractal` :: !(Complex Real) !Int !(Complex Real) -> Int
fractal` z iter c
	| (((r*r) + (i*i)) > limit)	= 0
	| iter == 1			= mandel_iter
	| otherwise			= fractal` z` (iter-1) c
where
	(r,i)	= z*z+c
	z`		= (r,i)
	limit	= 4.0

toArray l = {c \\ c <- l}

makePBM :: {#Int} -> .{#Char}
makePBM a
	= toArray (makePBM 0 0 a)
where
	m = size a

	makePBM :: !Int !Int !{#Int} -> [Char]
	makePBM i acc a
		# i8	= i bitand 7
		| i == m
			= [(toChar (acc * 2^(8-i8)))]
		| i8 == 0
			# x	= a.[i]
			# n = if (x==mandel_iter) 1 0
			= [toChar acc : makePBM (i+1) n a]
		# x	= a.[i]
		# n = if (x==mandel_iter) (acc*2+1) (acc*2)
		= makePBM (i+1) n a

// Complex

:: Complex a :== (!a,!a)

instance + (Complex a) | + a
where
	(+) (rl,il) (rr,ir)
		= (rl+rr,il+ir)

instance * (Complex a) | *,+,- a
where
	(*) (rl,il) (rr,ir)
		= (rl*rr - il*ir, rl*ir + rr*il)

--Apple-Mail-15-290792190--