Читаем Программирование на языке Ruby полностью

Так как последняя цифра числа n равна остатку от деления на 10 (n%10), а целочисленное деление на 10 (n/10) равносильно удалению последней цифры, то построить цикл while, вычисляющий требуемую сумму, не слишком сложно. Обратите внимание на метод to_i, преобразующий строку в целое число. Его необходимо делать явно в отличие от вызываемого автоматически при работе puts метода to_s, выполняющего обратное преобразование числа в строку. Запустить эту программу, содержащуюся в файле sum1.rb, можно так: ruby suml.rb 12345.


n=ARGV[0].to_i

s = 0

while n > 0

     s += n%10

     n /= 10

end

puts s


Для опытного человека написание подобной программы не является проблемой, но новичок может сделать в ней несколько самых разных ошибок, поэтому будущих программистов знакомят с математическими методами проектирования циклов. Подобные знания зачастую абсолютно необходимы, но рассматриваемую задачу даже новичок сможет решить безошибочно, если воспользуется так называемым подходом Ruby (Ruby way). Он предполагает активное использование стандартных библиотек, что позволяет создавать короткие и ясные программы, не содержащие циклов, при проектировании которых так легко совершить ошибку.

Новая версия программы содержит последовательный вызов всего трёх методов и состоит из одной строки.

Метод scan[3] с параметром /./ преобразует строковое представление числа АRGV[0]в массив цифр, который обрабатывается методом inject – одним из так называемых итераторов, последовательно выполняющим действия, указанные в блоке (код в фигурных скобках), над каждым из элементов массива. При этом переменная s сначала инициализируется нулём, а на каждой итерации увеличивается на величину x.to_i, равную числовому значению очередной цифры х. Полученный результат затем печатается методом puts.

Отметим, что inject является методом модуля Enumerable, который включается (mix in) в различные классы, расширяя их возможности. Кроме массивов таким классом являются диапазоны (Ranges), чаще всего используемые в качестве последовательностей элементов: натуральные числа от 3 до 9 (3...9 или 3…10), латинские буквы от D до H (’D’..’H’) и т.п. При решении следующей задачи использование итератора each для диапазона чисел является вполне естественной идей.

Пример 4. Является ли простым число 15485863?

Напомним, что натуральное число является простым, если оно имеет ровно два различных делителя. Интерес к простым числам связан прежде всего с их использованием в криптографии. Подробнее об этом можно узнать на сайте http://en.wikipedia.org/wiki/Prime_numbers.


n=15_485_863

 (2...n).each do|i|

    if n % i == 0

      puts false; exit

    end

end

puts true


Наивный алгоритм проверки простоты числа n очевиден: будем последовательно находить остатки от деления n на числа 2, 3, 4 и так далее, вплоть до n-1. Если хотя бы один из остатков окажется нулевым, то число простым не является. Итератор each для каждого элемента диапазона выполняет блок (начинающийся do и заканчивающийся end[4]), проверяющий это условие и прекращающий выполнение программы (метод exit) в случае его выполнения. В Ruby операторы if, while и некоторые другие являются просто модификаторами выражений, что не так во многих других языках (обязательно ознакомьтесь с примерами на стр. 49).

Программа станет намного изящнее и понятнее, если воспользоваться методом any? (в Ruby имя метода может оканчиваться вопросительным знаком [5]) модуля Enumerable. Этот метод проверяет для элементов i диапазона (2...n) заданное в блоке условие n%i==0 и возвращает «истину» (true), как только встретит элемент, ему удовлетворяющий. Если же таких элементов не найдётся, то метод возвратит «ложь» (false). Отрицание (!) полученного результата является ответом на вопрос о простоте числа n.


n=15_485_863;put s !(2...n).any?{|i|n%i==0}


Аналогичный методу any? метод all? модуля Enumerable позволяет проверить истинность заданного в блоке условия для всех элементов коллекции. Этот модуль определяет ещё целый ряд методов, полный перечень можно получить с помощью команды ri Enumerable.

Пример 5. Найдите минимальное четырёхзначное число, уменьшающееся на 27 после перестановки его последней цифры на первую позицию.

puts(1000...10000).find{|x|x/10+1000*(x%10) == x-27}

Последняя цифра числа x – это x%10, а число, получающееся после её перестановки на первую позицию, равно значению выражения x/10+1000*(x%10). Таким образом, нам нужно найти (find) первое число из диапазона 1000…10000, для которого выполняется условие x/10+1000*(x%10) == x-27. Это делает метод find (или detect).

Заметим, что методы find_all и select, будучи применёнными к коллекции, возвращают массив всех тех её элементов, которые удовлетворяют заданному в блоке условию, а метод reject возвращает элементы, для которых условие оказывается ложным.

Перейти на страницу:

Похожие книги

Язык программирования Euphoria. Справочное руководство
Язык программирования Euphoria. Справочное руководство

Euphoria (юфо'ри, также рус. эйфори'я, ра'дость) — язык программирования, созданный Робертом Крейгом (Rapid Deployment Software) в Канаде, Торонто. Название Euphoria — это акроним для «End-User Programming with Hierarchical Objects for Robust Interpreted Applications».Euphoria — интерпретируемый императивный язык высокого уровня общего назначения. C помощью транслятора из исходного кода на Euphoria может быть сгенерирован исходный код на языке Си, который в свою очередь может быть скомпилирован в исполнияемый файл или динамическую библиотеку при помощи таких компиляторов, как GCC, OpenWatcom и др. Программа Euphoria также может быть «связана» с интерпретатором для получения самостоятельного исполняемого файла. Поддерживается несколько GUI-библиотек, включая Win32lib и оберток для wxWidgets, GTK+ и IUP. Euphoria имеет встроенную простую систему баз данных и обертки для работы с другими типам баз данных.[Материал из Википедии]

Коллектив авторов

Программирование, программы, базы данных