Правила просты:
- Первые n простых чисел (не простых ниже n ) должны быть напечатаны в стандартный вывод, разделенные символами новой строки (простые числа должны быть сгенерированы в коде)
- простые числа не могут быть сгенерированы встроенной функцией или библиотекой , то есть использование встроенной или библиотечной функции, такой как, prime = get_nth_prime (n), is_a_prime (number) или factorlist = list_all_factors (number), не будет очень креативным.
Оценка - скажем, мы определяем Score = f ([число символов в коде]), O ( f (n)) - сложность вашего алгоритма, где n - число простых чисел, которые он находит. Так, например, если у вас есть 300-символьный код со сложностью O (n ^ 2), оценка составляет 300 ^ 2 = 90000 , для 300 знаков с O (n * ln (n)) оценка становится 300 * 5.7 = 1711.13 ( давайте для простоты предположим, что все журналы являются натуральными)
Используйте любой существующий язык программирования, выигрывает самый низкий балл
Изменить: проблема была изменена с поиска «первых 1000000 простых чисел» на «первые n простых чисел» из-за путаницы в том, что такое «n» в O (f (n)), n - это число найденных простых чисел (поиск простых чисел проблема здесь и так сложность задачи зависит от числа найденных простых чисел)
Примечание: уточнить некоторые неурядицы на сложности, если «п» число простых чисел , вы найдете и «N» является п - й премьер - Found, сложность в терминах п и N не эквивалентны т.е. O (F (N))! = O (f (N)) as, f (N)! = Постоянная * f (n) и N! = Постоянная * n, потому что мы знаем, что n-я простая функция не является линейной, хотя, так как мы находили 'n' сложность простых чисел должна быть легко выражаемой через 'n'.
Как указал Кибби, вы можете посетить этот сайт, чтобы проверить свои решения ( здесь приведен старый список документов Google)
Пожалуйста, включите их в ваше решение -
Какова сложность вашей программы (включая базовый анализ, если не тривиальный)
длина символа
окончательный расчетный балл
Это мой первый вопрос CodeGolf, поэтому, если в вышеприведенных правилах есть ошибка или лазейка, пожалуйста, укажите на них.
источник
1[\p:i.78498
моим ответом для этого1[\p:i.1000000
. Даже если предположить, что внутренний простой алгоритм J равен O (n ^ 2), мой счет все равно будет только 196.n
является ли число простых чисел или максимальным простым, и все игнорируют тот факт, что сложение чисел в диапазоне0..n
равноO(logn)
, а умножение и деление еще дороже. Я предлагаю вам привести несколько примеров алгоритмов вместе с их правильной сложностью.O-tilde(k^6)
. Это приводит к тому, что любой, кто заявляет, что время выполнения лучше, чем кто-тоO-tilde(n ln n (ln(n ln n))^6)
, неправильно понял некоторую часть проблемы; и на вопрос о том, какO-tilde
сложности должны быть обработаны в оценке.Ответы:
Python (129 символов, O (n * log log n), оценка 203,948)
Я бы сказал, что Сито Эратосфена - это путь. Очень просто и относительно быстро.
Улучшен код с ранее.
Python (
191 156152 символа, O (n * log log n) (?), Оценка 252,620 (?))Я вообще не могу вычислить сложность, это лучшее приближение, которое я могу дать.
n*int(l(n)+l(l(n)))
является верхней границей вn
го простого числа.источник
n
но не на количестве простых чисел. Таким образом, я предполагаю, что оценка должна быть выше. Смотрите мой комментарий выше.n
? Что это такое?N=15485864
. Для вычисления сложности на основеn=1000000
, вы можете сказатьN=n*log(n)
(из-за плотности простых чисел).Haskell, n ^ 1.1, эмпирическая скорость роста, 89 символов, оценка 139 (?)
Следующее работает в подсказке GHCi, когда используемая им общая библиотека уже загружена. Выведите n-е простое число на основе 1:
let s=3:minus[5,7..](unionAll[[p*p,p*p+2*p..]|p<-s])in getLine>>=(print.((0:2:s)!!).read)
Это неограниченное сито Эратосфена, использующее универсальную библиотеку для упорядоченных списков. Эмпирическая сложность от 100 000 до 200 000 простых чисел
O(n^1.1)
. Подходит дляO(n*log(n)*log(log n))
.Об оценке сложности
Я измерил время выполнения для простых чисел 100 и 200 000, затем рассчитал
logBase 2 (t2/t1)
, что получилосьn^1.09
. Определениеg n = n*log n*log(log n)
, расчетlogBase 2 (g 200000 / g 100000)
даетn^1.12
.Тогда
89**1.1 = 139
, хотяg(89) = 600
. --- (?)Похоже, что для оценки следует использовать расчетную скорость роста вместо самой функции сложности. Например,
g2 n = n*((log n)**2)*log(log n)
намного лучше, чемn**1.5
, но для 100 символов оба дают результат3239
и1000
, соответственно. Это не может быть правдой. Оценка на диапазоне 200к / 100к даетlogBase 2 (g2 200000 / g2 100000) = 1.2
и, таким образом, оценку100**1.2 = 251
.Кроме того, я не пытаюсь распечатать все простые числа, а просто n- ое простое.
Без импорта, 240 символов. n ^ 1,15 эмпирическая скорость роста, оценка 546.
источник
Haskell,
7289 символов, O (n ^ 2), оценка 7921Самый высокий балл за счет символа выигрывает, верно? Модифицировано для первого N. Также я, видимо, не могу использовать калькулятор, поэтому мой результат не так ужасен, как я думал. (используя сложность для базового пробного деления, как показано в источнике ниже).
В соответствии с Will Ness нижеприведенное не является полной программой на Haskell (на самом деле она основана на REPL). Ниже приведена более полная программа с псевдоситом (при импорте фактически сохраняется символ, но мне не нравится импорт в кодовом гольфе).
Эта версия, несомненно, (п ^ 2). Алгоритм - всего лишь гольф-версия наивного "сита", как видно здесь Old ghci 1 liner
Оставляя старый, обманчивый ответ, потому что библиотека, на которую он ссылается, довольно хороша.
Смотрите здесь для реализации и ссылки для сложности времени. К сожалению, у колес есть время поиска журнала (n), что в некоторой степени замедляет нас.
источник
C #, 447 символов, байт 452, счет?
Вариант scriptcs, 381 символ, 385 байт, оценка?
Если вы устанавливаете скриптки, вы можете запустить его.
PS я написал это в Vim
:D
источник
=
и<
знак. Кроме того, я не думаю, что есть разница в байтах и символах для этого кода - это 548 символов и 548 байтов.GolfScript (45 символов, оценка ~ 7708)
Это делает простое пробное деление на простые числа. Если на переднем крае Ruby (то есть с использованием 1.9.3.0), арифметика использует умножение Toom-Cook 3, поэтому пробное деление равно O (n ^ 1.465), а общая стоимость делений равна
O((n ln n)^1.5 ln (n ln n)^0.465) = O(n^1.5 (ln n)^1.965)
†. Однако в GolfScript добавление элемента в массив требует копирования массива. Я оптимизировал это, чтобы копировать список простых чисел только тогда, когда он находит новое простое число, так что всего лишьn
раз. Каждая операция копирования - этоO(n)
элементы размераO(ln(n ln n)) = O(ln n)
†, дающиеO(n^2 ln n)
.И вот, мальчики и девочки, именно поэтому GolfScript используется для игры в гольф, а не для серьезного программирования.
†
O(ln (n ln n)) = O(ln n + ln ln n) = O(ln n)
. Я должен был заметить это, прежде чем комментировать различные сообщения ...источник
Это так просто, даже мой текстовый редактор может сделать это!
Vim: 143 нажатия клавиш (115 действий): O (n ^ 2 * log (n)): оценка: 101485,21
Подача конкурсных предложений:
Ввод: N должен быть в первой строке пустого документа. После этого каждое простое число от 2 до N будет отдельной строкой.
Выполнение команд:
Во-первых, обратите внимание, что любые команды с кареткой перед ними означают, что вам нужно удерживать Ctrl и вводить следующую букву (например, ^ V - это, Ctrl-vа ^ R - Ctrl-r).
Это перезапишет что-нибудь в ваших регистрах @a, @b, @d и @p.
Поскольку для этого используются qкоманды, его нельзя просто поместить в макрос. Тем не менее, вот несколько советов для его запуска.
qpqqdq
просто очищает регистрыA^V^Ayyp<Esc>3h"aC@a<Esc>0C1<Esc>@"dd
создаст список чисел от 2 до N + 1. Это разрыв между двумя основными частями, поэтому, как только это будет сделано, вам не нужно делать это сноваmpqdmd"bywo^Ra ^Rb 0 0 `pj@p ^Ra 0 ^R=@a%@b<Enter> `pdd@p 0 `dj@d<Esc>0*w*wyiWdd@0qqpmp"aywgg@dqgg@p
нужно набирать за один раз. Старайтесь избегать возврата, поскольку это может что-то испортить.qdqqpq
попробуйте эту строку еще раз.Для больших N это очень медленно. Потребовалось около 27 минут, чтобы запустить N = 5000; Считай себя предупрежденным.
Алгоритм:
Это использует основной рекурсивный алгоритм для поиска простых чисел. Учитывая список всех простых чисел от 1 до A, A + 1 является простым, если оно не делится ни на одно из чисел в списке простых чисел. Начните с A = 2 и добавьте простые числа в список по мере их обнаружения. После N рекурсий список будет содержать все простые числа до N
сложность
Этот алгоритм имеет сложность O (nN), где N - это входное число, а n - это число простых чисел до N. Каждая рекурсия проверяет n чисел, и выполняется N рекурсий, давая O (nN).
Тем не менее, N ~ n * log (n), давая окончательную сложность как O (n 2 * log (n)) ( https://en.wikipedia.org/wiki/Prime_number_theorem#Approximations_for_the_nth_prime_number )
объяснение
Нелегко отличить поток программы от команд vim, поэтому я переписал его на Python, следуя тому же потоку. Как и код Vim, код python выдаст ошибку, когда достигнет конца. Python не любит слишком много рекурсии; если вы попробуете этот код с N> 150 или около того, он достигнет максимальной глубины рекурсии
Теперь, чтобы сломать фактические нажатия клавиш!
qpqqdq
Очищает регистры @d и @p. Это гарантирует, что при настройке этих рекурсивных макросов ничего не запускается.A^V^Ayyp<Esc>3h"aC@a<Esc>0C1<Esc>@"dd
Превращает ввод в список чисел от 2 до N + 1. Запись N + 1 удаляется как побочный эффект настройки макроса @d.mpqdmd"bywo^Ra ^Rb 0 0 `pj@p ^Ra 0 ^R=@a%@b<Enter> `pdd@p 0 `dj@d<Esc>0*w*wyiWdd@0q
пишет макрос @d, который реализует функцию d () выше. Операторы «If» интересно реализовать в Vim. Используя оператор поиска *, можно выбрать определенный путь для следования. Разбивая команду дальше мы получаемmpqd
Установите здесь метку p и начните запись макроса @d. Метка p должна быть установлена, поэтому есть известная точка, к которой можно перейтиo^Ra ^Rb 0 0 `pj@p ^Ra 0 ^R=@a%@b<Enter> `pdd@p 0 `dj@d<Esc>
Записывает текст оператора if / else0*w*wyiWdd@0
фактически выполняет оператор if.@a @b 0 0 `pj@p @a 0 (@a%@b) `pdd@p 0 `dj@d
0
перемещает курсор в начало строки*w*w
Перемещает курсор к коду для выполнения следующего`pj@p
, который переходит к следующему числу для @a и запускает @p на нем.`pdd@p
удаляет текущее число @a, а затем запускает @p для следующего.`dj@d
проверяет следующее число для @b, чтобы увидеть, является ли оно фактором @ayiWdd@0
объединяет команду в регистр 0, удаляет строку и запускает командуq
заканчивает запись макроса @dПри первом запуске
`pdd@p
команда запускается, удаляя строку N + 1.qpmp"aywgg@dq
записывает макрос @p, который сохраняет число под курсором, затем переходит к первой записи и запускает @d для этого.gg@p
на самом деле выполняет @p, так что он будет перебирать весь файл.источник
QBASIC, 98 символов, сложность N Sqrt (N), оценка 970
источник
IF K=
(поэтому длина программы не будет включать цифру). В существующем состоянии программа печатает первые n простых чисел, не включая 2, которые можно исправить, добавив?2
в начале и изменивK=...
наK=...-1
. Программа также может быть golfed немного, беря пространства из состоянияJ=2 TO
,J=0 THEN
,K=...-1 THEN
и пути удаления отступов. Я считаю, что это приводит к программе из 96 символов.Scala 263 персонажа
Обновлен в соответствии с новыми требованиями. 25% кода посвящены поиску разумной верхней границы для вычисления простых чисел ниже.
Я тоже получил сито.
Вот эмпирический тест расчета затрат, не проявленный к анализу:
приводит к следующим подсчетам:
Я не уверен, как рассчитать счет. Стоит ли писать еще 5 символов?
Для больших n это сокращает вычисления примерно на 16% в этом диапазоне, но на самом деле для формулы оценки мы не учитываем постоянные факторы?
новые соображения Big-O:
Чтобы найти 1 000, 10 000, 100 000 простых чисел и так далее, я использую формулу о плотности простых чисел x => (math.log (x) * x * 1.3, которая определяет внешний цикл, который я запускаю.
Таким образом, для значений i от 1 до 6 => NPrimes (10 ^ i) выполняется 9399, 133768 ... раз внешний цикл.
Я нашел эту O-функцию итеративно с помощью комментария Питера Тейлора, который предложил гораздо более высокое значение для возведения в степень, а не 1,01, он предложил 1,5:
O: (n: Int) Long
ns: List [Long] = List (102, 4152, 91532, 1612894, 25192460, 364664351)
Это частное, если я использую 1.01 в качестве показателя степени. Вот что счетчик находит эмпирически:
Первые два значения являются выбросами, потому что я сделал постоянную коррекцию для моей оценки, формульной для небольших значений (до 1000).
С предложением Питера Тейлорса 1,5 это будет выглядеть так:
Теперь с моей ценностью я получаю:
Но я не уверен, насколько близко я могу приблизиться с моей O-функцией к наблюдаемым значениям.
источник
O(M^1.5 / ln M)
, и каждый раз, когда вы выполняетеO(ln M)
работу (сложение), так что в целом это такO(M^1.5) = O((n ln n)^1.5)
.def O(n:Int) = (math.pow((n * math.log (n)), 1.02)).toLong
я гораздо ближе к значениям, найденным эмпирически с помощью моего счетчика. Я вставляю свои выводы в свой пост.Ruby 66 символов, O (n ^ 2) оценка - 4356
lazy
доступен начиная с Ruby 2.0, и1.0/0
это крутой трюк для получения бесконечного диапазона:источник
(2..(1.0/0)).lazy.select{|i|!(2...i).any?{|j|i%j<1}}.take(n).to_a
(2..(1.0/0)).lazy.select{|i|(2..i).one?{|j|i%j<1}}.take(n).to_a
. Это сбривает еще двух персонажей.(2..(1.0/0)).lazy.select{|i|!(2...i).any?{|j|i%j<1}}.first(n)
получится 61 символ.Рубин, 84 символа, 84 байта, оценка?
Этот, вероятно, слишком новичок для этих частей, но я весело провел время, делая это. Он просто повторяется до тех пор, пока
f
(найденные простые числа) не будут равныn
желаемому числу простых чисел, которые будут найдены.Самое интересное в том, что для каждого цикла создается массив от 2 до одного меньше проверяемого числа. Затем он сопоставляет каждый элемент в массиве с модулем исходного числа и элемента и проверяет, равен ли какой-либо из результатов нулю.
Кроме того, я понятия не имею, как его забить.
Обновить
Код сжат и включает (совершенно произвольное) значение для
n
оригинал
i += 1
Бит иuntil
петли являются своего рода прыжки на меня , как области для улучшения, но на этой трассе я вроде застрял. Во всяком случае, было весело думать.источник
Скала, 124 персонажа
Простое пробное деление до квадратного корня. Сложность поэтому должна быть O (n ^ (1,5 + эпсилон))
124 ^ 1,5 <1381, так что это будет мой счет, я думаю?
источник
Perl - 94 символа, O (n log (n)) - Оценка: 427
Python - 113 символов
источник
AWK,
9686 байтПодзаголовок: Смотри, мама! Только добавление и некоторая бухгалтерия!
Файл
fsoe3.awk
:Бег:
BASH, 133 байта
Файл
x.bash
:Бег:
Простые числа вычисляются, позволяя уже найденным простым числам прыгать на «ленте натуральных чисел». В основном это сериализованное Сито Эратосфена.
... является тем же алгоритмом в Python и печатает время, когда
l
было найдено -мое простое число вместо самого простого.Вывод с
gnuplot
графиком дает следующее:Переходы, вероятно, связаны с задержками ввода / вывода из-за записи буферизованных данных на диск ...
Использование гораздо большего числа простых чисел для поиска приведет к дополнительным системно-зависимым задержкам в игре, например, массив, представляющий «ленту положительных целых чисел», непрерывно растет и рано или поздно заставит каждый компьютер потребовать больше оперативной памяти (или более позднюю замену).
... так что понимание сложности эксперимента не очень помогает ... :-(
Теперь посчитаем дополнения, необходимые для поиска
n
простых чисел:источник
Gnuplot
сset term xterm
и затем скриншотомxterm
графического окна России (вероятно, почти забытая особенность). ;-)Scala 121 (99 без эталона основного класса)
источник
Python 3,
117106 байтЭто решение немного тривиально, так как оно выдает 0, где число не простое, но я все равно опубликую его:
Кроме того, я не уверен, как решить сложность алгоритма. Пожалуйста, не отрицайте из-за этого. Вместо этого будьте добры и прокомментируйте, как я мог бы это решить. Кроме того, скажите мне, как я мог сократить это.
источник
print(i)
на той же линии, что и для цикла и удалить пробелы вin [2]
,0 if
,0 in [i%j
и+1,2)] else
.Haskell (52² = 2704)
источник
Perl 6, 152 байта, O (n log n log (n log n) log (log (n log n))) (?), 9594,79 балла
Согласно этой странице , сложность нахождения всех простых чисел до n равна O (n log n log log n); Приведенная выше сложность использует тот факт, что n-е простое число пропорционально n log n.
источник
Groovy (50 байт) - O (n * sqrt (n)) - оценка 353,553390593
Принимает n и выводит все числа от 1 до n, которые являются простыми.
Алгоритм, который я выбрал, выдает только простые числа n> 2, поэтому в начале необходимо добавить 1,2.
Сломать
x%it
- Неявная истина, если она не делится, ложь, если она есть.(2..x**0.5).every{...}
- Для всех значений от 2 до sqrt (x) убедитесь, что они не делятся, для того, чтобы это возвращало true, должно возвращаться true для каждого .(1..it).findAll{x->...}
- Для всех значений от 1 до n найдите все, что соответствует критериям неделимости между 2 и sqrt (n).{[1,2]+...}
- Добавьте 1 и 2, потому что они всегда простые и никогда не охватываются алгоритмом.источник
Ракетка 155 байт
Он хранит список найденных простых чисел и проверяет делимость каждого следующего числа на уже найденные простые числа. Более того, он проверяет только до квадратного корня проверяемого числа, поскольку этого достаточно.
Ungolfed:
Тестирование:
Выход:
источник
awk 45 (сложность N ^ 2)
другой
awk
, для простых чисел до 100, используйте этокод гольф считается частью
который можно поместить в файл сценария и запустить как
awk -f prime.awk <(seq 100)
источник
Javascript, 61 символ
Немного хуже, чем O (n ^ 2), не хватит места в стеке для больших n.
источник