2016-07-28 2 views
0

Как я могу вернуть массив чисел палиндрома в заданном массиве? Не палиндромные числа, такие как 11, 22, 33, 44, & c., Но числа, которые являются палиндромными для другого числа в том же массиве. Предположим, что все элементы положительны, и результат не должен возвращать однозначные цифры (пример ниже)Возвращаемые элементы, которые являются палиндром друг к другу в массиве

Предположим, у меня есть array = [13, 31, 51, 79, 83, 97]. С 13 & 31 и 79 & 97 являются палиндромов, я хочу, чтобы вернуть array_pali = [13, 31, 79, 97]

def pali_array(array) 
    array_reverse = array.map{|el| el.to_s.reverse.to_i} 
    array_pali = array & array_reverse 
    return array_pali 
end 

Мой первоначальный план должен придумать реверсе этого массива, array_reverse = array.map{|el| el.to_s.reverse.to_i} и пересекают их: array & array_reverse

А проблема что происходит, если я хочу, чтобы вернуть массив простых чисел от 2-100, как указано:

array = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 

и я его вспять:

array_reverse = array.map{|el| el.to_s.reverse.to_i} 
=> [2, 3, 5, 7, 11, 31, 71, 91, 32, 92, 13, 73, 14, 34, 74, 35, 95, 16, 76, 17, 37, 97, 38, 98, 79] 

Она возвращает:

array & array_reverse 
=> [2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, 97] 

Проблема с этим подходом:

2, 3, 5, 7 и 11 не являются палиндромами к другим элементам. Обратное однозначное число - это само число, и это заставляет код возвращать все одиночные цифры и все палиндромное число (например, 11, 22, 33). Она должна возвращать только [13, 17, 31, 37, 71, 73, 79, 97]

Как я могу сделать это, чтобы вернуть только элементы, которые палиндромический к другому элементу в том же массиве?

+0

Просто добавьте еще один шаг фильтра, чтобы удалить палиндромные цифры. – Amit

+0

Нет такой вещи, как «палиндромный». 1, 121 и 12321 - все [по определению палиндромы] (https://en.wikipedia.org/wiki/Palindromic_number). 13 и 31 не являются «палиндромными», они являются одинаковыми числами с цифрами, противоположными. – tadman

+1

Я только что увидел этот вопрос и был удивлен, увидев, что вы выбрали ответ только через 35 минут! Почему бы не задержаться хотя бы на пару часов, чтобы поощрить другие ответы. Вы не знаете, что вам нужно. –

ответ

1

Думаю, что это работает, если вы хотите альтернативу:

array = [13, 31, 51, 79, 83, 97] 
array.combination(2) 
    .select {|pair| pair.first.to_s == pair.last.to_s.reverse } 
    .flatten 

#=> [13, 31, 79, 97] 

Используйте Array#combination, чтобы получить каждую пару комбо, то мы выбрать только те палиндром-пар. Затем просто сгладьте свой массив.

+3

O (N^2). Удвоение входного времени в четыре раза: –

+0

True. Для того, что я делаю, Big O на самом деле не имеет значения. Хороший улов, хотя! – Iggy

2

Вот очень наивная и ленивая реализация. Не сохраняет оригинальный порядок элементов. Должен быть O (N).

Надеюсь, код не требует пояснений.

array = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 

require 'set' 
seen_numbers = Set.new 
result = [] 

array.each do |elem| 
    next if elem < 10 

    normal_str = elem.to_s 
    rev_str = normal_str.reverse 

    if seen_numbers.include?(rev_str) 
    result << rev_str.to_i 
    result << elem 
    end 

    seen_numbers << normal_str 
end 

result # => [13, 31, 17, 71, 37, 73, 79, 97] 
1
arr = [7, 13, 31, 51, 31, 60, 70, 13, 79, 83, 79, 97] 

Обратите внимание, что в arr имеются различные повторяющиеся значения.

arr.reject { |n| n < 10 || (n%10).zero? }. 
    group_by { |n| n.to_s.each_char.sort }. 
    values. 
    reject { |arr| arr.size == 1 }. 
    flat_map { |arr| arr.group_by(&:itself).values.min_by(&:size) } 
    #=> [13, 13, 97] 

Соответствующие значения достаточно просты для вычисления, если требуется.

|| (n%10).zero? был добавлен, чтобы немного ускорить работу.

Шаги следующие.

a = arr.reject { |n| n < 10 || (n%10).zero? } 
    #=> [13, 31, 51, 31, 13, 79, 83, 79, 97] 
b = a.group_by { |n| n.to_s.each_char.sort } 
    #=> {["1", "3"]=>[13, 31, 31, 13], ["1", "5"]=>[51], 
    # ["7", "9"]=>[79, 79, 97], ["3", "8"]=>[83]} 
c = b.values 
    #=> [[13, 31, 31, 13], [51], [79, 79, 97], [83]] 
d = c.reject { |arr| arr.size == 1 } 
    #=> [[13, 31, 31, 13], [79, 79, 97]] 
d.flat_map { |arr| arr.group_by(&:itself).values.min_by(&:size) } 
    #=> [13, 13, 97] 

Рассмотрите на последнем шаге.flat_map проходит первый элемент d к своему блоку и устанавливает переменную блока к этому значению:

arr = d[0] 
    #=> [13, 31, 31, 13] 

и выполняет вычисление блока:

e = arr.group_by(&:itself) 
    #=> {13=>[13, 13], 31=>[31, 31]} 
f = e.values 
    #=> [[13, 13], [31, 31]] 
f.min_by(&:size) 
    #=> [13, 13] 

Далее,

arr = d[1] 
    #=> [79, 79, 97] 
e = arr.group_by(&:itself) 
    #=> {79=>[79, 79], 97=>[97]} 
f = e.values 
    #=> [[79, 79], [97]] 
f.min_by(&:size) 
    #=> [97] 

flat_map поэтому возвращается

[*[13, 13], *[97]] 
    #=> [13, 13, 97] 
Смежные вопросы