Сильно составные числа

23

Высоко составное число является положительным целым числом , которое имеет больше делителей , чем любое меньшее положительное целое число имеет. Это последовательность OEIS A002182 . Его первые 20 сроков

1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680, 2520, 5040, 7560

Например, 4находится в последовательности, потому что имеет 3 делителя (а именно 1, 2, 4), тогда как 3 имеет только 2 делителя, 2 также имеет 2 делителя, а 1 имеет 1 делитель.

Вызов

Если задано положительное целое число n , выведите либо n- ое очень сложное число, либо первые n очень сложное число по вашему выбору (но выбор должен быть одинаковым для каждого входа n ).

правила

Программа или функция должны теоретически работать для произвольно больших входных данных, учитывая бесконечное время и память, без учета ограничений на тип данных. По сути, это означает отсутствие жесткого кодирования конечного числа значений.

На практике программа или функция должны запускаться за разумное время, скажем, менее 1 минуты, при n до 20. Максимальный ввод или вывод может быть ограничен типом данных вашего языка (но опять-таки алгоритм должен работать теоретически). для сколь угодно больших чисел).

Разрешен любой разумный формат ввода и вывода, в том числе одинарный.

Код гольф. Побеждает несколько байтов.

Луис Мендо
источник
Этот разговор был перемещен в чат .
Деннис
Может ли n- й индекс быть нулевым или это должен быть 1-индексированный?
Аднан
@ANN Я не думал об этом, так что, скажем, оба приняты. (Кажется, я вспоминаю мета-пост, в котором говорится, что разрешены как на основе 1, так и 0, но я не могу его найти. Кто-нибудь?)
Луис Мендо,

Ответы:

4

05AB1E , 15 14 байтов

Вход в ноль индексируется. Это означает, что n = 0дает 1, n = 1дает 2и т. Д. Код:

$µ>DÑgD®›i©¼}\

Объяснение:

$               # Pushes 1 and input
 µ              # Counting loop, executes until the counting variable is equal to input
  >             # Increment (n + 1)
   DÑ           # Duplicate and calculate all divisors
     gD         # Get the length of the array and duplicate
       ®        # Retrieve element, standardized to zero
        ›i  }   # If greater than, do...
          ©     #   Copy value into the register
           ¼    #   Increment on the counting variable
             \  # Pop the last element in the stack

Вычисляет n = 19 , что должно дать 7560около 10 секунд.

Попробуйте онлайн!

Использует кодировку CP-1252 .

Аднан
источник
5

Желе, 15 байт

,®ÆDL€ṛ©0>/?µƓ#

Для ввода n это печатает первые n сильно составных чисел.

Для n = 20 это займет не более двух секунд. Попробуйте онлайн!

Как это работает

,®ÆDL€ṛ©0>/?µƓ#  Main link. No implicit input.

            µ    Push the chain to the left on the local link stack.
             Ɠ   Read an integer n from STDIN.
              #  Execute the chain for k = 0, 1, 2, ..., until it returned a truthy
                 value n times. Return the list of matches.

,®               Pair k with the value in the register (initially 0).
  ÆD             Compute the divisors of k and the register value.
    L€           Count both lists of divisors.
           ?     If
         >/        k has more divisors than the register value:
      ṛ©             Save k in the register and return k.
        0          Else: Return 0.

Альтернативная версия, 13 байт (не конкурирует)

Хотя приведенный ниже код работал в последней версии Jelly, которая предшествовала этой проблеме, реализация Mбыла очень медленной, и она не соответствовала ограничениям по времени. Это было исправлено.

ÆDL®;©MḢ’>µƓ#

Попробуйте онлайн!

Как это работает

ÆDL®;©MḢ’>µƓ#  Main link. No implicit input.

          µ    Push the chain to the left on the local link stack.
           Ɠ   Read an integer n from STDIN.
            #  Execute the chain for k = 0, 1, 2, ..., until it returned a truthy
               value n times. Return the list of matches.

ÆD             Compute the divisors of k.
  L            Count them.
   ®;          Append the count to the list in the register (initially 0 / [0]).
     ©         Save the updated list in the register.
      M        Obtain all indices the correspond to maximal elements.
       Ḣ       Retrieve the first result.
        ’>     Subtract 1 and compare with k.
               This essentially checks if the first maximal index is k + 2, where
               the "plus 2" accounts for two leading zeroes (initial value of the
               register and result for k = 0).
Деннис
источник
1
Также есть RÆDL€MḢ=µƓ#(11 байт), но на моей машине это занимает 44 минуты ...
Деннис
3

MATL , 26 24 байта

~XKx`K@@:\~s<?@5MXKx]NG<

Попробуйте онлайн!

Текущее наибольшее число найденных делителей хранится в буфере обмена K. Высокосоставные числа (HCN) хранятся непосредственно в стеке. Цикл продолжает проверять кандидатов на HCN. Когда он найден, он остается в стеке, а буфер обмена K обновляется. Цикл завершается, когда найдено желаемое количество HCN.

~         % take input implicitly (gets stored in clipboard G). Transform into a 0 
          % by means of logical negation
XKx       % copy that 0 into clipboard K, and delete
`         % do...while
  K       %   push largest number of divisors found up to now
  @       %   push iteration index, i: current candidate to HCN
  @:      %   range [1,...,i]
  \       %   modulo operation
  ~s      %   number of zeros. This is the number of divisors of current candidate
  <       %   is it larger than previous largest number of divisors?
  ?       %   if so: a new HCN has been found
    @     %     push that number
    5M    %     push the number of divisors that was found
    XKx   %     update clipboard K, and delete
  ]       %   end if
  N       %   number of elements in stack
  G<      %   is it less than input? This the loop condition: exit when false
          % end do...while implicitly
          % display all numbers implicitly
