Ruby и красивый код #2
ноября 18, 2010 | Published in Ruby, Основы | 15 Comments
Это 2я статья из серии «Ruby и красивый код».
Ruby и красивый код #1
Задача №1 по высокоуровневому программированию (ФГОУ ДПО МЭТТ ГАИ)
Эта задача использовались автоматизированной системой тестирования при проведении контрольных работ по предметам: «Программирование на языке высокого уровня» и «Программное обеспечение компьютерных сетей» в 2006-2007 учебном году.
Задача: Дан целочисленный массив. Необходимо вывести вначале его элементы с четными индексами, а затем — с нечетными.
Решение #1
arr = (1..9).to_a indexes, p, np = [], [], [] arr.each_index{|i| indexes << i} for i in indexes if i % 2 == 0 p << i else np << i end end for i in p puts arr[i] end puts "---" for i in np puts arr[i] end
Решение #2
arr = (1..9).to_a arr.each_with_index do |elem, index| puts elem if (index % 2) == 0 end arr.each_with_index do |elem, index| puts elem if (index % 2) != 0 end
Решение #3 - Немного измененное решение #2
arr = (1..9).to_a n, np = [], [] arr.each_with_index do |elem, index| if (index % 2) == 0 p << elem else np << elem end end puts p puts "---" puts np
Первое решение задачи - решение человека, не знающего о существовании метода each_with_index (мое). Второе решение - решение моего друга, который значительно более опытный програмист чем я и который знает о существовании метода each_with_index (Максим, спасибо!). Третье решение - мое, его я создал для решения некоторых недостатков решения номер 2, а именно: вместо двух обходов по массиву теперь остался лишь один, кроме того значения под парными и непарными индексами не просто выводятся на экран, но и сохраняются в соответствующие масивы p и np для возможности их дальнейшего использования.
Выводы: Первое решение можно отнести к over engineering, так как в нем слишком много кода, что связано с малым опытом работы на языке Ruby. Второй метод наиболее лаконичный и читабельный, а третий найдет большее применение.
Создаем себе Золотое правило: Прежде, чем писать код, следует убедиться в том, что метода реализующего полностью или частично необходимую функциональность, нету. Спешка и нежелание работать с документацией - большие враги программиста!
Обновление #1:
Вот придумал еще один интересный способ решения:
arr = (1..9).to_a p, np = [], [] arr.each_index do |i| i%2 == 0 ? p << i : np << i end puts arr.values_at(*p) puts arr.values_at(*np)
Обновление #2:
Максим предоставил еще более изящный вариант решения задачи:
arr = (1..9).to_a even_indexes, odd_indexes = (0..(arr.size - 1)).partition {|i| i % 2 == 0} puts arr.values_at(*even_indexes) puts arr.values_at(*odd_indexes)
Браво!
ноября 18, 2010 at 20:56 (#)
Предлагайте свои варианты решения сей задачи.
ноября 18, 2010 at 20:58 (#)
а как же логические методы .even? и .odd? ?
ноября 18, 2010 at 21:23 (#)
Как вариант с занесением в разные массивы:
ноября 18, 2010 at 21:31 (#)
ну или вот так:
ноября 18, 2010 at 21:47 (#)
RomanY, здорово! ;-)
ноября 19, 2010 at 21:50 (#)
RomanY и Максим уже показали много всего красивого, лаконичного, правильного…
Так что следующие варианты приведены сугубо для рашрирения кругозора и знания ruby.
Ссылки:
ноября 19, 2010 at 22:42 (#)
dre3k, спасибо за полезные, особенно в плане знакомства с новыми методами, примеры!
ноября 24, 2010 at 23:12 (#)
Поскольку в условии задачи не сказано что элементы должны выводиться в том же порядке в каком встречаются в исходном массиве, то можно предложить еще такой вариант:
декабря 28, 2010 at 14:40 (#)
[...] Предыдущие статьи из рубрики: Ruby и красивый код #1 Ruby и красивый код #2 [...]
августа 11, 2011 at 16:55 (#)
#!/usr/bin/ruby -w
#Дан целочисленный массив. Необходимо вывести вначале его элементы с четными
#идексами, а затем — с нечетными.
arr = Array.new(10) { |index| index+1 }
arr.each_with_index { |elem, index| print «#{elem}» unless index%2 != 0 }
puts «»
arr.each_with_index { |elem, index| print «#{elem}» unless index%2 == 0}
puts «»
февраля 13, 2012 at 22:35 (#)
Блин, изучаю руби пару дней, но по-моему мое решение лучше большинства …
мая 13, 2012 at 15:21 (#)
a = [1, 2, 3, 4, 5, 6, 7, 8]
a1 = []
a2 = []
a.length.times { |i| (i.odd? ? a1 : a2) << a[i] }
puts a1
puts a2
октября 15, 2012 at 14:11 (#)
Понравилось решение Val’a, только всё-таки добавил бы исходный порядок следования элементов
ноября 6, 2012 at 12:27 (#)
p arr.partition { |e| arr.index(e).even? }
июня 1, 2013 at 17:05 (#)
[language]
[* 1..100].partition { |i| i.even? } .each { |e| p e }
[language]