Умножьте все четные целые числа на два

Желая взять фиксированное число целых чисел и умножить все четные (проиндексированные) целые числа на два. Я решил, что лучший способ сделать это - сначала превратить fixnum в массив. Итак, допустим следующее число из 16 цифр: a = 4408041234567901

Я знаю, что мог:

a.to_s.split('')

Который вернет "а" массиву "строковых" чисел. Но тогда я не могу ответить:

a.map!.with_index {|i,n| i.even? n*2}

Думаю, я застрял на том, как создать метод для этого. Так что мой вопрос может быть даже в том, как превратить эту группу чисел в массив фиксированных чисел / целых чисел вместо строк.

3 ответа

Решение

Чтобы изменить его на массив, вы можете сделать

a = 4408041234567901
arr = a.to_s.chars.map(&:to_i)
# => [4, 4, 0, 8, 0, 4, 1, 2, 3, 4, 5, 6, 7, 9, 0, 1]

Вы также можете умножить альтернативные числа на 2

arr = a.to_s.chars.map.with_index {|n,i| i.even? ? n.to_i * 2 : n.to_i }
# => [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]

Улучшив немного, вы можете использовать Hash найти число для умножения.

h = {true => 2, false => 1}
a.to_s.each_char.map.with_index {|n,i| n.to_i * h[i.even?]}

РЕДАКТИРОВАТЬ

Я могу объяснить каждый шаг, но будет лучше, если вы попытаетесь понять это самостоятельно. Open irb, тип a.to_s и проверьте вывод. Затем введите a.to_s.chars и проверить вывод и тд..

Я бы предпочел полностью удалить условное выражение из цикла, создав Enumerator который содержит коэффициенты, на которые вы хотите умножить (2 для четных индексов и 1 для нечетных.)

coef = [2, 1].cycle

Это по сути создает Enumerator который поочередно возвращает 2 а также 1 когда next называется на это. Вы можете использовать это, чтобы упростить map чтобы:

a.to_s.each_char.map { |v| v.to_i * coef.next }
a = 4408041234567901

even_odd = [:even, :odd].cycle
   #=> #<Enumerator: [:even, :odd]:cycle> 

Если индексация начинается с самой высокой (самой левой) цифры:

a.to_s.each_char.map { |d|
  (even_odd.next == :even) ? 2*d.to_i : d.to_i }
  #=> [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]

Если индексация начинается с цифры:

s = a.to_s
even_odd.next if s.size.even?
s.each_char.map { |d| ( even_odd.next == :even) ? 2*d.to_i : d.to_i }
  #=> [4, 8, 0, 16, 0, 8, 1, 4, 3, 8, 5, 12, 7, 18, 0, 2] 

Вот шаги для примера, когда индексация с нуля начинается с цифры высшего порядка.

Массив # цикл преобразует массив [:even, :odd] перечислителю:

even_odd = [:even, :odd].cycle
even_odd.next #=> :even
even_odd.next #=> :odd
even_odd.next #=> :even
even_odd.next #=> :odd
...

b = a.to_s
  #=> "4408041234567901" 
enum0 = b.each_char
  #=> #<Enumerator: "4408041234567901":each_char> 

Перечислитель enum0 передает цифры b в map, Я мог бы вместо этого написать:

b = a.to_s.chars
  # => ["4", "4", "0", "8", "0", "4", "1", "2",
  #     "3", "4", "5", "6", "7", "9", "0", "1"] 

но это создает промежуточный массив. Перечислитель не является и, следовательно, более эффективным. Продолжение...

enum1 = enum0.map     
  #=> #<Enumerator: #<Enumerator: "4408041234567901":each_char>:map> 

Вы можете думать об этом как о "составном перечислителе". Мы можем увидеть его содержимое, преобразовав его в массив:

enum1.to_a
  #=> ["4", "4", "0", "8", "0", "4", "1", "2",
  #    "3", "4", "5", "6", "7", "9", "0", "1"] 

Метод each передаст каждый элемент перечислителя в блок. Доказательство:

enum1.each { |d| (enum.next == :even) ? 2*d.to_i : d.to_i }
  # => [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]

Мы можем вручную пройтись по элементам enum1 с помощью Enumerator # next. Мы присвоим значение переменной блока d и выполнить расчет в блоке для сопоставления цифры d:

d = enum1.next
  #=> "4" 
(enum.next == :even) ? 2*d.to_i : d.to_i
  #=> (:even == :even) ? 2*"4".to_i : "4".to_i
  #=> (true) ? 8 : 4
  #=> 8 ("4" is mapped to 8)

d = enum1.next
  #=> "4" 
(enum.next == :even) ? 2*d.to_i : d.to_i
  #=> (:odd == :even) ? 2*"4".to_i : "4".to_i
  #=> (false) ? 8 : 4
  #=> 4 ("4" is mapped to 4)

d = enum1.next
  #=> "0" 
  #=> (:even == :even) ? 2*"0".to_i : "0".to_i
  #=> (true) ? 0 : 0
  #=> 8 ("0" is mapped to 0)

и так далее.

Другие вопросы по тегам