Целые числа отсортированы по их цифровым корням


24

Цифровой корень (также повторяющаяся цифровая сумма) положительного целого числа - это (однозначное число) значение, полученное в результате итеративного процесса суммирования цифр на каждой итерации, используя результат предыдущей итерации для вычисления суммы цифр. Процесс продолжается до достижения однозначного числа.

Например, цифровой корень 65536 равен 7 , потому что 6 + 5 + 5 + 3 + 6 = 25 и 2 + 5 = 7 .


Сортировка всех цифровых корней не имеет особого смысла, поскольку она будет начинаться с бесконечного числа 1 с.

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

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

Наконец, мы объединим эти списки в одну последовательность. Эта последовательность начинается со всех однозначных чисел, затем со всех двузначных чисел (отсортированных по их цифровому корню), затем со всех трехзначных чисел и так далее.


Вызов:

Возьмите положительное целое число n в качестве входных данных и выведите n -ое число в последовательности, описанной выше. Вы можете выбрать, является ли список 0 -индексированным 1- индексированным.

Последовательность выглядит следующим образом:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 19, 28, 37, 46, 55, 64, 73, 82, 91, 11, 20, 29 ... 
72, 81, 90, 99, 100, 109, 118, ... 
981, 990, 999, 1000, 1009, 1018, 1027, ...

Тестовые случаи:

Тестовые случаи 1-индексированы.

   n   f(n)  
   9      9
  10     10
  11     19
  40     13
  41     22
  42     31
  43     40
  44     49
  45     58
 600    105
 601    114
 602    123
 603    132
 604    141
 605    150
4050   1453
4051   1462
4052   1471
4053   1480
4054   1489
4055   1498

Проще скопировать:

n =    9, 10, 11, 40, 41, 42, 43, 44, 45, 600, 601, 602, 603, 604, 605, 4050, 4051, 4052, 4053, 4054, 4055, 
f(n) = 9, 10, 19, 13, 22, 31, 40, 49, 58, 105, 114, 123, 132, 141, 150, 1453, 1462, 1471, 1480, 1489, 1498

Разъяснения:

  • Вы не можете вывести все n первых элементов. Вы должны только вывести n 'th.
  • Код должен теоретически работать для всех целых чисел вплоть до 10 ^ 9 , но это нормально, если он истекает в TIO (или других интерпретаторах с ограничениями по времени) для входных данных, больших 999 .
  • Пояснения приветствуются.

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


2
Забавное примечание: это еще не в OEIS
apnorton

Ответы:


16

Python 2 , 78 60 52 46 45 байт

-6 байт благодаря ГБ .
-1 байт благодаря Якобу .

n=input()
b=10**~-len(`n`)
print~-b+n/b+n%b*9

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

Наконец-то добрался до закрытой формы, 1-индексируется.


Python 2 , 78 байт

0 индексированные.

d=10;k=1
exec'\nk+=9\nif k>d+7:k=d;d*=10\nif k>=d:k-=d/10*9-1'*input()
print k

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


2
Я надеялся увидеть решение, которое не создавало бы всю последовательность. Молодцы :-)
Стьюи Гриффин

Как вы получили решение в закрытой форме? (правка: похоже, что в википедии есть объяснение )
sevko

@sevko 78-byter было мое оригинальное решение (несколько ungolfed вариант здесь ). Это уже работает без вычисления каких-либо корней куба, а скорее путем генерации порядкового номера по номеру на основе правил, которые я соблюдал в последовательности. На основании этих итерационных вычислений можно подсчитать, сколько раз каждое выражение выполняется.
овс

@sevko с помощью WolframAlpha мне удалось построить закрытую форму. Сначала программа, использующая закрытую форму, была намного длиннее (~ 95 байт), но с некоторыми играми в гольф и WolframAlpha она достигла своей текущей формы.
овс

4

Python 3 , 80 байт

