Вернуть n-ую цифру последовательности аликвотных рядов

20

0. ОПРЕДЕЛЕНИЯ

Последовательность представляет собой список номеров. Ряд представляет собой сумму списка чисел. Множество натуральных чисел содержит все «неотрицательные целые числа больше нуля». Делитель (в данном контексте) из натурального J представляет собой натуральное число я , таким образом, что J ÷ я также натуральное число.



1. ПРЕАМБУЛА

В паре других вопросов на этом сайте упоминается понятие аликвоты или последовательности делителей натурального числа a, которые меньше a . Определение дружественных чисел включает вычисление суммы этих делителей, называемой аликвотной суммой или аликвотным рядом. Каждое натуральное число имеет свою собственную сумму аликвот, хотя значение суммы аликвот числа не обязательно уникально для этого числа. ( Например , каждое простое число имеет аликвоту 1.)

2. ВЫЗОВ

Если задано натуральное число n, верните nцифру последовательности аликвотных сумм. Первые несколько серий в последовательности, начиная с серии за 1:

{0, 1, 1, 3, 1, 6, 1, 7, 4, 8, 1, 16, 1, 10, 9, 15, 1, 21, 1, 22, 11, 14, 1, 36, 6, 16, 13}

Объединенные, они выглядят как:

0113161748116110915121122111413661613

В зависимости от ваших предпочтений, ввод может быть с нулевой или одной индексацией. Решения должны быть программами или функциями, способными возвращать 10 000-ю цифру (ввод до 9999или 10000). Самое короткое рабочее решение побеждает.

3. ТЕСТОВЫЕ СЛУЧАИ

Правильные пары ввода-вывода должны включать, но не ограничиваются следующим:

   0 or     1    ->    0
   4 or     5    ->    1
  12 or    13    ->    6
9999 or 10000    ->    7

Число, предшествующее «или», имеет индекс 0; число после 1 индексируется.
Дополнительные тестовые случаи могут быть предоставлены по запросу.

4. ССЫЛКИ

OEIS имеет список номеров и их аликвотные суммы.

Джо
источник
2
Хороший первый вызов, кстати. :)
Мартин Эндер
1
если язык не может управлять 10k строк символов? (например, ужасный лимит Oracle SQL 4k ), верен ли ответ, если это лимит языка?
Джакомо Гарабелло
@MartinEnder, спасибо! И спасибо за эту ссылку; это было поучительно. Есть ли что-нибудь, что объясняет, как относиться к ответам на языках с ограничениями? Я ничего не мог найти, но я знаю, что это не значит, что его там нет. :)
Джо
Я могу быть совсем толстым, но как рассчитываются числа в этом ряду?
Том Карпентер
@TomCarpenter: для первого элемента возьмите все делители 1, которые меньше 1, и сложите их вместе. (1 - единственный делитель 1, поэтому первый элемент в конечном итоге равен нулю.) Второй элемент, делители 2 меньше 2 (подходит только 1); в-третьих, делители 3 (все еще только 1); и так далее. Делителями на 4 являются {1, 2} и 1 + 2 == 3, поэтому четвертым элементом является 3. Мне тоже потребовалось время, чтобы понять это;)
Джо

Ответы:

6

05AB1E , 14 11 10 байт

Вычислить n = 9999 примерно за 15 секунд. Код:

ÌL€Ñ€¨OJ¹è

Объяснение:

Ì           # Increment implicit input by 2
 L          # Generate the list [1 .. input + 2]
  ۄ        # For each, get the divisors
    ۬      # For each, pop the last one out
      O     # Sum all the arrays in the array
       J    # Join them all together
        ¹è  # Get the nth element

Использует кодировку CP-1252 . Попробуйте онлайн! ,

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

Mathematica, 51 байт

