Неудачные номера!


22

Что нужно знать:

Во-первых, счастливые числа.

Счастливые числа генерируются так:

Возьмите все натуральные числа:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20...

Затем удалите каждый второй номер.

1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39...

Теперь 3безопасно.

Удалить каждый третий номер:

1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49, 51, 55, 59...

Теперь 7безопасно.

Удалить каждый 7-й номер.

Продолжите и удалите каждый nномер, где nнаходится первый безопасный номер после исключения.

Финальный список безопасных чисел - счастливые числа.


Неудачные числа составлены из отдельных списков чисел, которые есть [U1, U2, U3... Un].

U1 это первый набор чисел, удаляемых из счастливых «кандидатов», поэтому они:

2, 4, 6, 8, 10, 12, 14, 16, 18, 20...

U2 удален второй набор чисел:

5, 11, 17, 23, 29, 35, 41, 47, 53, 59...

И так далее, и тому подобное ( U3третий список, U4четвертый и т. Д.)


Вызов:

Ваша задача, когда дано два входа mи n, сгенерировать mчисло в списке Un.

Пример входов и выходов:

(5, 2) -> 29
(10, 1) -> 20

Технические характеристики:

  • Ваша программа должна работать mдо 1e6и nдо 100.
    • Вам гарантировано, что оба mи nявляются положительными целыми числами.
    • Если вам интересно, U(1e6, 100)= 5,333,213,163. (Спасибо, @pacholik!)
  • Ваша программа должна вычислить это в течение 1 дня на разумном современном компьютере.

Это , поэтому выигрывает самый короткий код в байтах!

PS: Было бы хорошо, если бы кто-то придумал общую формулу для их генерации. Если у вас есть формула, укажите ее в своем ответе!


В OEIS: A219178 и A255543
Арно


2
Вы реализовали код, который действительно может выполнять (1e6,1e6)?
Джонатан Аллан

2
Если вам требуется время, вам нужно указать среду синхронизации (например, ваш компьютер, свободно доступную виртуальную машину или «разумный современный компьютер»).
Мего

1
Допустимо ли, чтобы функция не работала для n=1случая? Поскольку это особенное - для всех остальных случаев индекс следующего счастливого числа на основе 0 равен n-1.
Миридиум

Ответы:


1

CJam , 74 байта

