From: Sander Land Date: 2007-12-28T21:27:36+09:00 Subject: Re: Thought I'd share this and get some advice On Dec 28, 2007 12:57 PM, Hiato Xaero wrote: > I decided to take it upon myself to write a text Mandelbrot Set Generator in > Ruby (seeing as I couldn't find any...) > > Anyway, here is the code, it's procedural style, not entirely utilizing Ruby > to its fullest, but hey > > p ' ' > p "NOTE: Do not run this from a console that has less than 128 columns, 130 > to be safe! If you fail to do so, then you will see rubbish inplace of the > mandelbrot set" > p ' ' > > i = -24.00 > until (i>=24) > k = -64.00 > s = '' > until (k>=63) > p = 0 > x = 0 > y = 0 > while ((x*x)+(y*y)<4) > xt = x*x - y*y + (k-23)/43.5 > yt = 2*x*y + i/22 > x = xt > y = yt > p = p + 6 > break unless p<260 > end > case p > when 1..10: s << 'A' > when 10..20: s << 'B' > when 20..30: s << 'C' > when 30..40: s << 'D' > when 40..50: s << 'E' > when 50..60: s << 'F' > when 60..70: s << 'G' > when 70..80: s << 'H' > when 80..90: s << 'I' > when 90..100: s << 'J' > when 100..110: s << 'K' > when 110..120: s << 'L' > when 120..130: s << 'M' > when 130..140: s << 'N' > when 140..150: s << 'O' > when 150..160: s << 'P' > when 160..170: s << 'Q' > when 170..180: s << 'R' > when 180..190: s << 'S' > when 190..200: s << 'T' > when 200..210: s << 'U' > when 210..220: s << 'V' > when 220..230: s << 'W' > when 230..240: s << 'X' > when 240..250: s << 'Y' > when 250..400: s << ' ' > end > k = k + 1.00 > end > p s > i = i + 1.00 > end > > p ' ' > p "NOTE: Do not run this from a console that has less than 128 columns, 130 > to be safe! If you fail to do so, then you will see rubbish inplace of the > mandelbrot set" > p ' ' > > gets() > > Finally, any feedback is welcome, and I'm just wondering if there isn't a > more efficient way to do this. > > Anyway, cheers and thanks for reading > Hi Hiato, Cool little script. The Mandelbrot is always nice to see. :) Some comments: First of all, the case statement in Ruby is really just equivalent to if/elsif/elsif/..., so this is not very efficient. Better to replace this with some arithmetic. puts s over p s to avoid printing the quotes i = i + 1.00 can be written as i += 1, but its probably better to replace the 'until' loop with a for loop: for i in -24...24 (or just (-24...24).each{|i| ) You can replace the loop on k and the s with a map call, and use parallel assignment instead of xt/yt. for i in -24...24 puts (-64...63).map{|k| p = x = y = 0 while ((x*x)+(y*y)<4) x, y = x*x - y*y + (k-23)/43.5, 2*x*y + i/22.0 # parallel assignment, and /22.0 for automatic to_f on i p = p + 6 break unless p<260 end if p >= 250 ' ' else (?A + (p-1)/10).chr # ?A.ord in 1.9 end }.join end