Bilangan bulat diurutkan berdasarkan akar digitalnya

24

Root digital (juga jumlah digital yang diulang) dari bilangan bulat positif adalah nilai (satu digit) yang diperoleh dengan proses iteratif menjumlahkan digit, pada setiap iterasi menggunakan hasil dari iterasi sebelumnya untuk menghitung jumlah digit. Proses berlanjut hingga nomor satu digit tercapai.

Sebagai contoh, root digital 65536 adalah 7 , karena 6 + 5 + 5 + 3 + 6 = 25 dan 2 + 5 = 7 .


Menyortir semua akar digital tidak masuk akal, karena hanya akan dimulai dengan banyak 1 detik.

Sebagai gantinya, kami akan membuat daftar semua bilangan bulat tunggal beserta akar digitalnya, lalu semua angka dua digit beserta akar digitalnya, lalu rangkap tiga, empat kali lipat dan seterusnya.

Sekarang, untuk masing-masing daftar tersebut, kami akan mengurutkannya sehingga semua bilangan bulat dengan akar digital 1 muncul terlebih dahulu, lalu semua bilangan bulat dengan akar digital 2 dan seterusnya. Penyortiran akan stabil, sehingga daftar bilangan bulat dengan akar digital tertentu harus dalam urutan naik setelah penyortiran.

Akhirnya kami akan menggabungkan daftar ini menjadi satu urutan tunggal. Urutan ini akan mulai dengan semua angka satu digit, lalu semua angka dua digit (diurutkan berdasarkan akar digitalnya), lalu semua angka tiga digit dan seterusnya.


Tantangan:

Ambil bilangan bulat positif n sebagai input, dan hasilkan angka ke - n dalam urutan yang dijelaskan di atas. Anda dapat memilih jika daftar tersebut adalah 0 -indeks dari 1 -indeks.

Urutannya seperti ini:

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, ...

Kasus uji:

Kasus uji diindeks 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

Lebih mudah disalin:

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

Klarifikasi:

  • Anda tidak boleh menampilkan semua n elemen pertama. Anda hanya akan menampilkan tanggal n .
  • Secara teoritis kode harus bekerja untuk semua bilangan bulat hingga 10 ^ 9 , tetapi tidak apa-apa jika habis pada TIO (atau penerjemah lain dengan batasan waktu) untuk input yang lebih besar dari 999 .
  • Penjelasan didorong.

Ini , jadi kode terpendek di setiap bahasa menang! Jangan berkecil hati dengan solusi lain dalam bahasa yang Anda inginkan untuk bermain golf, bahkan jika mereka lebih pendek dari yang Anda bisa kelola!

Stewie Griffin
sumber
2
Catatan menyenangkan: ini belum OEIS
apnorton

Jawaban:

16

Python 2 , 78 60 52 46 45 byte

-6 byte berkat GB .
-1 byte terima kasih kepada Jakob .

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

Cobalah online!

Akhirnya mencapai bentuk tertutup, 1-diindeks.


Python 2 , 78 byte

Diindeks 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

Cobalah online!

ovs
sumber
2
Saya berharap melihat solusi yang tidak menciptakan seluruh urutan. Bagus sekali :-)
Stewie Griffin
Bagaimana Anda mendapatkan solusi form tertutup? (sunting: sepertinya ada penjelasan di wikipedia )
sevko
@ Sevko 78-byter adalah solusi asli saya (varian agak ungolfed di sini ). Ini sudah bekerja tanpa menghitung akar pangkat tiga, melainkan dengan menghasilkan nomor urut berdasarkan angka, berdasarkan aturan yang saya amati dalam urutan. Berdasarkan perhitungan berulang ini orang dapat menghitung berapa kali setiap ekspresi dieksekusi.
Ovs
@sevko dengan bantuan WolframAlpha, saya dapat membuat formulir tertutup. Pada awalnya program menggunakan formulir tertutup jauh lebih lama (~ 95 byte) tetapi dengan beberapa golf dan WolframAlpha ini sampai ke bentuk saat ini.
Ovs
4

