Цілі особи відсортовані за своїми цифровими коріннями


24

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

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


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

Натомість ми створимо списки всіх цілих одноцифрових чисел разом із їх цифровими коренями, потім усі двоцифрові числа разом із їх цифровими коренями, потім потрійні, чотириразові тощо.

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

Нарешті ми об'єднаємо ці списки в одну послідовність. Ця послідовність розпочнеться з усіх одноцифрових чисел, потім усіх двоцифрових чисел (відсортованих за їх цифровим коренем), потім усіх трицифрових чисел тощо.


Виклик:

Візьмемо позитивне ціле число п в якості вхідних даних, і виведення п «й номер в послідовності , описаної вище. Ви можете вибрати, якщо список 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 '-ю.
  • Код теоретично повинен працювати для всіх цілих чисел до 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 . Таким чином, ми можемо генерувати (цілий) діапазон [пол (k / 10), k) , який в основному включає всі цілі числа, які є:

  • більша або дорівнює найбільшій потужності на 10 менше або дорівнює i
  • менше k , найменша потужність на 10 більша за i

Оскільки ми нехтуємо цілими числами, меншими за 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 байти thx для містера XCoder ; та 1 байт thx для H.PWiz .

Це 0-індексується.


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

@ Mr.Xcoder: Ха! Ти маєш рацію ...
Chas Brown

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, десятків у десятковій.
Це те саме, що дев'ять разів перевищує значення c-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

Розширено:

{  # 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 " . Здається, це не так ...?
Стюі Гріффін

Ургу. Тоді я скористаюсь одним із бонусних відповідей, оскільки мені не вистачить пам'яті, намагаючись обчислити до 10e6, не кажучи вже про 10e9. Виправимо пізніше.
Стрітер


0

J, 24 байти

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

Цей мовчазний вираз загортається в парени, щоб означати, що до нього слід ставитися самостійно, а не як до складу будь-якого наступного виразу (як аргументи).

Фраза '] /:' замовляє (зростає '/:') початковий масив ']' на суму '+ /' цифр Вираз

". &> ":

перетворює число у векторний символ з "": ", а потім застосовує його зворотний" "." - символ до числа - застосовується до кожного пункту '&>'. Отже, 65536 -> '65536' -> 6 5 5 3 6.

Силова сполука '^:' наприкінці виразу застосовує код, який ми щойно пояснили (зліва) задану кількість разів. У цьому випадку вказана кількість разів є нескінченністю "_", що означає продовжувати застосовувати, поки результат не перестане змінюватися.

Заключний "0" означає застосувати весь вираз зліва до кожного скалярного (0-мірного) елемента праворуч, який би був масивом чисел, до яких ми хочемо це застосувати.


Як ви створюєте список (и) введення? Я пишу рішення на K, але половина відповіді генерує списки ...
Стрітер

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

Msgstr " Візьміть натуральне число 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.