Array[##&@@IntegerDigits[Tr@Divisors@#-#]&,#][[#]]&

Безымянная функция, которая принимает и возвращает целое число и использует индексирование на основе 1. Обрабатывает ввод 10000мгновенно.

объяснение

Это очень прямая реализация определения, использующая тот факт, что nсуммы первых делителей всегда достаточно для определения nцифры th. Как обычно, порядок чтения Mathematica в гольфе немного смешной:

Array[...&,#]...&

Это создает список со всеми результатами применения безымянной функции слева ко всем значениям iот 1до nвключительно.

...Tr@Divisors@#-#...

Мы начнем с вычисления делителей i, их суммирования Trи вычитания i, так что это просто сумма делителей меньше, чем i.

...IntegerDigits[...]...

Это превращает результат в список десятичных цифр.

##&@@...

И это удаляет заголовок «списка», так что все списки цифр автоматически объединяются в результате Array. Подробнее о том ##, как это работает, см. В разделе «Последовательность аргументов» в этом посте .

...[[#]]

Наконец, мы выбираем nth цифру из результата.

Мартин Эндер
источник
4

Брахилог , 40 байт

:2-I,?:?:1yrc:Im.;0.
:1e:2f+.
>.>0,?:.%0

Это индексируется 1, занимает около 0,15 секунды N = 100, 15 секунд N = 1000. Я в настоящее время баллотируюсь N = 10000, я сообщу время выполнения, как только оно закончится (Если моя оценка верна, это должно занять около 8 часов)

Изменить : исправив распространение преждевременных ограничений в Brachylog, теперь это (для кода длиной 3 байта) занимает около 2.5минуты, 10000но возвращает out of global stackошибку.

объяснение

  • Главный предикат: Input = N

    :2-I,                 I = N - 2
         ?:?:1y           Find the N first valid outputs of predicate 1 with input N
               rc         Reverse and concatenate into a single number
                 :Im.     Output is the Ith digit of that number
                     ;    Or (I strictly less than 0)
                      0.  Output is 0
    
  • Предикат 1: вычисляет сумму делителей

    :1e                   Get a number between N and 1
       :2f                Find all valid outputs of predicate 2 with that number as input
          +.              Output is the sum of those outputs
    
  • Предикат 2: объединяет вывод с делителем ввода

    >.>0,                 Output is a number between Input and 0
         ?:.%0            Input is divisible by Output
    
Fatalize
источник
1
Вы можете выделить более глобальный стек с помощью -Gопции. По умолчанию только 128M. Вы можете использовать, например: swipl -G2Gиспользовать 2 GO.
мат
4

Pyth, 26 21 20 15 байт

@sm`sf!%dTtUdSh

Попробуйте онлайн. Тестирование.

Использует индексирование на основе 0. Программа на O (n²) завершается для n = 9999 примерно за 14 минут на моей машине 2008 года.

PurkkaKoodari
источник
Что за сложный поиск делителей? f!%dTr1dнамного короче (но и медленнее)
Якуб
@Jakube whoops, изменила неверную версию для 20-байтового решения.
PurkkaKoodari
f!%TYtUTэто то, что я имел раньше
PurkkaKoodari
@ Якуб, я перешел на это. Это все еще работает для n = 9999, было более 5 минут сейчас: \
PurkkaKoodari
4

Желе, 13 11 10 байт

2 байта благодаря @Adnan и еще 1 благодаря @Dennis.

ÆDṖSDµ€Fị@

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

Использует индексирование на основе 1. Завершается при n = 10000 менее чем за 2 секунды онлайн.

PurkkaKoodari
источник
ÆDṖSDµ€Fị@сохраняет байт.
Деннис
@ Денис, так это относится ко всей первой цепочке?
PurkkaKoodari
@ Pietu1998: Да, именно так: в общем, на время разбора применяется к chain.pop() if chain else chains.pop(). Вновь начатая цепочка пуста, поэтому вместо нее используется последняя законченная цепочка.
Линн
3

PHP, 90 байт

0 проиндексировано

<?php for(;strlen($s)<=$a=$argv[1];$s.=$n)for($n=0,$j=++$i;--$j;)$i%$j||$n+=$j;echo$s[$a];

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

user55641
источник
3

J , 34 байта

{[:;1<@":@(-~>:@#.~/.~&.q:)@+i.@>:

Он индексируется нулем и использует приведенную ниже формулу для расчета сумм делителей.

формула

объяснение

{[:;1<@":@(-~>:@#.~/.~&.q:)@+i.@>:  Input: n
                                >:  Increment n
                             i.@    Create the range [0, 1, ..., n]
    1                       +       Add one to each to get [1, 2, ..., n+1]
          (               )@        For each value
                        q:            Get the prime factors
                   /.~&.              For each group of equal prime factors
                #.~                     Raise the first to the first power, the second
                                        squared and so on, and sum them
             >:@                        Increment that sum
                      &.q:            Reduce the groups using multiplication
           -~                         Subtract the initial value from that sum
       ":@                            Convert each to a string
     <@                               Box each
 [:;                                Unbox each and concatenate the strings
{                                   Select the character from that string at index n
                                    and return it
миль
источник
2

MATL , 16 15 байт

:"@@q:\~fsV]vG)

Индексирование основано на 1.

Последний тестовый пример истекает в онлайн-компиляторе, но он дает правильный результат с автономным компилятором, примерно через 15 секунд.

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

:         % Take input n. Push [1 2 ... n]
"         % For each k in [1 2 ... n]
  @       %   Push k
  @q:     %   Push [1 2 ... k-1]
  \       %   Modulo. Zero values correspond to divisors
  ~f      %   Indices of zeros. These are the divisors
  s       %   Sum
  V       %   Convert to string
]         % End for each
v         % Concatenate all stack contents vertically
G)        % Take n-th digit. Implicitly display
Луис Мендо
источник
2

Haskell, 52 байта

(([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!)

Пример использования: (([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!) 12-> 6.

Это прямая реализация определения: foreach nsum - это делители и преобразовать их в строку. Объедините все такие строки и выберите элемент по запрошенному индексу. Лень Хаскелла отбирает nиз бесконечного списка только столько s, [1..]сколько нужно.

Ними
источник
1

Python 3.5, 103 93 92 байта:

R=range;A=lambda f:''.join([str(sum([j for j in R(1,i)if i/j%1==0]))for i in R(1,f+1)])[f-1]

Довольно простая реализация метода, описанного в посте.

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

Не совсем завершается в течение выделенных 5 секунд в онлайн-компиляторе для ввода 10000, но завершается на моей машине для того же ввода в течение примерно 8,5 секунд.

Р. Кап
источник
1

Октава, 71 байт

Это только октава. Это не будет работать в MATLAB. Создается виртуальная функция, которая работает с 1-индексированными числами. Вероятно, это может быть упрощено немного дальше. Посмотрим сегодня вечером.

@(x)c((c=num2str(arrayfun(@(n)sum(b(~rem(n,b=(1:n-1)))),1:x)))~=' ')(x)

Вы можете попробовать онлайн здесь .

Просто запустите приведенную выше команду с префиксом a=или с чем- либо (только для того, чтобы вы могли использовать ее несколько раз), а затем сделайте a(10000)или как угодно. Требуется приблизительно 7 секунд, чтобы вычислить, что 10000-ая цифра - 7.

Том Карпентер
источник
1

Java 8, 220 байт

import java.util.stream.IntStream;
char a(int n){return IntStream.range(1,n+2).map(i->IntStream.range(1,i).filter(k->i%k==0).sum()).mapToObj(Integer::toString).collect(java.util.stream.Collectors.joining("")).charAt(n);}

Ну, это как минимум быстро. В среднем 0,3 секунды получается 9999/10000-го элемента на моей машине. Он генерирует столько сумм аликвот, сколько и указанный вами индекс. Это означает, что в большинстве случаев строка будет немного длиннее, чем ваш индекс, поскольку некоторые аликвотные суммы имеют 2 или более цифр, но по большей части генерирует только такую ​​длину строки, которая нам нужна.

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

public static void main(String[] args) {
    System.out.println(a(0));
    System.out.println(a(4));
    System.out.println(a(12));
    System.out.println(a(9999));
}

Ungolfed:

public static void main(String[] args) {
    System.out.println(all(0));
    System.out.println(all(4));
    System.out.println(all(12));
    System.out.println(all(9999));
}

static int aliquotSum(int n) {
    return IntStream.range(1, n).filter(k -> n % k == 0).sum();
}

static IntStream sums(int n) {
    return IntStream.range(1, n + 2).map(i -> aliquotSum(i));
}

static String arraycat(IntStream a) {
    return a.mapToObj(Integer::toString).collect(java.util.stream.Collectors.joining(""));
}

static char all(int index) {
    return arraycat(sums(index)).charAt(index);
}
Джастин
источник