Python 3 , 80 byte

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)

Cobalah online!

1-diindeks. Ini adalah yang terbaik yang bisa saya kelola di Python 3 (well, kecuali untuk byter 78 , yang merupakan port dari solusi Python 2 saya di bawah ini; saya pikir yang ini jauh lebih keren, sih). Program penuh Python 2 diuntungkan untuk tantangan khusus ini, karena input()kebutuhan konversi ke intdalam Python 3 (+5 byte), execadalah fungsi, bukan pernyataan (+2 byte) dan /melakukan pembagian integer secara default jika argumennya adalah integer dalam Py 2 (+1 byte), jadi ini pasti lebih pendek dari jawaban porting ovs .

Bagaimana itu bekerja

Mendirikan

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

Ini mendefinisikan fungsi rekursif f yang mengambil satu argumen integer i dan yang lain, k , yang default ke 1 . Sementara k ≤ i , fungsi f mengembalikan f (i, 10k) , mengalikan k dengan 10 setiap kali hingga menjadi lebih besar dari i .

Rentang target dan pengindeksan yang benar

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

Setelah rangkaian operasi ini, kita pergi dengan i , input awal dan variabel k yang mewakili kekuatan terkecil 10 lebih besar dari i . Dengan cara ini, kami dapat menghasilkan kisaran (bilangan bulat) [lantai (k / 10), k) , yang pada dasarnya mencakup semua bilangan bulat yang:

  • lebih besar atau sama dengan kekuatan tertinggi 10 kurang dari atau sama dengan i
  • kurang dari k , kekuatan terkecil 10 lebih besar dari i

Karena kita mengabaikan bilangan bulat yang lebih kecil dari x = lantai (k / 10) , kita harus menggeser pengindeksan sehingga kita menghitung angka yang hilang. Cara yang jelas adalah dengan mengurangi jumlah mereka, x , dari i , sehingga kita indeks ke dalam daftar (setelah pengurutan, yang dijelaskan di bawah), oleh karena itu memiliki ix . Namun, karena daftar berisi 9k / 10 , item, dan pengindeksan dalam daftar di indeks -y untuk beberapa y positif menghasilkan elemen ke- y dari akhir dengan Python, ini hanya setara dengan pengindeksan dengan ik , sehingga menghemat 4 byte.

Menyortir setiap potongan berdasarkan root digital

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

Rumus untuk fungsi root digital adalah 1 + ((n-1) mod 9) (lihat bagian rumus Kesesuaian dari artikel Wikipedia ini ). Karena 1 cara ini akan ditambahkan ke masing-masing, itu berlebihan ketika menyortir, jadi kita pergi dengan (n-1) mod 9 . Cara %operator Python bekerja ketika diberi angka negatif pada RHS sangat mudah, karena kita dapat menggunakan n pymod -9 sebagai gantinya untuk menyimpan byte anther.


Python 2 , 72 byte

Terinspirasi oleh pengajuan Chas Brown .

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

Cobalah online!

Tuan Xcoder
sumber
4

Python 2 , 73 71 70 byte

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

Cobalah online!

2 byte thx ke Tn. XCoder ; dan 1 byte thx ke H.PWiz .

Ini diindeks 0.

Chas Brown
sumber
Nah, i%9seharusnya sudah cukup daripada i%9+1... dengan cara ini Anda mengalahkan 72 byter saya: DD:
Mr. Xcoder
@ Mr.Xcoder: Ha! Anda benar ...
Chas Brown
len(`~i`)harus bekerja
H.PWiz
4

Jelly ,  15 14 10  9 byte

D,Ḣ$‘Ḍḅ9’

Cobalah online!

Bagaimana?

Menggunakan versi golf dari solusi bentuk tertutup yang dibuat oleh ovs dalam jawaban Python mereka ...

Rumus yang diekspos oleh ovs adalah: 9 * (n% b) + (n / b) + b - 1 di mana b = 10 lantai (log (n, 10))