ri0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A0@{@:B:(_0#):D{D(_A=tD<BD>+}&@)@DU=-}h]1=

Попробуйте онлайн! Тайм-аут для более крупных случаев, более подробно о временных ограничениях ниже.


Объяснение:

Наша программа беззастенчиво заимствует код aditsu для генерации списка из N счастливых чисел, замена 1 на 2 дает приращение в каждой фазе сита. Оставшийся код уменьшается в каждом элементе до тех пор, пока не будет найден ноль (путем нарезки и добавления невырожденного хвоста), и эффективно подсчитывает шаги в каждой из N фаз решета сразу.

ri                               e# read M
0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A  e# list steps (also becomes B)
0@                               e# arrange stack [B I M]
{                                e# while M
   @:B                           e#   get current B
   :(                            e#   decrement every element in B
   _0#):D                        e#   find first 0
   {                             e#   if there is a 0
      D(_A=t                     e#     reset that element in B
      D<BD>+                     e#     replace tail after 0
   }&                            e#   end if
   @)                            e#   increment I
   @DU=-                         e#   decrement M if N-th phase of sieve
}h                               e# end loop
]1=                              e# return I

Сроки:

Если вам абсолютно необходимо запустить программу в браузере для больших чисел, вы можете использовать этот интерпретатор и разрешить выполнение сценария, если будет предложено, но это может быть слишком медленным для определения. Использование ( M , N ) = (100,100) занимает ~ 247 с. Итерация программ относительно линейна с точки зрения M , поэтому вычисления (1 6 100) могут занять ~ 29 дней.

Используя интерпретатор оболочки на ПК, программа вычисляет (100 100) за ~ 6 с и вычисляет (1 e4 100) за ~ 463 с. Программа должна быть в состоянии вычислить (1e6,100) в ~ 13-17 часов. В этом случае я буду считать, что программа соответствует требованиям.

Обратите внимание, что все времена были округлены в обоих измерениях и расчетах.


7

Perl, 87 85 82 81 байт

Включает +4 для -pX

Введите ввод в STDIN одной строкой с первым n (обратите внимание, что это обратный порядок, предложенный в тесте). Итак, для расчета U(1000000, 100):

unlucky.pl <<< "100 1000000"

Алгоритм, основанный на счастливых числах ответа aditsu. Сложность времени заключается в том, что он достаточно быстр для требуемого диапазона. O(n^2)100, 1000000Случай дает 5333213163в 0,7 секунды. Из-за проблем, которые Perl имеет с do$0основанной рекурсией, он использует много памяти. Переписав его как функцию, можно использовать памятьO(n) но на несколько байт длиннее

unlucky.pl:

#!/usr/bin/perl -pX
$_=$a{$_}||=/\d+$/>--$_?2*$&+$^S:($_=$_.A.(do$0,$^S?0|$&+$&/~-$_:$&*$_-1),do$0)

Это работает, как показано, но использовать буквальный ^S чтобы получить заявленную оценку.

Я не знаю о каком-либо более раннем использовании $^Sв Perlgolf.


Но сколько времени это займет (1e6,100)?
Миридиум

@ Myridium Из-за взрыва памяти, вызванного do$0этим, в основном недоступен на любом реалистичном компьютере. Но если такая память существовала около 2 лет. Я действительно не написал и не протестировал нормальную версию для подпрограмм, но я ожидал, что она закончится через несколько месяцев и будет запущена даже на компьютерах с очень небольшим объемом памяти. Поэтому хорошо, что эти значения не находятся в требуемом диапазоне для этой задачи.
Тон Хоспел

Разве задача не рассчитать в (1e6,100)течение дня? Что вы имеете в виду, эти значения не обязательны?
Миридиум

@ Myridium Обратите внимание, что в моей программе nи mданы в обратном порядке. 100 1000000Вход вычисляет U(1000000, 100)и выдает 5,333,213,163в 0,7 секунды. Это, безусловно, самая быстрая программа из всех опубликованных на данный момент
Тон Хоспел,

А, ладно, я ожидал, (100,1e6)что это будет намного быстрее (1e6,100), и подумал, что это объяснение молниеносной скорости 0,7 секунды!
Миридиум

7

Питон 3, 170

from itertools import*
def L(n,k=1):
 if n<2:yield from count(2+k,2)
 t=L(n-1);l=next(t)
 for i in t:
  n+=1
  if(n%l>0)==k:yield i
U=lambda m,n:sum(islice(L(n,0),m-1,m))

Функция L генерирует ряд возможных счастливых чисел (если k - True) или Un (если False). Оценивается лениво (поэтому мне не нужно генерировать n-1 бесконечных списков, если я хочу Un ).

Запустить функцию U .

скорость

U (1 000 000; 100) требуется около 1 часа 45 минут, чтобы работать на моей машине с PyPy. Я подозреваю, что около четырех часов с CPython. (Да, 4ч 20мин, если быть точным.)

Если бы я использовал список вместо генераторов, я мог бы получить некоторую скорость, но мне нужен список большего размера, чем позволяет мне Python. И если бы это произошло, потребовались бы десятки гигабайт оперативной памяти.


Да, и U (1 000 000; 100) = 5 333 213 163 .


Должен быть действительным сейчас.
clismique

3

Haskell

Невозможно вычислить для n = 1: 175 160 байтов

После компиляции моему компьютеру потребовалось 2 часа 35 минут, чтобы вычислить следующие данные (1000000,100):

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 2=[1,3..]
l m=((l$m-1)!!(m-2))%(l$m-1)
m?n=(((l n)!!(n-1))#(l$n))!!(m-1)

Я попытался избавиться от whereмодулей, но они, кажется, влияют на скорость, и я не уверен, почему ... Но я думаю, что здесь нужно сделать больше обрезки.

Метод, используемый m?nдля запроса ответа, заданного mи n.

Ungolfed

everynth n xs = y:(everynth n ys) -- Takes every nth element from a list 'xs'
  where y:ys = drop (n-1) xs

skipeverynth n xs = f' n xs $ []  -- Removes every nth element from a list 'xs'
  where f' n xs = (take (n-1) xs ++) . f' n (drop n xs) 

l 2 = [1,3..] -- The base case of the list of lucky numbers for 'n=2'
l m = skipeverynth ((l$m-1)!!(m-2)) (l$m-1) -- Recursively defining next case as being the last one with every 'ath' element skipped. Here, 'a' is the (m-1)th elemnent of the (l (m-1)) list.
ul m = everynth ((l m)!!(m-1)) (l$m) -- This is not used other than to compute the final, required unlucky number list. It picks out every 'ath' element.

ans m n = (ul n)!!(m-1) -- The function giving the answer.

Я считаю, что возможно объединить функции 'skipeverynth' и 'everynth' в одну функцию, которая возвращает пару.

Я использовал код этого доброго человека для пропуска каждого n-го элемента. Я сам делал это несколько раз, но это всегда было гораздо более неэффективно, и я не мог понять, почему.

Возможность вычислить для всех n: 170 байт

Это в основном то же самое, но maxдля обработки особого случая пришлось добавить пару функций n=1.

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 1=[1..]
l m=((l$m-1)!!(max 1$m-2))%(l$m-1)
m?n=(((l n)!!(max 1$n-1))#(l$n))!!(m-1)

2

R 82 байта

f<-function(m,n){a=1:2e8
i=1
while(i<n){a=c(0,a)[c(F,rep(T,i))]
i=i+1}
a[(n+1)*m]}

использование

f(5,2)
Returns 29

Для этого нужно иметь достаточно большой вектор, чтобы осталось достаточно чисел для возврата значения. Созданный вектор уже имеет размер около 800 Мб, и функция может обрабатывать до m = 1e4 и n = 100, поэтому все еще далеко от цели.

Чтобы создать достаточно большой вектор для вычисления f (1e6,100), потребуется начальный вектор 1: 2e10. Из-за процедур выделения данных Rs это создает вектор> 70Gb, который не может быть запущен на любом компьютере, который я знаю, хотя код будет работать.

Error: cannot allocate vector of size 74.5 Gb

Для справки f (1e4,100) работает примерно за 30 секунд. На основании этого и нескольких небольших тестов f (1e6,100) потребуется около часа.


Пометка вашего ответа как неконкурентного не освобождает его от несоблюдения требований к вызову.
Мего

@Mego Ive видел множество ответов, которые не отвечают требованиям (есть еще как минимум 1 в этой задаче). Я закодировал его и чувствую, что он соответствует духу запроса на кодирование, я также четко указал, где он не удался. Также, как вы упоминаете в своих комментариях к вопросу, в нем не указано, на каком типе компьютера он должен тестироваться. Я уверен, что есть компьютеры, которые могли бы записать 7 ГБ в память и обработать ее. Тот, на котором я был, не мог сделать это, но я все еще хотел опубликовать, и я думал, что ясное заявление было допустимым компромиссом.
gtwebb

У нас есть четкая политика в отношении ответов, не отвечающих требованиям конкурса . При этом я не уверен, почему вы отметили свой ответ как не конкурирующий. Если я правильно понимаю, это должно работать при достаточном объеме памяти, но вы не можете проверить это, потому что у вас недостаточно ОЗУ. Это верно?
Деннис

1
1. Эта политика будет проводится в жизнь, но четыре модераторов не может проверить все ответы на сайте. Если вы найдете сообщение, которое не соответствует правилам, пометьте его как модераторское, чтобы мы могли посмотреть. 2. Вам не нужно изучать язык игры в гольф для участия. Языки производства, такие как R, также приветствуются. Я выкладываю ответы на Python самостоятельно на регулярной основе.
Деннис

1
3. В спецификации не упоминаются ограничения памяти, но есть ограничение по времени 24 часа. В отсутствие компьютера с 70 ГиБ (или вы имели в виду гигабитные биты ), чтобы проверить это, трудно определить, является ли этот ответ действительным или нет. Я предлагаю попытаться экстраполировать среду выполнения так хорошо, как вы можете. Если это менее одного дня, удалите неконкурентный заголовок и включите экстраполяцию в пост. Если это займет больше времени, ваша заявка должна быть оптимизирована или удалена.
Деннис

1

Ракетка 332 байта

(λ(N m n)(let loop((l(filter odd?(range 1 N)))(i 1))(define x (list-ref l i))(if(= i (sub1 n))
(begin(set! l(for/list((j(length l))#:when(= 0(modulo(add1 j)x)))(list-ref l j)))(list-ref l(sub1 m)))
(begin(set! l(for/list((j(length l))#:unless(= 0(modulo(add1 j) x)))(list-ref l j)))(if(>= i(sub1 (length l)))l
(loop l(add1 i)))))))

Безголовая версия:

(define f
  (λ(N m n)
    (let loop ((l (filter odd? (range 1 N))) (i 1))
      (define x (list-ref l i))
      (if (= i (sub1 n))
          (begin (set! l (for/list ((j (length l)) 
                                   #:when (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (list-ref l (sub1 m)))
          (begin (set! l (for/list ((j (length l)) 
                                   #:unless (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (if (>= i (sub1 (length l)))
                     l
                     (loop l (add1 i))))))))

Тестирование:

(f 100 5 2)

Выход:

29

1

Clojure, 221 байт

Могучий долго, но обрабатывает дело (f 1). Без этого особого случая это было 183 байта. Это было слишком много усилий, чтобы не публиковать его.

(defn f([n](if(< n 2)(take-nth 2(drop 2(range)))(f n 1(take-nth 2(rest(range))))))([n i c](if (< n 2)c(let[N(first(drop i c))F #((if(= 2 n)= >)(mod(inc %)N)0)](f(dec n)(inc i)(filter some?(map-indexed #(if(F %)%2)c)))))))

Пример выходов:

(pprint (map #(take 10 (f %)) (range 1 10)))
((2 4 6 8 10 12 14 16 18 20)
 (5 11 17 23 29 35 41 47 53 59)
 (19 39 61 81 103 123 145 165 187 207)
 (27 57 91 121 153 183 217 247 279 309)
 (45 97 147 199 253 301 351 403 453 507)
 (55 117 181 243 315 379 441 505 571 633)
 (85 177 277 369 471 567 663 757 853 949)
 (109 225 345 465 589 705 829 945 1063 1185)
 (139 295 447 603 765 913 1075 1227 1377 1537))

Случай 1000000 100 был рассчитан примерно за 4,7 часа, по крайней мере, он не вылетел.

java -jar target\stackoverflow-0.0.1-SNAPSHOT-standalone.jar 1000000 100
5333213163
"Elapsed time: 1.7227805535565E7 msecs"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.