开发者

Converting this into a Ruby one-liner

I'm currently trying to making my obfuscated, short mandelbrot set code into a one-liner, but I'm having a lot of trouble in doing so. \

It was originally written in Python, but due to Python's limitations, I could not compress the code to one line. So now I'm going to try Ruby. I'm familiar with the language, but I'm not very skilled in using blocks - which is where I am having the issue.

Anyway, the code I want to "convert" is

for q in range(801):
 if q%40==0:print s;s=''
 i,k=0,0
 while(abs(k)<2*(i<15)):k,i=k**2+complex(q%40*.075-2,q/40*-.1+1),i+1
 开发者_如何学Pythons+=h[i/3]

Which I've attempted to rewrite in Ruby...

h,s='.;*&8#',''
0.upto(800).each {|q|
  if !q%40
    s=''
    p s 
  end
  i,k=0,0
  while(k.abs<2*(i<15)) 
    k,i=k**2+Complex(q%40*0.075-2,q/40*-0.1+1),i+1 
  end
  s+=h[i/3]
}

Which throws the error

Line 2:in `upto': no block given (LocalJumpError)
    from t.rb:2

After sorting this out, I'd like to shorten it further to one line. Which I've started here...

h,s='.;*&8#','';0.upto(800).each {|q| if !q%40 then s='';p s end;i,k=0,0;while(k.abs<2*(i<15))do k,i=k**2+Complex(q%40*0.075-2,q/40*-0.1+1),i+1 end}

But anyway, I'm just doing this for fun, and hoping to learn a little more Ruby in the process. So if anyone can explain to me what is throw these errors, that would be great.


require 'complex'

h,s='.;*&8#',''
0.upto(800).each {|q|
  if q%40 == 0
    p s
    s=''
  end
  i,k=0,0
  while(k.abs<2 && (i<15))
    k,i=k**2+Complex(q%40*0.075-2,q/40*-0.1+1),i+1
  end
  s+=h[i/3, 1]
}

Issues I dealt with:

  • Ruby conditionals return boolean values, not 1 or 0, and ! has a high priority
  • You were clobbering s before printing it
  • To work on 1.8.x and 1.9.x you need to index strings with [x, 1]

And here it is rearranged a little as a better starting point for a one-liner:

require 'complex'
h,s='.;*&8#',''
800.times { |q|
  (p s; s='') if q%40 == 0
  i,k=0,0
  k,i=k**2+Complex(q%40*0.075-2,q/40*-0.1+1),i+1 while k.abs<2 && i<15
  s+=h[i/3, 1]
}


Fist, get rid of the each, the block should go with upto. Once you did that, you'll get another error: undefined method '%' for false:FalseClass. This is because of !q%40, since precedence will first do the logical negation of q (anything but nil and false are true) and then try to evaluate false%40. Also you seem to assume that a zero would evaluate to false, which it doesn't. Then the next problem will be in the condition of your while loop, since k.abs<2 as well as i<15 evaluate to boolen values (`*': true can't be coerced into Fixnum). This should get you started...


Here's a multi-line version; feel free to put it all on one line:

h,s='.;*&8#','';
0.upto(800).each { |q|
 (puts s;s='') if q%40==0;
 i,k=0,0;
 k,i=k**2+Complex(q%40*0.075-2,q/40*-0.1+1),i+1 while k.abs<2*(i<15?1:0);
 s+=h[i/3]
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