通过数组进行高级迭代

时间:2014-04-18 22:39:09

标签: ruby

我有一个包含100个错误值的数组:[false,false,false,....]。第一次迭代应该用true值替换每个false值。第二个应该替换数组中的所有其他值,与其相反。第三个应该替换数组中的每个第三个值,与它的相反。等等..我能够通过while循环实现这一点。但是,我知道这可以简化,但我无法弄清楚。

array = []
100.times
    array << false
end

i = 1
while i < 100
    j = 0
    while i < array.length
        if array[j] == false
            array[j] = true
        elsif array[j] == true
            array[j] = false
        end
        j += i
    end
    i += 1
end

4 个答案:

答案 0 :(得分:4)

你去......

a = Array.new(100, false)

(1...a.length).each do |stepsize|
  (0...a.length).step(stepsize) {|i| a[i] = !a[i]}
end

另一种选择是:

a = Array.new(100, false)

(1...a.length).each do |stepsize|
  (0...a.length).step(stepsize) {|i| a[i] ^= true}
end

^=正在进行独占或true,因此true将切换为false,反之亦然。

另一个替代方案是使用Numeric&#39; s step迭代器:

a = Array.new(100, false)

(1...a.length).each do |stepsize|
  0.step(a.length-1, stepsize) {|i| a[i] ^= true}
end

答案 1 :(得分:2)

当且仅当数组中的元素数是奇数时,数组的第一个元素才是true。当且仅当它们是完美的正方形时,其他元素将是true

我假设翻转操作要执行n次,其中n是数组的大小。如果它是n-1次,则第一个元素被反转,但所有其他元素保持不变。

<强>代码

def doit(n)
  (0...n).map do |i|
    if i == 0 
      n.odd?
    else   
      m = Math.sqrt(i).floor
      m*m == i
    end
  end
end

<强>实施例

doit(9)
  #=> [true, true, false, false, true, false, false, false, false]
doit(10)
 #=> [false, true, false, false, true, false, false, false, false, true]

对于n = 100true值处于这些偏移位置:

doit(100).each_with_index.select { |t,i| t }.map(&:last)
  #=> [1, 4, 9, 16, 25, 36, 49, 64, 81]

<强>解释

偏移i > 0处的元素将在falsetrue之间翻转,每个数字j1 <= j <= i,其中jii%j.zero?)的除数。因此,对于i > 0,我们只需要确定除数的数量是奇数还是偶数。计算数字n的除数数的标准方法如下:

def divisors(n)
  m = Math.sqrt(n).floor
  tot = (1..m).reduce(0) { |t,i| (t += 2) if (n%i).zero?; t }
  tot -= 1 if m*m == n
  tot.odd?
end

我们只需要检查号码i最多mm = Math.sqrt(n).floor),因为如果in的除数,n/i也将是一个除数。但是,如果m*m == n,我们需要减去一个以避免重复计算i = m。对于这个问题,我们只需要知道总数是偶数还是奇数,所以我们只需检查m*m == n是否为i < m,因为每个除数{{1}}对总数有两个除数。

答案 2 :(得分:0)

略有不同的方法,但这样我保留了所有让我进行最终计算的步骤。

array = 100.times.collect {false}
steps = array.size.times.inject([array]) do |result,mod|
  last = result.last
  result << last.collect.with_index do | x, i |
    (i%(mod+1) == 0) ? (!x) : (x)
  end
  result
end

答案 3 :(得分:0)

array = Array.new(100, false)
array.each_index do |i|
  i += 1
  array.each_index{|j| array[j] ^= true if (j % i).zero?}
end