Ruby и красивый код #2

ноября 18, 2010  |  Published in Ruby, Основы

rubyЭто 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)

Браво!

Tags: , ,

Ruby и красивый код #1

октября 19, 2010  |  Published in Ruby, Основы

ruby Благодаря некоторым особенностям Ruby, код на нем можно писать значительно более лаконичный, чем вы можете себе это представить. Например, благодаря тому, что Ruby возвращает значение последнего выражения, можно сократить количество кода не только за счет отказа от использования return, там, где это возможно, но и за счет написания простых методов, которые в итоге своей работы возвращают только true или false не используя при этом логический конструкций типа if..else, и т.д.
Read the rest of this entry »

Tags: ,