Поверніть n-ту цифру послідовності аликвотного ряду


20

0. ВИЗНАЧЕННЯ

Послідовність є список номерів. Ряд є сумою списку чисел. Набір натуральних чисел містить усі "невід'ємні цілі числа, що перевищують нуль". Дільник (в даному контексті) з натурального J являє собою натуральне число я , таким чином, що J ÷ я також натуральне число.



1. ПЕРЕДМОВА

Кілька інших питань на цьому сайті згадують поняття аликвоти або послідовності дільників натурального числа a, які менші за a . Визначення дружних чисел включає обчислення суми цих дільників, що називається аликвотною сумою або аликвотним рядом. У кожного натурального числа є своя аликвотна сума, хоча значення аликвотної суми числа не обов'язково унікальне для цього числа. ( Наприклад, gratia , кожне просте число має аликвотну суму 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-тисячну цифру (вхід до 9999або 10000). Виграє найкоротше робоче рішення.

3. ТЕСТОВНІ СПРАВИ

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

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

Число, що передує "або", є 0-індексованим; наступне число є 1-індексованим.
За запитом можуть бути надані додаткові тестові випадки.

4. ДОВІДКИ

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


2
Гарний перший виклик, btw. :)
Мартін Ендер

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

Математика, 51 байт

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

Неназвана функція, яка приймає та повертає ціле число та використовує індексацію на основі 1. Обробляє введення 10000миттєво.

Пояснення

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

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

Це створює список з усіма результатами застосування безіменній функції зліва , щоб все значень iвід 1до nвключно.

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

Почнемо з обчислення дільників i, підсумовуючи їх Trі віднімаючи iсебе так, що це просто сума дільників менше, ніж i.

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

Це перетворює результат у список його десяткових цифр.

##&@@...

І це видаляє заголовок "списку", так що всі розрядні списки автоматично з'єднуються в результаті Array. Детальніше про те, як ##працює, дивіться розділ «Послідовність аргументів» у цій публікації .

...[[#]]

Нарешті, ми вибираємо nту цифру з результату.


4

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

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

Це 1-індексація, займає приблизно 0,15 секунди N = 100, 15 секунд протягом N = 1000. В даний час я балотуюсь N = 10000, я повідомлю про час виконання, коли він закінчиться (Якщо моя оцінка правильна, це займе близько 8 годин)

Редагувати : виправляючи розповсюдження передчасних обмежень у Брахілозі, тепер (на 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
    

1
Ви можете виділити більш глобальний стек за допомогою цієї -Gопції. За замовчуванням лише 128M. Ви можете використовувати, наприклад: swipl -G2Gдля використання 2 GO.
мат

4

Pyth, 26 21 20 15 байт

@sm`sf!%dTtUdSh

Спробуйте в Інтернеті. Тестовий набір.

Використовує індексацію на основі 0. Програма становить O (n²) і завершується за n = 9999 приблизно за 14 хвилин на моїй машині 2008 року.


Що з цим складним пошуком дільника? f!%dTr1dнабагато коротше (але також повільніше)
Jakube

@Jakube whoops, змінив неправильну версію для 20-байтного рішення.
PurkkaKoodari

f!%TYtUTце те, що я мав раніше.
PurkkaKoodari

@Jakube Я змінив це. Він триває протягом n = 9999, зараз вже понад 5 хвилин: \
PurkkaKoodari

4

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

2 байти завдяки @Adnan і ще 1 подяка @Dennis.

ÆDṖSDµ€Fị@

Спробуйте в Інтернеті!

Використовує індексацію на основі 1. Завершує за n = 10000 за 2 секунди в Інтернеті.


Æ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];

Зовсім не тонкі або з розумним способом підходити до цього взагалі.
Також, як завжди, складається три повідомлення, які ігноруються.


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.

Це пряма реалізація визначення: передбачити nсуму дільників і перетворити її в рядок. Об'єднайте всі такі рядки та виберіть елемент у запитуваному індексі. Лінь Хаскелла бере лише стільки, скільки потрібно nз нескінченного списку [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]

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

Спробуйте в Інтернеті! (Ідеон)

Не зовсім закінчується протягом відведених 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)чи що завгодно. На обчислення того, що 10000-а цифра - це 7, потрібно приблизно 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));
}

Безголівки:

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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.