Sekarang jika c adalah jumlah digit desimal n maka b-1 adalah c-1 nines dalam desimal.
Ini sama dengan sembilan kali nilai c-1 dalam desimal (misalnya 111*9=999).

Selanjutnya n / b adalah digit terdepan dari n dan n% b adalah sisa digit sebagai angka desimal.

Rumus seperti b * x + y dapat diimplementasikan sebagai konversi dari [x,y]dari basis b
(yaitu b ^ 1 * x + b ^ 0 * y = b * x + y )

Dengan demikian kita dapat mengambil angka, n (misalnya 7045), membaginya menjadi digit terdepan dan tertinggal, menempatkan digit terdepan di akhir ( [[0,4,5],7]), menambahkan satu ke semua digit item pertama untuk memenuhi penambahan b-1 ( [[1,5,6],7]) mengonversi ini dari daftar desimal ke integer ( [156,7]), dan mengonversi itu dari basis sembilan ( 1411).

Dalam implementasi di bawah ini kami menambahkan satu ke semua digit dari kedua item saat memenuhi b-1 ( [[0,4,5],8]), konversikan dari daftar desimal ke integer ( [156,8]), konversikan dari basis sembilan ( 1412) dan kemudian kurangi dengan yang ditambahkan oleh proses ini ( 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

Sebelumnya, 14 byter:

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

Cobalah online!

Yang ini membangun daftar hingga kekuatan 10 di atas input dengan mengurutkan angka-angka alami ini [digitalRoot, digitCount]kemudian menemukan nilai pada indeks yang dimasukkan.

Jonathan Allan
sumber
3

Haskell , 94 88 byte

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

Cobalah online! Diindeks 0.

Penjelasan:

Pemahaman daftar menghasilkan urutan sebagai daftar tak terbatas di mana kami indeks dengan !!:

  • x kurang dari jumlah digit saat ini dan diambil dari daftar tak terbatas [0,1,2,3, ...]
  • iiterates pada rentang dari 1ke 9dan digunakan untuk menyortir oleh akar digital
  • niterates atas semua angka dengan x+1digit
  • until(<10)(sum.map(read.pure).show)menghitung root digital ( lihat di sini untuk penjelasan )
  • nditambahkan ke daftar jika akar digitalnya sama i.
Laikoni
sumber
2

Retina , 65 byte

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

Cobalah online! 1-diindeks. Penjelasan:

.
9
.+
*
L$`
$`

Buat daftar garis _s dari 0 hingga pangkat 10 berikutnya (eksklusif).

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

Urutkan semuanya dalam urutan root digital.

_+
$.&

Konversi dari unary ke desimal.

N$`
$.&

Urutkan sesuai urutan panjangnya.

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

Ekstrak nelemen th.

Neil
sumber
2

Pyth ,  36 31 25 24 23  22 byte

1-diindeks.

@o%tN9rFK^LThBlt`Q-QhK

Suite uji!

Cara kerjanya (ketinggalan jaman)

@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.
Tuan Xcoder
sumber
2

05AB1E , 19 11 byte

Pelabuhan jawaban Python saya .

-6 byte (!) Terima kasih kepada Kevin Cruijssen .

g<°©‰`9*®O<

Cobalah online!

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
ovs
sumber
Anda mengalahkan saya untuk itu, sedang mengerjakan jawaban yang merupakan port dari jawaban Python Anda. ;) 13 bytes:g<°©÷¹®%9*®O< . Di sini penjelasan yang akan saya posting untuk itu .
Kevin Cruijssen
1
@KevinCruijssen terima kasih banyak. Register sepertinya cukup berguna. Saya bisa mendapatkannya dua byte lagi menggunakan divmod.
Ovs
1

Perl 6 ,  68  58 byte

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

Uji berdasarkan 0

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

Uji berdasarkan 1

Diperluas:

{  # 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
}
Brad Gilbert b2gills
sumber
1

Ruby , 43 38 byte

->x{9*(x%b=10**~-x.to_s.size)+x/b+b-1}

Cobalah online!

Awalnya port jawaban Python yang sangat baik oleh ovs, kemudian disederhanakan lagi.

GB
sumber
1

Java 8, 68 byte

n->{int b=(int)Math.pow(10,(n+"").length()-1);return~-b+n/b+n%b*9;}

Membosankan port jawaban Python 2 @ovs ' , jadi pastikan untuk mengungguli dia!
-1 byte terima kasih kepada @Jakob

Cobalah online.

Kevin Cruijssen
sumber
1

K4 , 38 byte

Larutan:

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

Contoh:

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

Penjelasan:

Solusi Port of Jonathan Allan saat saya kehabisan memori membangun akar digital dari 1 hingga 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

Bonus:

Terjemahan solusi ovs lebih sederhana tetapi lebih lama:

-1+b+/1 9*(_%;.q.mod).\:x,b:10 xexp#1_$x:
streetster
sumber
Secara eksplisit dinyatakan bahwa: "Kode secara teoritis harus bekerja untuk semua bilangan bulat hingga 10 ^ 9 " . Tampaknya ini bukan ...?
Stewie Griffin
Urgh. Maka saya akan menggunakan salah satu jawaban bonus karena saya kehabisan memori mencoba menghitung hingga 10e6 apalagi 10e9. Akan diperbaiki nanti.
streetster
0

Jelly , 19 byte

æḟ©ræċɗ⁵Ṗ%Þ-9⁸‘_®¤ị

Cobalah online!

-1 terima kasih kepada Tn. Xcoder . .

1-diindeks.

Erik the Outgolfer
sumber
0

J, 24 byte

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

Ini diam-diam ekspresi dibungkus dalam parens untuk menandakan bahwa itu harus diperlakukan sendiri bukan sebagai bagian dari ekspresi berikut (seperti argumen).

Ungkapan '] /:' pesanan (naik '/:') array asli ']' dengan jumlah '+ /' dari digit Ekspresi

". &> ":

mengonversi angka menjadi vektor karakter dengan '":', lalu menerapkan kebalikannya '".' - karakter ke nomor - diterapkan ke setiap item '&>'. Jadi, 65536 -> '65536' -> 6 5 5 3 6.

Sambungan daya '^:' di dekat akhir ekspresi menerapkan kode yang baru saja kami jelaskan (di sebelah kiri) beberapa kali. Dalam hal ini, jumlah waktu yang ditentukan adalah tak terhingga '_' yang berarti tetap menerapkan sampai hasilnya berhenti berubah.

'' 0 'akhir berarti menerapkan seluruh ekspresi di sebelah kiri untuk setiap item skalar (0-dimensi) di sebelah kanan, yang akan menjadi array angka yang ingin kita terapkan ini.

DevonMcC
sumber
Bagaimana Anda membuat daftar input? Saya menulis solusi dalam K tetapi setengah jawabannya menghasilkan daftar ...
streetster
Saya berasumsi daftar tersebut adalah input eksternal. Saya tidak melihat di mana membuat daftar adalah bagian dari masalah.
DevonMcC
" Ambil bilangan bulat positif n sebagai input , dan hasilkan angka ke- n dalam urutan yang dijelaskan di atas." Anda harus membuat urutan (atau menemukan cara untuk berkeliling menghasilkan urutan - lihat jawaban lain).
streetster
0

Elixir , 239 byte

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

Cobalah online!

Penjelasan masuk (perlahan)! Saya tidak berpikir ini bisa menjadi jauh lebih pendek dari ini, tetapi saya selalu terbuka untuk saran

Dave
sumber
0

Perl 5 -pF , 27 byte

$_=9x$#F+$_%10**$#F*9+$F[0]

Cobalah online!

Menggunakan formula @ ovs dan penjelasan @ JonathanAllen untuk menghasilkan potongan kode yang bagus.

Xcali
sumber