Луис Мендо
источник
3

Perl 60 57 + 1 = 58 байт

$,++;$==grep$,%$_<1,1..$,;$_--,$m=$=if$=>$m;$_?redo:say$,

Требуется -nи свободный -M5.010| -E:

$ perl -nE'$,++;$==grep$,%$_<1,1..$,;$_--,$m=$=if$=>$m;$_?redo:say$,' <<< 10 
120

Как это работает:

$,++;
     $==grep$,%$_<1,1..$,;                                # Calculate total numbers of divisors for `$,`
                          $_--,$m=$=if$=>$m;              # Set `$m`ax divisors to `$=`ivisors if `$m>$=`
                                            $_?redo:say$, # Repeat or print
andlrc
источник
2

JavaScript (ES6) 72

Простая реализация. Время около 20 сек для входа 20

x=>{for(i=e=n=0;i<x;d>e&&(++i,e=d))for(d=1,j=++n;--j;)n%j||++d;return n}

Трюк Eval может сохранить байт, удваивающий время выполнения.

x=>eval("for(i=e=n=0;i<x;d>e&&(++i,e=d))for(d=1,j=++n;--j;)n%j||++d;n")

Меньше гольфа

x=>{
  for(i = e = 0, n = 1; i < x; n++)
  {
    for(d = 1, j = n; --j; )
    {
      if (n%j == 0) 
        ++d;
    }
    if (d > e)
      ++i,
      e = d;
  }
  return n;
}
edc65
источник
2

Pyth, 17 16 байт

1 байт благодаря Якубе

uf<Fml{yPd,GTGQ1

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

Принимает n -индексированное n и возвращает n-е очень сложное число.

Объяснение:

uf<Fml{yPd,GThGQ1
                     Input: Q = eval(input())
u              Q1    Apply the following function Q times, starting with 1.
                     Then output the result. lambda G.
 f           hG      Count up from G+1 until the following is truthy, lambda T.
          ,GT        Start with [G, T] (current highly comp., next number).
    m                Map over those two, lambda d.
        Pd           Take the prime factorization of d, with multiplicity.
       y             Take all subsets of those primes.
      {              Deduplicate. At this point, we have a list of lists of primes.
                     Each list is the prime factorization of a different factor.
     l               Take the length, the number of factors.
  <F                 Check whether the number of factors of the previous highly
                     composite number is smaller than that of the current number.
isaacg
источник
1

Рубин, 70 69 67 66 64 62

->n{r=k=0
0until(r<t=(1..k+=1).count{|d|k%d<1})&&1>n-=t/r=t
k}

Простая реализация.

Митч Шварц
источник
1

C 98 байт

f,i,n,j;main(m){for(scanf("%d",&n);n--;printf("%d ",i))for(m=f;f<=m;)for(j=++i,f=0;j;)i%j--||f++;}

Попробуй это здесь .

Ungolfed

f,i,n,j;

main(m)
{
    for(scanf("%d",&n); /* Get input */
            n--; /* Loop while still HCN's to calculate... */
            printf("%d ",i)) /* Print out the last calculated HCN */
        for(m=f;f<=m;) /* Loop until an HCN is found... */
            for(j=++i,f=0;j;) /* Count the number of factors */
                i%j--||f++;
}
Коул Камерон
источник
1

Python 3, 97 байт

i=p=q=0;n=int(input())
while q<n:
 c=j=0;i+=1
 while j<i:j+=1;c+=i%j==0
 if c>p:p=c;q+=1
print(i)

Полная программа, которая принимает входные данные из STDIN и печатает выходные данные в STDOUT. Это возвращает n1-индексированное высоко составное число.

Как это работает

Это простая реализация. Ввод nпредставляет собой очень сложный числовой индекс.

Программа перебирает целые числа i. Для каждого целого числа jменьше i, i mod jберется; если это так 0, jдолжен быть коэффициент, iи счетчик cувеличивается, давая количество делителей iпосле цикла. pявляется предыдущим наибольшим числом делителей, поэтому, если c > pбыло найдено новое очень сложное число и счетчик qувеличивается. После того q = n, iдолжно быть nй высоко составное число, и это будет напечатано.

Попробуйте это на Ideone

(Это занимает ~ 15 секунд n = 20, что превышает ограничение по времени для Ideone. Следовательно, приведенный пример предназначен для n = 18.)

TheBikingViking
источник
0

Python 2, 207 байт

n,i,r,o=input(),1,[],[]
while len(o)<n:
 r+=[(lambda n:len(set(reduce(list.__add__,([i,n//i]for i in range(1,int(n**0.5)+1)if n%i==0)))))(i)];h=max(r)
 if r.index(h)>i-2 and r.count(h)<2:o+=[i]
 i+=1
print o

Использует тот же метод, что и ответ Денниса «Желе». Вычисляет первые 20 слагаемых в <2секундах.

Зак Гейтс
источник