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]
}
精彩评论