В настоящее время я работаю над проблемой проекта Эйлера 14 .
Я решил это, используя плохо закодированную программу, без напоминаний, для выполнения которой потребовалось 386 5 секунд (см. Редактирование).
Вот оно:
step :: (Integer, Int) -> Integer -> (Integer, Int)
step (i, m) n | nextValue > m = (n, nextValue)
| otherwise = (i, m)
where nextValue = syr n 1
syr :: Integer -> Int -> Int
syr 1 acc = acc
syr x acc | even x = syr (x `div` 2) (acc + 1)
| otherwise = syr (3 * x + 1) (acc + 1)
p14 = foldl step (0, 0) [500000..999999]
У меня вопрос к нескольким комментариям в теме, относящимся к этой проблеме, где упоминалось время выполнения программ менее 1 с, как указано ниже (код C, кредиты пользователю форума проекта euler ix для кода - примечание: я не проверял, что время выполнения на самом деле соответствует указанному):
#include <stdio.h>
int main(int argc, char **argv) {
int longest = 0;
int terms = 0;
int i;
unsigned long j;
for (i = 1; i <= 1000000; i++) {
j = i;
int this_terms = 1;
while (j != 1) {
this_terms++;
if (this_terms > terms) {
terms = this_terms;
longest = i;
}
if (j % 2 == 0) {
j = j / 2;
} else {
j = 3 * j + 1;
}
}
}
printf("longest: %d (%d)\n", longest, terms);
return 0;
}
Мне кажется, что эти программы похожи, если говорить об алгоритме.
Так мне интересно, почему такая большая разница? Или есть какие-то принципиальные различия между нашими двумя алгоритмами, которые могут оправдать фактор x6 в производительности?
Кстати, в настоящее время я пытаюсь реализовать этот алгоритм с запоминанием, но я немного растерялся, его гораздо проще реализовать на императивном языке (и я пока не манипулирую монадами, поэтому не могу использовать эта парадигма). Поэтому, если у вас есть хороший учебник, который подходит новичку для изучения запоминания, я буду рад (те, с которыми я столкнулся, были недостаточно подробными или вышли из моей лиги).
Примечание: я пришел к декларативной парадигме через Пролог и все еще нахожусь в очень раннем процессе открытия Хаскелла, поэтому я могу пропустить важные вещи.
Примечание 2: любые общие советы по поводу моего кода приветствуются.
РЕДАКТИРОВАТЬ: благодаря помощи Делнана я скомпилировал программу, и теперь она запускается через 5 секунд, поэтому я в основном ищу подсказки по запоминанию (даже если идеи о существующем разрыве x6 все еще приветствуются) .