Если записать числа от 1 до 5 английскими словами (one, two, three, four, five), то используется всего 3 + 3 + 5 + 4 + 4 = 19 букв.
Сколько букв понадобится для записи всех чисел от 1 до 1000 (one thousand) включительно?
Примечание: Не считайте пробелы и дефисы. Например, число 342 (three hundred and forty-two) состоит из 23 букв, число 115 (one hundred and fifteen) – из 20 букв. Использование “and” при записи чисел соответствует правилам британского английского.
Задачи проекта Эйлера “цепляются” друг за друга и решения, потому что выработанные в первых задачах могут пригодиться в последующих, более сложных. Потому не стал все писать в функцию main(), а выделил подсчет букв в числе в отдельную функцию.
В итоге в main() только измеряется время выполнения программы и перебираются числа от 1 до 1000.
Это прототип функции. Пишется перед функцией main().
Сама реализация функции при этом определяется позже.
Описание работы функции count_letters()
Для начала сделал себе небольшую шпаргалку – выписал все числа и посчитал цифры в них.
При этом нужно помнить, что между сотнями и десятками добавляется and.
Для хранения длин чисел использовал массив:
массив[число] = длина числительного;
массив[12] = 6; //twelve
Также отдельно записаны длины 100, 1000 и and. Можно, конечно, в коде оперировать сразу цифрами, однако потом все конечно позабудется и станет непонятным.
Итак, числительное состоит из нескольких слов:
three hundred and forty-two
Потому сначала считаются тысячи в числе и прибавляется длина этих числительных:
count += 11 //one thousand
После – сотни:
count += 10 //one hundred
Далее, если count не равен нулю (т.е. в числе есть сотни или тысячи) и существует еще остаток числа (т.е. десятки и единицы) – добавляется and (count += 3).
В итоге подобным же образом добавляются длины десятков и единиц.
Контролируем корректность работы функции count_letters()
Поскольку в дальнейшем эта функция может быть применена в другой программе, то контекст может измениться. Потому, чтобы избежать неправильной работы, в ней сделана проверка корректности принимаемого значения.
if (num > 9999 || num < 1)
В итоге значения чисел, выходящие за рамки, на которые рассчитана функция, она считать не будет и сразу вернет 0.
Однако программа при этом не прервется, просто будет считаться длина следующих чисел. Потому, чтобы не гадать потом о причинах некорректного ответа, функция выведет некорректное число и предупреждение в консоль.
Измеряем время работы программы
Для измерения времени работы программы подключаем библиотеку time.h:
#include <time.h>
С помощью функции clock() измеряем время начала (begin) и окончания (end) работы программы. В итоге время работы будем находить как разность между ними.
CLOCKS_PER_SEC – это константа, сохраненная в библиотеке и зависящая от типа устройства, на котором запускается программа. В данном случае – это просто 1000
Ответ и скорость работы программы (проект Эйлера - 17 задача)
В итоге ответ на 17 задачу проекта Эйлера составил 21124, программа считает ответ мгновенно.
По традиции хотелось бы выразить глубочайшую признательность Сергею Балакиреву за его титанический труд по созданию бесплатных курсов и в частности, за “Язык программирования C/C++ для начинающих“.
Есть вопросы, господа? Отвечаем спокойно, четко и только по делу))