Здравствуйте, Seon, Вы писали:
S>Здравствуйте, Erop, Вы писали:
E>>Вариант с двумя цифрами на байт: E>>Вариант с четырьмя цифрами на short: E>>Вариант с четырьмя цифрами на short, и без проверок цепочек нулей, не выходящих на границы цепочек (очевидно, что для k > 2 это не важно)
S>А как на счет 8 на INT?
S>... а еще есть вариант 4 цифры на ИНТ, (по 1 на байт)
E>>Будет время -- попробую обработать переполнение кэша.
S>Есть более радикальное решение: S>Обрабатывать числа по частям. Ведь для удвоения нам достаточно знать цифру с которой начинать, а это всегда 1, и значение переноса из предыдущего разряда, это 1 или 0 — его запоминать в файле.
S>Расчитываем числа, длиной например в 1 000 000, — это приблизительно 3 200 000-я степень двойки. Продолжаем считать их например до 1000 000 000 000, запоминая в файле для каждой степени один байт, в котором 1 бит — значение переноса, остальные биты — количество нулей, которые имело число с левой стороны. Таким образом получаем файл в 1000 000 байт.
S>Затем мы расчитываем числа со степени 3 200 000, начиная с 1, учитывая значения переноса из файла. А при подсчете нулей, начальное количество нулей берем так же из файла.
S>Ресурс файла по количеству нулей — 127. То есть эта схема файла позволит рассчитать числа до 127 нулей подряд.
S>Этот алгоритм позволит избавить поиск чисел от зависимости на количество используемой памяти программой. И кстати легко может быть распределен между компьютерами. S>1-й ищет части числа 1 000 000 000 000? второй 1 000 000 000 000, третий 1 000 000 000 000, четвертый 1 000 000 000 000.
S>Кто возьмется писать такую программу, просьба маленькая : S>- сделать консольную программу, которая в качестве параметров принимает количество итераций, выходной файл переносов, входной файл переносов. (2 параметра — считать что перенос всегда 0) S>- программа должна делать периодическое сохранение промежуточных данных (всего массива чисел), для того чтобы в любой момент можно было продолжить вычисления. S>- должна позволить продолжить вычисления, получив четвертый параметр — текущее состояние
S>
S>Удачи, программисты!
Кстати отсюда вылезает задача о повторяемости:
Через какое количество итераций, числа 1 000 000 000 начнут повторяться, и можно будет для 1 000 000 000 использовать один и тот же файл...
0:00:01 : 2^242 = 3, 3, len = 73
E>>0:00:01 : 2^377 = 4, 4, len = 114
E>>0:00:01 : 2^1491 = 5, 5, len = 449
E>>0:00:01 : 2^1492 = 6, 6, len = 450
E>>0:00:01 : 2^6801 = 7, 7, len = 2048
E>>0:00:01 : 2^14007 = 8, 8, len = 4217
E>>0:00:09 : 2^100823 = 9, 9, len = 30351
E>>0:04:24 : 2^559940 = 10, 10, len = 168559
E>>0:18:23 : 2^1148303 = 11, 11, len = 345674
Гонял на Core(TM) Duo CPU T2450 2,00 GHz под вистой... E>>А ты?
S> Семпрон 1.8 W2003 в belownormal
S>a(12) — 2^4036332 11 часов 18 минут
3:47:15 : 2^4036338 = 12, 12, len = 1215059
3:47:16 : 2^4036339 = 13, 13, len = 1215060
Не совсем понятно от чего 13 не попался сразу. Короче медленно всё. Даже до известного a(17), который пол миллиард, и то бесконечно долго считать будет
S>сейчас приближается к 10 миллионам со скоростью где-то 20 чисел в секунду
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Spiceman, Вы писали:
S>Больше всего понравилось решение на Хаскеле. В одну строчку — впечатлило!
Ну на любом языке с поддержкой длинных чисел будет коротко. Вот на С++ с соответствующей библиотекой, например
Другое дело, что будет медленно.
Кстати, чтобы было веселее, предлагаю немного изменить условие задачи — посчитать функцию a( k, base ), где base -- основание системы счисления.
Конечно для степеней двойки задача вырождается, но можно рассмотреть основание 9 или 11, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Roman Odaisky, Вы писали:
RO>А вот моя версия. Подход немножко другой, используется 10¹⁶-ричная система счисления.
И что? Как работает?
IMHO, отдельно умножать, и отдельно подсчитывать нули очень невыгодно, так как достаточно длинное число придётся тягать в кэш дважды за тестируемую степень двойки, о хотелось бы на много степеней двойки тягать число в кэш только один раз...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Seon, Вы писали:
S>Не понял, почему вырождается?
потому, что "2 в степени 666" в 8-ричной системе записывается как 1 с 222 нулями
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, vadimcher, Вы писали:
V>Было бы здорово, если бы все еще свой код выкладывали. Просто интересно сравнить эффективность/простоту для разных языков.
Имхо, суть не в применяемых языках, а в алгоритме. Все приведенные здесь примеры что я пересмотрел (все не смотрел — лень) производят умножения по одной цифре. Я же использую int64 с 17 цифрами, то есть я умножаю в 17 раз быстрее.
Кстати, основная сложность не в умножении, а в проверке числа. Здесь у меня другая оптимизация, но это пока секрет .
Здравствуйте, Seon, Вы писали:
S>А где же результаты работы? :)) S>Степени + временные интервалы? :shuffle:
~/src :) time ./kzeros 7
6801
./kzeros 7 0.12s user 0.00s system 100% cpu 0.124 total
~/src :) time ./kzeros 8
...10000...
14007
./kzeros 8 0.46s user 0.01s system 99% cpu 0.472 total
Здравствуйте, Pro100Oleh, Вы писали:
PO>Здравствуйте, vadimcher, Вы писали:
V>>Было бы здорово, если бы все еще свой код выкладывали. Просто интересно сравнить эффективность/простоту для разных языков.
PO>Имхо, суть не в применяемых языках, а в алгоритме. Все приведенные здесь примеры что я пересмотрел (все не смотрел — лень) производят умножения по одной цифре. Я же использую int64 с 17 цифрами, то есть я умножаю в 17 раз быстрее. PO>Кстати, основная сложность не в умножении, а в проверке числа. Здесь у меня другая оптимизация, но это пока секрет .
Вот вас и просят показать свой алгоритм...
Интересно как это вы в инт64 впихнули 17 цифр
вы говорите в 17 раз быстрее...
У вас на 4 кирпичах — a(11) — 10 минут
У меня на 1 кирпиче — а(11) — 47 минут
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Seon, Вы писали:
S>>Не понял, почему вырождается? E>потому, что "2 в степени 666" в 8-ричной системе записывается как 1 с 222 нулями
RO>~/src :) time ./kzeros 7
RO>6801
RO>./kzeros 7 0.12s user 0.00s system 100% cpu 0.124 total
RO>~/src :) time ./kzeros 8
RO>...10000...
RO>14007
RO>./kzeros 8 0.46s user 0.01s system 99% cpu 0.472 total
RO>
Мдя... медленновато.
Вы тратите много времени на перевод в 10-ю, видимо.
Мы тутачки работаем ужо сразу в десятичной.
14007 считается — 1-2 секунды.
S>>Меня смутил ретурн вот здесь S>>
RO>Это же return из main. Там раньше был еще return 1 на случай ненахождения результата, но я потом его убрал.
Та при чем тут 0 или 1. Зачем вываливаться из цикла как только нашли результат? Не уж-то нельзя продолжить поиск следующего числа?
Зачем потом тратить время опять на умножение сначала?
Здравствуйте, Seon, Вы писали:
S>Здравствуйте, Pro100Oleh, Вы писали:
PO>>Здравствуйте, vadimcher, Вы писали:
V>>>Было бы здорово, если бы все еще свой код выкладывали. Просто интересно сравнить эффективность/простоту для разных языков.
PO>>Имхо, суть не в применяемых языках, а в алгоритме. Все приведенные здесь примеры что я пересмотрел (все не смотрел — лень) производят умножения по одной цифре. Я же использую int64 с 17 цифрами, то есть я умножаю в 17 раз быстрее. PO>>Кстати, основная сложность не в умножении, а в проверке числа. Здесь у меня другая оптимизация, но это пока секрет .
S>Вот вас и просят показать свой алгоритм... S>Интересно как это вы в инт64 впихнули 17 цифр
S>вы говорите в 17 раз быстрее...
S>У вас на 4 кирпичах — a(11) — 10 минут S>У меня на 1 кирпиче — а(11) — 47 минут
S>Где же тут в 17 раз быстрее? интересно
В 17 раз — имеется ввиду теоретическое улутчение в операции умножения, так как я за раз умножаю 17 цифр, а не одну. Но кроме самого умножения выполняются и проверка на нули. Кстати, здесь минус моего алгоритма, так как мне приходится искать втутри многоцифренномго числа нули.
На самом деле можно использовать даже 18 цифр, потому что мы используем только умножения на два: (10е18-1)*2 < Int64.MaxValue = 9,223,372,036,854,775,807. По поводу алгоритма — чуть розже, так как с сегодняшнего дня я в отпуске, а код остался на работе.
RO>>~/src :) time ./kzeros 7
RO>>6801
RO>>./kzeros 7 0.12s user 0.00s system 100% cpu 0.124 total
RO>>~/src :) time ./kzeros 8
RO>>...10000...
RO>>14007
RO>>./kzeros 8 0.46s user 0.01s system 99% cpu 0.472 total
RO>>
S>Мдя... медленновато. :-\
S>Вы тратите много времени на перевод в 10-ю, видимо. S>Мы тутачки работаем ужо сразу в десятичной. S>14007 считается 1—2 секунды.
Написано же — 0,46 с.
S>Зачем вываливаться из цикла как только нашли результат? Неужто нельзя продолжить поиск следующего числа? S>Зачем потом тратить время опять на умножение сначала?