f=lambda i,k=1:k>i and sorted(range(k//10,k),key=lambda n:n%-9)[i-k]or f(i,k*10)

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

1-индексироваться. Это лучшее, что я мог бы сделать в Python 3 (ну, за исключением 78-байтового , который является портом моего решения Python 2 ниже; я думаю, что это гораздо круче). Полные программы на Python 2 имеют преимущества для этой конкретной задачи, потому что input()требует преобразования intв Python 3 (+5 байт), execявляется функцией, а не оператором (+2 байта) и /выполняет целочисленное деление по умолчанию, если его аргументы являются целыми числами в Py 2 (+1 байт), так что это определенно короче, чем перенос ответа ovs .

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

Настроить

f=lambda i,k=1:k>i and ... or f(i,k*10)

Это определяет рекурсивную функцию f, которая принимает один целочисленный аргумент i и другой, k , который по умолчанию равен 1 . В то время как k ≤ i , функция f возвращает f (i, 10k) , умножая k на 10 каждый раз, пока она не станет больше, чем i .

Целевой диапазон и правильная индексация

...range(k//10,k)...[i-k]

После этого набора операций у нас остается i , начальный вход и переменная k, которая представляет наименьшую степень на 10 больше, чем i . Таким образом, мы можем сгенерировать (целочисленный) диапазон [floor (k / 10), k) , который в основном включает все целые числа:

  • больше или равно наибольшей степени 10 меньше или равно I
  • меньше, чем k , наименьшая мощность 10 больше, чем я

Поскольку мы игнорируем целые числа, меньшие чем x = floor (k / 10) , мы должны сдвинуть индексирование так, чтобы мы учитывали пропущенные числа. Очевидный способ состоит в том, чтобы вычесть их число x из i , чтобы мы проиндексировали их в списке (после сортировки, которая описана ниже), следовательно, имея ix . Однако, поскольку список содержит 9k / 10 , элементы и индексацию в списке с индексом -y для некоторого положительного значения y, получается y- й элемент с конца в Python, это просто эквивалентно индексации с помощью ik , следовательно, сохраняя 4 байта.

Сортировка каждого чанка по цифровому корню

sorted(...,key=lambda n:n%-9)

Формула для цифровой корневой функции имеет вид 1 + ((n-1) mod 9) (см. Раздел « Формула конгруэнтности » в этой статье Википедии ). Так как 1 будет добавлен таким образом к каждому из них, при сортировке это излишне, поэтому у нас остается (n-1) mod 9 . Способ %работы оператора Python, когда в RHS заданы отрицательные числа, очень удобен, потому что вместо него можно использовать n pymod -9, чтобы сохранить еще один другой байт.


Python 2 , 72 байта

Вдохновленный представлением Часа Брауна .

lambda i:sorted(range(1,10**len(`i`)),key=lambda n:(len(`n`),n%-9))[i-1]

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


4

Python 2 , 73 71 70 байт

lambda n:sorted(range(10**len(`n`)),key=lambda i:(len(`~i`),i%9))[n]+1

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

2 байта спасибо мистеру XCoder ; и 1 байт спасибо H.PWiz .

Это 0-индексированный.


Ну, i%9должно быть достаточно вместо i%9+1... таким образом, вы побили мой 72 байт: DD:
Мистер Xcoder

@ Mr.Xcoder: Ха! Ты прав ...
Час Браун

len(`~i`)должен работать
H.PWiz

4

Желе ,  15 14 10  9 байт

D,Ḣ$‘Ḍḅ9’

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

Как?

Использует версию для гольфа в закрытом виде, созданную ovs в своем ответе на Python ...

Формула, представленная ovs: 9 * (n% b) + (n / b) + b - 1, где b = 10 этаж (log (n, 10))

Теперь, если c - это количество десятичных цифр n, тогда b-1 - это c-1 девяток в десятичной дроби.
Это то же самое, что девятикратное значение с-1 в десятичном виде (например 111*9=999).

Кроме того, n / b - это начальная цифра n, а n% b - это остальные цифры в виде десятичного числа.

Формула типа b * x + y может быть реализована как преобразование [x,y]из базы b
(то есть b ^ 1 * x + b ^ 0 * y = b * x + y )

Таким образом, мы можем взять число, например n ( 7045), разделить его на начальную и конечную цифры, поместив начальную цифру в конец ( [[0,4,5],7]), добавить одну ко всем цифрам первого элемента, чтобы обслужить добавление b-1 ( [[1,5,6],7]) преобразует их из десятичных списков в целые числа ( [156,7]) и преобразует их из базы девять ( 1411).

В приведенной ниже реализации мы добавляем одну ко всем цифрам обоих элементов при обработке b-1 ( [[0,4,5],8]), конвертируем из десятичных списков в целые числа ( [156,8]), конвертируем из базы девять ( 1412) и затем вычитаем ту, которую этот процесс добавил ( 1411).

D,Ḣ$‘Ḍḅ9’ - Link: positive integer, n    e.g. 4091
D         - to base ten                       [4, 0, 9, 1]
   $      - last two links as a monad:
  Ḣ       -   head (modifies the list too)    4
 ,        -   pair (the modified list) with   [[0, 9, 1], 4]
    ‘     - increment (vectorises)            [[1, 10, 2], 5]
     Ḍ    - from base ten (vectorises)        [202, 5] (since 1*10^2+10*10^1+2*10^0 = 100+100+2 = 202)  
      ḅ9  - convert from base 9               1823 (since 202*9^1 + 5*9^0 = 202*9 + 6*9 = 1818 + 5 = 1823)
        ’ - decrement                         1822

Предыдущая, 14 байт:

æċ⁵DL,’%9ƊƲÞị@

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

Этот строит список до следующей степени 10 над входом, сортируя эти натуральные числа, а [digitalRoot, digitCount]затем находит значение по введенному индексу.


3

Haskell , 94 88 байт

([n|x<-[0..],i<-[1..9],n<-[10^x..10^(x+1)-1],until(<10)(sum.map(read.pure).show)n==i]!!)

Попробуйте онлайн! 0 индексированные.

Объяснение:

Понимание списка генерирует последовательность как бесконечный список, в который мы индексируем !!:

  • x на единицу меньше текущего числа цифр и берется из бесконечного списка [0,1,2,3, ...]
  • iперебирает диапазон от 1до 9и используется для сортировки по цифровым корням
  • nперебирает все числа с x+1цифрами
  • until(<10)(sum.map(read.pure).show)вычисляет цифровой корень ( см. здесь для объяснения )
  • nдобавляется в список, если его цифровой корень равен i.

2

Сетчатка , 65 байт

.
9
.+
*
L$`
$`
O$`_(_{9})*(_*)
$2
_+
$.&
N$`
$.&
"$+L`^|\d+"^~G`

Попробуйте онлайн! 1-индексироваться. Объяснение:

.
9
.+
*
L$`
$`

Составьте список строк _s от 0 до следующей степени 10 (эксклюзив).

O$`_(_{9})*(_*)
$2

Сортируйте их все в порядке цифрового корня.

_+
$.&

Преобразовать из одинарного в десятичное.

N$`
$.&

Сортируйте их в порядке длины.

"$+L`^|\d+"^~G`

Извлеките nэлемент.


2

Pyth ,  36 31 25 24 23  22 байта

1-индексироваться.

@o%tN9rFK^LThBlt`Q-QhK

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

Как это работает (устарело)

@smo%tN9dcU^TKhs.lQT^LTSK – Full program. Q = input.
             Khs.lQT      – Take floor(log10(Q))+1 and store it in K.
          U^T             – Generate [0 ... T^K).
         c                – Cut at locations...
                    ^LTSK – Of the powers of 10 less than K.
  m     d                 – Map over those.
   o  N                   – Sort them by...
    %t 9                  – Themselves decremented, modulo 9.
@s                        – Flatten the result and retrieve the Q'th entry.

2

05AB1E , 19 11 байт

Порт моего Python ответа .

-6 байт (!) Благодаря Кевину Круйссену .

g<°©‰`9*®O<

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

Code           Explanation            Stack
               implicit input         [n]
g              length                 [len(n)]
 <             decrement              [len(n)-1]
  °            10 ** a                [10**(len(n) - 1)]
   ©           store value            [10**(len(n) - 1)]
    ‰          divmod                 [[n // 10**(len(n) - 1), n % 10**(len(n) - 1)]]
     `         push items to stack    [n // 10**(len(n) - 1), n % 10**(len(n) - 1)]
      9*       multiply by 9          [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9]
        ®      retrieve value         [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9, 10**(len(n) - 1)]
         O     sum the stack          [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1)]
          <    decrement              [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1) - 1]
               implicit output

Вы опередили меня, работали над ответом, который был портом вашего Python-ответа. ;) 13 байт:g<°©÷¹®%9*®O< . Вот объяснение, которое я собирался опубликовать для него .
Кевин Круйссен

1
@KevinCruijssen большое спасибо. Реестр кажется весьма полезным. Я смог записать еще два байта, используя divmod.
овс


1

Perl 6 ,  68  58 байт

{({|(10**$++..^10**++$).sort({({.comb.sum}…*==*).tail})}…*)[$_]}

Проверьте это на основе 0

{sort({.chars,({.comb.sum}…*==*).tail},^10**.chars)[$_]}

Проверьте это 1 на основе

Expanded:

{  # bare block lambda with implicit parameter $_

  sort(
    {
      .chars,         # sort by the length first

      (  # generate sequence to find digital sum

        { .comb.sum } # one round of digital sum
         * == *      # stop when the digital sum matches itself (1..9)

      ).tail          # get the last value
    },

    ^                 # Range up to (and excluding)
      10 ** .chars    # the next power of 10

  )[ $_ ] # index into the sequence
}



1

К4 , 38 байт

Решение:

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:

Примеры:

q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:40
13
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:601
114
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:4051
1462

Объяснение:

Порт Джонатана Аллана, поскольку у меня не хватает памяти для построения цифровых корней от 1 до 1e9.

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\: / the solution
                                  10\: / convert to base 10
                                1+     / add 1
                              x:       / save as x
                             #         / take from x
                     (      )          / do together
                          #x           / count x
                        c:             / save as c
                      1+               / add 1
                   1_                  / drop the first
                  _                    / cut at these indices
           ( ;   )                     / 2-item list
              c-1                      / length - 1
            0                          / .. zero
      10/:'                            / convert each from base 10
   9/:                                 / convert from base 9
-1+                                    / subtract 1

Бонус:

Перевод решения ovs проще, но дольше:

-1+b+/1 9*(_%;.q.mod).\:x,b:10 xexp#1_$x:

Явно сказано, что: «Код должен теоретически работать для всех целых чисел до 10 ^ 9 » . Похоже, это не ...?
Стьюи Гриффин

Urgh. Затем я воспользуюсь одним из бонусных ответов, так как мне не хватит памяти, пытаясь вычислить до 10e6, не говоря уже о 10e9. Исправлю позже.
Стритстер


0

J, 24 байта

(]/:([:+/[:".&>":)^:_"0)

Это молчаливое выражение заключено в скобки, чтобы показать, что его следует рассматривать отдельно, а не как часть любого последующего выражения (например, аргументов).

Фраза '] /:' заказывает (по возрастанию '/:') исходный массив ']' на сумму '+ /' цифр. Выражение

". &> ":

преобразует число в символьный вектор с помощью "": ", затем применяет его обратное значение" ". - символ к номеру - применяется к каждому элементу «&>». Итак, 65536 -> '65536' -> 6 5 5 3 6.

Соединение степеней «^:» в конце выражения применяет код, который мы только что объяснили (слева), указанное количество раз. В этом случае указанное число раз равно бесконечности '_', что означает, что необходимо продолжать применять, пока результат не перестанет меняться.

Последний «0» означает применять все выражение слева к каждому скалярному (0-мерному) элементу справа, который будет массивом чисел, к которому мы хотим применить это.


Как вы создаете входной список (ы)? Я пишу решение на K, но половина ответа - это создание списков ...
streetter

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

« Возьмите положительное целое число n в качестве входных данных и выведите n-ое число в последовательности, описанной выше». Вы должны создать последовательность (или найти способ обойти генерацию последовательности - см. Другие ответы).
Стритстер

0

Эликсир , 239 байт

q=:math
e=Enum
r=fn x,f->cond do
x<10->x
1->f.(e.sum(Integer.digits x),f)end end
fn p->e.at(e.at(Stream.unfold({0,[0]},fn {a,c}->{c,{a+1,c++e.sort(trunc(q.pow 10,a)..trunc(q.pow 10,a+1)-1,&r.(&1,r)<=r.(&2,r))}}end),1+trunc q.log10 p),p)end

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

Объяснение поступает (медленно)! Я не думаю, что это может стать намного короче этого, но я всегда открыт для предложений


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.