将其转换为Ruby单线程

时间:2011-07-09 15:28:20

标签: ruby

我目前正试图将我的混淆,简短的mandelbrot设置代码变成一个单行,但我在这方面遇到了很多麻烦。 \

它是originally written in Python,但由于Python的限制,我无法将代码压缩到一行。所以现在我要尝试Ruby。我对这门语言很熟悉,但是我不熟练使用块 - 这就是我遇到问题的地方。

无论如何,我想要“转换”的代码是

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
 s+=h[i/3]

我试图在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]
}

引发错误

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

在对此进行排序之后,我想将其进一步缩短为一行。我从这里开始......

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}

但无论如何,我只是为了好玩而做这件事,并希望在这个过程中学习更多的Ruby。所以如果有人能向我解释是什么引发了这些错误,那就太棒了。

3 个答案:

答案 0 :(得分:2)

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]
}

我处理的问题:

  • Ruby条件返回布尔值,而不是1或0,和!
  • 具有高优先级
  • 在打印之前,你正在打击它
  • 要处理1.8.x和1.9.x,您需要使用[ x ,1]
  • 索引字符串

在这里,它重新排列为一个单线的更好的起点:

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]
}

答案 1 :(得分:1)

拳头,摆脱each,该块应与upto一致。完成后,您将收到另一个错误:undefined method '%' for false:FalseClass。这是因为!q%40,因为优先级将首先对qnilfalse之外的任何内容都是真的)进行逻辑否定,然后尝试评估false%40 }。此外,您似乎假设零将评估为false,但它不会。然后,下一个问题将出现在你的while循环中,因为k.abs<2以及i<15会评估为boolen值(`*': true can't be coerced into Fixnum)。这应该让你开始......

答案 2 :(得分:1)

这是一个多行版本;随意把它全部放在一行:

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]
}