在给定字符串中具有奇数和偶数索引的元素串联后,输出以 2 行给出

Output is given in 2 lines after concatenation of elements with odd and even indexes in a given string

我编写了一个函数,它获取所有具有奇数索引的元素,并将它们与给定字符串中所有具有偶数索引的元素连接 n 次:

def encrypt(text,n)
  while n > 0
    n -= 1
    str_array = text.split("")
    even_values = str_array.select.with_index { |_, i| i.even? }
    odd_values = str_array.select.with_index { |_, i| i.odd? }
    text = (odd_values+even_values).join
  end
  puts text
end

puts 'Type your message to encrypt:'
text = gets
puts 'Type number of times to run encryption:'
n = gets.to_i
encrypt(text,n)

问题在于,如果输入文本包含奇数个元素,则该函数将 return 文本分两行。同时,如果输入文本的元素数量是偶数,则输出是我想要的 1 行文本。

输入文本中包含 10 个元素的控制台输出:

Type your message to encrypt:
abcdefghij 
Type number of times to run encryption:
1
bdfhjacegi

输入文本中包含 11 个元素的控制台输出:

Type your message to encrypt:
abcdefghijk
Type number of times to run encryption:
1
bdfhj
acegik

对于n = 1

def doit(str)
  enum = [false, true].cycle
  str.each_char.partition { enum.next }.map(&:join).join
end
doit "abcdefghij"
  #=> "bdfhjacegi"
doit "abcdefghijk"
  #=> "bdfhjacegik"

对于n > 1

n.times.reduce(str) { |s,_| doit(s) }

例如:

4.times.reduce(str) { |s,_| doit(s) }
  #=>"ejdichbgafk"

参见 Enumerable#reduce(a.k.a。inject


现在考虑 doit.

执行的计算

首先考虑使用方法 Array#cycle:

创建的枚举器 enum
 enum = [false, true].cycle
   #=> #<Enumerator: [false, true]:cycle>

我们可以使用方法 Enumerator#next 查看此枚举器 enum 将生成什么值:

 enum.next
   #=> false
 enum.next
   #=> true
 enum.next
   #=> false
 ... ad infinitum

现在让我们使用 Enumerator#rewind:

重置枚举器
 enum.rewind
   #<Enumerator: [false, true]:cycle>

假设

str = "abcdefghijk"

然后

e = str.each_char
  #=> #<Enumerator: "abcdefghijk":each_char>

我们可以将此枚举器转换为数组以查看它将生成哪些元素。

e.to_a
  #=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]

继续,

a = e.partition { enum.next }
  #=> [["b", "d", "f", "h", "j"], ["a", "c", "e", "g", "i", "k"]]
b = a.map(&:join)
  #=> ["bdfhj", "acegik"]  
b.join
  #=> "bdfhjacegik"

注意 a.map(&:join) 对于 a.map { |arr| arr.join } 是 shorthand。

参见 String#each_char, Enumerable#partition and Array#join